{"openapi":"3.0.3","info":{"title":"Tasks API - Unified Workflow & Task Management Service","version":"1.0.0","description":"\n# Tasks API\n\nA multi-tenant API for workflow and task management.\n\n## Quick Start\n\n1. Get your API key from organization settings\n2. Include in requests: `X-API-Key: your-key` or `Authorization: Bearer your-key`\n3. All endpoints under `/api/v1/` except webhooks and health\n\n## Core Concepts\n\n| Concept | Description |\n|---------|-------------|\n| **Organization** | Your tenant - all data is isolated |\n| **Project** | Container for tasks |\n| **Task** | Actionable work item with forms and attachments |\n| **Workflow** | Multi-stage business process from a template |\n| **Workflow Template** | Reusable workflow definition |\n\n## Authentication\n\n| Method | Header |\n|--------|--------|\n| API Key | `X-API-Key: your-key` |\n| Bearer | `Authorization: Bearer your-key` |\n| Portal Token | `X-Portal-Token: jwt-token` |\n\n## Pagination\n\nList endpoints accept:\n- `page` - Page number (default: 1)\n- `limit` - Items per page (default: 20, max: 100)\n\n## Error Format\n\n```json\n{\n  \"error\": {\n    \"code\": \"ERROR_CODE\",\n    \"message\": \"Human readable message\",\n    \"details\": {}\n  }\n}\n```\n\n## Status Codes\n\n| Code | Meaning |\n|------|---------|\n| 200 | Success |\n| 201 | Created |\n| 400 | Bad Request |\n| 401 | Unauthorized |\n| 404 | Not Found |\n| 422 | Business Logic Error |\n| 500 | Server Error |\n","termsOfService":"https://apart.tech/terms","contact":{"name":"Apart Technologies","url":"https://apart.tech","email":"support@apart.tech"},"license":{"name":"Proprietary","url":"https://apart.tech/license"}},"servers":[{"url":"https://tasks-prod-4itf6cgkyq-ew.a.run.app","description":"Production Server"},{"url":"https://tasks-staging-4itf6cgkyq-ew.a.run.app","description":"Staging Server"},{"url":"http://localhost:8080","description":"Development Server"}],"paths":{"/api/v1/workflow-templates/{templateId}/phases":{"get":{"tags":["Workflow Phases"],"summary":"List all phases for a workflow template","description":"Retrieve all phases configured for a specific workflow template","operationId":"listPhases","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"query","name":"includePortalConfigs","schema":{"type":"string","enum":["true","false"]},"description":"Include portal-specific configurations"},{"in":"query","name":"includeStageMappings","schema":{"type":"string","enum":["true","false"]},"description":"Include stage mappings for each phase"}],"responses":{"200":{"description":"Phases retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowPhase"}},"meta":{"type":"object","properties":{"total":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Workflow Phases"],"summary":"Create a new phase","description":"Create a new phase for a workflow template","operationId":"createPhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePhaseRequest"}}}},"responses":{"201":{"description":"Phase created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Phase already exists"}}}},"/api/v1/workflow-templates/{templateId}/phases/reorder":{"post":{"tags":["Workflow Phases"],"summary":"Reorder phases","description":"Reorder phases within a workflow template","operationId":"reorderPhases","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderPhasesRequest"}}}},"responses":{"200":{"description":"Phases reordered successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflow-templates/{templateId}/phases/{phaseCode}":{"get":{"tags":["Workflow Phases"],"summary":"Get a phase by code","description":"Retrieve a specific phase by its code","operationId":"getPhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"},{"in":"query","name":"includePortalConfigs","schema":{"type":"string","enum":["true","false"]},"description":"Include portal-specific configurations"},{"in":"query","name":"includeStageMappings","schema":{"type":"string","enum":["true","false"]},"description":"Include stage mappings"}],"responses":{"200":{"description":"Phase retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Workflow Phases"],"summary":"Update a phase","description":"Update an existing phase","operationId":"updatePhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePhaseRequest"}}}},"responses":{"200":{"description":"Phase updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Workflow Phases"],"summary":"Delete a phase","description":"Delete a phase and reorder remaining phases","operationId":"deletePhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"}],"responses":{"204":{"description":"Phase deleted successfully"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflow-templates/{templateId}/phases/{phaseCode}/stages":{"post":{"tags":["Workflow Phases"],"summary":"Add stages to a phase","description":"Add one or more stages to a phase","operationId":"addStagesToPhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddStagesToPhaseRequest"}}}},"responses":{"201":{"description":"Stages added successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Stage already mapped"}}}},"/api/v1/workflow-templates/{templateId}/phases/{phaseCode}/stages/{stageId}":{"patch":{"tags":["Workflow Phases"],"summary":"Update a stage mapping","description":"Update the configuration of a stage within a phase","operationId":"updateStageMapping","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"},{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stage ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStageMappingRequest"}}}},"responses":{"200":{"description":"Stage mapping updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Workflow Phases"],"summary":"Remove a stage from a phase","description":"Remove a stage mapping from a phase","operationId":"removeStageFromPhase","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"},{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Stage ID"}],"responses":{"204":{"description":"Stage removed successfully"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflow-templates/{templateId}/phases/{phaseCode}/portal-configs":{"get":{"tags":["Workflow Phases"],"summary":"Get portal configurations for a phase","description":"Retrieve all portal-specific configurations for a phase","operationId":"getPortalConfigs","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"}],"responses":{"200":{"description":"Portal configs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowPhasePortalConfig"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflow-templates/{templateId}/phases/{phaseCode}/portal-configs/{portalCode}":{"put":{"tags":["Workflow Phases"],"summary":"Set portal configuration for a phase","description":"Create or update portal-specific configuration for a phase","operationId":"setPortalConfig","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"},{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetPortalConfigRequest"}}}},"responses":{"200":{"description":"Portal config set successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPhase"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Workflow Phases"],"summary":"Remove portal configuration for a phase","description":"Remove portal-specific configuration from a phase","operationId":"removePortalConfig","parameters":[{"in":"path","name":"templateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code (kebab-case)"},{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code"}],"responses":{"204":{"description":"Portal config removed successfully"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflows/{workflowId}/phase-overrides":{"get":{"tags":["Instance Overrides"],"summary":"List instance overrides for a workflow","description":"Retrieve all per-instance phase customizations for a specific workflow","operationId":"listInstanceOverrides","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow instance ID"},{"in":"query","name":"portalCode","schema":{"type":"string"},"description":"Filter by portal code"}],"responses":{"200":{"description":"List of instance overrides","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowInstancePhaseOverride"}},"meta":{"type":"object","properties":{"total":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/workflows/{workflowId}/phase-overrides/{phaseCode}/{portalCode}":{"get":{"tags":["Instance Overrides"],"summary":"Get a specific instance override","description":"Retrieve phase customization for a specific workflow, phase, and portal","operationId":"getInstanceOverride","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow instance ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code"},{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code"}],"responses":{"200":{"description":"Instance override retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowInstancePhaseOverride"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Instance Overrides"],"summary":"Set instance override for a phase","description":"Create or update phase customization for a specific workflow instance","operationId":"setInstanceOverride","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow instance ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code"},{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetInstanceOverrideRequest"}}}},"responses":{"200":{"description":"Override set successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowInstancePhaseOverride"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Instance Overrides"],"summary":"Remove instance override for a phase","description":"Delete phase customization for a specific workflow instance","operationId":"removeInstanceOverride","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow instance ID"},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"},"description":"Phase code"},{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code"}],"responses":{"204":{"description":"Override removed successfully"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/organization/portal-view-configs":{"get":{"summary":"List all portal view configurations","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"List of portal view configurations","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortalViewConfigWithPortalCode"}},"meta":{"type":"object","properties":{"total":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/organization/portals/{portalCode}/view-config":{"get":{"summary":"Get portal view configuration","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code (e.g., customer_portal)"}],"responses":{"200":{"description":"Portal view configuration","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalViewConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create portal view configuration","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePortalViewConfigRequest"}}}},"responses":{"201":{"description":"Configuration created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalViewConfig"}}}}}},"400":{"description":"Invalid visibility rules","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Configuration already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"summary":"Update portal view configuration","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePortalViewConfigRequest"}}}},"responses":{"200":{"description":"Configuration updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalViewConfig"}}}}}},"400":{"description":"Invalid visibility rules","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete portal view configuration","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Configuration deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/organization/portals/{portalCode}/view-config/ensure":{"post":{"summary":"Get or create default portal view configuration","tags":["Portal View Configuration"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Portal view configuration (existing or newly created)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalViewConfig"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/portal/{portalCode}/config":{"get":{"summary":"Get portal configuration (public info)","description":"Returns public configuration for a portal (locale, summary settings)","tags":["Portal Views"],"security":[{"ApiKeyAuth":[]},{"PortalTokenAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"},"description":"Portal code (e.g., customer_portal)"}],"responses":{"200":{"description":"Portal configuration","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"defaultLocale":{"type":"string","example":"en-US"},"showSummaryOnly":{"type":"boolean"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/portal/{portalCode}/labels":{"get":{"summary":"Get entity labels for portal","description":"Returns translated entity type labels (Task, Project, etc.)","tags":["Portal Views"],"security":[{"ApiKeyAuth":[]},{"PortalTokenAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}},{"in":"query","name":"locale","schema":{"type":"string","pattern":"^[a-z]{2}-[A-Z]{2}$"},"description":"Locale code (e.g., de-DE)"}],"responses":{"200":{"description":"Entity labels","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":{"type":"string"},"example":{"TASK":"Action Item","PROJECT":"Engagement"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/portal/{portalCode}/workflows/{workflowId}":{"get":{"summary":"Get workflow view for portal","description":"Returns workflow with phases, translated names, and computed progress","tags":["Portal Views"],"security":[{"ApiKeyAuth":[]},{"PortalTokenAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}},{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"locale","schema":{"type":"string"}},{"in":"query","name":"includePhases","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Workflow portal view","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowPortalView"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Workflow not visible on this portal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/portal/{portalCode}/workflows/{workflowId}/phases":{"get":{"summary":"Get phases for portal","description":"Returns workflow phases with translated names and computed status","tags":["Portal Views"],"security":[{"ApiKeyAuth":[]},{"PortalTokenAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}},{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"locale","schema":{"type":"string"}}],"responses":{"200":{"description":"Phase list with progress","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PhasePortalView"}},"overallProgress":{"$ref":"#/components/schemas/OverallProgress"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/portal/{portalCode}/workflows/{workflowId}/phases/{phaseCode}":{"get":{"summary":"Get single phase for portal","description":"Returns a specific phase with full details","tags":["Portal Views"],"security":[{"ApiKeyAuth":[]},{"PortalTokenAuth":[]}],"parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string"}},{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"path","name":"phaseCode","required":true,"schema":{"type":"string"}},{"in":"query","name":"locale","schema":{"type":"string"}},{"in":"query","name":"includeVisibleTasks","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Phase portal view","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PhasePortalView"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Phase not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/organization/portals/{portalCode}/tokens":{"post":{"tags":["Portal Administration"],"summary":"Generate portal access token","description":"Generate a JWT token for external user portal access. Tokens expire in 30 days by default.","parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string","example":"customer_portal"},"description":"Portal code to generate token for"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalTokenRequest"}}}},"responses":{"201":{"description":"Token generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalTokenResponse"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validation_error":{"value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid email format"}}}}}}},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"portal_not_found":{"value":{"error":{"code":"PORTAL_NOT_FOUND","message":"Portal PROPERTY_OWNERS not found"}}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]}]},"get":{"tags":["Portal Administration"],"summary":"List portal tokens","description":"Retrieve all active tokens for a portal with usage and expiration information.","parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string","example":"customer_portal"},"description":"Portal code to list tokens for"},{"in":"query","name":"includeExpired","required":false,"schema":{"type":"boolean","default":false},"description":"Include expired tokens in results"}],"responses":{"200":{"description":"Tokens retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalTokenListResponse"}}}},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/api/v1/organization/portals/{portalCode}/tokens/{tokenId}":{"delete":{"tags":["Portal Administration"],"summary":"Revoke portal token","description":"Immediately revoke a portal access token. Returns 204 on success.","parameters":[{"in":"path","name":"portalCode","required":true,"schema":{"type":"string","example":"customer_portal"},"description":"Portal code"},{"in":"path","name":"tokenId","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440030"},"description":"ID of token to revoke"}],"responses":{"204":{"description":"Token revoked successfully"},"404":{"description":"Token or portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"ApiKeyAuth":[]}]}},"/api/v1/portal/profile":{"get":{"tags":["Portal Access"],"summary":"Get portal user profile","description":"Retrieve portal user profile including permissions, token info, and visibility counts.","responses":{"200":{"description":"Profile retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalProfile"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"token_missing":{"value":{"error":{"code":"PORTAL_TOKEN_MISSING","message":"Portal authentication required"}}},"token_invalid":{"value":{"error":{"code":"PORTAL_TOKEN_INVALID","message":"Invalid portal token"}}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks":{"get":{"tags":["Portal Access"],"summary":"List visible tasks","description":"Retrieve tasks visible to the portal user, filtered by visibility rules. Supports status and search filters.","parameters":[{"in":"query","name":"page","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination","example":1},{"in":"query","name":"pageSize","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of tasks per page (max 100)","example":20},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["PENDING","TODO","IN_PROGRESS","BLOCKED","COMPLETED","CANCELLED"]},"description":"Filter by task status","example":"TODO"},{"in":"query","name":"search","required":false,"schema":{"type":"string"},"description":"Search tasks by title or description (case-insensitive)","example":"inspection"}],"responses":{"200":{"description":"Tasks retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortalTask"}},"total":{"type":"integer","description":"Total number of visible tasks","example":42},"page":{"type":"integer","description":"Current page number","example":1},"pageSize":{"type":"integer","description":"Number of items per page","example":20},"totalPages":{"type":"integer","description":"Total number of pages","example":3}}},"examples":{"success":{"summary":"Successful response with tasks","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440001","title":"Schedule property inspection","description":"Quarterly inspection for unit 203","status":"TODO","priority":"HIGH","project":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Q1 Property Maintenance","status":"ACTIVE"},"dueDate":"2024-02-15T10:00:00Z","createdAt":"2024-01-15T10:30:00Z"}],"total":42,"page":1,"pageSize":20,"totalPages":3}},"no_tasks":{"summary":"No tasks visible","value":{"data":[],"total":0,"message":"No tasks visible to this portal user"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]},"post":{"tags":["Portal Access"],"summary":"Create a new task","description":"Create a task in a visible project.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalTaskCreateRequest"}}}},"responses":{"201":{"description":"Task created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalTask"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Portal authentication required"},"403":{"description":"Not allowed to create tasks in this project"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks/{id}":{"get":{"tags":["Portal Access"],"summary":"Get specific task","description":"Retrieve task details. Task must be visible to the portal user.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"description":"Task ID"}],"responses":{"200":{"description":"Task retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalTask"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]},"put":{"tags":["Portal Access"],"summary":"Update a task","description":"Update task details. Task must be visible to the portal user.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Task ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalTaskUpdateRequest"}}}},"responses":{"200":{"description":"Task updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalTask"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Portal authentication required"},"403":{"description":"Not allowed to update this task"},"404":{"description":"Task not found or not visible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks/{id}/comment":{"post":{"tags":["Portal Access"],"summary":"Add comment to task","description":"Add a comment to a visible task. Cannot comment on completed or cancelled tasks.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Task ID","example":"550e8400-e29b-41d4-a716-446655440001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","minLength":1,"maxLength":2000,"description":"Comment text content","example":"I can schedule the inspection for next Tuesday morning at 10 AM."}}},"examples":{"schedule_response":{"summary":"Scheduling response","value":{"content":"I can schedule the inspection for next Tuesday morning at 10 AM."}},"status_update":{"summary":"Status update","value":{"content":"All preparations are complete. Ready for final review."}}}}}},"responses":{"201":{"description":"Comment added successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalComment"},"message":{"type":"string","example":"Comment added successfully"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks/{id}/complete":{"post":{"tags":["Portal Access"],"summary":"Complete task","description":"Mark a task as completed with optional notes. Task must be visible and allow portal completion.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"description":"Task ID"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCompletionRequest"}}}},"responses":{"200":{"description":"Task completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalTask"},"message":{"type":"string","example":"Task completed successfully"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks/{id}/comments":{"get":{"tags":["Portal Access"],"summary":"Get task comments","description":"Retrieve all comments for a visible task.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"},"description":"Task ID"}],"responses":{"200":{"description":"Comments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortalComment"}},"total":{"type":"integer","example":3}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found or not visible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/comments/{id}":{"put":{"tags":["Portal Access"],"summary":"Update comment","description":"Update own comment. Users can only edit comments they created.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440050"},"description":"Comment ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentUpdateRequest"}}}},"responses":{"200":{"description":"Comment updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalComment"},"message":{"type":"string","example":"Comment updated successfully"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Cannot edit comment not owned by user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"not_owned":{"value":{"error":{"code":"COMMENT_NOT_OWNED","message":"You can only edit your own comments"}}}}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]},"delete":{"tags":["Portal Access"],"summary":"Delete comment","description":"Delete own comment. Users can only delete comments they created.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440050"},"description":"Comment ID"}],"responses":{"200":{"description":"Comment deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Comment deleted successfully"}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Cannot delete comment not owned by user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/projects":{"get":{"tags":["Portal Access"],"summary":"List visible projects","description":"Retrieve visible projects with task/section counts. Maximum page size is 50.","parameters":[{"in":"query","name":"page","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination","example":1},{"in":"query","name":"pageSize","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"description":"Number of projects per page (max 50)","example":20}],"responses":{"200":{"description":"Projects retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortalProject"}},"total":{"type":"integer","description":"Total number of visible projects","example":3},"page":{"type":"integer","description":"Current page number","example":1},"pageSize":{"type":"integer","description":"Number of items per page","example":20},"totalPages":{"type":"integer","description":"Total number of pages","example":1}}},"examples":{"with_projects":{"summary":"Projects with task counts","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Q1 2024 Property Maintenance","description":"Quarterly maintenance for all properties","status":"ACTIVE","_count":{"tasks":15,"sections":3},"createdAt":"2024-01-01T00:00:00Z"}],"total":3,"page":1,"pageSize":20,"totalPages":1}}}}}},"401":{"description":"Portal authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"PortalTokenAuth":[]}]},"post":{"tags":["Portal Access"],"summary":"Create a new project","description":"Create a new project.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalProjectCreateRequest"}}}},"responses":{"201":{"description":"Project created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalProject"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Portal authentication required"},"403":{"description":"Not allowed to create projects"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/projects/{id}":{"get":{"tags":["Portal Access"],"summary":"Get project details","description":"Retrieve project details. Project must be visible to the portal user.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Project ID"}],"responses":{"200":{"description":"Project retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalProject"}}}}}},"401":{"description":"Portal authentication required"},"404":{"description":"Project not found or not visible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/workflows":{"get":{"tags":["Portal Access"],"summary":"List visible workflows","description":"Retrieve visible workflows with stage counts, ordered by creation date (newest first).","parameters":[{"in":"query","name":"page","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination","example":1},{"in":"query","name":"pageSize","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of workflows per page","example":20},{"in":"query","name":"status","required":false,"schema":{"type":"string","enum":["PENDING","ACTIVE","PAUSED","COMPLETED","CANCELLED"]},"description":"Filter by workflow status","example":"ACTIVE"}],"responses":{"200":{"description":"Workflows retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PortalWorkflow"}},"total":{"type":"integer","description":"Total number of visible workflows","example":5},"page":{"type":"integer","description":"Current page number","example":1},"pageSize":{"type":"integer","description":"Number of items per page","example":20},"totalPages":{"type":"integer","description":"Total number of pages","example":1}}},"examples":{"active_workflows":{"summary":"Active workflows","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440200","name":"Lease Renewal Process - Unit 203","status":"ACTIVE","_count":{"workflow_stages":5},"created_at":"2024-01-15T10:30:00Z"}],"total":5,"page":1,"pageSize":20,"totalPages":1}}}}}},"401":{"description":"Portal authentication required"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]},"post":{"tags":["Portal Access"],"summary":"Create workflow from template","description":"Create a new workflow instance from an available template.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalWorkflowCreateRequest"}}}},"responses":{"201":{"description":"Workflow created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalWorkflow"}}}}}},"400":{"description":"Invalid request"},"401":{"description":"Portal authentication required"},"403":{"description":"Not allowed to create workflows"},"404":{"description":"Template not found"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/workflows/{id}":{"get":{"tags":["Portal Access"],"summary":"Get workflow details","description":"Retrieve workflow details including stages and tasks. Workflow must be visible to the portal user.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow ID"}],"responses":{"200":{"description":"Workflow retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalWorkflow"}}}}}},"401":{"description":"Portal authentication required"},"404":{"description":"Workflow not found or not visible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/workflow-templates":{"get":{"tags":["Portal Access"],"summary":"List available workflow templates","description":"Retrieve active workflow templates, ordered alphabetically by name.","responses":{"200":{"description":"Templates retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440100"},"name":{"type":"string","example":"Standard Lease Renewal"},"description":{"type":"string","example":"Template for processing lease renewals"},"category":{"type":"string","example":"LEASE_MANAGEMENT"},"_count":{"type":"object","properties":{"workflow_template_stages":{"type":"integer","example":5}}}}}}}},"examples":{"templates":{"summary":"Available templates","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440100","name":"Standard Lease Renewal","description":"Template for processing lease renewals","category":"LEASE_MANAGEMENT","_count":{"workflow_template_stages":5}}]}}}}}},"401":{"description":"Portal authentication required"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/tasks/{id}/attachments":{"post":{"tags":["Portal Access"],"summary":"Upload attachment to task","description":"Upload a file attachment to a visible task. Maximum file size is 100MB.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Task ID"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"File to upload"},"description":{"type":"string","description":"Optional description of the attachment"}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Attachment"}}}}}},"400":{"description":"Invalid file or exceeds size limit"},"401":{"description":"Portal authentication required"},"404":{"description":"Task not found or not visible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]},"get":{"tags":["Portal Access"],"summary":"List task attachments","description":"Retrieve all attachments for a visible task.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Task ID"}],"responses":{"200":{"description":"Attachments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Attachment"}}}}}}},"401":{"description":"Portal authentication required"},"404":{"description":"Task not found or not visible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/portal/attachments/{id}/download":{"get":{"tags":["Portal Access"],"summary":"Download attachment","description":"Download a file attachment. The attachment's task must be visible to the portal user.","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID"}],"responses":{"200":{"description":"File download successful","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Portal authentication required"},"404":{"description":"Attachment not found or not accessible"},"500":{"description":"Internal server error"}},"security":[{"PortalTokenAuth":[]}]}},"/api/v1/assignee-resolutions/pending":{"get":{"tags":["Assignee Resolutions"],"summary":"List pending assignee resolutions","description":"Retrieves pending resolutions requiring manual selection from multiple position options","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"taskId","schema":{"type":"string","format":"uuid"}},{"in":"query","name":"roleId","schema":{"type":"string"}},{"in":"query","name":"entityId","schema":{"type":"string"}},{"in":"query","name":"createdAfter","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"createdBefore","schema":{"type":"string","format":"date-time"}},{"in":"query","name":"resolved","schema":{"type":"boolean"}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"default":0}},{"in":"query","name":"orderBy","schema":{"type":"string","enum":["created_at","resolved_at"],"default":"created_at"}},{"in":"query","name":"orderDirection","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"List retrieved successfully"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}}}},"/api/v1/assignee-resolutions/{id}":{"get":{"tags":["Assignee Resolutions"],"summary":"Get pending resolution by ID","description":"Retrieves a specific pending resolution with task details and available positions","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resolution ID"}],"responses":{"200":{"description":"Resolution retrieved successfully"},"401":{"description":"Unauthorized"},"404":{"description":"Resolution not found"},"500":{"description":"Internal server error"}}},"delete":{"tags":["Assignee Resolutions"],"summary":"Cancel pending resolution","description":"Cancels a pending resolution and marks the task as requiring manual assignment","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resolution ID"}],"responses":{"200":{"description":"Resolution cancelled successfully"},"401":{"description":"Unauthorized"},"404":{"description":"Resolution not found or already resolved"},"500":{"description":"Internal server error"}}}},"/api/v1/assignee-resolutions/{id}/resolve":{"post":{"tags":["Assignee Resolutions"],"summary":"Resolve pending assignment","description":"Manually resolve a pending assignment by selecting a position from available options","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Resolution ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["positionId"],"properties":{"positionId":{"type":"string","description":"Selected position ID"},"reason":{"type":"string","maxLength":1000,"description":"Optional reason for manual resolution"}}}}}},"responses":{"200":{"description":"Resolution completed successfully"},"400":{"description":"Invalid request or resolution failed"},"401":{"description":"Unauthorized"},"404":{"description":"Resolution not found"},"500":{"description":"Internal server error"}}}},"/api/v1/assignee-resolutions/stats":{"get":{"tags":["Assignee Resolutions"],"summary":"Get resolution statistics","description":"Retrieves statistics on assignee resolutions including success rates and pending counts","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"startDate","schema":{"type":"string","format":"date-time"},"description":"Filter statistics from this date"},{"in":"query","name":"endDate","schema":{"type":"string","format":"date-time"},"description":"Filter statistics until this date"},{"in":"query","name":"assigneeType","schema":{"type":"string","enum":["USER","POSITION","ROLE"]},"description":"Filter by assignee type"}],"responses":{"200":{"description":"Statistics retrieved successfully"},"401":{"description":"Unauthorized"},"500":{"description":"Internal server error"}}}},"/api/v1/assignment-type-resolvers":{"get":{"summary":"List assignment type resolvers","description":"Get all configured assignment type resolvers for the organization.\nResolvers define how ROLE, POSITION, and USER assignments are resolved to actual assignees.\n\n## Multi-Resolver Support\nOrganizations can have multiple resolvers per assignment type, each targeting\nspecific role identifiers. For example:\n- \"Letting Officer\" role → resolves to POSITION (internal employee)\n- \"Applicant\" role → resolves to USER (external user)\n\n## Business Use Cases\n- View all configured resolution rules for your organization\n- Filter by specific assignment types (e.g., only ROLE resolvers)\n- Find resolvers with custom Context Operations\n- Filter by specific role identifiers\n- Find default resolvers vs specific identifier resolvers\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"assignmentTypes","schema":{"type":"string","example":"ROLE,POSITION"},"description":"Comma-separated list of assignment types to filter by"},{"in":"query","name":"hasResolutionOperation","schema":{"type":"boolean"},"description":"Filter resolvers that have (true) or don't have (false) custom operations"},{"in":"query","name":"assignmentIdentifier","schema":{"type":"string","maxLength":100,"example":"Applicant"},"description":"Filter by specific role identifier (e.g., \"Applicant\", \"Letting Officer\")"},{"in":"query","name":"resolutionTargetType","schema":{"type":"string","enum":["ROLE","POSITION","USER"],"example":"USER"},"description":"Filter by resolution target type (what the resolver outputs)"},{"in":"query","name":"isDefault","schema":{"type":"boolean"},"description":"Filter default resolvers (true) or specific identifier resolvers (false)"}],"responses":{"200":{"description":"List of resolvers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}}},"401":{"description":"Unauthorized - Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/assignment-type-resolvers/{assignmentType}":{"get":{"summary":"Get assignment type resolver","description":"Get the resolver configuration for a specific assignment type.\n\n## Business Use Cases\n- Check how ROLE assignments are resolved (e.g., which API or operation is used)\n- View multi-match behavior settings\n- Audit resolver configurations\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type (ROLE, POSITION, or USER)"}],"responses":{"200":{"description":"Resolver configuration","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}},"400":{"description":"Invalid assignment type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resolver not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"value":{"error":{"code":"ASSIGNMENT_RESOLVER_NOT_FOUND","message":"No resolver configured for assignment type ROLE"}}}}}}}}},"post":{"summary":"Create or update assignment type resolver","description":"Create a new resolver or update an existing one for a specific assignment type.\n\n## Business Use Cases\n- Configure how ROLE assignments should be resolved (e.g., via Apart API)\n- Set multi-match behavior (take first, manual selection, or fail)\n- Link to custom Context Operations for advanced resolution logic\n- Update existing resolver settings\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type to configure"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssignmentTypeResolverRequest"},"examples":{"basicRole":{"summary":"Basic ROLE resolver with Apart API","value":{"multiMatchBehavior":"FIRST"}},"customOperation":{"summary":"Custom Context Operation resolver","value":{"resolutionOperationId":"550e8400-e29b-41d4-a716-446655440003","multiMatchBehavior":"PENDING_MANUAL","parameterConfig":{"parameters":{"entityId":{"source":"entity","entityField":"entityId"}}},"responseMapping":{"assigneeId":"data.id","assigneeType":"data.type"}}}}}}},"responses":{"201":{"description":"Resolver created or updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"summary":"Update assignment type resolver","description":"Update an existing resolver configuration for a specific assignment type.\nReturns 404 if the resolver does not exist. Use POST to create or update.\n\n## Business Use Cases\n- Modify multi-match behavior for existing resolver\n- Update Context Operation linkage\n- Adjust parameter mappings\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type to update"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAssignmentTypeResolverRequest"}}}},"responses":{"200":{"description":"Resolver updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resolver not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete assignment type resolver","description":"Remove the resolver configuration for a specific assignment type.\nAfter deletion, that assignment type will return NO_RESOLVER status when resolution is attempted.\n\n## Business Use Cases\n- Remove unused resolver configurations\n- Reset to default behavior for an assignment type\n- Clean up test configurations\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type to delete"}],"responses":{"204":{"description":"Resolver deleted successfully"},"400":{"description":"Invalid assignment type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resolver not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/assignment-type-resolvers/preview":{"post":{"summary":"Preview assignment resolution","description":"Test assignment resolution without making permanent changes.\nUse this to validate resolver configurations and see how assignments would be resolved.\n\n## Business Use Cases\n- Test ROLE resolution before configuring workflows\n- Verify how multi-match scenarios are handled\n- Debug assignment resolution issues\n- See which positions would be returned for a given role\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewResolutionRequest"},"examples":{"roleResolution":{"summary":"Test ROLE resolution","value":{"assignmentType":"ROLE","assignmentId":"property_manager","entityType":"property","entityId":"prop-123"}},"positionDirect":{"summary":"Test direct POSITION","value":{"assignmentType":"POSITION","assignmentId":"position-456"}},"userDirect":{"summary":"Test direct USER","value":{"assignmentType":"USER","assignmentId":"user-789"}}}}}},"responses":{"200":{"description":"Resolution result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentResolutionResult"}}},"examples":{"resolved":{"summary":"Successfully resolved to a position","value":{"data":{"status":"RESOLVED","assigneeType":"POSITION","assigneeId":"position-123","assigneeName":"John Doe - Property Manager","resolvedFrom":{"source":"apart_api","entityType":"property","entityId":"prop-123","timestamp":"2025-01-15T10:30:00.000Z"},"resolutionLog":{"executionTimeMs":245}}}},"pendingManual":{"summary":"Multiple matches require manual selection","value":{"data":{"status":"PENDING_MANUAL","positions":[{"contactId":"contact-1","positionId":"position-1","businessRole":"property_manager","name":"John Doe","email":"john@example.com"},{"contactId":"contact-2","positionId":"position-2","businessRole":"property_manager","name":"Jane Smith","email":"jane@example.com"}]}}},"noResolver":{"summary":"No resolver configured","value":{"data":{"status":"NO_RESOLVER","error":{"code":"NO_RESOLVER_CONFIGURED","message":"No resolver configured for assignment type ROLE"}}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/assignment-type-resolvers/{assignmentType}/{identifier}":{"get":{"summary":"Get resolver by identifier","description":"Get the resolver configuration for a specific assignment type and identifier combination.\n\n## Multi-Resolver Support\nDifferent identifiers can have different resolvers. For example:\n- ROLE \"Letting Officer\" → POSITION resolver (internal employees)\n- ROLE \"Applicant\" → USER resolver (external users via Context Operation)\n\n## Lookup Order\n1. Exact match on (organization, assignmentType, identifier)\n2. If not found, returns 404\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type (ROLE, POSITION, or USER)"},{"in":"path","name":"identifier","required":true,"schema":{"type":"string","maxLength":100},"description":"The specific identifier (e.g., \"Applicant\", \"Letting Officer\")"}],"responses":{"200":{"description":"Resolver configuration","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}},"400":{"description":"Invalid assignment type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resolver not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"summary":"Create or update resolver with identifier","description":"Create a new resolver or update an existing one for a specific assignment type\nand identifier combination.\n\n## Multi-Resolver Configuration\nUse this to configure different resolution strategies for different roles:\n\n**Internal Employee (Letting Officer)**:\n```json\n{\n  \"resolutionTargetType\": \"POSITION\",\n  \"isDefault\": false,\n  \"priority\": 100,\n  \"multiMatchBehavior\": \"FIRST\"\n}\n```\n\n**External User (Applicant)**:\n```json\n{\n  \"resolutionTargetType\": \"USER\",\n  \"isDefault\": false,\n  \"priority\": 100,\n  \"resolutionOperationId\": \"operation-uuid\",\n  \"responseMapping\": {\n    \"assigneeId\": \"data.userId\",\n    \"assigneeName\": \"data.applicantName\"\n  }\n}\n```\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type to configure"},{"in":"path","name":"identifier","required":true,"schema":{"type":"string","maxLength":100},"description":"The specific identifier (e.g., \"Applicant\", \"Letting Officer\")"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAssignmentTypeResolverRequest"},"examples":{"externalUser":{"summary":"External user resolver (e.g., Applicant)","value":{"resolutionTargetType":"USER","isDefault":false,"priority":100,"resolutionOperationId":"550e8400-e29b-41d4-a716-446655440003","parameterConfig":{"parameters":{"applicationId":{"source":"context","contextPath":"workflow.applicationId"}}},"responseMapping":{"assigneeId":"data.userId","assigneeName":"data.applicantName"}}},"internalEmployee":{"summary":"Internal employee resolver (default ROLE)","value":{"resolutionTargetType":"POSITION","isDefault":false,"priority":50,"multiMatchBehavior":"FIRST"}}}}}},"responses":{"201":{"description":"Resolver created or updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AssignmentTypeResolverConfig"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete resolver by identifier","description":"Remove the resolver configuration for a specific assignment type and identifier.\nAfter deletion, resolution requests for this identifier will fall back to the\ndefault resolver (if configured) or return NO_RESOLVER status.\n","tags":["Assignment Resolution"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"assignmentType","required":true,"schema":{"$ref":"#/components/schemas/AssignmentType"},"description":"The assignment type"},{"in":"path","name":"identifier","required":true,"schema":{"type":"string","maxLength":100},"description":"The specific identifier to delete"}],"responses":{"204":{"description":"Resolver deleted successfully"},"400":{"description":"Invalid assignment type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Resolver not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/projects/attachments/summary":{"get":{"tags":["Projects","Attachments"],"summary":"Get attachment summary for multiple projects","description":"Get attachment statistics summary across multiple projects for the authenticated organization.\nProvides aggregate statistics and per-project breakdown.\n\n**Use Cases:**\n- Organization-wide storage reporting\n- Project comparison dashboards\n- Capacity planning and analysis\n- Administrative overview interfaces\n\n**Statistics Included:**\n- Per-project attachment counts and file sizes\n- Aggregate totals across all projects\n- Average attachments per project\n- Latest attachment dates\n\n**Performance:** Optimized for large organizations with many projects\n","operationId":"getProjectAttachmentsSummary","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"projectIds","schema":{"type":"array","items":{"type":"string","format":"uuid"}},"style":"form","explode":false,"description":"Specific project IDs to include (comma-separated). If not provided, includes all projects.","example":"project1-uuid,project2-uuid"},{"in":"query","name":"includeEmpty","schema":{"type":"boolean"},"description":"Include projects with zero attachments in results","example":false}],"responses":{"200":{"description":"Project attachment summary retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentSummaryResponse"}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/attachments/summary":{"get":{"tags":["Tasks","Attachments"],"summary":"Get attachment summary for multiple tasks","description":"Get attachment statistics summary across multiple tasks for the authenticated organization.\nProvides aggregate statistics and per-task breakdown with project context.\n\n**Use Cases:**\n- Team productivity reporting\n- Task completion analysis\n- Storage usage by task\n- Project-level task attachment overview\n\n**Statistics Included:**\n- Per-task attachment counts and file sizes\n- Aggregate totals across all tasks\n- Average attachments per task\n- Project context for each task\n- Latest attachment dates\n\n**Performance:** Optimized for large organizations with many tasks\n","operationId":"getTaskAttachmentsSummary","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"taskIds","schema":{"type":"array","items":{"type":"string","format":"uuid"}},"style":"form","explode":false,"description":"Specific task IDs to include (comma-separated). If not provided, includes all tasks.","example":"task1-uuid,task2-uuid"},{"in":"query","name":"projectId","schema":{"type":"string","format":"uuid"},"description":"Filter tasks by project ID","example":"project-uuid"},{"in":"query","name":"includeEmpty","schema":{"type":"boolean"},"description":"Include tasks with zero attachments in results","example":false}],"responses":{"200":{"description":"Task attachment summary retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentSummaryResponse"}}}}}},"400":{"description":"Bad Request - Invalid project filter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/attachments":{"post":{"operationId":"uploadAttachment","summary":"Upload file attachment to entity","description":"Upload files to projects, tasks, comments, or workflows. Files are securely stored in Google Cloud Storage with organization-scoped isolation.\nSupports files up to 100MB with virus scanning and automatic event publishing.\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file","targetType","targetId"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload (max 100MB)"},"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Type of entity the attachment belongs to","example":"task"},"targetId":{"type":"string","format":"uuid","description":"ID of the target entity","example":"123e4567-e89b-12d3-a456-426614174000"},"externalDocumentId":{"type":"string","description":"External document identifier for integration tracking","example":"EXT-DOC-12345"},"public":{"type":"boolean","description":"Whether to make the file publicly accessible (no authentication required)","default":false,"example":false}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"operationId":"getAttachments","summary":"List attachments with filtering","description":"Retrieve paginated attachments with filtering by entity, type, and MIME type. Optionally include signed download URLs.","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"targetType","schema":{"type":"string","enum":["project","task","workflow","comment"]},"description":"Filter by target entity type","example":"project"},{"in":"query","name":"targetId","schema":{"type":"string","format":"uuid"},"description":"Filter by target entity ID","example":"123e4567-e89b-12d3-a456-426614174000"},{"in":"query","name":"mimeType","schema":{"type":"string"},"description":"Filter by MIME type (partial match)","example":"application/pdf"},{"in":"query","name":"includeDownloadUrls","schema":{"type":"boolean","default":false},"description":"Include signed download URLs (valid for 15 minutes)"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"List of attachments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentListResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/attachments/upload-url":{"post":{"operationId":"requestUploadUrl","summary":"Request presigned URL for direct upload","description":"Generate a presigned URL for direct file upload to Google Cloud Storage.\nThis bypasses the API server for the actual file transfer, enabling uploads\nlarger than serverless function limits (e.g., Vercel's 4.5MB limit).\n\n## Flow\n1. Call this endpoint to get a presigned upload URL\n2. Upload file directly to GCS using the returned URL and headers\n3. Call `/attachments/confirm-upload` to create the database record\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestUploadUrlRequest"}}}},"responses":{"200":{"description":"Presigned upload URL generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestUploadUrlResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/attachments/confirm-upload":{"post":{"operationId":"confirmUpload","summary":"Confirm upload and create attachment record","description":"Confirm that a file has been uploaded via presigned URL and create the database record.\nCall this endpoint after successfully uploading a file directly to GCS.\n\nThe endpoint verifies the file exists in storage before creating the record.\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmUploadRequest"}}}},"responses":{"201":{"description":"Attachment record created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/attachments/{id}":{"get":{"operationId":"getAttachmentById","summary":"Get attachment details","description":"Retrieve attachment metadata with a 15-minute signed download URL. All access is organization-scoped and logged.","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"Attachment details with signed download URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"operationId":"updateAttachment","summary":"Update attachment metadata","description":"Update attachment metadata fields (e.g., external document ID). File content is immutable - upload a new file to replace content.","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID","example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAttachmentRequest"}}}},"responses":{"200":{"description":"Attachment updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"operationId":"deleteAttachment","summary":"Delete attachment","description":"Permanently delete attachment from both database and cloud storage. This action cannot be undone.","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"204":{"description":"Attachment deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/attachments/{id}/download":{"get":{"operationId":"downloadAttachment","summary":"Download attachment file","description":"Securely download attachment with rate limiting, quota enforcement, and audit logging. Redirects to a 24-hour signed URL.","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID","example":"123e4567-e89b-12d3-a456-426614174000"},{"in":"query","name":"variant","schema":{"type":"string","enum":["thumbnail","small","medium","large"]},"description":"Request a specific image variant size"},{"in":"query","name":"format","schema":{"type":"string","enum":["webp","jpeg"],"default":"webp"},"description":"Image variant format (default webp)"}],"responses":{"202":{"description":"Variant is still being processed (retry after delay)"},"302":{"description":"Redirect to signed download URL"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFoundError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/api/v1/attachments/{id}/download-url":{"get":{"operationId":"generateDownloadUrl","summary":"Generate signed download URL with custom expiration","description":"Generate a time-limited signed URL for direct file access with configurable expiration.\nPerfect for embedding download links in emails or external applications.\n\n## Business Logic\n\nProvides flexible URL generation for various integration scenarios:\n- **Custom Expiration**: 1 minute to 24 hours (configurable per request)\n- **Security Validation**: Same comprehensive checks as direct download\n- **URL Structure**: Direct Google Cloud Storage signed URLs\n- **No Redirect**: Returns URL in JSON response for programmatic use\n\n## Use Cases\n\n### Email Integration\n```\nGET /api/v1/attachments/123/download-url?expiresInMinutes=60\n```\nGenerate 1-hour URLs for email attachments\n\n### Frontend Applications\n```\nGET /api/v1/attachments/456/download-url?expiresInMinutes=15\n```\nShort-lived URLs for immediate use in web applications\n\n### API Integration\n```\nGET /api/v1/attachments/789/download-url?expiresInMinutes=1440\n```\nLong-lived URLs for batch processing systems\n\n## Security Considerations\n\n- **Shorter Expiration**: More secure but requires frequent regeneration\n- **Longer Expiration**: More convenient but higher security risk\n- **URL Sharing**: URLs can be shared but expire automatically\n- **Organization Scoping**: URLs only work within organization context\n\n## Response Format\n\nReturns JSON with signed URL and ISO 8601 expiration timestamp\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID"},{"in":"query","name":"expiresInMinutes","schema":{"type":"integer","minimum":1,"maximum":1440},"description":"URL expiration time in minutes (default 15, max 24 hours)"},{"in":"query","name":"variant","schema":{"type":"string","enum":["thumbnail","small","medium","large"]},"description":"Request a specific image variant size"},{"in":"query","name":"format","schema":{"type":"string","enum":["webp","jpeg"],"default":"webp"},"description":"Image variant format (default webp)"}],"responses":{"200":{"description":"Signed download URL","content":{"application/json":{"schema":{"type":"object","properties":{"downloadUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"string","format":"date-time"},"variant":{"type":"string"},"format":{"type":"string"}}}}}}}}},"/api/v1/attachments/{id}/stream":{"get":{"operationId":"streamAttachment","summary":"Stream file content with HTTP range support","description":"Stream file content directly through the API server with support for HTTP range requests.\nPerfect for media playback, large file downloads, and progressive loading.\n\n## Business Logic\n\nProvides efficient file streaming with advanced features:\n- **Range Requests**: HTTP 206 partial content support for large files\n- **Direct Streaming**: No intermediate storage or temp files\n- **Security Integration**: Same validation as download endpoints\n- **Bandwidth Management**: Configurable transfer rate limits\n\n## Use Cases\n\n### Media Playback\n- Stream video and audio files with range request support\n- Enable scrubbing and seeking in media players\n- Progressive download for large media files\n\n### Large File Downloads\n- Resume interrupted downloads with range requests\n- Parallel download segments for faster transfer\n- Bandwidth-limited environments\n\n### Document Viewing\n- Progressive loading of large PDF documents\n- Streaming access for document viewers\n- Memory-efficient file access\n\n## Technical Features\n\n- **HTTP 206 Support**: Partial content responses\n- **Content-Length**: Accurate file size headers\n- **MIME Type Detection**: Automatic content type headers\n- **ETag Support**: Caching and conditional requests\n\n## Performance Characteristics\n\n- **Memory Efficient**: Streams directly from storage\n- **Bandwidth Aware**: Respects client connection limits\n- **Cache Friendly**: Proper HTTP caching headers\n- **Resume Support**: Broken download recovery\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID"},{"in":"header","name":"Range","schema":{"type":"string"},"description":"Byte range for partial download"}],"responses":{"200":{"description":"File content stream"},"206":{"description":"Partial content (range request)"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/attachments/{id}/preview":{"get":{"operationId":"previewAttachment","summary":"Generate file preview, thumbnail, or text extraction","description":"Generate previews, thumbnails, or text extracts for supported file types.\nPerfect for file browsers, document management, and quick content inspection.\n\n## Business Logic\n\nIntelligent preview generation based on file type:\n- **Image Files**: Generate thumbnails in small/medium/large sizes\n- **PDF Documents**: Extract first page as JPEG thumbnail\n- **Text Documents**: Extract first 1000 characters with metadata\n- **Unsupported Files**: Return error with supported format list\n\n## Use Cases\n\n### File Browser Interface\n```\nGET /api/v1/attachments/123/preview?size=medium\n```\nGenerate medium-sized thumbnails for grid view\n\n### Document Management\n```\nGET /api/v1/attachments/456/preview\n```\nExtract text preview for document search indexing\n\n### Real Estate Listings\n```\nGET /api/v1/attachments/789/preview?size=large\n```\nHigh-quality property photo thumbnails\n\n## Supported File Types\n\n### Images (Thumbnail Generation)\n- JPEG, PNG, GIF, WebP, TIFF\n- SVG (converted to raster format)\n- RAW formats (with conversion)\n\n### Documents (Text Extraction)\n- PDF (first page + text content)\n- Microsoft Office (Word, Excel, PowerPoint)\n- OpenDocument formats\n- Plain text files\n\n### Unsupported\n- Video files (use streaming endpoint)\n- Audio files (metadata only)\n- Archives and compressed files\n\n## Performance Features\n\n- **Caching**: 1-hour cache headers for generated previews\n- **Lazy Generation**: Previews generated on-demand\n- **Size Optimization**: Efficient compression and sizing\n- **Rate Limiting**: Lighter limits for preview requests\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID"},{"in":"query","name":"size","schema":{"type":"string","enum":["small","medium","large"]},"description":"Preview size for images"}],"responses":{"200":{"description":"Preview content","content":{"image/*":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"metadata":{"type":"object"}}}}}}}}},"/api/v1/attachments/{id}/access-log":{"get":{"operationId":"getAttachmentAccessLog","summary":"Retrieve comprehensive download audit log","description":"Get detailed audit log of all access attempts for a specific attachment.\nIncludes successful downloads, failed attempts, and security events.\n\n## Business Logic\n\nProvides complete access history for compliance and security:\n- **All Access Types**: Downloads, streams, previews, and URL generation\n- **Success/Failure Tracking**: Both successful and blocked attempts\n- **User Attribution**: User ID, name, and role information\n- **Network Context**: IP addresses, user agents, and geographic data\n- **Security Events**: Rate limiting, quota violations, suspicious activity\n\n## Use Cases\n\n### Compliance Reporting\n- Generate access reports for regulatory audits\n- Track sensitive document access patterns\n- Demonstrate data governance controls\n\n### Security Investigation\n- Investigate suspicious file access patterns\n- Track potential data breaches or leaks\n- Identify compromised user accounts\n\n### Usage Analytics\n- Understand file usage patterns\n- Identify frequently accessed documents\n- Plan storage and access optimization\n\n## Log Entry Details\n\nEach log entry includes:\n- **Timestamp**: Precise access time with timezone\n- **User Information**: ID, name, organization role\n- **Access Method**: Download, stream, preview, or URL generation\n- **Network Data**: IP address, user agent, geolocation\n- **Outcome**: Success, failure, or security block\n- **Security Context**: Rate limits, quotas, suspicious activity flags\n\n## Privacy and Retention\n\n- **Organization Scoped**: Only organization members can access logs\n- **Retention Policy**: Logs retained per organization data policy\n- **Anonymization**: PII can be anonymized for long-term analytics\n","tags":["Attachments"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Attachment ID"}],"responses":{"200":{"description":"Download audit log","content":{"application/json":{"schema":{"type":"object","properties":{"accessLog":{"type":"array","items":{"$ref":"#/components/schemas/DownloadAudit"}}}}}}}}}},"/api/v1/calendar/auth/connect":{"get":{"tags":["Calendar Authentication"],"summary":"Generate OAuth authorization URL","description":"Generate a Cronofy OAuth authorization URL for calendar connection. The user should be redirected to this URL to authorize calendar access.","operationId":"generateCalendarAuthUrl","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Authorization URL generated successfully","content":{"application/json":{"schema":{"type":"object","required":["authorization_url","state","message"],"properties":{"authorization_url":{"type":"string","format":"uri","description":"The URL to redirect user for authorization","example":"https://app.cronofy.com/oauth/authorize?..."},"state":{"type":"string","description":"State parameter for OAuth security","example":"org_123:user_456"},"message":{"type":"string","description":"Instructions for the authorization process","example":"Redirect user to this URL to authorize calendar access"}}}}}},"500":{"description":"Failed to generate authorization URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/auth/callback":{"get":{"tags":["Calendar Authentication"],"summary":"Handle OAuth callback","description":"Handle OAuth callback from Cronofy and exchange authorization code for access tokens. This endpoint is called by Cronofy after user authorizes calendar access. Supports both JSON response (default) and redirect flow for improved frontend UX.","operationId":"handleCalendarAuthCallback","parameters":[{"in":"query","name":"code","required":false,"schema":{"type":"string"},"description":"Authorization code from OAuth provider (required unless error is present)","example":"auth_code_12345"},{"in":"query","name":"state","required":true,"schema":{"type":"string"},"description":"State parameter for OAuth security verification (format: organizationId:userId:token)","example":"org_123:user_456:random_token"},{"in":"query","name":"error","required":false,"schema":{"type":"string"},"description":"Error code if authorization failed","example":"access_denied"},{"in":"query","name":"redirect_url","required":false,"schema":{"type":"string","format":"uri"},"description":"Optional HTTPS URL to redirect to instead of returning JSON response. Must be from an allowed domain.","example":"https://app.example.com/calendar/callback"}],"responses":{"200":{"description":"Calendar connection successful (JSON response when no redirect_url provided)","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean","description":"Whether the connection was successful","example":true},"message":{"type":"string","description":"Success message","example":"Calendar connected successfully"},"connection":{"type":"object","description":"Information about connected calendar account","properties":{"id":{"type":"string","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"provider":{"type":"string","example":"cronofy"},"email":{"type":"string","format":"email","example":"user@example.com"},"name":{"type":"string","example":"John Doe"},"created_at":{"type":"string","format":"date-time","example":"2024-01-15T10:30:00.000Z"}}}}}}}},"302":{"description":"Redirect response (when redirect_url is provided)","headers":{"Location":{"schema":{"type":"string","format":"uri","description":"Redirect URL with success/error parameters","example":"https://app.example.com/calendar/callback?success=true&message=Calendar+connected+successfully&connectionId=123e4567-e89b-12d3-a456-426614174000"}}}},"400":{"description":"Invalid callback parameters, authorization denied, or invalid redirect URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Failed to process callback","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/auth/status":{"get":{"tags":["Calendar Authentication"],"summary":"Check connection status","description":"Check the current calendar connection status for the authenticated user","operationId":"getCalendarConnectionStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Connection status retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["connected"],"properties":{"connected":{"type":"boolean","description":"Whether calendar is connected","example":true},"connection":{"type":"object","description":"Connection details (if connected)","properties":{"id":{"type":"string","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"},"provider":{"type":"string","example":"cronofy"},"email":{"type":"string","format":"email","example":"user@example.com"},"connected_at":{"type":"string","format":"date-time","example":"2024-01-15T10:30:00.000Z"},"last_sync":{"type":"string","format":"date-time","nullable":true,"example":"2024-01-15T14:20:00.000Z"}}}}}}}},"500":{"description":"Failed to retrieve connection status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/auth/refresh":{"post":{"tags":["Calendar Authentication"],"summary":"Refresh access tokens","description":"Refresh expired access tokens for the calendar connection","operationId":"refreshCalendarTokens","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Tokens refreshed successfully","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean","description":"Whether token refresh was successful","example":true},"message":{"type":"string","description":"Success message","example":"Tokens refreshed successfully"},"expires_at":{"type":"string","format":"date-time","description":"When the new tokens expire","example":"2024-01-16T10:30:00.000Z"}}}}}},"404":{"description":"No calendar connection found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Failed to refresh tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/auth/disconnect":{"delete":{"tags":["Calendar Authentication"],"summary":"Revoke calendar access","description":"Disconnect and revoke calendar access for the authenticated user","operationId":"disconnectCalendar","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Calendar disconnected successfully","content":{"application/json":{"schema":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean","description":"Whether disconnection was successful","example":true},"message":{"type":"string","description":"Success message","example":"Calendar disconnected successfully"}}}}}},"404":{"description":"No calendar connection found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Failed to disconnect calendar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/auth/test":{"post":{"tags":["Calendar Authentication"],"summary":"Test connection health","description":"Test the calendar connection health and verify API access","operationId":"testCalendarConnection","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Connection test successful","content":{"application/json":{"schema":{"type":"object","required":["success","message","test_results"],"properties":{"success":{"type":"boolean","description":"Whether connection test passed","example":true},"message":{"type":"string","description":"Test result message","example":"Calendar connection is healthy"},"test_results":{"type":"object","description":"Detailed test results","properties":{"connection_valid":{"type":"boolean","example":true},"api_accessible":{"type":"boolean","example":true},"last_sync":{"type":"string","format":"date-time","nullable":true,"example":"2024-01-15T14:20:00.000Z"},"calendars_count":{"type":"integer","example":3}}}}}}}},"404":{"description":"No calendar connection found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Connection test failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/calendar/events/{eventId}/attendee-outcomes":{"post":{"summary":"Record attendee outcome","description":"Record or update an outcome for a specific attendee of a calendar event. Uses upsert — if an outcome already exists for this attendee, it will be updated.","operationId":"recordAttendeeOutcome","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAttendeeOutcomeRequest"}}}},"responses":{"201":{"description":"Outcome recorded","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AttendeeOutcome"}}}}}},"400":{"description":"Validation error (invalid outcome code)"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Calendar event not found"}}},"get":{"summary":"List attendee outcomes","description":"Retrieve all recorded attendee outcomes for a calendar event.","operationId":"listAttendeeOutcomes","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}},{"name":"outcome","in":"query","description":"Filter by outcome code","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum results (default 100)","schema":{"type":"integer"}},{"name":"offset","in":"query","description":"Pagination offset","schema":{"type":"integer"}}],"responses":{"200":{"description":"List of attendee outcomes","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AttendeeOutcome"}},"total":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Calendar event not found"}}}},"/api/v1/calendar/events/{eventId}/attendee-outcomes/batch":{"post":{"summary":"Batch record attendee outcomes","description":"Record outcomes for multiple attendees at once (max 200). Each outcome is upserted individually within a transaction.","operationId":"batchRecordAttendeeOutcomes","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAttendeeOutcomeRequest"}}}},"responses":{"200":{"description":"Batch results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchAttendeeOutcomeResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Calendar event not found"}}}},"/api/v1/calendar/events/{eventId}/attendee-outcomes/summary":{"get":{"summary":"Outcome summary","description":"Aggregated outcome counts by outcome code for a calendar event.","operationId":"getAttendeeOutcomeSummary","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Summary of outcomes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttendeeOutcomeSummary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Calendar event not found"}}}},"/api/v1/calendar/events/{eventId}/attendee-outcomes/{email}":{"get":{"summary":"Get attendee outcome","description":"Retrieve the outcome for a specific attendee of a calendar event.","operationId":"getAttendeeOutcome","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}},{"name":"email","in":"path","required":true,"description":"Attendee email address","schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Attendee outcome","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AttendeeOutcome"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Outcome not found"}}},"patch":{"summary":"Update attendee outcome","description":"Update an existing attendee outcome. Only provided fields will be changed.","operationId":"updateAttendeeOutcome","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}},{"name":"email","in":"path","required":true,"description":"Attendee email address","schema":{"type":"string","format":"email"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAttendeeOutcomeRequest"}}}},"responses":{"200":{"description":"Updated outcome","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AttendeeOutcome"}}}}}},"400":{"description":"Validation error"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Outcome not found"}}},"delete":{"summary":"Delete attendee outcome","description":"Remove a recorded outcome for a specific attendee.","operationId":"deleteAttendeeOutcome","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event UUID","schema":{"type":"string","format":"uuid"}},{"name":"email","in":"path","required":true,"description":"Attendee email address","schema":{"type":"string","format":"email"}}],"responses":{"204":{"description":"Outcome deleted"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Outcome not found"}}}},"/api/v1/calendar/attendee-outcomes/by-email/{email}":{"get":{"summary":"Cross-event attendee outcomes","description":"Look up all outcomes across events for a specific attendee email address.","operationId":"getAttendeeOutcomesByEmail","tags":["Attendee Outcomes"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"email","in":"path","required":true,"description":"Attendee email address","schema":{"type":"string","format":"email"}},{"name":"limit","in":"query","description":"Maximum results (default 100)","schema":{"type":"integer"}},{"name":"offset","in":"query","description":"Pagination offset","schema":{"type":"integer"}}],"responses":{"200":{"description":"List of attendee outcomes across events","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AttendeeOutcome"}},"total":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/event-types":{"post":{"summary":"Create an event type","description":"Create a new calendar event type for the organization. Event types define defaults, capacity settings, outcome tracking, and metadata schemas for calendar events.","operationId":"createEventType","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventTypeRequest"}}}},"responses":{"201":{"description":"Event type created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CalendarEventType"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Event type with this code already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"summary":"List event types","description":"Retrieve all event types for the organization with optional filtering by category and active status.","operationId":"listEventTypes","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"category","in":"query","description":"Filter by category","schema":{"type":"string","example":"property"}},{"name":"activeOnly","in":"query","description":"Only return active event types (default true)","schema":{"type":"boolean","default":true}},{"name":"capacityEnabled","in":"query","description":"Filter to only capacity-enabled types","schema":{"type":"boolean"}}],"responses":{"200":{"description":"List of event types","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEventType"}},"meta":{"type":"object","properties":{"count":{"type":"integer","example":5}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/event-types/{id}":{"get":{"summary":"Get event type by ID","description":"Retrieve a specific event type by its UUID.","operationId":"getEventType","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event type details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CalendarEventType"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"summary":"Update event type","description":"Update an existing event type. Only provided fields will be updated.","operationId":"updateEventType","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventTypeRequest"}}}},"responses":{"200":{"description":"Event type updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CalendarEventType"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Delete event type","description":"Delete an event type. Will fail if events exist using this type.","operationId":"deleteEventType","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Event type UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Event type deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Event type deleted"}}}}}},"400":{"description":"Cannot delete - events exist using this type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/event-types/code/{code}":{"get":{"summary":"Get event type by code","description":"Retrieve a specific event type by its unique code identifier.","operationId":"getEventTypeByCode","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"code","in":"path","required":true,"description":"Event type code (e.g., 'open_house', 'property_viewing')","schema":{"type":"string","example":"open_house"}}],"responses":{"200":{"description":"Event type details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/CalendarEventType"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/event-types/categories":{"get":{"summary":"Get event type categories","description":"Retrieve all distinct categories used by event types in the organization.","operationId":"getEventTypeCategories","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"List of categories","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"string"},"example":["property","internal","client"]}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/event-types/{code}/validate-metadata":{"post":{"summary":"Validate metadata against event type schema","description":"Validate custom metadata against the JSON schema defined for an event type. Returns validation result with any errors.","operationId":"validateEventTypeMetadata","tags":["Calendar Event Types"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"code","in":"path","required":true,"description":"Event type code","schema":{"type":"string","example":"open_house"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["metadata"],"properties":{"metadata":{"type":"object","description":"Metadata object to validate","example":{"propertyId":"prop-123","expectedAttendees":25}}}}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"valid":{"type":"boolean","example":true},"errors":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/webhooks/cronofy":{"post":{"operationId":"handleCronofyWebhook","summary":"Process Cronofy calendar webhook events","description":"Handle incoming Cronofy calendar webhook notifications and synchronize with task management system.\nThis endpoint is the core integration point for real-time calendar synchronization.\n\n## Business Logic\n\nComprehensive webhook processing for calendar integration:\n- **HMAC Verification**: Cryptographic signature validation for security\n- **Event Synchronization**: Real-time sync of calendar events with tasks\n- **Invitation Tracking**: Monitor RSVP responses and attendee status\n- **Multi-tenant Isolation**: Organization-scoped event processing\n\n## Webhook Event Types\n\n### Event Lifecycle\n- **event.created**: New calendar events from connected calendars\n- **event.updated**: Changes to existing calendar events\n- **event.deleted**: Calendar event deletions and cancellations\n\n### Invitation Management  \n- **invitation.created**: New meeting invitations sent\n- **invitation.updated**: RSVP responses (accepted, declined, tentative)\n\n## Use Cases\n\n### Property Management\n- Sync property viewing appointments with tasks\n- Track contractor meeting attendance\n- Monitor client appointment responses\n\n### Team Coordination\n- Update task status based on meeting outcomes\n- Track team availability and scheduling conflicts\n- Synchronize project milestones with calendar\n\n### Compliance & Audit\n- Maintain accurate records of scheduled activities\n- Track meeting attendance for regulatory compliance\n- Generate audit trails for client interactions\n\n## Security Features\n\n- **HMAC-SHA256**: Webhook signature verification\n- **Organization Scoping**: Multi-tenant data isolation\n- **Rate Limiting**: Prevent webhook abuse\n- **Error Handling**: Graceful failure with detailed logging\n\nProcesses calendar events from Cronofy and synchronizes with tasks\n","tags":["Calendar","Webhooks"],"security":[],"parameters":[{"in":"header","name":"X-Cronofy-HMAC-SHA256","required":true,"schema":{"type":"string"},"description":"HMAC signature for webhook verification"},{"in":"header","name":"X-Organization-Id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Organization ID for scoping webhook events"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronofyWebhook"},"examples":{"eventCreated":{"summary":"Calendar event created","value":{"type":"event.created","event":{"event_id":"evt_external_54008b1a4a41730f8d5c6037","summary":"Updated Meeting Title","start":"2024-01-15T10:00:00Z","end":"2024-01-15T11:00:00Z","location":"Conference Room A"},"changes_since":"2024-01-15T09:45:00Z"}},"eventUpdated":{"summary":"Calendar event updated","value":{"type":"event.updated","event":{"event_id":"task-abc123","summary":"Updated Task Title","start":"2024-01-15T14:00:00Z","end":"2024-01-15T15:00:00Z"},"changes_since":"2024-01-15T13:30:00Z"}},"invitationUpdated":{"summary":"Meeting invitation response","value":{"type":"invitation.updated","invitation":{"event_id":"meeting-def456","attendee_email":"user@example.com","status":"accepted"},"changes_since":"2024-01-15T12:00:00Z"}}}}}},"responses":{"200":{"description":"Webhook processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Webhook processed successfully"},"processed":{"type":"object","properties":{"type":{"type":"string","description":"Webhook event type processed"},"eventId":{"type":"string","description":"Calendar event ID (if applicable)"},"taskId":{"type":"string","description":"Associated task ID (if found)"}}}}}}}},"400":{"description":"Invalid webhook payload or missing required headers","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"INVALID_WEBHOOK_PAYLOAD"},"message":{"type":"string","example":"Invalid webhook payload format"}}}}}}}},"401":{"description":"Webhook signature verification failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"WEBHOOK_VERIFICATION_FAILED"},"message":{"type":"string","example":"Webhook signature verification failed"}}}}}}}},"500":{"description":"Internal server error during webhook processing"}}}},"/api/webhooks/cronofy/health":{"get":{"operationId":"checkWebhookHealth","summary":"Check Cronofy webhook service health","description":"Returns comprehensive health status of the Cronofy webhook processing service.\nEssential for monitoring calendar integration health and diagnosing issues.\n\n## Health Monitoring\n\nProvides detailed service status including:\n- **Service Availability**: Basic webhook endpoint health\n- **Configuration Status**: Webhook and sync settings validation\n- **Security Configuration**: Webhook secret presence verification\n- **Environment Settings**: Development vs production configuration\n\n## Use Cases\n\n### Integration Monitoring\n- Monitor calendar integration health in dashboards\n- Set up alerts for webhook service failures\n- Verify configuration after deployments\n\n### Troubleshooting\n- Diagnose calendar sync issues\n- Verify webhook configuration problems\n- Check service readiness for webhook processing\n\n### DevOps & Monitoring\n- Include in health check aggregation services\n- Monitor integration dependencies\n- Validate deployment configuration\n\nReturns health status of the Cronofy webhook processing service\n","tags":["Calendar","Webhooks"],"security":[],"responses":{"200":{"description":"Webhook service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"healthy"},"service":{"type":"string","example":"cronofy-webhook-handler"},"timestamp":{"type":"string","format":"date-time"},"configuration":{"type":"object","properties":{"webhookEnabled":{"type":"boolean"},"syncEnabled":{"type":"boolean"},"hasWebhookSecret":{"type":"boolean"}}}}}}}}}}},"/api/webhooks/cronofy/test":{"post":{"operationId":"testWebhookProcessing","summary":"Test webhook processing without Cronofy (development only)","description":"Manual testing endpoint for webhook processing logic without requiring actual Cronofy webhooks.\nOnly available in development environments for testing and debugging.\n\n## Testing Capabilities\n\nComprehensive webhook testing functionality:\n- **Mock Webhook Events**: Test all webhook event types without Cronofy\n- **Processing Validation**: Verify webhook handling logic works correctly\n- **Error Simulation**: Test error handling and recovery scenarios\n- **Development Only**: Automatically disabled in production environments\n\n## Use Cases\n\n### Development Testing\n- Test webhook processing during feature development\n- Validate calendar sync logic without external dependencies\n- Debug webhook event handling issues\n\n### Integration Testing\n- Simulate various webhook scenarios in test suites\n- Test edge cases and error conditions\n- Validate webhook event processing before deployment\n\n### Debugging\n- Reproduce webhook processing issues locally\n- Test fixes for webhook handling problems\n- Validate webhook event parsing and processing\n\n## Security Notes\n\n- **Production Protection**: Automatically returns 403 in production\n- **Authentication Required**: Requires valid API authentication\n- **Organization Scoped**: Events processed within organization context\n\nAllows manual testing of webhook processing logic without Cronofy\n","tags":["Calendar","Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Organization-Id","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CronofyWebhook"}}}},"responses":{"200":{"description":"Test webhook processed successfully"},"400":{"description":"Invalid test payload"},"403":{"description":"Test endpoint disabled in production"}}}},"/api/v1/calendar/events":{"post":{"operationId":"createCalendarEvent","summary":"Create calendar event","description":"Create a calendar event from an existing task or create a new task with an integrated calendar event. Supports attendee invitations, location details, and automatic reminders.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["taskId"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of existing task to create calendar event for"},"summary":{"type":"string","description":"Custom event title (overrides task title if provided)"},"description":{"type":"string","description":"Custom event description (overrides task description if provided)"},"calendarId":{"type":"string","default":"primary","description":"Target calendar ID"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Event attendees"},"location":{"type":"string","description":"Event location"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Event duration in minutes"},"reminders":{"type":"array","items":{"type":"object","properties":{"minutes":{"type":"integer","description":"Minutes before event to remind"}}},"description":"Event reminders"},"responseTracking":{"type":"boolean","default":false,"description":"Enable RSVP tracking via Smart Invites. When true, sends trackable calendar invitations to each attendee with automated response callbacks. Requires at least one attendee."}}},{"type":"object","required":["task"],"properties":{"task":{"type":"object","required":["title"],"properties":{"title":{"type":"string","description":"Task title"},"description":{"type":"string","description":"Task description"},"projectId":{"type":"string","format":"uuid","description":"Project ID for the task (optional)"},"sectionId":{"type":"string","format":"uuid","description":"Section ID for the task"},"dueDate":{"type":"string","format":"date-time","description":"Task due date"},"scheduledAt":{"type":"string","format":"date-time","description":"Task scheduled time"},"assigneeUserId":{"type":"string","format":"uuid","description":"User ID to assign task to"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority"}}},"calendarId":{"type":"string","default":"primary","description":"Target calendar ID"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Event attendees"},"location":{"type":"string","description":"Event location"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Event duration in minutes"},"reminders":{"type":"array","items":{"type":"object","properties":{"minutes":{"type":"integer","description":"Minutes before event to remind"}}},"description":"Event reminders"},"responseTracking":{"type":"boolean","default":false,"description":"Enable RSVP tracking via Smart Invites. When true, sends trackable calendar invitations to each attendee with automated response callbacks. Requires at least one attendee."}}}]}}}},"responses":{"201":{"description":"Calendar event created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"event":{"$ref":"#/components/schemas/CalendarEvent"},"task":{"type":"object","description":"Task with calendar metadata (existing or newly created)"},"responseTracking":{"type":"object","description":"Response tracking details (only present when responseTracking=true)","properties":{"enabled":{"type":"boolean","example":true},"invitesSent":{"type":"integer","description":"Number of Smart Invites successfully sent"},"invitesFailed":{"type":"integer","description":"Number of Smart Invites that failed to send"},"attendees":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"smartInviteId":{"type":"string"},"status":{"type":"string","enum":["sent","failed"]},"error":{"type":"string","description":"Error message if status is failed"}}}}}}}}}}},"400":{"description":"Invalid request parameters"},"401":{"description":"Invalid or missing Cronofy token"},"403":{"description":"Calendar features not enabled for organization"},"404":{"description":"Task not found"},"409":{"description":"Calendar event already exists for task"}}},"get":{"operationId":"getCalendarEvents","summary":"List calendar events","description":"Retrieve calendar events with filtering by date range, status, and calendar. Includes task integration, attendee details, and location data.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":false,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations (optional if user has stored connection)"},{"in":"query","name":"dateRange.start","required":true,"schema":{"type":"string","format":"date-time"},"description":"Start date for event filtering (ISO 8601)"},{"in":"query","name":"dateRange.end","required":true,"schema":{"type":"string","format":"date-time"},"description":"End date for event filtering (ISO 8601)"},{"in":"query","name":"calendarId","required":false,"schema":{"type":"string"},"description":"Filter events from specific calendar"},{"in":"query","name":"taskIds","required":false,"schema":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":50},"style":"form","explode":true,"description":"Filter events by associated task IDs (can specify multiple)"},{"in":"query","name":"hasOutcome","required":false,"schema":{"type":"boolean"},"description":"Filter by outcome presence (true = has outcome, false = no outcome)"},{"in":"query","name":"outcome","required":false,"schema":{"type":"string","maxLength":100},"description":"Filter by specific outcome code"},{"in":"query","name":"status","required":false,"schema":{"type":"array","items":{"type":"string","enum":["confirmed","tentative","cancelled"]}},"style":"form","explode":true,"description":"Filter events by status (can specify multiple)"},{"in":"query","name":"includeManaged","required":false,"schema":{"type":"boolean","default":true},"description":"Include events created by this application"},{"in":"query","name":"includeDeleted","required":false,"schema":{"type":"boolean","default":false},"description":"Include deleted events"},{"in":"query","name":"maxResults","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"Maximum number of events to return"},{"in":"query","name":"tzid","required":false,"schema":{"type":"string","default":"Etc/UTC"},"description":"Timezone identifier for event times"}],"responses":{"200":{"description":"Calendar events retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"events":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEvent"}},"metadata":{"type":"object","properties":{"totalEvents":{"type":"integer","description":"Total number of events found"},"filteredCount":{"type":"integer","description":"Number of events after filtering"},"dateRange":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}}}}}}}}},"400":{"description":"Invalid request parameters (missing date range)"},"401":{"description":"Invalid or missing Cronofy token"}}}},"/api/v1/calendar/availability":{"post":{"operationId":"checkCalendarAvailability","summary":"Check participant availability","description":"Check availability across multiple participants to find optimal meeting times with conflict detection and timezone support.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["participants","duration","timeframe"],"properties":{"participants":{"type":"array","items":{"type":"string","format":"email"},"description":"Email addresses of participants"},"duration":{"type":"integer","minimum":15,"maximum":480,"description":"Required duration in minutes"},"timeframe":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time","description":"Start of availability window"},"end":{"type":"string","format":"date-time","description":"End of availability window"}}},"preferences":{"type":"object","properties":{"timeOfDay":{"type":"string","enum":["morning","afternoon","evening"],"description":"Preferred time of day"},"daysOfWeek":{"type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]},"description":"Preferred days of the week"}}}}}}}},"responses":{"200":{"description":"Availability data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"availability":{"type":"object","properties":{"available_periods":{"type":"array","items":{"$ref":"#/components/schemas/AvailabilitySlot"}}}},"suggestions":{"type":"array","items":{"type":"string","format":"date-time"},"description":"Top 5 suggested meeting times"}}}}}}}}},"/api/v1/calendar/meetings":{"post":{"operationId":"createMeetingInvitation","summary":"Create meeting invitation","description":"Create calendar invitations with automatic attendee management, RSVP tracking, and support for physical and virtual meeting locations.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["taskId","organizer","attendees"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of the task for the meeting"},"organizer":{"type":"string","format":"email","description":"Meeting organizer email"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Meeting attendees"},"location":{"type":"string","description":"Meeting location"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Meeting duration in minutes"},"scheduledAt":{"type":"string","format":"date-time","description":"Scheduled meeting time (defaults to task.scheduledAt)"}}}}}},"responses":{"201":{"description":"Meeting invitation created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"meeting":{"$ref":"#/components/schemas/CalendarEvent"},"task":{"type":"object","description":"Updated task with meeting metadata"}}}}}}}}},"/api/v1/calendar/events/{eventId}":{"get":{"operationId":"getCalendarEvent","summary":"Get calendar event details","description":"Retrieve detailed information for a specific calendar event.\n\n**Lookup Order:**\n1. First checks local database (works for any organization member)\n2. Falls back to Cronofy API if not found in database (requires calendar connection)\n\nThis allows retrieving events created by other users in the same organization\nwithout requiring a calendar connection.\n","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"},{"in":"header","name":"X-Cronofy-Token","required":false,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations (only needed if event not in database)"},{"in":"query","name":"calendarId","required":false,"schema":{"type":"string"},"description":"Calendar ID to search within (only used for Cronofy fallback)"},{"in":"query","name":"tzid","required":false,"schema":{"type":"string","default":"Etc/UTC"},"description":"Timezone identifier for event times"}],"responses":{"200":{"description":"Calendar event retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"event":{"$ref":"#/components/schemas/CalendarEvent"}}}}}},"401":{"description":"Invalid or missing Cronofy token (only when database lookup fails)"},"404":{"description":"Calendar event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"CALENDAR_EVENT_NOT_FOUND","message":"Calendar event not found"}}}}}}},"put":{"operationId":"updateCalendarEvent","summary":"Update calendar event","description":"Update an existing calendar event with new details, duration, or task information.\n\n**Validation:**\n- Event must exist in database (organization-scoped check)\n- Requires active calendar connection for sync to external calendar\n","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"},{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["taskId"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of the task to update calendar event for"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Event duration in minutes"}}}}}},"responses":{"200":{"description":"Calendar event updated successfully"},"401":{"description":"No active calendar connection"},"404":{"description":"Event or task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"summary":"Delete calendar event","description":"Delete a calendar event.\n\n**Behavior:**\n- Event must exist in database (organization-scoped check)\n- Soft-deletes event in local database first (source of truth)\n- Attempts Cronofy deletion as best-effort (won't fail if Cronofy delete fails)\n- Works even without calendar connection (local deletion only)\n","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"},{"in":"header","name":"X-Cronofy-Token","required":false,"schema":{"type":"string"},"description":"Cronofy access token (optional - deletion works without it)"}],"responses":{"200":{"description":"Calendar event deleted successfully"},"404":{"description":"Event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"CALENDAR_EVENT_NOT_FOUND","message":"Calendar event not found"}}}}}}}},"/api/v1/calendar/calendars":{"get":{"operationId":"getUserCalendars","summary":"List user calendars","description":"Retrieve all calendars accessible to the authenticated user across connected providers with permission levels and default calendar indication.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"responses":{"200":{"description":"Calendars retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"calendars":{"type":"array","items":{"type":"object","properties":{"calendar_id":{"type":"string","description":"Calendar identifier"},"calendar_name":{"type":"string","description":"Calendar display name"},"calendar_readonly":{"type":"boolean","description":"Whether calendar is read-only"},"calendar_primary":{"type":"boolean","description":"Whether this is the primary calendar"},"permission_level":{"type":"string","enum":["unrestricted","read_only","editor"],"description":"User's permission level"}}}}}}}}}}}},"/api/v1/calendar/events/{eventId}/reschedule":{"post":{"tags":["Calendar"],"summary":"Reschedule calendar event","description":"Atomically reschedule a calendar event by updating both the task and calendar event in a single transaction.\n\n**Registration Notifications:**\nAfter the reschedule completes, updated calendar invites are automatically sent to all confirmed\nevent registrations that previously received an invite. The `registrationNotifications` field\nin the response provides details on which registrations were notified.\n\n**Validation:**\n- Event must exist in database (organization-scoped check)\n- Requires active calendar connection\n","operationId":"rescheduleCalendarEvent","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"},{"in":"header","name":"X-Cronofy-Token","required":true,"schema":{"type":"string"},"description":"Cronofy access token for calendar operations"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RescheduleEventRequest"},"examples":{"clientMeeting":{"summary":"Reschedule client meeting","value":{"taskId":"550e8400-e29b-41d4-a716-446655440001","scheduledAt":"2025-01-20T14:00:00Z","dueDate":"2025-01-20T15:30:00Z","duration":90,"location":"Conference Room A","attendees":[{"email":"client@example.com","displayName":"Alex Johnson","responseRequired":true},{"email":"team.lead@company.com","displayName":"Sarah Williams","responseRequired":true}],"rescheduleReason":"Participant unavailable","notifyAttendees":true}},"teamReview":{"summary":"Postpone team review","value":{"taskId":"550e8400-e29b-41d4-a716-446655440002","scheduledAt":"2025-01-25T09:00:00Z","dueDate":"2025-01-25T12:00:00Z","duration":180,"rescheduleReason":"Scheduling conflict resolved","notifyAttendees":true}}}}}},"responses":{"200":{"description":"Event successfully rescheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RescheduleEventResponse"},"example":{"success":true,"task":{"id":"550e8400-e29b-41d4-a716-446655440001","title":"Client Meeting - Q1 Review","scheduledAt":"2025-01-20T14:00:00Z","dueDate":"2025-01-20T15:30:00Z","status":"scheduled","metadata":{"calendar":{"eventId":"task-550e8400-e29b-41d4-a716-446655440001","eventUrl":"https://cal.cronofy.com/events/evt_5f3e2a1b7c4d","calendarId":"primary","lastSyncedAt":"2025-01-13T10:30:00Z","rescheduleHistory":[{"timestamp":"2025-01-13T10:30:00Z","reason":"Participant unavailable","previousScheduledAt":"2025-01-15T14:00:00Z","previousDueDate":"2025-01-15T15:30:00Z"}]}}},"event":{"event_id":"task-550e8400-e29b-41d4-a716-446655440001","summary":"Client Meeting - Q1 Review","description":"Quarterly review meeting with client","start":"2025-01-20T14:00:00Z","end":"2025-01-20T15:30:00Z","location":"Conference Room A","attendees":[{"email":"client@example.com","displayName":"Alex Johnson","responseRequired":true,"status":"needs-action"},{"email":"team.lead@company.com","displayName":"Sarah Williams","responseRequired":true,"status":"needs-action"}],"url":"https://cal.cronofy.com/events/evt_5f3e2a1b7c4d"},"notifications":{"sent":2,"failed":0,"recipients":["client@example.com","team.lead@company.com"]},"registrationNotifications":{"total":3,"sent":3,"failed":0,"results":[{"registrationId":"reg-123","email":"attendee1@example.com","success":true},{"registrationId":"reg-456","email":"attendee2@example.com","success":true},{"registrationId":"reg-789","email":"attendee3@example.com","success":true}]}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"value":{"error":{"code":"VALIDATION_ERROR","message":"Calendar event reschedule validation failed","details":{"validationErrors":["taskId must be a valid UUID","scheduledAt must be in the future"]}}}},"missingFields":{"value":{"error":{"code":"VALIDATION_ERROR","message":"At least one field must be provided for rescheduling"}}}}}}},"401":{"description":"Unauthorized - No valid calendar token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"CALENDAR_NOT_CONNECTED","message":"No active calendar connection found. Please connect your calendar first."}}}}},"403":{"description":"Forbidden - Calendar features disabled or task not owned","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"featuresDisabled":{"value":{"error":{"code":"CALENDAR_FEATURES_DISABLED","message":"Calendar features are not enabled for this organization"}}},"taskNotOwned":{"value":{"error":{"code":"FORBIDDEN","message":"You do not have permission to reschedule this task"}}}}}}},"404":{"description":"Task or event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"taskNotFound":{"value":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found"}}},"eventNotFound":{"value":{"error":{"code":"CALENDAR_EVENT_NOT_FOUND","message":"Calendar event not found for this task"}}}}}}},"500":{"description":"Internal server error during reschedule","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"CALENDAR_EVENT_RESCHEDULE_FAILED","message":"Failed to reschedule calendar event"}}}}}}}},"/api/v1/calendar/events/{eventId}/rsvp":{"get":{"operationId":"getEventRsvpSummary","summary":"Get RSVP summary","description":"Retrieve RSVP status information for a calendar event including attendee response statistics and individual response details.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"}],"responses":{"200":{"description":"RSVP summary retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"eventId":{"type":"string","description":"Calendar event identifier"},"summary":{"type":"string","description":"Event title/summary"},"startTime":{"type":"string","format":"date-time","description":"Event start time"},"rsvpSummary":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of attendees"},"accepted":{"type":"integer","description":"Number who accepted"},"declined":{"type":"integer","description":"Number who declined"},"tentative":{"type":"integer","description":"Number marked tentative"},"pending":{"type":"integer","description":"Number who haven't responded"}}},"attendees":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string","format":"email"},"displayName":{"type":"string"},"status":{"type":"string","enum":["accepted","declined","tentative","needs-action"]},"respondedAt":{"type":"string","format":"date-time"}}}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/pending-rsvp":{"get":{"operationId":"getEventsWithPendingRsvp","summary":"Get events with pending RSVPs","description":"Retrieve calendar events that have attendees who haven't yet responded to their invitations. Supports filtering by date range and includes RSVP summaries.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"Filter events starting after this date"},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"},"description":"Filter events ending before this date"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":200},"description":"Maximum number of events to return"}],"responses":{"200":{"description":"Events with pending RSVPs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string"},"summary":{"type":"string"},"startTime":{"type":"string","format":"date-time"},"endTime":{"type":"string","format":"date-time"},"location":{"type":"string"},"taskId":{"type":"string","format":"uuid"},"rsvpSummary":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"declined":{"type":"integer"},"tentative":{"type":"integer"},"pending":{"type":"integer"}}}}}},"meta":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/attendees/{email}/events":{"get":{"operationId":"getEventsByAttendee","summary":"Get events for a specific attendee","description":"Retrieve all calendar events where a specific person (by email) is invited as an attendee. Supports filtering by date range and RSVP status.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"Attendee email address (URL encoded)"},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"Filter events starting after this date"},{"in":"query","name":"status","schema":{"type":"array","items":{"type":"string","enum":["accepted","declined","tentative","needs-action"]}},"style":"form","explode":true,"description":"Filter by attendee's RSVP status"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":200},"description":"Maximum number of events to return"}],"responses":{"200":{"description":"Attendee events retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string"},"summary":{"type":"string"},"startTime":{"type":"string","format":"date-time"},"endTime":{"type":"string","format":"date-time"},"location":{"type":"string"},"taskId":{"type":"string","format":"uuid"},"attendeeStatus":{"type":"string","enum":["accepted","declined","tentative","needs-action"],"description":"This attendee's RSVP status"},"respondedAt":{"type":"string","format":"date-time","description":"When this attendee responded"}}}},"meta":{"type":"object","properties":{"attendeeEmail":{"type":"string","format":"email"},"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/events/typed":{"post":{"operationId":"createTypedEvent","summary":"Create a typed calendar event","description":"Create a calendar event using predefined event type configurations. Event types provide standardized defaults, capacity settings, metadata validation, and outcome tracking options.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"header","name":"X-Cronofy-Token","required":false,"schema":{"type":"string"},"description":"Cronofy access token (optional if user has stored connection)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTypedEventRequest"}}}},"responses":{"201":{"description":"Typed event created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/CalendarEvent"},"eventRecord":{"type":"object","description":"Database record of the event"}}}}}}}},"400":{"description":"Invalid event type or metadata validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Event type not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/calendar/events/{eventId}/outcome":{"patch":{"operationId":"recordEventOutcome","summary":"Record outcome for a calendar event","description":"Record the outcome of a completed calendar event with optional follow-up task creation. Validates outcomes against event type configuration and can automatically update linked task status.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"Calendar event ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOutcomeRequest"}}}},"responses":{"200":{"description":"Outcome recorded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"eventId":{"type":"string"},"outcome":{"type":"string"},"followUpTaskId":{"type":"string","format":"uuid","description":"ID of auto-created follow-up task (if applicable)"}}}}}}}},"400":{"description":"Invalid outcome for event type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/requiring-outcome":{"get":{"operationId":"getEventsRequiringOutcome","summary":"Get events requiring outcome recording","description":"Retrieve calendar events that have ended but don't yet have an outcome recorded. Supports filtering by event type and end date.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"eventTypeCode","schema":{"type":"string"},"description":"Filter by event type code"},{"in":"query","name":"endedBefore","schema":{"type":"string","format":"date-time"},"description":"Filter events that ended before this date"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":200},"description":"Maximum number of events to return"}],"responses":{"200":{"description":"Events requiring outcome retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","description":"Calendar event records without outcomes"}},"meta":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/events/requiring-follow-up":{"get":{"operationId":"getEventsRequiringFollowUp","summary":"Get events requiring follow-up","description":"Retrieve calendar events that have been flagged as requiring follow-up actions. Supports filtering by follow-up due date and includes past-due option.","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"dueBefore","schema":{"type":"string","format":"date-time"},"description":"Filter events with follow-up due before this date"},{"in":"query","name":"includePastDue","schema":{"type":"boolean","default":false},"description":"Include events with past-due follow-ups"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":200},"description":"Maximum number of events to return"}],"responses":{"200":{"description":"Events requiring follow-up retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","description":"Calendar event records requiring follow-up"}},"meta":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/events/{eventId}/attendees/{email}/rsvp":{"patch":{"operationId":"overrideAttendeeRsvp","summary":"Manually override attendee RSVP status","description":"Manually set an attendee's RSVP status for a calendar event. Useful for phone confirmations, in-person confirmations, or admin corrections. The change is recorded with source 'manual' in the response history.\n","tags":["Calendar"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"eventId","required":true,"schema":{"type":"string"},"description":"The calendar event ID"},{"in":"path","name":"email","required":true,"schema":{"type":"string","format":"email"},"description":"Attendee email address (URL encoded)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["accepted","declined","tentative","needs-action"],"description":"The new RSVP status"},"notes":{"type":"string","maxLength":1000,"description":"Optional context for the override (e.g. \"Confirmed by phone\")"}}},"example":{"status":"accepted","notes":"Confirmed by phone"}}}},"responses":{"200":{"description":"RSVP status updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"eventId":{"type":"string"},"attendeeEmail":{"type":"string","format":"email"},"previousStatus":{"type":"string","enum":["accepted","declined","tentative","needs-action"]},"newStatus":{"type":"string","enum":["accepted","declined","tentative","needs-action"]},"source":{"type":"string","example":"manual"},"notes":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"rsvpSummary":{"type":"object","properties":{"total":{"type":"integer"},"accepted":{"type":"integer"},"declined":{"type":"integer"},"tentative":{"type":"integer"},"pending":{"type":"integer"},"responseRate":{"type":"integer"}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/comments":{"get":{"tags":["Comments"],"summary":"List comments","description":"Retrieves a paginated list of comments belonging to the authenticated organization.\nComments can be filtered by target entity and sorted by creation date.\n\n**Use Cases:**\n- Display comments for tasks, projects, workflows, or workflow stages\n- Comment threading and conversation views\n- Activity feeds and audit trails\n- Communication tracking\n\n**Filtering:** \n- Filter by target entity using `targetType` and `targetId` parameters\n- Filter by author using `authorType` and `authorId` parameters\n- Control threading with `includeReplies` parameter\n- Results automatically scoped to authenticated organization\n\n**Threading:** Set `includeReplies=true` to include nested replies\n**Sorting:** Configurable by creation or update date\n","operationId":"getComments","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"targetType","in":"query","description":"Type of entity being commented on (e.g., 'task', 'project', 'workflow', 'workflow_stage')","schema":{"type":"string","example":"task"}},{"name":"targetId","in":"query","description":"ID of the entity being commented on","schema":{"type":"string","format":"uuid","example":"789e0123-e89b-12d3-a456-426614174222"}},{"name":"authorType","in":"query","description":"Type of comment author (e.g., 'user', 'system', 'service')","schema":{"type":"string","example":"user"}},{"name":"authorId","in":"query","description":"ID of the comment author","schema":{"type":"string","example":"user-123"}},{"name":"parentCommentId","in":"query","description":"Filter by parent comment (for threading)","schema":{"type":"string","format":"uuid"}},{"name":"includeReplies","in":"query","description":"Include nested replies in the response","schema":{"type":"string","enum":["true","false"],"default":"false"}},{"name":"sortBy","in":"query","description":"Field to sort by","schema":{"type":"string","enum":["created_at","updated_at"],"default":"created_at"}},{"name":"sortOrder","in":"query","description":"Sort order","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"Comments retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Comment"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Comments"],"summary":"Create a new comment","description":"Creates a new comment on any target entity (task, project, workflow, workflow stage, etc.).\nSupports comment threading through the parentCommentId field.\n\n**Use Cases:**\n- Add comments to tasks, projects, workflows, stages\n- Reply to existing comments (threading)\n- External service integration via externalMessageId\n- Activity logging and audit trails\n- Team communication and collaboration\n\n**Threading:** Use `parentCommentId` to create reply comments\n**Content Types:** Supports 'text' and 'markdown' content\n**Author Information:** Automatically derives author details from authenticated user if not provided\n**Events:** Publishes 'comment.created' event to Pub/Sub\n","operationId":"createComment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targetType","targetId","content"],"properties":{"targetType":{"type":"string","description":"Type of entity being commented on","example":"task"},"targetId":{"type":"string","format":"uuid","description":"ID of the entity being commented on","example":"789e0123-e89b-12d3-a456-426614174222"},"content":{"type":"string","description":"Comment content","example":"This task looks great! Ready for review."},"contentType":{"type":"string","enum":["text","markdown"],"default":"text","description":"Format of the comment content"},"authorType":{"type":"string","description":"Type of comment author (auto-derived from authenticated user if not provided)","example":"USER"},"authorId":{"type":"string","description":"ID of the comment author (auto-derived from authenticated user if not provided)","example":"user-123"},"authorName":{"type":"string","description":"Display name of the comment author (auto-derived from authenticated user if not provided)","example":"John Doe"},"parentCommentId":{"type":"string","format":"uuid","description":"ID of parent comment (for replies)"},"externalMessageId":{"type":"string","description":"External system message ID"},"actor":{"type":"string","description":"Actor performing the action (for audit)","example":"user-123"}}},"examples":{"simpleComment":{"summary":"Simple comment (author auto-derived)","value":{"targetType":"task","targetId":"789e0123-e89b-12d3-a456-426614174222","content":"This task is ready for testing. All requirements met."}},"taskComment":{"summary":"Comment with explicit author","value":{"targetType":"task","targetId":"789e0123-e89b-12d3-a456-426614174222","content":"This task is ready for testing. All requirements met.","contentType":"text","authorType":"USER","authorId":"user-123","authorName":"John Doe"}},"replyComment":{"summary":"Reply comment example","value":{"targetType":"task","targetId":"789e0123-e89b-12d3-a456-426614174222","content":"Great work! I have a few suggestions...","contentType":"text","authorType":"user","authorId":"user-456","authorName":"Jane Smith","parentCommentId":"123e4567-e89b-12d3-a456-426614174888","actor":"user-456"}}}}}},"responses":{"201":{"description":"Comment created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/comments/{id}":{"get":{"tags":["Comments"],"summary":"Get comment by ID","description":"Retrieves a specific comment by its ID, including any child comments (replies).\n\n**Use Cases:**\n- Display individual comment details\n- Comment threading and conversation views\n- Deep linking to specific comments\n- Comment moderation workflows\n\n**Threading:** Response includes nested child comments\n**Organization Scoping:** Results automatically scoped to authenticated organization\n","operationId":"getCommentById","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Comment ID","schema":{"type":"string","format":"uuid","example":"789e0123-e89b-12d3-a456-426614174222"}}],"responses":{"200":{"description":"Comment retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Comments"],"summary":"Update comment content","description":"Updates the content of an existing comment. Only the content and contentType\ncan be modified after creation.\n\n**Use Cases:**\n- Edit comment text for corrections\n- Update formatting (text to markdown)\n- Content moderation and cleanup\n\n**Limitations:** Only content and contentType can be updated\n**Events:** Publishes 'comment.updated' event to Pub/Sub\n**Organization Scoping:** Can only update comments within authenticated organization\n","operationId":"updateComment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Comment ID","schema":{"type":"string","format":"uuid","example":"789e0123-e89b-12d3-a456-426614174222"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","description":"Updated comment content","example":"Updated: This task is ready for testing. All requirements met."},"contentType":{"type":"string","enum":["text","markdown"],"description":"Format of the comment content"},"actor":{"type":"string","description":"Actor performing the action (for audit)","example":"user-123"}}},"examples":{"contentUpdate":{"summary":"Update comment content","value":{"content":"Updated: This task is now ready for final review.","contentType":"text","actor":"user-123"}}}}}},"responses":{"200":{"description":"Comment updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Comment"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Comments"],"summary":"Delete comment","description":"Deletes a comment and all its child comments (replies). This is a permanent\naction that cannot be undone.\n\n**Use Cases:**\n- Remove inappropriate or outdated comments\n- Content moderation\n- Data cleanup and maintenance\n\n**Cascade:** Deletes all child comments (replies) as well\n**Events:** Publishes 'comment.deleted' event to Pub/Sub\n**Organization Scoping:** Can only delete comments within authenticated organization\n","operationId":"deleteComment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Comment ID","schema":{"type":"string","format":"uuid","example":"789e0123-e89b-12d3-a456-426614174222"}},{"name":"actor","in":"query","description":"Actor performing the deletion (for audit)","schema":{"type":"string","example":"user-123"}}],"responses":{"204":{"description":"Comment deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/comments/{id}/attachments":{"post":{"tags":["Comments","Attachments"],"summary":"Upload comment attachment","description":"Upload a file attachment to a specific comment.\nFiles are stored in organization-scoped Google Cloud Storage with security controls.\n\n**Use Cases:**\n- Attach supporting documents to comment discussions\n- Include screenshots or visual references in comments\n- Share files related to comment threads\n- Store communication artifacts and documentation\n\n**File Handling:**\n- Maximum file size: 100MB (configurable)\n- Supports all common file types\n- Files are stored in organization-scoped Google Cloud Storage\n- Original filename is preserved with timestamp prefix\n\n**Response includes entity context with comment information**\n","operationId":"uploadCommentAttachment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload (max 100MB)"},"externalDocumentId":{"type":"string","description":"External document identifier for tracking"}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentResponse"}}}},"400":{"description":"Bad request (invalid file or missing comment)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_FILE","message":"No file provided or file exceeds size limit."}}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"COMMENT_NOT_FOUND","message":"Comment not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Comments","Attachments"],"summary":"Get comment attachments","description":"Retrieves all attachments associated with a specific comment.\nSupports filtering, pagination, and optional signed download URLs.\n\n**Use Cases:**\n- List all files attached to a comment discussion\n- Filter attachments by type (images, documents, etc.)\n- Generate temporary download links for attachments\n- Display attachment thumbnails in comment threads\n\n**Security:**\n- Organization-scoped access control\n- Optional signed URLs with expiration\n- Audit trail logging\n","operationId":"getCommentAttachments","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"},{"in":"query","name":"mimeType","schema":{"type":"string"},"description":"Filter by MIME type (partial match)","example":"image/"},{"in":"query","name":"includeDownloadUrls","schema":{"type":"boolean","default":false},"description":"Include signed download URLs (valid for 15 minutes)"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of items per page"},{"in":"query","name":"sortBy","schema":{"type":"string","enum":["created_at","file_size","original_filename"],"default":"created_at"},"description":"Field to sort by"},{"in":"query","name":"sortOrder","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Sort direction"},{"in":"query","name":"uploadedAfter","schema":{"type":"string","format":"date-time"},"description":"Filter attachments uploaded after this date"},{"in":"query","name":"uploadedBefore","schema":{"type":"string","format":"date-time"},"description":"Filter attachments uploaded before this date"}],"responses":{"200":{"description":"Attachments retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentListResponse"}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/comments/{id}/attachments/stats":{"get":{"tags":["Comments","Attachments"],"summary":"Get comment attachment statistics","description":"Retrieves statistical information about all attachments for a comment.\n\n**Use Cases:**\n- Display attachment summary in comment views\n- Monitor storage usage per comment\n- Analyze attachment patterns\n- Storage quota management\n\n**Statistics Include:**\n- Total count and size\n- Breakdown by MIME type\n- Average file size\n- Upload date range\n","operationId":"getCommentAttachmentStats","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Statistics retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachmentStats"},"example":{"entityType":"comment","entityId":"123e4567-e89b-12d3-a456-426614174000","count":5,"totalSize":15728640,"averageSize":3145728,"byMimeType":{"image/png":{"count":2,"totalSize":5242880},"application/pdf":{"count":3,"totalSize":10485760}},"oldestUpload":"2024-01-01T00:00:00.000Z","newestUpload":"2024-01-15T12:30:00.000Z"}}}},"404":{"description":"Comment not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types/{id}/actions":{"post":{"tags":["Context Actions"],"summary":"Execute context action","description":"Execute a context action manually for a specific context type.\nThis endpoint allows manual execution of CREATE, UPDATE, or DELETE actions\non external systems through the configured context type.\n","operationId":"executeContextAction","parameters":[{"name":"id","in":"path","required":true,"description":"Context type UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteActionRequest"}}}},"responses":{"201":{"description":"Action executed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteActionResponse"}}}},"202":{"description":"Action accepted for processing (may retry)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteActionResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Context Actions"],"summary":"Get action history","description":"Get paginated action history for a specific context type.\nReturns a list of executed actions with their status and details.\n","operationId":"getContextActionHistory","parameters":[{"name":"id","in":"path","required":true,"description":"Context type UUID","schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"Page number (default 1)","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page (default 20, max 100)","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"entityId","in":"query","description":"Filter by entity ID","schema":{"type":"string"}},{"name":"entityType","in":"query","description":"Filter by entity type","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by action status","schema":{"type":"string","enum":["SUCCESS","FAILED","PENDING","RETRYING"]}},{"name":"actionType","in":"query","description":"Filter by action type","schema":{"type":"string","enum":["CREATE","UPDATE","DELETE"]}},{"name":"fromDate","in":"query","description":"Filter from date (ISO string)","schema":{"type":"string","format":"date-time"}},{"name":"toDate","in":"query","description":"Filter to date (ISO string)","schema":{"type":"string","format":"date-time"}},{"name":"sortBy","in":"query","description":"Sort field (default created_at)","schema":{"type":"string"}},{"name":"sortOrder","in":"query","description":"Sort order (default desc)","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"Action history retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionHistoryResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types/{id}/test-action":{"post":{"tags":["Context Actions"],"summary":"Test context action","description":"Test a context action without actually executing it.\nThis endpoint validates the action request and authentication\nwithout making changes to external systems.\n","operationId":"testContextAction","parameters":[{"name":"id","in":"path","required":true,"description":"Context type UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestActionRequest"}}}},"responses":{"200":{"description":"Test results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestActionResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-actions/{actionId}/retry":{"post":{"tags":["Context Actions"],"summary":"Retry failed action","description":"Retry a failed context action. This endpoint allows re-execution\nof actions that failed due to temporary issues or external system problems.\n","operationId":"retryContextAction","parameters":[{"name":"actionId","in":"path","required":true,"description":"Action log UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryActionRequest"}}}},"responses":{"200":{"description":"Retry initiated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryActionResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-actions/{actionId}":{"get":{"tags":["Context Actions"],"summary":"Get action details","description":"Get detailed information about a specific context action execution.\nReturns request data, response data, and execution status.\n","operationId":"getContextActionDetails","parameters":[{"name":"actionId","in":"path","required":true,"description":"Action log UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Action details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionDetailsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types/{id}/metrics":{"get":{"tags":["Context Actions"],"summary":"Get action metrics","description":"Get action metrics and statistics for a specific context type.\nReturns success rates, retry counts, and performance data.\n","operationId":"getContextActionMetrics","parameters":[{"name":"id","in":"path","required":true,"description":"Context type UUID","schema":{"type":"string","format":"uuid"}},{"name":"days","in":"query","description":"Number of days to include in metrics (default 7, max 30)","schema":{"type":"integer","minimum":1,"maximum":30}}],"responses":{"200":{"description":"Action metrics retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionMetricsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types":{"get":{"tags":["Context Types"],"summary":"List context types for organization","description":"Retrieves a paginated list of context type configurations for external API integrations.\nContext types define how to fetch live data from external systems.\n\n**Use Cases:**\n- Configure API integrations for property management systems\n- Set up customer data enrichment from CRM systems\n- Define external service connections for workflow automation\n\n**Filtering Options:**\n- Filter by active/inactive status\n- Search by context type code or name\n- Filter by authentication method or HTTP method\n","operationId":"getContextTypes","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"code","in":"query","schema":{"type":"string"},"description":"Filter by context type code","example":"property_lookup"},{"name":"name","in":"query","schema":{"type":"string"},"description":"Search by context type name","example":"Property Management API"},{"name":"isActive","in":"query","schema":{"type":"string","enum":[true,false]},"description":"Filter by active status"},{"name":"authenticationType","in":"query","schema":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC","INTERNAL"]},"description":"Filter by authentication method"},{"name":"httpMethod","in":"query","schema":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"description":"Filter by HTTP method"}],"responses":{"200":{"description":"Successfully retrieved context types","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ContextType"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Context Types"],"summary":"Create a new context type","description":"Creates a new context type configuration for external API integration.\nContext types define how to fetch live data from external systems.\n\n**Examples:**\n- Property management system integration\n- Customer data enrichment from CRM\n- Municipality data lookup\n- Document management system integration\n","operationId":"createContextType","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContextTypeRequest"}}}},"responses":{"201":{"description":"Context type created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ContextType"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"409":{"description":"Context type code already exists"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types/{id}":{"get":{"tags":["Context Types"],"summary":"Get context type by ID","description":"Retrieves a specific context type configuration by its ID","operationId":"getContextType","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Context type ID"}],"responses":{"200":{"description":"Context type retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ContextType"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Context Types"],"summary":"Update context type","description":"Updates an existing context type configuration","operationId":"updateContextType","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Context type ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContextTypeRequest"}}}},"responses":{"200":{"description":"Context type updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ContextType"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Context Types"],"summary":"Delete context type","description":"Deletes a context type configuration. This will also remove all associated entity contexts.\nUse with caution as this action cannot be undone.\n","operationId":"deleteContextType","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Context type ID"}],"responses":{"204":{"description":"Context type deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-types/{id}/test":{"post":{"tags":["Context Types"],"summary":"Test context type configuration","description":"Tests a context type configuration by making a sample API call.\nThis helps validate the configuration before applying it to entities.\n","operationId":"testContextType","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Context type ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestContextTypeRequest"}}}},"responses":{"200":{"description":"Test completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TestContextTypeResponse"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/operations":{"get":{"tags":["Context V2"],"summary":"List all context operations","description":"Get paginated list of all available context operations for the organization.\nSupports filtering by context type and operation type.\n","operationId":"getContextOperations","parameters":[{"name":"page","in":"query","description":"Page number (default 1)","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page (default 20, max 100)","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"contextTypeId","in":"query","description":"Filter by context type ID","schema":{"type":"string","format":"uuid"}},{"name":"operationType","in":"query","description":"Filter by operation type","schema":{"type":"string","enum":["RETRIEVE","CREATE","UPDATE","DELETE"]}},{"name":"isActive","in":"query","description":"Filter by active status","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Operations retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedOperationsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Context V2"],"summary":"Create context operation","description":"Create a new context operation for data retrieval or manipulation","operationId":"createContextOperation","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContextOperationRequest"}}}},"responses":{"201":{"description":"Operation created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextOperationResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"409":{"$ref":"#/components/responses/ConflictError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/operations/{id}":{"get":{"tags":["Context V2"],"summary":"Get operation details","description":"Get detailed information about a specific context operation","operationId":"getContextOperation","parameters":[{"name":"id","in":"path","required":true,"description":"Operation ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Operation details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextOperationResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Context V2"],"summary":"Update context operation","description":"Update an existing context operation configuration","operationId":"updateContextOperation","parameters":[{"name":"id","in":"path","required":true,"description":"Operation ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContextOperationRequest"}}}},"responses":{"200":{"description":"Operation updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextOperationResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Context V2"],"summary":"Delete context operation","description":"Delete a context operation and all its configurations","operationId":"deleteContextOperation","parameters":[{"name":"id","in":"path","required":true,"description":"Operation ID","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Operation deleted successfully"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/operations/{id}/execute":{"post":{"tags":["Context V2"],"summary":"Execute context operation","description":"Execute a context operation with specified parameters","operationId":"executeContextOperation","parameters":[{"name":"id","in":"path","required":true,"description":"Operation ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOperationRequest"}}}},"responses":{"200":{"description":"Operation executed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOperationResponse"}}}},"202":{"description":"Operation accepted for async processing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteOperationResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/data/{level}/{entityId}":{"get":{"tags":["Context V2"],"summary":"Get context data","description":"Get context data for a specific entity at the specified level","operationId":"getContextData","parameters":[{"name":"level","in":"path","required":true,"description":"Context data level","schema":{"type":"string","enum":["workflow","stage","task"]}},{"name":"entityId","in":"path","required":true,"description":"Entity ID","schema":{"type":"string","format":"uuid"}},{"name":"includeStale","in":"query","description":"Include stale/expired data","schema":{"type":"boolean"}},{"name":"keys","in":"query","description":"Comma-separated list of specific keys to retrieve","schema":{"type":"string"}}],"responses":{"200":{"description":"Context data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextDataResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/data":{"post":{"tags":["Context V2"],"summary":"Store context data","description":"Store context data for an entity at the specified level","operationId":"storeContextData","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StoreContextDataRequest"}}}},"responses":{"201":{"description":"Context data stored successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/data/{level}/{entityId}/{key}":{"put":{"tags":["Context V2"],"summary":"Update context data","description":"Update a specific context data key for an entity","operationId":"updateContextData","parameters":[{"name":"level","in":"path","required":true,"description":"Context data level","schema":{"type":"string","enum":["workflow","stage","task"]}},{"name":"entityId","in":"path","required":true,"description":"Entity ID","schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"description":"Context data key","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContextDataRequest"}}}},"responses":{"200":{"description":"Context data updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextDataResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Context V2"],"summary":"Delete context data","description":"Delete a specific context data key for an entity","operationId":"deleteContextData","parameters":[{"name":"level","in":"path","required":true,"description":"Context data level","schema":{"type":"string","enum":["workflow","stage","task"]}},{"name":"entityId","in":"path","required":true,"description":"Entity ID","schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"description":"Context data key","schema":{"type":"string"}}],"responses":{"204":{"description":"Context data deleted successfully"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/data/hierarchical/{workflowId}/{stageId}":{"get":{"tags":["Context V2"],"summary":"Get hierarchical context data","description":"Get hierarchical context data showing inheritance from workflow to stage to task.\nReturns merged context data with inheritance applied.\n","operationId":"getHierarchicalContextData","parameters":[{"name":"workflowId","in":"path","required":true,"description":"Workflow ID","schema":{"type":"string","format":"uuid"}},{"name":"stageId","in":"path","required":true,"description":"Stage ID","schema":{"type":"string","format":"uuid"}},{"name":"taskId","in":"query","description":"Optional task ID for task-level context","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Hierarchical context data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HierarchicalContextDataResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/templates/{templateId}/config":{"get":{"tags":["Context V2"],"summary":"Get template context configuration","description":"Get context configuration for a workflow template","operationId":"getTemplateContextConfig","parameters":[{"name":"templateId","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Template context configuration retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateContextConfigResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Context V2"],"summary":"Create template context configuration","description":"Create context configuration for a workflow template","operationId":"createTemplateContextConfig","parameters":[{"name":"templateId","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateContextConfigRequest"}}}},"responses":{"201":{"description":"Template context configuration created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateContextConfigResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/templates/{templateId}/config/{configId}":{"put":{"tags":["Context V2"],"summary":"Update template context configuration","description":"Update context configuration for a workflow template","operationId":"updateTemplateContextConfig","parameters":[{"name":"templateId","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}},{"name":"configId","in":"path","required":true,"description":"Context configuration ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateContextConfigRequest"}}}},"responses":{"200":{"description":"Template context configuration updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateContextConfigResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Context V2"],"summary":"Delete template context configuration","description":"Delete context configuration for a workflow template","operationId":"deleteTemplateContextConfig","parameters":[{"name":"templateId","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}},{"name":"configId","in":"path","required":true,"description":"Context configuration ID","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Template context configuration deleted successfully"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/logs":{"get":{"tags":["Context V2"],"summary":"Get execution logs","description":"Get paginated list of context operation execution logs","operationId":"getExecutionLogs","parameters":[{"name":"page","in":"query","description":"Page number (default 1)","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page (default 20, max 100)","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"operationId","in":"query","description":"Filter by operation ID","schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","description":"Filter by execution status","schema":{"type":"string","enum":["pending","success","failure","timeout","skipped"]}},{"name":"entityType","in":"query","description":"Filter by entity type","schema":{"type":"string","enum":["workflow","stage","task"]}},{"name":"entityId","in":"query","description":"Filter by entity ID","schema":{"type":"string","format":"uuid"}},{"name":"startDate","in":"query","description":"Filter by start date (ISO string)","schema":{"type":"string","format":"date-time"}},{"name":"endDate","in":"query","description":"Filter by end date (ISO string)","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Execution logs retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedExecutionLogsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/logs/{id}":{"get":{"tags":["Context V2"],"summary":"Get execution log details","description":"Get detailed information about a specific execution log","operationId":"getExecutionLog","parameters":[{"name":"id","in":"path","required":true,"description":"Execution log ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Execution log details retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionLogResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/logs/operation/{operationId}":{"get":{"tags":["Context V2"],"summary":"Get logs for operation","description":"Get execution logs for a specific context operation","operationId":"getOperationExecutionLogs","parameters":[{"name":"operationId","in":"path","required":true,"description":"Context operation ID","schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"Page number (default 1)","schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","description":"Items per page (default 20, max 100)","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"status","in":"query","description":"Filter by execution status","schema":{"type":"string","enum":["pending","success","failure","timeout","skipped"]}}],"responses":{"200":{"description":"Operation execution logs retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedExecutionLogsResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/forms/submit":{"post":{"tags":["Context V2"],"summary":"Submit form to context","description":"Submit form data to be stored as context data","operationId":"submitFormToContext","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormSubmissionRequest"}}}},"responses":{"201":{"description":"Form submitted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormSubmissionResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/forms/{level}/{entityId}/{key}":{"get":{"tags":["Context V2"],"summary":"Get form data from context","description":"Retrieve form data from context storage","operationId":"getFormDataFromContext","parameters":[{"name":"level","in":"path","required":true,"description":"Context data level","schema":{"type":"string","enum":["workflow","stage","task"]}},{"name":"entityId","in":"path","required":true,"description":"Entity ID","schema":{"type":"string","format":"uuid"}},{"name":"key","in":"path","required":true,"description":"Form data key","schema":{"type":"string"}}],"responses":{"200":{"description":"Form data retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormDataResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/context-v2/forms/aggregate":{"post":{"tags":["Context V2"],"summary":"Aggregate form data","description":"Aggregate form data from multiple entities and context levels","operationId":"aggregateFormData","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregateFormDataRequest"}}}},"responses":{"200":{"description":"Form data aggregated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregatedFormDataResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/conversations":{"get":{"tags":["Users","Conversations"],"summary":"Get all conversations for current user","description":"Retrieves entities with comments where user is involved (as author or mentioned), with pagination and filtering options.","operationId":"getUserConversations","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"page","in":"query","description":"Page number for pagination","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Number of items per page","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"entity_type","in":"query","description":"Filter by entity type","schema":{"type":"string","enum":["task","project","workflow","workflow_stage"]}},{"name":"involvement_type","in":"query","description":"Filter by type of user involvement","schema":{"type":"string","enum":["author","mentioned","all"],"default":"all"}},{"name":"unread_only","in":"query","description":"Only show conversations with unread mentions","schema":{"type":"string","enum":["true","false"],"default":"false"}},{"name":"authorId","in":"query","description":"Override the user ID to search for (defaults to authenticated user's contact_id or userId)","schema":{"type":"string","format":"uuid"}},{"name":"sort","in":"query","description":"Sort conversations by","schema":{"type":"string","enum":["latest_activity","unread_count","comment_count"],"default":"latest_activity"}}],"responses":{"200":{"description":"Conversations retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"entity_type":{"type":"string","enum":["task","project","workflow","workflow_stage"],"example":"task"},"entity_id":{"type":"string","format":"uuid"},"entity_title":{"type":"string","nullable":true,"example":"Fix login authentication bug"},"entity_metadata":{"type":"object","nullable":true,"properties":{"status":{"type":"string"},"project_id":{"type":"string","format":"uuid"}}},"user_involvement":{"type":"object","properties":{"is_author":{"type":"boolean","description":"User has authored comments"},"is_mentioned":{"type":"boolean","description":"User was mentioned in comments"},"mention_count":{"type":"integer","description":"Total times user was mentioned"},"unread_mentions":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of unread mention IDs"}}},"comment_count":{"type":"integer","description":"Total comments on this entity"},"unread_mention_count":{"type":"integer","description":"Unread mentions for current user"},"latest_activity_at":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of most recent comment"},"latest_comment":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string","description":"Preview of comment (truncated to 100 chars)"},"author_id":{"type":"string","nullable":true},"author_name":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}},"examples":{"taskConversations":{"summary":"User conversations on tasks","value":{"data":[{"entity_type":"task","entity_id":"789e0123-e89b-12d3-a456-426614174222","entity_title":"Fix login authentication bug","entity_metadata":{"status":"in_progress","project_id":"123e4567-e89b-12d3-a456-426614174000"},"user_involvement":{"is_author":true,"is_mentioned":true,"mention_count":2,"unread_mentions":["abc123"]},"comment_count":5,"unread_mention_count":1,"latest_activity_at":"2025-12-02T10:30:00Z","latest_comment":{"id":"def456","content":"I think we should also check the session timeout configuration...","author_id":"user-456","author_name":"Jane Doe","created_at":"2025-12-02T10:30:00Z"}}],"meta":{"total":42,"page":1,"limit":20}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/conversations/{entity_type}/{entity_id}":{"get":{"tags":["Users","Conversations"],"summary":"Get detailed conversation view for a specific entity","description":"Retrieves complete conversation for an entity including all comments with threading, user involvement, and entity metadata.","operationId":"getConversationDetails","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entity_type","in":"path","required":true,"description":"Type of entity","schema":{"type":"string","enum":["task","project","workflow","workflow_stage"]}},{"name":"entity_id","in":"path","required":true,"description":"Entity ID","schema":{"type":"string","format":"uuid"}},{"name":"authorId","in":"query","description":"Override the user ID to search for (defaults to authenticated user's contact_id or userId)","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Conversation details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"entity":{"type":"object","properties":{"type":{"type":"string","enum":["task","project","workflow","workflow_stage"]},"id":{"type":"string","format":"uuid"},"title":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true}}},"user_involvement":{"type":"object","properties":{"is_author":{"type":"boolean"},"is_mentioned":{"type":"boolean"},"mention_count":{"type":"integer"},"unread_mentions":{"type":"array","items":{"type":"string","format":"uuid"}}}},"comments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string"},"content_type":{"type":"string","enum":["text","markdown"]},"author_id":{"type":"string","nullable":true},"author_name":{"type":"string","nullable":true},"author_type":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"parent_comment_id":{"type":"string","format":"uuid","nullable":true},"mentions_current_user":{"type":"boolean","description":"Whether this comment mentions the current user"},"replies":{"type":"array","description":"Child comments (replies)","items":{"type":"object"}}}}}}}}},"examples":{"taskConversation":{"summary":"Conversation on a task","value":{"data":{"entity":{"type":"task","id":"789e0123-e89b-12d3-a456-426614174222","title":"Fix login authentication bug","metadata":{"status":"in_progress","project_id":"123e4567-e89b-12d3-a456-426614174000"}},"user_involvement":{"is_author":true,"is_mentioned":true,"mention_count":2,"unread_mentions":["abc123"]},"comments":[{"id":"comment-1","content":"This needs to be fixed ASAP","content_type":"text","author_id":"user-123","author_name":"John Doe","author_type":"USER","created_at":"2025-12-01T10:00:00Z","updated_at":"2025-12-01T10:00:00Z","parent_comment_id":null,"mentions_current_user":false,"replies":[{"id":"comment-2","content":"I agree, working on it now user:550e8400-e29b-41d4-a716-446655440000","content_type":"text","author_id":"user-456","author_name":"Jane Doe","author_type":"USER","created_at":"2025-12-01T11:00:00Z","updated_at":"2025-12-01T11:00:00Z","parent_comment_id":"comment-1","mentions_current_user":true,"replies":[]}]}]}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Entity not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/dependencies":{"get":{"tags":["Dependencies"],"summary":"List all dependencies for organization","description":"Retrieves a paginated list of dependencies belonging to the authenticated organization.\nDependencies define relationships between tasks and workflow stages.\n\n**Use Cases:**\n- Display project dependency diagrams\n- Generate Gantt charts\n- Dependency management interfaces\n- Critical path analysis\n- Scheduling optimization\n\n**Filtering:** \n- Filter by entity type, constraint type, or specific entities\n- Results automatically scoped to authenticated organization\n\n**Includes:** Dependency responses include related entity details\n**Sorting:** Newest dependencies first (by creation date)\n","operationId":"getDependencies","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"dependentType","in":"query","description":"Filter by dependent entity type","schema":{"type":"string","enum":["task","workflow_stage"]}},{"name":"dependentId","in":"query","description":"Filter by specific dependent entity ID","schema":{"type":"string","format":"uuid"}},{"name":"prerequisiteType","in":"query","description":"Filter by prerequisite entity type","schema":{"type":"string","enum":["task","workflow_stage"]}},{"name":"prerequisiteId","in":"query","description":"Filter by specific prerequisite entity ID","schema":{"type":"string","format":"uuid"}},{"name":"constraintType","in":"query","description":"Filter by constraint type","schema":{"type":"string","enum":["HARD","SOFT"]}},{"name":"workflowId","in":"query","description":"Filter by workflow ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Dependencies retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Dependencies"],"summary":"Create a new dependency","description":"Creates a new dependency relationship between two entities (tasks or workflow stages).\n\n**Use Cases:**\n- Establish task dependencies in project planning\n- Define workflow stage prerequisites\n- Create complex project schedules\n- Set up automated workflow progression\n\n**Dependency Types:**\n- `HARD`: Blocking dependency - prerequisite must be completed\n- `SOFT`: Advisory dependency - for planning purposes only\n\n**Relation Types:**\n- `FINISH_TO_START`: Prerequisite must finish before dependent starts (default)\n- `START_TO_START`: Both entities start together\n- `FINISH_TO_FINISH`: Both entities finish together\n- `START_TO_FINISH`: Prerequisite starts before dependent finishes\n\n**Validation:** System prevents circular dependencies and validates entity existence\n","operationId":"createDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDependencyRequest"}}}},"responses":{"201":{"description":"Dependency created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DependencyResponse"}}}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"circular":{"summary":"Circular dependency detected","value":{"error":{"code":"CIRCULAR_DEPENDENCY_DETECTED","message":"Creating this dependency would create a circular dependency","details":{"cycle":["task-1","task-2","task-3","task-1"]}}}},"duplicate":{"summary":"Dependency already exists","value":{"error":{"code":"DEPENDENCY_ALREADY_EXISTS","message":"A dependency between these entities already exists"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/dependencies/{id}":{"get":{"tags":["Dependencies"],"summary":"Get specific dependency details","description":"Retrieves detailed information for a specific dependency by its UUID.\nThe dependency must belong to the authenticated organization.\n\n**Use Cases:**\n- Display dependency details\n- Load dependency context for editing\n- Validate dependency relationships\n- Integration with external systems\n\n**Security:** Dependency access is automatically scoped to the authenticated organization\n","operationId":"getDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Dependency details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DependencyResponse"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Dependency not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"DEPENDENCY_NOT_FOUND","message":"Dependency not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Dependencies"],"summary":"Update an existing dependency","description":"Updates an existing dependency's properties. Only provided fields will be updated.\n\n**Use Cases:**\n- Modify dependency constraints\n- Update relation types\n- Adjust lag times\n- Change dependency status\n\n**Partial Updates:** Only include fields you want to change\n**Security:** Can only update dependencies belonging to the authenticated organization\n","operationId":"updateDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDependencyRequest"}}}},"responses":{"200":{"description":"Dependency updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DependencyResponse"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Dependency not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"DEPENDENCY_NOT_FOUND","message":"Dependency not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Dependencies"],"summary":"Delete a dependency","description":"Permanently deletes a dependency relationship.\n\n**⚠️ Warning:** This action is irreversible\n\n**Use Cases:**\n- Remove incorrect dependencies\n- Cleanup outdated relationships\n- Administrative cleanup\n\n**Impact:** Deleting dependencies may affect:\n- Project schedules and timelines\n- Critical path calculations\n- Workflow progression logic\n\n**Security:** Can only delete dependencies belonging to the authenticated organization\n","operationId":"deleteDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Dependency deleted successfully"},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Dependency not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"DEPENDENCY_NOT_FOUND","message":"Dependency not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{taskId}/dependencies":{"get":{"tags":["Dependencies"],"summary":"Get dependencies for a specific task","description":"Retrieves all dependencies where the specified task is either the dependent or prerequisite.\n\n**Use Cases:**\n- Display task dependency details\n- Validate task readiness\n- Project planning interfaces\n\n**Returns:** Both incoming and outgoing dependencies for the task\n","operationId":"getTaskDependencies","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"UUID of the task","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Task dependencies retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"incoming":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"},"description":"Dependencies where this task is the dependent"},"outgoing":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"},"description":"Dependencies where this task is the prerequisite"}}}}}}}},"404":{"description":"Task not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Dependencies"],"summary":"Add a dependency to a specific task","description":"Creates a new dependency where the specified task is the dependent entity.\n\n**Use Cases:**\n- Add prerequisites to tasks\n- Set up task scheduling constraints\n- Define workflow dependencies\n","operationId":"addTaskDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"UUID of the task that will be dependent","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prerequisiteType","prerequisiteId"],"properties":{"prerequisiteType":{"type":"string","enum":["task","workflow_stage"]},"prerequisiteId":{"type":"string","format":"uuid"},"constraintType":{"$ref":"#/components/schemas/DependencyConstraint"},"relationType":{"$ref":"#/components/schemas/DependencyRelation"},"lagDays":{"type":"integer","minimum":0},"workflowId":{"type":"string","format":"uuid"}}}}}},"responses":{"201":{"description":"Dependency created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DependencyResponse"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"404":{"description":"Task not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{workflowId}/dependencies":{"get":{"tags":["Dependencies"],"summary":"Get dependencies for a specific workflow","description":"Retrieves all dependencies within a workflow, including stage-to-stage dependencies.\n\n**Use Cases:**\n- Display workflow progression logic\n- Validate workflow readiness\n- Generate workflow diagrams\n","operationId":"getWorkflowDependencies","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"description":"UUID of the workflow","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workflow dependencies retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"}}}}}}},"404":{"description":"Workflow not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{stageId}/dependencies":{"get":{"tags":["Dependencies"],"summary":"Get dependencies for a specific workflow stage","description":"Retrieves all dependencies where the specified workflow stage is either the dependent or prerequisite.\n\n**Use Cases:**\n- Display stage dependency details\n- Validate stage readiness\n- Workflow planning interfaces\n","operationId":"getWorkflowStageDependencies","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"stageId","in":"path","required":true,"description":"UUID of the workflow stage","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Workflow stage dependencies retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"incoming":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"}},"outgoing":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"}}}}}}}}},"404":{"description":"Workflow stage not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{projectId}/gantt-data":{"get":{"tags":["Dependencies"],"summary":"Generate Gantt chart data for a project","description":"Generates comprehensive Gantt chart data including tasks, workflow stages, dependencies,\nand calculated scheduling information for project visualization.\n\n**Use Cases:**\n- Project management dashboards\n- Timeline visualization\n- Resource planning\n- Progress tracking\n\n**Includes:**\n- Task and stage scheduling\n- Critical path identification\n- Dependency relationships\n- Timeline calculations\n","operationId":"getProjectGanttData","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"projectId","in":"path","required":true,"description":"UUID of the project","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Gantt chart data generated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/GanttChartData"}}}}}},"404":{"description":"Project not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{projectId}/critical-path":{"get":{"tags":["Dependencies"],"summary":"Get critical path analysis for a project","description":"Analyzes project dependencies to identify the critical path - the sequence of tasks\nthat determines the minimum project duration.\n\n**Use Cases:**\n- Project schedule optimization\n- Resource allocation decisions\n- Risk identification\n- Timeline planning\n\n**Analysis Includes:**\n- Critical path sequence\n- Bottleneck identification\n- Risk factor assessment\n- Duration calculations\n","operationId":"getProjectCriticalPath","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"projectId","in":"path","required":true,"description":"UUID of the project","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Critical path analysis completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/CriticalPathAnalysis"}}}}}},"404":{"description":"Project not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{projectId}/recalculate-schedule":{"post":{"tags":["Dependencies"],"summary":"Trigger schedule recalculation for a project","description":"Recalculates project schedule based on current dependencies, constraints,\nand task durations. Updates calculated start/end dates for all tasks.\n\n**Use Cases:**\n- Schedule updates after dependency changes\n- Resource reallocation\n- Timeline adjustments\n- Progress updates\n\n**Process:**\n- Analyzes current dependencies\n- Recalculates task schedules\n- Updates critical path\n- Identifies scheduling conflicts\n","operationId":"recalculateProjectSchedule","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"projectId","in":"path","required":true,"description":"UUID of the project","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Schedule recalculation completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ScheduleRecalculationResult"}}}}}},"404":{"description":"Project not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/dependencies/{id}/validate":{"post":{"tags":["Dependencies"],"summary":"Validate a specific dependency","description":"Validates a dependency for circular references, constraint violations,\nand logical consistency.\n\n**Use Cases:**\n- Dependency validation before creation\n- Troubleshooting dependency issues\n- Data integrity checks\n- Automated validation processes\n\n**Validation Checks:**\n- Circular dependency detection\n- Entity existence verification\n- Constraint consistency\n- Business rule validation\n","operationId":"validateDependency","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Dependency validation completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/DependencyValidationResult"}}}}}},"404":{"description":"Dependency not found"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/entity-cache/stats":{"get":{"summary":"Get entity cache statistics","description":"Retrieves comprehensive statistics about the entity cache including\nentry counts, status distribution, and memory usage estimates.\nUseful for monitoring and debugging cache performance.\n","tags":["Entity Cache"],"responses":{"200":{"description":"Cache statistics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"totalEntries":{"type":"integer","description":"Total number of cache entries","example":1250},"entriesByType":{"type":"object","additionalProperties":{"type":"integer"},"description":"Entry counts grouped by entity type ID","example":{"contract":450,"client":300,"property":500}},"entriesByStatus":{"type":"object","properties":{"SUCCESS":{"type":"integer"},"FAILED":{"type":"integer"},"PENDING":{"type":"integer"},"TIMEOUT":{"type":"integer"}},"example":{"SUCCESS":1180,"FAILED":45,"PENDING":15,"TIMEOUT":10}},"staleEntries":{"type":"integer","description":"Number of stale entries needing refresh","example":85},"totalSizeBytes":{"type":"integer","description":"Estimated total cache size in bytes","example":2560000},"oldestEntry":{"type":"string","format":"date-time","description":"Timestamp of oldest cache entry"},"newestEntry":{"type":"string","format":"date-time","description":"Timestamp of newest cache entry"}}}}}}}}},"/api/v1/entity-cache":{"delete":{"summary":"Invalidate entity cache entries","description":"Invalidates (deletes) entity cache entries based on the provided criteria.\nAt least one filter parameter must be specified. This operation cannot\nbe undone and will force fresh retrieval for affected entities.\n","tags":["Entity Cache"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"entityType":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"Invalidate all entries for specific entity type code","example":"contract"},"entityId":{"type":"string","description":"Invalidate entries for specific entity ID","example":"CONTRACT-2024-001"},"olderThan":{"type":"string","format":"date-time","description":"Invalidate entries retrieved before this timestamp","example":"2024-01-01T00:00:00Z"},"status":{"type":"array","items":{"type":"string","enum":["SUCCESS","FAILED","PENDING","TIMEOUT"]},"description":"Invalidate entries with specific statuses","example":["FAILED","TIMEOUT"]}}}}}},"responses":{"200":{"description":"Cache entries invalidated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"invalidated":{"type":"integer","description":"Number of cache entries invalidated","example":45},"message":{"type":"string","example":"Cache entries invalidated successfully"}}}}}},"400":{"description":"Invalid request data or no filter criteria provided"}}}},"/api/v1/entity-cache/refresh":{"post":{"summary":"Refresh stale entity cache entries","description":"Triggers a batch refresh of stale entity cache entries. This operation\nattempts to fetch fresh data for entities that have expired or are\nmarked as stale. Useful for proactive cache warming.\n","tags":["Entity Cache"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"batchSize":{"type":"integer","minimum":1,"maximum":100,"default":10,"description":"Maximum number of entities to refresh in this operation"},"maxAge":{"type":"integer","minimum":60,"maximum":86400,"description":"Only refresh entities older than this (seconds)"},"entityTypes":{"type":"array","items":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$"},"description":"Limit refresh to specific entity type codes","example":["contract","client"]}}}}}},"responses":{"200":{"description":"Refresh operation completed","content":{"application/json":{"schema":{"type":"object","properties":{"refreshed":{"type":"integer","description":"Number of entities successfully refreshed","example":8},"failed":{"type":"integer","description":"Number of entities that failed refresh","example":1},"skipped":{"type":"integer","description":"Number of entities skipped (not stale or no config)","example":1},"executionTime":{"type":"number","description":"Total execution time in milliseconds","example":2450},"message":{"type":"string","example":"Refresh operation completed successfully"}}}}}},"400":{"description":"Invalid request data"}}}},"/api/v1/entity-cache/mark-stale":{"patch":{"summary":"Mark cache entries as stale","description":"Marks cache entries as stale without deleting them. Stale entries\nwill be refreshed on next access (depending on cache strategy) or\ncan be batch refreshed using the refresh endpoint.\n","tags":["Entity Cache"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"entityType":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"Mark entries for specific entity type as stale","example":"contract"},"olderThan":{"type":"string","format":"date-time","description":"Mark entries older than this timestamp as stale","example":"2024-01-01T00:00:00Z"}}}}}},"responses":{"200":{"description":"Cache entries marked as stale","content":{"application/json":{"schema":{"type":"object","properties":{"markedStale":{"type":"integer","description":"Number of entries marked as stale","example":25},"message":{"type":"string","example":"Cache entries marked as stale successfully"}}}}}}}}},"/api/v1/{entityType}/{entityId}/context":{"get":{"tags":["Entity Context"],"summary":"Get entity contexts with live data","description":"Retrieves all context configurations for an entity and fetches live data from external APIs.\nThis endpoint returns fresh, real-time data from configured external systems.\n\n**Important:** Data is fetched live and not cached. Response times depend on external API performance.\n","operationId":"getEntityContexts","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["project","workflow","task","section"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity ID"}],"responses":{"200":{"description":"Entity contexts with live data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LiveContextData"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Entity Context"],"summary":"Add context to entity","description":"Attaches a context configuration to an entity for live data fetching.\nThis creates the connection between the entity and external data source.\n","operationId":"createEntityContext","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["project","workflow","task","section"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEntityContextRequest"}}}},"responses":{"201":{"description":"Entity context created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EntityContext"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/{entityType}/{entityId}/context/{contextId}":{"put":{"tags":["Entity Context"],"summary":"Update entity context","description":"Updates an existing entity context configuration","operationId":"updateEntityContext","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["project","workflow","task","section"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity ID"},{"name":"contextId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity context ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEntityContextRequest"}}}},"responses":{"200":{"description":"Entity context updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/EntityContext"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Entity Context"],"summary":"Remove context from entity","description":"Removes a context configuration from an entity","operationId":"deleteEntityContext","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["project","workflow","task","section"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity ID"},{"name":"contextId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity context ID"}],"responses":{"204":{"description":"Entity context deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/{entityType}/{entityId}/context/refresh":{"post":{"tags":["Entity Context"],"summary":"Refresh entity context data","description":"Forces a refresh of all context data for an entity.\nThis is useful for debugging or when you need to ensure fresh data.\n","operationId":"refreshEntityContexts","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["project","workflow","task","section"]},"description":"Type of entity"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Entity ID"}],"responses":{"200":{"description":"Entity contexts refreshed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LiveContextData"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/entity-links":{"post":{"summary":"Create a new entity link","description":"Creates a supplementary link between entities","tags":["Entity Links"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sourceType","sourceId","linkedEntityType","linkedEntityId"],"properties":{"sourceType":{"type":"string","enum":["task","project","workflow","section"]},"sourceId":{"type":"string","format":"uuid"},"linkedEntityType":{"type":"string"},"linkedEntityId":{"type":"string"},"linkType":{"type":"string","enum":["related","reference","associated"]},"metadata":{"type":"object"}}}}}},"responses":{"201":{"description":"Entity link created successfully"},"400":{"description":"Invalid request data"},"403":{"description":"Forbidden - entity not in organization"},"404":{"description":"Source entity not found"},"409":{"description":"Link already exists"}}},"get":{"summary":"List entity links","description":"Lists entity links with optional filtering","tags":["Entity Links"],"parameters":[{"in":"query","name":"sourceType","schema":{"type":"string","enum":["task","project","workflow","section"]}},{"in":"query","name":"sourceId","schema":{"type":"string"}},{"in":"query","name":"linkedEntityType","schema":{"type":"string"}},{"in":"query","name":"linkedEntityId","schema":{"type":"string"}},{"in":"query","name":"linkType","schema":{"type":"string","enum":["related","reference","associated"]}},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Entity links retrieved successfully"}}}},"/api/v1/entity-links/bulk":{"post":{"summary":"Bulk create entity links","description":"Creates multiple supplementary links for a single source entity","tags":["Entity Links"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sourceType","sourceId","links"],"properties":{"sourceType":{"type":"string","enum":["task","project","workflow","section"]},"sourceId":{"type":"string","format":"uuid"},"links":{"type":"array","items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string"},"entityId":{"type":"string"},"linkType":{"type":"string","enum":["related","reference","associated"]},"metadata":{"type":"object"}}}}}}}}},"responses":{"201":{"description":"Entity links created successfully"},"400":{"description":"Invalid request data"},"404":{"description":"Source entity not found"}}}},"/api/v1/entity-links/{linkId}":{"get":{"summary":"Get entity link by ID","description":"Retrieves a specific entity link","tags":["Entity Links"],"parameters":[{"in":"path","name":"linkId","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Entity link retrieved successfully"},"404":{"description":"Entity link not found"}}},"patch":{"summary":"Update entity link","description":"Updates metadata or link type of an entity link","tags":["Entity Links"],"parameters":[{"in":"path","name":"linkId","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"linkType":{"type":"string","enum":["related","reference","associated"]},"metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"Entity link updated successfully"},"400":{"description":"Invalid request data"},"404":{"description":"Entity link not found"}}},"delete":{"summary":"Delete entity link","description":"Deletes a specific entity link","tags":["Entity Links"],"parameters":[{"in":"path","name":"linkId","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Entity link deleted successfully"},"404":{"description":"Entity link not found"}}}},"/api/v1/share-tokens":{"post":{"summary":"Create a new share token","description":"Creates share token for external access to entities with specified permissions","tags":["Entity Sharing"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityType","entityId","permissions"],"properties":{"entityType":{"type":"string","enum":["task","project","workflow"],"description":"Type of entity to share"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity to share"},"permissions":{"type":"array","items":{"type":"string","enum":["read","update","comment","complete"]},"description":"Permissions granted to the token holder"},"cascadeAccess":{"type":"boolean","description":"Whether access cascades to child entities","default":false},"expiresAt":{"type":"string","format":"date-time","description":"Optional expiration date for the token"},"maxUses":{"type":"integer","minimum":1,"description":"Optional maximum number of uses"},"recipientEmail":{"type":"string","format":"email","description":"Email of the intended recipient"},"recipientName":{"type":"string","description":"Name of the intended recipient"},"shareMessage":{"type":"string","description":"Optional message to include with the share"},"metadata":{"type":"object","description":"Additional metadata for the share"}}}}}},"responses":{"201":{"description":"Share token created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"shareToken":{"$ref":"#/components/schemas/ShareToken"},"shareUrl":{"type":"string","description":"Full URL for accessing the shared entity"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"get":{"summary":"List share tokens","description":"Lists all share tokens for organization with filtering and pagination","tags":["Entity Sharing"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"entityType","schema":{"type":"string","enum":["task","project","workflow"]},"description":"Filter by entity type"},{"in":"query","name":"entityId","schema":{"type":"string","format":"uuid"},"description":"Filter by entity ID"},{"in":"query","name":"createdBy","schema":{"type":"string","format":"uuid"},"description":"Filter by creator user ID"},{"in":"query","name":"recipientEmail","schema":{"type":"string","format":"email"},"description":"Filter by recipient email"},{"in":"query","name":"isActive","schema":{"type":"boolean"},"description":"Filter by active status"},{"in":"query","name":"includeExpired","schema":{"type":"boolean","default":false},"description":"Include expired tokens"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Items per page"}],"responses":{"200":{"description":"Share tokens retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"shareTokens":{"type":"array","items":{"$ref":"#/components/schemas/ShareToken"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/share/{token}":{"get":{"summary":"Get shared entity","description":"Retrieves entity via share token with optional data inclusions (public endpoint)","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"},{"in":"query","name":"includeFormData","schema":{"type":"boolean","default":false},"description":"Include form templates and responses (responses require update permission)"},{"in":"query","name":"includeContext","schema":{"type":"boolean","default":false},"description":"Include entity context data (sensitive fields sanitized)"},{"in":"query","name":"includeAttachments","schema":{"type":"boolean","default":false},"description":"Include file attachments"},{"in":"query","name":"includeComments","schema":{"type":"boolean","default":false},"description":"Include comments (requires comment permission)"},{"in":"query","name":"includeDependencies","schema":{"type":"boolean","default":false},"description":"Include task dependencies"},{"in":"query","name":"includeCustomFields","schema":{"type":"boolean","default":false},"description":"Include custom field values"},{"in":"query","name":"includeChecklistItems","schema":{"type":"boolean","default":false},"description":"Include checklist items"},{"in":"query","name":"includeWorkflowStages","schema":{"type":"boolean","default":false},"description":"Include workflow stages"},{"in":"query","name":"commentLimit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Maximum number of comments to return"},{"in":"query","name":"attachmentLimit","schema":{"type":"integer","minimum":1,"maximum":50,"default":50},"description":"Maximum number of attachments to return"}],"responses":{"200":{"description":"Shared entity retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","description":"The shared entity (task, project, or workflow)"}}}}}},"401":{"description":"Invalid or expired token"},"403":{"description":"Insufficient permissions"},"404":{"description":"Shared entity not found"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/children":{"get":{"summary":"Get shared entity children","description":"Retrieves child entities when cascade access is enabled (public endpoint)","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"responses":{"200":{"description":"Child entities retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"children":{"type":"array","items":{"type":"object"},"description":"List of accessible child entities"}}}}}}}},"401":{"description":"Invalid or expired token"},"403":{"description":"Cascade access not enabled or insufficient permissions"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/comment":{"post":{"summary":"Add comment to shared entity","description":"Adds comment to shared entity (public endpoint)","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["comment"],"properties":{"comment":{"type":"string","description":"The comment text"},"metadata":{"type":"object","description":"Additional metadata for the comment"}}}}}},"responses":{"200":{"description":"Comment added successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"400":{"description":"Invalid comment data"},"401":{"description":"Invalid or expired token"},"403":{"description":"Comment permission not granted"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/update":{"patch":{"summary":"Update shared entity","description":"Updates shared entity fields (public endpoint)","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"Entity fields to update"},"metadata":{"type":"object","description":"Additional metadata for the update"}}}}}},"responses":{"200":{"description":"Entity updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"400":{"description":"Invalid update data"},"401":{"description":"Invalid or expired token"},"403":{"description":"Update permission not granted"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/complete":{"post":{"summary":"Complete shared entity","description":"Marks shared entity as complete (public endpoint)","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"metadata":{"type":"object","description":"Additional metadata for the completion"}}}}}},"responses":{"200":{"description":"Entity completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"401":{"description":"Invalid or expired token"},"403":{"description":"Complete permission not granted"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/form":{"post":{"summary":"Submit form via share token","description":"Submit form data for a shared task via share token.\nCreates a FormResponse record and triggers form actions.\nRequires 'update' permission on the share token.\nOnly supported for task entities with a form template assigned.\n","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["response"],"properties":{"response":{"type":"object","description":"Form field values matching the form template schema","additionalProperties":true},"submittedBy":{"type":"string","description":"Optional identifier for the person submitting the form"}}},"example":{"response":{"rating":5,"feedback":"Great experience working with this person","recommendation":true},"submittedBy":"john.doe@example.com"}}}},"responses":{"200":{"description":"Form submitted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"success":{"type":"boolean"},"actionTaken":{"type":"string","example":"form_submitted"},"message":{"type":"string"},"data":{"type":"object","properties":{"formResponseId":{"type":"string","format":"uuid"},"taskId":{"type":"string","format":"uuid"},"formTemplateId":{"type":"string","format":"uuid"},"submittedAt":{"type":"string","format":"date-time"},"submittedBy":{"type":"string"}}}}}}}}}},"400":{"description":"Invalid form data or task has no form template"},"401":{"description":"Invalid or expired token"},"403":{"description":"Update permission not granted or entity is not a task"},"404":{"description":"Task not found"},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/share-tokens/{id}":{"patch":{"summary":"Update share token","description":"Updates existing share token settings","tags":["Entity Sharing"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Share token ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"permissions":{"type":"array","items":{"type":"string","enum":["read","update","comment","complete"]}},"cascadeAccess":{"type":"boolean"},"isActive":{"type":"boolean"},"expiresAt":{"type":"string","format":"date-time"},"maxUses":{"type":"integer","minimum":1},"recipientEmail":{"type":"string","format":"email"},"recipientName":{"type":"string"},"shareMessage":{"type":"string"},"metadata":{"type":"object"}}}}}},"responses":{"200":{"description":"Share token updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ShareToken"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"summary":"Revoke share token","description":"Revokes share token, preventing further access","tags":["Entity Sharing"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Share token ID"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","description":"Optional reason for revocation"}}}}}},"responses":{"200":{"description":"Share token revoked successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/share-tokens/{id}/analytics":{"get":{"summary":"Get share token analytics","description":"Retrieves usage analytics for share token","tags":["Entity Sharing"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Share token ID"},{"in":"query","name":"startDate","schema":{"type":"string","format":"date"},"description":"Start date for analytics period"},{"in":"query","name":"endDate","schema":{"type":"string","format":"date"},"description":"End date for analytics period"}],"responses":{"200":{"description":"Analytics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"token":{"$ref":"#/components/schemas/ShareToken"},"analytics":{"type":"object","properties":{"totalAccesses":{"type":"integer"},"uniqueAccessors":{"type":"integer"},"actionBreakdown":{"type":"object"},"accessLogs":{"type":"array","items":{"type":"object"}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/share/{token}/attachment/{attachmentId}/download":{"get":{"summary":"Download attachment via share token","description":"Generate a signed download URL for an attachment accessible via share token.\nThe attachment must belong to the shared entity or one of its cascade-accessible children.\nRequires 'read' permission on the share token.\n","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"},{"in":"path","name":"attachmentId","required":true,"schema":{"type":"string","format":"uuid"},"description":"The attachment ID"},{"in":"query","name":"expiresInMinutes","schema":{"type":"integer","minimum":1,"maximum":60,"default":15},"description":"URL expiration time in minutes (max 60 for share tokens)"}],"responses":{"200":{"description":"Signed download URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"downloadUrl":{"type":"string","format":"uri","description":"Signed URL for downloading the file"},"expiresAt":{"type":"string","format":"date-time","description":"URL expiration timestamp"},"attachment":{"type":"object","properties":{"id":{"type":"string"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"integer"}}}}}}}}}},"401":{"description":"Invalid or expired token"},"403":{"description":"Insufficient permissions or attachment not accessible"},"404":{"description":"Attachment not found"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/attachment":{"post":{"summary":"Upload attachment via share token","description":"Upload a file attachment to the shared entity via share token.\nRequires 'update' permission on the share token.\nMaximum file size is 50MB for share token uploads.\n","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"The share token"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload (max 50MB)"}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"attachment":{"type":"object","properties":{"id":{"type":"string"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}}},"400":{"description":"Invalid file or missing file"},"401":{"description":"Invalid or expired token"},"403":{"description":"Update permission required"},"429":{"description":"Rate limit exceeded"}}}},"/share/{token}/upload-url":{"post":{"summary":"Request presigned upload URL via share token","description":"Generate a presigned URL for direct file upload to Google Cloud Storage via share token.\nThis bypasses the API server for the actual file transfer, enabling uploads up to 50MB.\n\n## Flow\n1. Call this endpoint to get a presigned upload URL\n2. Upload file directly to GCS using the returned URL and headers\n3. Call `/share/{token}/confirm-upload` to create the database record\n","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"Share token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filename","contentType","fileSize"],"properties":{"filename":{"type":"string","description":"Original filename"},"contentType":{"type":"string","description":"MIME type of the file"},"fileSize":{"type":"integer","description":"File size in bytes (max 50MB)","maximum":52428800},"public":{"type":"boolean","description":"Whether to make the attachment publicly accessible"},"externalDocumentId":{"type":"string","description":"Optional external document reference ID"}}}}}},"responses":{"200":{"description":"Presigned upload URL generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"uploadUrl":{"type":"string"},"storageFilename":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"headers":{"type":"object"},"maxFileSize":{"type":"integer"}}}}}}}},"400":{"description":"Validation error"},"401":{"description":"Invalid or expired share token"},"403":{"description":"Insufficient permissions"}}}},"/share/{token}/confirm-upload":{"post":{"summary":"Confirm presigned upload via share token","description":"Confirm that a file has been uploaded via presigned URL and create the database record.\nCall this endpoint after successfully uploading a file directly to GCS.\n\nThe endpoint verifies the file exists in storage before creating the record.\n","tags":["Public Share Access"],"parameters":[{"in":"path","name":"token","required":true,"schema":{"type":"string"},"description":"Share token"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["storageFilename","originalFilename","contentType","fileSize"],"properties":{"storageFilename":{"type":"string","description":"Storage filename returned from upload-url endpoint"},"originalFilename":{"type":"string","description":"Original filename"},"contentType":{"type":"string","description":"MIME type of the file"},"fileSize":{"type":"integer","description":"File size in bytes (max 50MB)","maximum":52428800},"public":{"type":"boolean","description":"Whether to make the attachment publicly accessible"},"externalDocumentId":{"type":"string","description":"Optional external document reference ID"}}}}}},"responses":{"201":{"description":"Attachment record created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"attachment":{"type":"object","properties":{"id":{"type":"string"},"originalFilename":{"type":"string"},"mimeType":{"type":"string"},"fileSize":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}}},"400":{"description":"Validation error or file not found in storage"},"401":{"description":"Invalid or expired share token"},"403":{"description":"Insufficient permissions"}}}},"/api/v1/entity-types":{"post":{"summary":"Create a new EntityType configuration","description":"Creates a new EntityType configuration that defines how external entities\nshould be automatically retrieved and cached. Entity types enable automated\nenrichment of API responses with external data from integrated systems.\n","tags":["Entity Types"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","name"],"properties":{"code":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","minLength":1,"maxLength":50,"example":"contract","description":"Unique identifier for the entity type within organization"},"name":{"type":"string","minLength":1,"maxLength":255,"example":"Contract","description":"Human-readable name for the entity type"},"description":{"type":"string","maxLength":1000,"example":"Legal contracts and agreements","description":"Optional description of the entity type"},"retrievalOperationId":{"type":"string","format":"uuid","description":"ID of the ContextOperation used to retrieve entity data"},"queryParamConfig":{"type":"object","description":"Configuration for query parameter mapping","properties":{"template":{"type":"string","example":"/api/contracts/{entity_id}"},"parameters":{"type":"object"}}},"cacheTtlSeconds":{"type":"integer","minimum":60,"maximum":604800,"default":3600,"description":"Cache TTL in seconds (1 minute to 7 days)"},"cacheStrategy":{"type":"string","enum":["STALE_WHILE_REVALIDATE","CACHE_FIRST","NO_CACHE"],"default":"STALE_WHILE_REVALIDATE"},"refreshIntervalMinutes":{"type":"integer","minimum":1,"maximum":10080,"description":"Optional scheduled refresh interval (1 minute to 7 days)"},"isActive":{"type":"boolean","default":true,"description":"Whether the entity type is active"}}}}}},"responses":{"201":{"description":"EntityType created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityType"}}}},"400":{"description":"Invalid request data or validation error"},"404":{"description":"Referenced ContextOperation not found"},"409":{"description":"EntityType with the same code already exists"}}},"get":{"summary":"List EntityType configurations","description":"Retrieves EntityType configurations for the organization with optional\nfiltering and pagination. Entity types define how external entities\nshould be automatically retrieved and cached.\n","tags":["Entity Types"],"parameters":[{"name":"page","in":"query","description":"Page number (1-based)","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Items per page","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"isActive","in":"query","description":"Filter by active status","schema":{"type":"boolean"}},{"name":"hasRetrievalOperation","in":"query","description":"Filter by presence of retrieval operation","schema":{"type":"boolean"}},{"name":"codes","in":"query","description":"Comma-separated list of entity type codes","schema":{"type":"string","example":"contract,client,property"}},{"name":"search","in":"query","description":"Search by name or description","schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"List of EntityTypes with pagination metadata","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/EntityType"}},"meta":{"type":"object","properties":{"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}},"filters":{"type":"object"}}}}}}}},"400":{"description":"Invalid query parameters"}}}},"/api/v1/entity-types/{id}":{"put":{"summary":"Update EntityType configuration","description":"Updates an existing EntityType configuration. Only provided fields\nwill be updated. Cache entries may be invalidated if caching\nconfiguration changes.\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"EntityType ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":1000},"retrievalOperationId":{"type":"string","format":"uuid","nullable":true},"queryParamConfig":{"type":"object","nullable":true},"cacheTtlSeconds":{"type":"integer","minimum":60,"maximum":604800},"cacheStrategy":{"type":"string","enum":["STALE_WHILE_REVALIDATE","CACHE_FIRST","NO_CACHE"]},"refreshIntervalMinutes":{"type":"integer","minimum":1,"maximum":10080,"nullable":true},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"EntityType updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityType"}}}},"400":{"description":"Invalid request data"},"404":{"description":"EntityType not found"}}},"delete":{"summary":"Delete EntityType configuration","description":"Deletes an EntityType configuration and all associated cache entries.\nThis operation cannot be undone.\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"EntityType ID","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"EntityType deleted successfully"},"404":{"description":"EntityType not found"}}}},"/api/v1/entity-types/{id}/test":{"post":{"summary":"Test EntityType retrieval operation","description":"Tests the retrieval operation for an EntityType by attempting to\nfetch a specific entity. Useful for validating configuration and\ndebugging integration issues.\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"EntityType ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityId"],"properties":{"entityId":{"type":"string","description":"External entity ID to test retrieval for","example":"CONTRACT-2024-001"},"timeout":{"type":"integer","minimum":1000,"maximum":60000,"default":30000,"description":"Request timeout in milliseconds"},"bypassCache":{"type":"boolean","default":false,"description":"Skip cache and fetch fresh data"}}}}}},"responses":{"200":{"description":"Test completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","description":"Retrieved entity data (if successful)"},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object"}}},"executionTime":{"type":"number","description":"Time taken for the test in milliseconds"}}}}}},"400":{"description":"Invalid request data"},"404":{"description":"EntityType not found"}}}},"/api/v1/calendar/events/{eventId}/registrations":{"post":{"summary":"Register for an event","description":"Register an attendee for a calendar event. Automatically handles capacity limits and waitlisting. Optionally sends a Smart Invite calendar invitation.","operationId":"createEventRegistration","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string","example":"task-123e4567-e89b-12d3-a456-426614174000"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRegistrationRequest"}}}},"responses":{"201":{"description":"Registration created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationResponse"}}}},"400":{"description":"Validation error or already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"get":{"summary":"List registrations for an event","description":"Retrieve all registrations for a calendar event with optional filtering and pagination.","operationId":"listEventRegistrations","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}},{"name":"status","in":"query","description":"Filter by registration status","schema":{"type":"string","enum":["confirmed","waitlisted","cancelled","declined"]}},{"name":"checkedIn","in":"query","description":"Filter by check-in status","schema":{"type":"boolean"}},{"name":"email","in":"query","description":"Filter by email","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Maximum number of results","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","description":"Number of results to skip","schema":{"type":"integer","default":0}},{"name":"orderBy","in":"query","description":"Field to order by","schema":{"type":"string","enum":["registeredAt","displayName","waitlistPosition","checkedInAt"]}},{"name":"orderDirection","in":"query","description":"Order direction","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"List of registrations","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}},"meta":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/{eventId}/registrations/bulk":{"post":{"summary":"Bulk register attendees","description":"Register multiple attendees for an event at once. Returns detailed results for each registration including successes and failures.","operationId":"createBulkRegistrations","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkRegistrationRequest"}}}},"responses":{"201":{"description":"Bulk registration results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkRegistrationResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/{eventId}/check-in":{"post":{"summary":"Check in an attendee","description":"Check in a registered attendee or create a walk-in registration. Supports multiple check-in methods (manual, QR code, self-service).","operationId":"checkInAttendee","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckInRequest"}}}},"responses":{"200":{"description":"Check-in successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckInResponse"}}}},"400":{"description":"Invalid check-in request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/registrations/{registrationId}":{"delete":{"summary":"Cancel a registration","description":"Cancel an event registration. Automatically promotes the next person from the waitlist if applicable.","operationId":"cancelRegistration","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"registrationId","in":"path","required":true,"description":"Registration UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRegistrationRequest"}}}},"responses":{"200":{"description":"Registration cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelRegistrationResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"summary":"Update a registration","description":"Update registration details such as display name, phone, party size, or metadata.","operationId":"updateRegistration","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"registrationId","in":"path","required":true,"description":"Registration UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRegistrationRequest"}}}},"responses":{"200":{"description":"Registration updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EventRegistration"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"get":{"summary":"Get registration by ID","description":"Retrieve a specific registration by its UUID.","operationId":"getRegistration","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"registrationId","in":"path","required":true,"description":"Registration UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Registration details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EventRegistration"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/{eventId}/registrations/summary":{"get":{"summary":"Get event registration summary","description":"Retrieve a comprehensive summary of registrations for an event including counts, capacity, and categorized registration lists.","operationId":"getEventRegistrationSummary","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Registration summary","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/EventRegistrationSummary"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/events/{eventId}/registrations/statistics":{"get":{"summary":"Get registration statistics","description":"Retrieve detailed statistics for event registrations including rates (confirmation, attendance, no-show, cancellation) and breakdowns by source and party size.","operationId":"getEventRegistrationStatistics","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Registration statistics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/RegistrationStatistics"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/calendar/registrations/by-email/{email}":{"get":{"summary":"Find registrations by email","description":"Retrieve all registrations for a specific email address across all events.","operationId":"getRegistrationsByEmail","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"email","in":"path","required":true,"description":"Attendee email address","schema":{"type":"string","format":"email"}},{"name":"startAfter","in":"query","description":"Only include events starting after this date","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","description":"Maximum number of results","schema":{"type":"integer","default":20}},{"name":"includeAll","in":"query","description":"Include cancelled registrations","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"List of registrations for the email","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}},"meta":{"type":"object","properties":{"email":{"type":"string"},"count":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/calendar/events/{eventId}/registrations/promote":{"post":{"summary":"Promote from waitlist","description":"Manually promote the next person from the waitlist to confirmed status. Sends a Smart Invite calendar invitation to the promoted registrant.","operationId":"promoteFromWaitlist","tags":["Event Registrations"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Waitlist promotion result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/WaitlistPromotionResult"}}}}}},"400":{"description":"No registrations in waitlist to promote","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/event-types":{"get":{"summary":"List event types","description":"Retrieves a paginated list of event types available in the organization.\nSupports filtering by category, trigger configuration, and search by name.\nAll results are automatically scoped to the authenticated organization.\n","tags":["Event Types"],"parameters":[{"in":"query","name":"category","schema":{"type":"string"},"description":"Filter by event category"},{"in":"query","name":"hasTriggerConfig","schema":{"type":"boolean"},"description":"Filter events that have trigger configuration"},{"in":"query","name":"triggerCategory","schema":{"type":"string"},"description":"Filter by trigger_config.metadata.category"},{"in":"query","name":"search","schema":{"type":"string"},"description":"Search in event name and description"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Number of items per page"}],"responses":{"200":{"description":"List of event types","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":"string","example":"task.created"},"name":{"type":"string","example":"Task Created"},"description":{"type":"string"},"category":{"type":"string","example":"trigger_events"},"isSystemEvent":{"type":"boolean"},"hasTriggerConfig":{"type":"boolean"},"triggerCategory":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}}}}}}},"400":{"description":"Invalid query parameters"},"401":{"description":"Unauthorized"}}}},"/api/v1/event-types/categories":{"get":{"summary":"List event categories","description":"Retrieves a list of unique event categories available in the organization.\nUseful for populating filter dropdowns in the frontend.\n","tags":["Event Types"],"responses":{"200":{"description":"List of event categories","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string","example":"trigger_events"},"count":{"type":"integer","example":15,"description":"Number of events in this category"}}}}}}}}},"401":{"description":"Unauthorized"}}}},"/api/v1/events":{"get":{"operationId":"getEvents","summary":"List organization events with comprehensive filtering","description":"**Event-Driven Architecture Hub** - Query the organization's complete event stream with advanced filtering capabilities.\n\nThis endpoint serves as the central access point for the event-driven architecture, providing comprehensive filtering \nand querying capabilities for audit trails, debugging, system monitoring, and business intelligence.\n\n## Business Context\n\nEvents are the backbone of the system's event-driven architecture, capturing every significant change and action \nacross all task management workflows. Each event represents a immutable record of what happened, when it \nhappened, who caused it, and what the state was before and after the change.\n\n**Key Use Cases:**\n- **Audit Trail**: Complete history of all changes for compliance and legal requirements\n- **System Monitoring**: Track system health, performance, and integration status\n- **Business Intelligence**: Analyze workflow patterns, user behavior, and process efficiency\n- **Debugging**: Trace issues across microservices using correlation IDs\n- **Event Replay**: Reconstruct system state and troubleshoot data inconsistencies\n- **Compliance Reporting**: Generate regulatory reports for task management transactions\n\n## Event Architecture\n\nThe platform uses **Domain-Driven Design** with events organized around business aggregates:\n- **Projects** (projects): Real estate development projects, sales processes\n- **Tasks** (tasks): Individual work items, assignments, and activities  \n- **Workflows** (workflows): Business process automation and orchestration\n- **Attachments** (attachments): Document management and file operations\n- **Sections** (sections): Task organization and project structure\n\n## Filtering Strategies\n\n**1. Entity-Based Filtering**\n- Filter by specific entities (project, task, workflow) using `aggregateType` + `aggregateId`\n- Use `entityType` + `entityId` for sub-entity filtering\n\n**2. Event Type Filtering**\n- Filter by specific event types: `eventType=project.created`\n- Use wildcards conceptually: all project events, all creation events\n\n**3. Actor-Based Filtering**\n- Track user actions vs system automation: `eventSource=USER|SYSTEM`\n- Correlation tracking across services: `correlationId`\n\n**4. Time-Based Analysis**\n- Date range filtering: `from` and `to` parameters\n- Activity patterns: daily, weekly, monthly analysis\n\n**5. Integration Monitoring**\n- Publication status tracking: `publishingStatus=FAILED` for troubleshooting\n- External system integration health monitoring\n\n## Performance Considerations\n\n- **Indexed Fields**: Queries on `eventType`, `aggregateType`, `organizationId`, and `createdAt` are optimized\n- **Date Range Limits**: For performance, avoid queries spanning more than 90 days without additional filters\n- **Pagination**: Use `limit` (max 100) and `offset` for large result sets\n- **Complex Filters**: Combine multiple filters to reduce result set size\n\n## Business Context\n\nEvents capture the complete lifecycle of workflow executions:\n- **Buy/Sell: Sales transaction workflows\n- **Document Processing: Legal document handling and approval workflows  \n- **Agent Services: Sales agent activity tracking\n- **Financing: Payment and financing process events\n- **Compliance: Planning and regulatory compliance\n","tags":["Events"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"eventType","schema":{"type":"string","enum":["project.created","project.updated","project.deleted","project.status_changed","project.archived","project.restored","task.created","task.updated","task.deleted","task.assigned","task.completed","task.status_changed","workflow.created","workflow.started","workflow.paused","workflow.resumed","workflow.completed","workflow.cancelled","workflow-stage.started","workflow-stage.completed","workflow-stage.skipped","workflow-stage.failed","attachment.uploaded","attachment.downloaded","attachment.deleted","attachment.virus_scanned","section.created","section.updated","section.deleted","service.registered","service.updated","service.deactivated"]},"description":"**Filter by specific event type** - Use this to focus on particular types of system activities.\n\n**Common Patterns:**\n- `project.created` - New projects initiated\n- `task.assigned` - Task assignments to users or services\n- `workflow.completed` - Business process completions\n- `attachment.uploaded` - Document uploads (contracts, plans, etc.)\n\n**Business Examples:**\n- Monitor new projects: `eventType=project.created`\n- Track document processing: `eventType=attachment.uploaded&eventType=attachment.virus_scanned`\n- Workflow completion rates: `eventType=workflow.completed`\n","example":"project.created"},{"in":"query","name":"aggregateType","schema":{"type":"string","enum":["project","task","workflow","workflow-stage","attachment","section","service","dependency"]},"description":"**Filter by aggregate root type** - Focus on events related to specific business domains.\n\n**Aggregate Types:**\n- `project` - Business projects, development initiatives, sales processes\n- `task` - Individual work items, assignments, activities\n- `workflow` - Business process automation, approval chains\n- `attachment` - Document management, file operations\n- `section` - Project organization, task grouping\n\n**Use Cases:**\n- All project-related activity: `aggregateType=project`\n- Document management audit: `aggregateType=attachment`\n- Workflow performance analysis: `aggregateType=workflow`\n","example":"project"},{"in":"query","name":"aggregateId","schema":{"type":"string","format":"uuid"},"description":"**Filter by specific aggregate instance** - Track all events for a particular entity.\n\n**Typical Scenarios:**\n- Complete project history: `aggregateType=project&aggregateId=<project-uuid>`\n- Task lifecycle tracking: `aggregateType=task&aggregateId=<task-uuid>`  \n- Workflow execution trace: `aggregateType=workflow&aggregateId=<workflow-uuid>`\n\n**Business Example:**\nTrack all events for \"Q4 Website Redesign\" project from creation to completion.\n","example":"456e7890-e89b-12d3-a456-426614174000"},{"in":"query","name":"entityType","schema":{"type":"string","maxLength":100},"description":"**Filter by specific entity type** - Useful when entity differs from aggregate.\n\n**Advanced Filtering:**\n- Sub-entity events within larger aggregates\n- Cross-aggregate relationship tracking\n- Fine-grained entity-specific filtering\n\n**Example:** Filter workflow-stage events within a workflow aggregate.\n","example":"project"},{"in":"query","name":"entityId","schema":{"type":"string","maxLength":50},"description":"**Filter by specific entity identifier** - Precise entity-level filtering.\n\n**Use with entityType** for exact entity matching.\nUseful for tracking specific sub-entities within larger business processes.\n","example":"456e7890-e89b-12d3-a456-426614174000"},{"in":"query","name":"eventSource","schema":{"type":"string","enum":["USER","SYSTEM","WEBHOOK","SCHEDULE"]},"description":"**Filter by event source** - Distinguish between different types of system activity.\n\n**Event Sources:**\n- `USER` - Direct user actions via web interface or API\n- `SYSTEM` - Automated system processes, background jobs\n- `WEBHOOK` - External system integrations, third-party callbacks\n- `SCHEDULE` - Time-based triggers, scheduled workflows\n\n**Analysis Scenarios:**\n- User activity monitoring: `eventSource=USER`\n- System automation audit: `eventSource=SYSTEM`\n- Integration health: `eventSource=WEBHOOK`\n- Scheduled process monitoring: `eventSource=SCHEDULE`\n","example":"USER"},{"in":"query","name":"correlationId","schema":{"type":"string","format":"uuid"},"description":"**Filter by correlation ID** - Track related events across microservices and business processes.\n\n**Distributed Tracing:**\n- Follow a business transaction across multiple services\n- Debug complex workflows spanning multiple aggregates\n- Trace user sessions and multi-step processes\n\n**Business Example:**\nTrack all events related to a project from initiation through completion,\nincluding document uploads, approval workflows, and financial processing.\n","example":"987fcdeb-51a2-43d7-b456-426614174000"},{"in":"query","name":"publishingStatus","schema":{"type":"string","enum":["PENDING","PUBLISHED","FAILED","PARTIAL"]},"description":"**Filter by publishing status** - Monitor event publication to external systems and integration health.\n\n**Publication Statuses:**\n- `PENDING` - Events waiting to be published to external topics\n- `PUBLISHED` - Successfully published to all configured topics\n- `FAILED` - Publication failed, requires investigation\n- `PARTIAL` - Published to some but not all topics\n\n**Operational Use Cases:**\n- Integration monitoring: `publishingStatus=FAILED`\n- System health checks: `publishingStatus=PARTIAL`\n- Publication queue monitoring: `publishingStatus=PENDING`\n\n**Troubleshooting:** Use `FAILED` status to identify integration issues.\n","example":"PUBLISHED"},{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"**Start date for time-range filtering** - Include events created on or after this timestamp.\n\n**Time-Based Analysis:**\n- Daily activity reports: Set `from` to start of day\n- Weekly/monthly trends: Use broader date ranges\n- Real-time monitoring: Recent events only\n\n**Performance Note:** For optimal performance, avoid date ranges exceeding 90 days without additional filters.\n\n**Business Hours:** Consider local timezone when analyzing user activity patterns.\n","example":"2024-02-01T00:00:00Z"},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"},"description":"**End date for time-range filtering** - Include events created on or before this timestamp.\n\n**Combine with `from`** to create precise time windows for analysis.\n\n**Analysis Patterns:**\n- Business day analysis: 08:00-18:00 CET\n- Weekend activity: Saturday-Sunday periods\n- Month-end processing: Last 3 days of month\n","example":"2024-02-29T23:59:59Z"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"**Maximum number of events to return** - Controls pagination and response size.\n\n**Optimization Guidelines:**\n- Small limit (10-20): Interactive dashboards, real-time updates\n- Medium limit (50-75): Reports and analysis\n- Large limit (100): Bulk data export, batch processing\n\n**Performance Impact:** Larger limits increase response time and memory usage.\n","example":20},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"default":0},"description":"**Number of events to skip** - Enables pagination through large result sets.\n\n**Pagination Pattern:**\n- Page 1: `offset=0&limit=20`\n- Page 2: `offset=20&limit=20`\n- Page 3: `offset=40&limit=20`\n\n**Large Datasets:** For very large result sets, consider using date-based pagination with `from`/`to` parameters.\n","example":0}],"responses":{"200":{"description":"**Successfully retrieved events** - Returns filtered list of events with pagination metadata.\n\nThe response includes comprehensive event details with publication status and topic information.\nEvents are ordered by creation time (newest first) for optimal relevance.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsListResponse"},"examples":{"recent_project_events":{"summary":"Recent Project Events","description":"Latest project-related events for monitoring project activity","value":{"events":[{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"project.created","eventSource":"USER","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174000","eventData":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Q4 Website Redesign","description":"Complete website redesign and launch","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"projectType":"apartment","rooms":3,"size":85,"address":"123 Main Street"}},"previousData":null,"actorId":"user-123","actorType":"USER","actorName":"Lars Andersen","version":"1.0","publishingStatus":"PUBLISHED","publishingError":null,"publishedAt":"2024-02-15T10:35:00.000Z","publishedToTopics":["topic-123e4567-e89b-12d3-a456-426614174000"],"createdAt":"2024-02-15T10:30:00.000Z","idempotencyKey":"project-create-456e7890-20240215103000","eventType":{"name":"Project Created","category":"PROJECT_LIFECYCLE"},"eventPublications":[{"id":"pub-123e4567-e89b-12d3-a456-426614174000","status":"PUBLISHED","topicId":"topic-123e4567-e89b-12d3-a456-426614174000","publishedAt":"2024-02-15T10:35:00.000Z","topic":{"topicName":"org-12345678-project-events"}}]}],"total":245,"limit":20,"offset":0}},"failed_publications":{"summary":"Failed Event Publications","description":"Events that failed to publish to external systems, requiring investigation","value":{"events":[{"id":"789e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"task.assigned","eventSource":"SYSTEM","aggregateType":"task","aggregateId":"321e7890-e89b-12d3-a456-426614174000","eventData":{"taskId":"321e7890-e89b-12d3-a456-426614174000","assigneeId":"user-456","projectId":"456e7890-e89b-12d3-a456-426614174000","dueDate":"2024-02-20T16:00:00Z"},"publishingStatus":"FAILED","publishingError":"Topic not found: org-12345678-task-events","publishedAt":null,"publishedToTopics":[],"createdAt":"2024-02-15T14:30:00.000Z","eventPublications":[{"id":"pub-789e4567-e89b-12d3-a456-426614174000","status":"FAILED","topicId":"topic-789e4567-e89b-12d3-a456-426614174000","publishedAt":null}]}],"total":12,"limit":20,"offset":0}},"workflow_trace":{"summary":"Workflow Execution Trace","description":"Complete trace of a workflow execution using correlation ID","value":{"events":[{"id":"111e4567-e89b-12d3-a456-426614174000","eventTypeCode":"workflow.started","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","aggregateType":"workflow","eventData":{"workflowId":"wf-123e4567-e89b-12d3-a456-426614174000","templateName":"Standard Project Workflow","projectId":"456e7890-e89b-12d3-a456-426614174000"},"createdAt":"2024-02-15T10:30:00.000Z"},{"id":"222e4567-e89b-12d3-a456-426614174000","eventTypeCode":"workflow-stage.started","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","aggregateType":"workflow-stage","eventData":{"stageId":"stage-123e4567-e89b-12d3-a456-426614174000","stageName":"Dokumentsamling","workflowId":"wf-123e4567-e89b-12d3-a456-426614174000"},"createdAt":"2024-02-15T10:31:00.000Z"}],"total":8,"limit":20,"offset":0}}}}}},"400":{"description":"**Invalid request parameters** - Validation errors in query parameters or malformed filters.\n\n**Common Issues:**\n- Invalid date format in `from`/`to` parameters\n- Invalid UUID format in ID parameters\n- Out-of-range values for `limit` or `offset`\n- Invalid enum values for `eventSource` or `publishingStatus`\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_QUERY_PARAMETERS","message":"Invalid date format in from parameter","details":{"field":"from","provided":"2024-02-30","expected":"ISO 8601 date-time format (YYYY-MM-DDTHH:mm:ssZ)"}}}}}},"401":{"description":"**Authentication required** - Missing or invalid API key.\n\nEnsure the `X-API-Key` header contains a valid organization-scoped API key.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"AUTHENTICATION_REQUIRED","message":"API key is required","details":{}}}}}},"403":{"description":"**Access forbidden** - API key valid but lacks permission for event access.\n\nThe provided API key may not have sufficient permissions to access event data.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"ACCESS_FORBIDDEN","message":"Insufficient permissions to access events","details":{"required_permission":"events:read"}}}}}},"500":{"description":"**Internal server error** - Unexpected system error during event retrieval.\n\n**Possible Causes:**\n- Database connectivity issues\n- Query timeout on large datasets\n- Internal service failures\n\n**Recommended Actions:**\n- Retry the request with smaller date ranges\n- Add more specific filters to reduce query complexity\n- Contact support if the issue persists\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to list events","details":{"error":"Database query timeout"}}}}}}}}},"/api/v1/events/publish":{"post":{"operationId":"publishEvent","tags":["Events"],"summary":"Manually publish events to the event system","description":"Enables manual creation and publication of events for integration, backfilling, and custom business logic.\nThis endpoint provides direct access to the event publishing system, allowing external systems and \nintegrations to participate in the organization's event-driven architecture.\n\n## Business Context\n\nManual event publishing serves critical business needs beyond automatic system-generated events:\n\n### Integration Events\nExternal systems can publish events to maintain consistency across the business ecosystem.\nExamples include CRM updates, external calendar changes, third-party data synchronization,\nand webhook-triggered state changes from partner systems.\n\n### Business Process Events\nCustom business logic can trigger events for workflows not directly managed by the platform.\nExamples include manual milestone completions, external approval notifications, regulatory\ncompliance events, and custom entity lifecycle events specific to task management.\n\n### Event Sourcing & Backfilling\nSupport for event sourcing patterns where historical events need reconstruction or missing\nevents require backfilling. Essential for data migration, system recovery, and audit trail\nreconstruction for compliance with compliance requirements.\n\n### Multi-System Orchestration\nCoordinate complex business processes spanning multiple systems by publishing coordination\nevents. Examples include project workflows involving CRM, legal systems, \nfinancial platforms, and government registration systems.\n\n## Event Publishing Features\n\n### Comprehensive Event Metadata\n- **Event Type Classification**: Support for all standard event types plus custom extensions\n- **Actor Tracking**: Complete audit trail with user, system, or service attribution\n- **Correlation Support**: Event chains for complex workflow tracking\n- **Entity Relationships**: Flexible entity linking for business object relationships\n\n### Publication Control\n- **Topic Selection**: Publish to specific topics or use automatic topic routing\n- **Message Attributes**: Custom attributes for routing, filtering, and processing\n- **Message Ordering**: Maintain event sequence integrity with ordering keys\n- **Idempotency Protection**: Prevent duplicate events with custom keys\n\n### Integration Patterns\n- **Webhook Integration**: Perfect for webhook handlers converting external events\n- **Batch Processing**: Support for bulk event creation and processing\n- **API Gateway**: Expose event publishing through API gateways and proxies\n- **Microservice Communication**: Inter-service event communication\n\n## Common Use Cases\n\n### External System Integration\nPublish events when external systems update entity status,\nassignment information, or status updates. Ensures all systems stay synchronized\nwith the latest entity data.\n\n### Financial System Integration\nCreate events for payment processing, invoice generation, and financial reporting.\nCritical for maintaining accurate financial records and triggering dependent workflows\nlike rent collection and expense tracking.\n\n### Compliance Events\nPublish compliance-related events for regulatory reporting, contract milestones,\nand legal document processing. Essential for compliance regulations and\nregulatory compliance.\n\n### Portal Integration\nEnable portal applications to publish events for user requests,\nstatus updates, and communication preferences. Maintains unified event\nhistory across all customer touchpoints.\n\n### Scheduling Integration\nPublish events for external calendar changes, appointment scheduling, and\navailability updates. Keeps meeting schedules and team calendars\nsynchronized across all platforms.\n\n## Event Data Structure\n\nEvents follow a comprehensive schema supporting:\n- Rich event metadata with full actor attribution\n- Flexible payload structure for any business data\n- Previous state tracking for audit and rollback capabilities\n- Correlation chains for complex workflow tracking\n- Custom attributes for specialized routing and processing\n\n## Publishing Strategy\n\n### Automatic Topic Routing\nWhen no specific topics are provided, events are automatically routed to appropriate\ntopics based on event type and entity relationships. This ensures consistent\nevent distribution without requiring detailed topic knowledge.\n\n### Targeted Publishing\nSpecify exact topic IDs for precise control over event distribution. Useful for\nspecialized integrations, testing scenarios, and custom business logic that\nrequires specific event routing.\n\n### Publication Monitoring\nAll published events include detailed publication status tracking, enabling\nmonitoring of integration health and troubleshooting of delivery issues.\n\n## Response Structure\n\nSuccessful publication returns:\n- Complete event details with assigned ID and timestamps\n- Publication status for each target topic\n- Message IDs for tracking in Pub/Sub systems\n- Error details for any failed publications\n\nThis enables full visibility into event publishing success and provides\ndata needed for retry logic and error handling.\n","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["eventTypeCode","aggregateType","aggregateId","eventData"],"properties":{"eventTypeCode":{"type":"string","maxLength":100,"description":"**Event type code defining the nature of the event** - Must match predefined event types or custom extensions.\n\n**Standard Event Types:**\n- Project lifecycle: `project.created`, `project.updated`, `project.status_changed`\n- Task management: `task.created`, `task.assigned`, `task.completed`\n- Workflow orchestration: `workflow.started`, `workflow.completed`, `workflow-stage.started`\n- File management: `attachment.uploaded`, `attachment.downloaded`\n- System integration: `service.registered`, `dependency.created`\n\n**Custom Event Types:** Organizations can define custom event types for specialized business logic.\n","example":"project.created","enum":["project.created","project.updated","project.deleted","project.status_changed","project.archived","project.restored","task.created","task.updated","task.deleted","task.assigned","task.completed","task.status_changed","workflow.created","workflow.started","workflow.paused","workflow.resumed","workflow.completed","workflow.cancelled","workflow-stage.started","workflow-stage.completed","workflow-stage.skipped","workflow-stage.failed","attachment.uploaded","attachment.downloaded","attachment.deleted","attachment.virus_scanned","section.created","section.updated","section.deleted","service.registered","service.updated","service.deactivated","dependency.created","dependency.updated","dependency.deleted"]},"eventSource":{"type":"string","enum":["USER","SYSTEM","WEBHOOK","SCHEDULE"],"default":"USER","description":"**Source that triggered the event** - Provides context for event origin and processing.\n\n**Event Sources:**\n- `USER` - Direct user actions through web interface or mobile app\n- `SYSTEM` - Automated system processes and scheduled tasks\n- `WEBHOOK` - External system notifications via webhook endpoints\n- `SCHEDULE` - Time-based triggers and recurring processes\n\n**Usage Guidelines:** Choose the source that best represents the actual trigger for the event.\n","example":"WEBHOOK"},"aggregateType":{"type":"string","maxLength":50,"description":"**Type of the aggregate root entity** - Defines the primary business object affected by this event.\n\n**Standard Aggregate Types:**\n- `project` - Business projects and business initiatives\n- `task` - Individual work items and assignments\n- `workflow` - Multi-stage business processes\n- `workflow-stage` - Individual workflow stages\n- `attachment` - File and document management\n- `section` - Task organization and grouping\n\n**Domain-Driven Design:** Aggregates represent transaction boundaries and consistency units.\n","example":"project","enum":["project","task","workflow","workflow-stage","attachment","section","service","dependency"]},"aggregateId":{"type":"string","format":"uuid","description":"**Identifier of the aggregate root entity** - The specific business object instance this event relates to.\n\n**Business Context:** This ID links the event to the actual business entity, enabling event sourcing\nand providing the foundation for rebuilding entity state from events.\n\n**Consistency:** Must be a valid UUID of an existing entity within the organization.\n","example":"456e7890-e89b-12d3-a456-426614174000"},"eventData":{"type":"object","description":"**Event payload containing current state and change details** - Flexible JSON structure containing all relevant business data.\n\n**Structure Guidelines:**\n- Include all data necessary for event consumers to process the change\n- Provide complete current state for create/update events\n- Include business-relevant metadata and context\n- Follow consistent naming conventions (camelCase)\n\n**Data Examples:**\n- Project events: name, description, status, dates, owner information\n- Task events: assignment details, due dates, completion status\n- Workflow events: stage information, progress, participant details\n","example":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Q4 Website Redesign","description":"Complete website redesign and launch","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"projectType":"development","teamSize":5,"budget":50000,"location":"123 Main Street"}}},"previousData":{"type":"object","nullable":true,"description":"**Previous state data for update events** - Captures the entity state before the change occurred.\n\n**Audit Trail:** Essential for compliance, rollback scenarios, and change tracking.\nRequired for compliance requirements that mandate audit trails.\n\n**Usage:**\n- Always include for update/delete events\n- Omit for create events (no previous state exists)\n- Include only changed fields or complete previous state\n","example":{"name":"Untitled Project","status":"DRAFT","description":null,"ownerId":null}},"correlationId":{"type":"string","format":"uuid","nullable":true,"description":"**Correlation ID for tracking related events across services** - Links events in complex workflows and business processes.\n\n**Event Chains:** Use the same correlation ID for all events that are part of the same business transaction\nor workflow. Essential for tracing complex business transactions involving multiple systems.\n\n**Distributed Tracing:** Enables tracking of business processes across microservices and external integrations.\n","example":"987fcdeb-51a2-43d7-b456-426614174000"},"entityType":{"type":"string","maxLength":100,"nullable":true,"description":"**Type of the specific entity affected** - May differ from aggregateType for composite business objects.\n\n**Granular Tracking:** While aggregateType defines the transaction boundary, entityType\nspecifies the exact object being modified. Useful for events affecting nested entities.\n\n**Example:** A task assignment might have aggregateType=project but entityType=task.\n","example":"project"},"entityId":{"type":"string","maxLength":50,"nullable":true,"description":"**Identifier of the specific entity** - The precise object instance affected by this event.\n\n**Business Context:** Enables fine-grained event filtering and processing. Essential for\nsystems that need to react to changes on specific business objects.\n","example":"456e7890-e89b-12d3-a456-426614174000"},"actorId":{"type":"string","maxLength":50,"nullable":true,"description":"**Identifier of the actor who performed the action** - User, system, or service responsible for the change.\n\n**Audit Requirements:** Required for compliance with compliance requirements.\nProvides accountability and enables user-specific event filtering.\n\n**Actor Types:** Can be user IDs, system identifiers, or service names depending on actorType.\n","example":"user-123"},"actorType":{"type":"string","maxLength":50,"nullable":true,"enum":["USER","SYSTEM","SERVICE","WORKFLOW"],"description":"**Type of actor that performed the action** - Categorizes the source of the change for processing and audit.\n\n**Actor Categories:**\n- `USER` - Human users through web interface or mobile apps\n- `SYSTEM` - Automated system processes and background tasks\n- `SERVICE` - External services and integrations\n- `WORKFLOW` - Workflow engine and automation processes\n","example":"USER"},"actorName":{"type":"string","maxLength":255,"nullable":true,"description":"**Display name of the actor** - Human-readable name for audit trails and user interfaces.\n\n**User Experience:** Provides context in event lists and audit logs. Essential for\ncompliance requirements that mandate readable audit trails.\n","example":"Lars Andersen"},"idempotencyKey":{"type":"string","maxLength":255,"nullable":true,"description":"**Idempotency key to prevent duplicate event creation** - Ensures exactly-once event processing even with retries.\n\n**Duplicate Prevention:** Multiple requests with the same idempotency key will return the same event\nwithout creating duplicates. Critical for reliable integration with external systems.\n\n**Key Strategy:** Use business-meaningful keys that naturally prevent duplicates:\n- `project-create-{projectId}-{timestamp}`\n- `task-assignment-{taskId}-{userId}-{date}`\n- `workflow-completion-{workflowId}-{stageId}`\n","example":"project-create-456e7890-20240215103000"},"topicIds":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true,"description":"**Specific topic IDs to publish to** - Override automatic topic routing with targeted publishing.\n\n**Targeted Publishing:** When specified, events are published only to these topics,\nbypassing automatic routing. Useful for:\n- Testing and staging environments\n- Specialized integration endpoints\n- Custom business logic requiring specific routing\n\n**Automatic Routing:** When omitted, events are routed based on event type and organization configuration.\n","example":["topic-123e4567-e89b-12d3-a456-426614174000","topic-789e4567-e89b-12d3-a456-426614174000"]},"attributes":{"type":"object","additionalProperties":{"type":"string"},"nullable":true,"description":"**Message attributes for Pub/Sub routing and filtering** - Key-value pairs providing metadata for message processing.\n\n**Routing Control:** Attributes enable sophisticated message routing, filtering, and processing\nby downstream systems. Examples:\n- `priority`: `high`, `normal`, `low`\n- `region`: `oslo`, `bergen`, `trondheim`\n- `category`: `business`, `user`, `operations`\n- `urgent`: `true`, `false`\n\n**Integration Patterns:** External systems can filter subscriptions based on attributes,\nreceiving only relevant events for their business domain.\n","example":{"priority":"high","region":"us-east","category":"project","source_system":"crm"}},"orderingKey":{"type":"string","maxLength":1024,"nullable":true,"description":"**Ordering key for message ordering in Pub/Sub** - Ensures messages with the same key are processed in order.\n\n**Sequence Guarantee:** Critical for events where order matters, such as:\n- Entity status changes that must be processed sequentially\n- Task state transitions that depend on previous states\n- Workflow stage progressions that require strict ordering\n\n**Key Strategy:** Use entity IDs or business process identifiers to maintain ordering\nwithin logical groups while allowing parallel processing across different entities.\n","example":"project-456e7890-e89b-12d3-a456-426614174000"}}},"examples":{"project_creation":{"summary":"Project Creation Example","description":"Creating a new project for tracking work","value":{"eventTypeCode":"project.created","eventSource":"USER","aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","eventData":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Q4 Website Redesign","description":"Complete website redesign and launch","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"projectType":"apartment","rooms":3,"size":85,"address":"123 Main Street","price":4500000}},"correlationId":"987fcdeb-51a2-43d7-b456-426614174000","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174000","actorId":"user-123","actorType":"USER","actorName":"Lars Andersen","idempotencyKey":"project-create-456e7890-20240215103000","attributes":{"priority":"high","region":"oslo","category":"business","projectType":"apartment"},"orderingKey":"project-456e7890-e89b-12d3-a456-426614174000"}},"task_assignment":{"summary":"Task Assignment Event","description":"Assigning a legal review task to a team member","value":{"eventTypeCode":"task.assigned","eventSource":"SYSTEM","aggregateType":"task","aggregateId":"321e7890-e89b-12d3-a456-426614174000","eventData":{"taskId":"321e7890-e89b-12d3-a456-426614174000","title":"Legal Document Review","description":"Review business transaction agreement and identify potential issues","assigneeId":"user-456","assigneeName":"Kari Nordmann","projectId":"456e7890-e89b-12d3-a456-426614174000","dueDate":"2024-02-20T16:00:00Z","priority":"HIGH","estimatedHours":4},"previousData":{"assigneeId":null,"assigneeName":null,"status":"UNASSIGNED"},"correlationId":"987fcdeb-51a2-43d7-b456-426614174000","entityType":"task","entityId":"321e7890-e89b-12d3-a456-426614174000","actorId":"system-workflow","actorType":"SYSTEM","actorName":"Workflow Engine","idempotencyKey":"task-assignment-321e7890-user456-20240215","attributes":{"priority":"high","department":"legal","skill_required":"business_law"},"orderingKey":"task-321e7890-e89b-12d3-a456-426614174000"}},"workflow_completion":{"summary":"Workflow Stage Completion","description":"Completing the document collection stage of a project acquisition workflow","value":{"eventTypeCode":"workflow-stage.completed","eventSource":"USER","aggregateType":"workflow-stage","aggregateId":"stage-123e4567-e89b-12d3-a456-426614174000","eventData":{"stageId":"stage-123e4567-e89b-12d3-a456-426614174000","stageName":"Dokumentsamling","workflowId":"wf-123e4567-e89b-12d3-a456-426614174000","workflowName":"Eiendomskjøp Standard","completedAt":"2024-02-15T14:30:00.000Z","completedBy":"user-789","completionNotes":"Alle nødvendige dokumenter er samlet inn og verifisert","documentsCollected":["title_deed","site_survey","energy_certificate","building_permits"],"qualityScore":95},"previousData":{"status":"IN_PROGRESS","completedAt":null,"completionNotes":null},"correlationId":"987fcdeb-51a2-43d7-b456-426614174000","entityType":"workflow-stage","entityId":"stage-123e4567-e89b-12d3-a456-426614174000","actorId":"user-789","actorType":"USER","actorName":"Erik Hansen","idempotencyKey":"stage-complete-stage123-20240215143000","attributes":{"workflow_type":"project_acquisition","completion_method":"manual","quality_score":"95"},"orderingKey":"workflow-wf-123e4567-e89b-12d3-a456-426614174000"}},"external_integration":{"summary":"External System Integration Event","description":"Publishing an event from a webhook integration with external management system","value":{"eventTypeCode":"service.updated","eventSource":"WEBHOOK","aggregateType":"service","aggregateId":"svc-987fcdeb-51a2-43d7-b456-426614174000","eventData":{"serviceId":"svc-987fcdeb-51a2-43d7-b456-426614174000","serviceName":"Management System","status":"ACTIVE","lastSyncAt":"2024-02-15T12:00:00.000Z","syncedRecords":245,"newProperties":12,"updatedProperties":15,"errors":[],"healthScore":98},"previousData":{"status":"SYNCING","lastSyncAt":"2024-02-14T12:00:00.000Z","syncedRecords":230},"correlationId":"111fcdeb-51a2-43d7-b456-426614174000","entityType":"service","entityId":"svc-987fcdeb-51a2-43d7-b456-426614174000","actorId":"webhook-external-system","actorType":"SERVICE","actorName":"External System Webhook","idempotencyKey":"sync-complete-externalSystem-20240215120000","topicIds":["topic-integrations-123","topic-entity-updates-456"],"attributes":{"integration_type":"external_system","webhook_source":"external_system","sync_type":"incremental","data_quality":"high"},"orderingKey":"service-svc-987fcdeb-51a2-43d7-b456-426614174000"}}}}}},"responses":{"201":{"description":"**Event created and published successfully** - The event has been created in the system and published to all relevant topics.\n\nReturns complete event details including publication status, allowing monitoring of event delivery\nand integration with downstream systems. The response provides all information needed for\ntracking, retry logic, and audit trail operations.\n","content":{"application/json":{"schema":{"type":"object","required":["event","publications"],"properties":{"event":{"$ref":"#/components/schemas/Event"},"publications":{"type":"array","items":{"type":"object","required":["id","topicId","topicName","status"],"properties":{"id":{"type":"string","format":"uuid","description":"Publication record identifier for tracking","example":"pub-123e4567-e89b-12d3-a456-426614174000"},"topicId":{"type":"string","format":"uuid","description":"Target topic identifier","example":"topic-123e4567-e89b-12d3-a456-426614174000"},"topicName":{"type":"string","description":"Human-readable topic name","example":"org-12345678-project-events"},"status":{"type":"string","enum":["PUBLISHED","FAILED","PENDING"],"description":"Publication status for this specific topic","example":"PUBLISHED"},"publishedAt":{"type":"string","format":"date-time","nullable":true,"description":"Publication timestamp (null if failed or pending)","example":"2024-02-15T10:35:00.000Z"},"pubsubMessageId":{"type":"string","nullable":true,"description":"Google Pub/Sub message ID for tracking","example":"7891234567890"},"errorMessage":{"type":"string","nullable":true,"description":"Error details if publication failed","example":null}}},"description":"Publication details for each target topic"}}},"examples":{"successful_publication":{"summary":"Successful Event Publication","description":"Event successfully published to all target topics","value":{"event":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"project.created","eventSource":"USER","aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","eventData":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Q4 Website Redesign","description":"Complete website redesign and launch","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"projectType":"apartment","rooms":3,"size":85}},"correlationId":"987fcdeb-51a2-43d7-b456-426614174000","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174000","actorId":"user-123","actorType":"USER","actorName":"Lars Andersen","version":"1.0","publishingStatus":"PUBLISHED","publishingError":null,"publishedAt":"2024-02-15T10:35:00.000Z","publishedToTopics":["topic-123e4567-e89b-12d3-a456-426614174000"],"createdAt":"2024-02-15T10:30:00.000Z","idempotencyKey":"project-create-456e7890-20240215103000"},"publications":[{"id":"pub-123e4567-e89b-12d3-a456-426614174000","topicId":"topic-123e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-project-events","status":"PUBLISHED","publishedAt":"2024-02-15T10:35:00.000Z","pubsubMessageId":"7891234567890","errorMessage":null}]}},"partial_publication":{"summary":"Partial Publication Success","description":"Event published to some topics but failed on others","value":{"event":{"id":"789e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"task.assigned","eventSource":"SYSTEM","aggregateType":"task","aggregateId":"321e7890-e89b-12d3-a456-426614174000","publishingStatus":"PARTIAL","publishingError":"Failed to publish to 1 of 2 topics","publishedAt":"2024-02-15T14:30:00.000Z","publishedToTopics":["topic-123e4567-e89b-12d3-a456-426614174000"],"createdAt":"2024-02-15T14:30:00.000Z"},"publications":[{"id":"pub-success-123","topicId":"topic-123e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-task-events","status":"PUBLISHED","publishedAt":"2024-02-15T14:30:00.000Z","pubsubMessageId":"1234567890123","errorMessage":null},{"id":"pub-failed-456","topicId":"topic-456e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-notifications","status":"FAILED","publishedAt":null,"pubsubMessageId":null,"errorMessage":"Topic does not exist or insufficient permissions"}]}}}}}},"400":{"description":"**Invalid request data** - Validation errors in the request body or missing required fields.\n\n**Common Validation Issues:**\n- Missing required fields (eventTypeCode, aggregateType, aggregateId, eventData)\n- Invalid event type codes not matching predefined types\n- Malformed UUIDs in ID fields\n- Invalid enum values for eventSource, aggregateType, or actorType\n- Payload size exceeding limits (typically 1MB for event data)\n- Invalid date formats in eventData or timestamp fields\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_required_fields":{"summary":"Missing Required Fields","description":"Request missing essential event data","value":{"error":{"code":"VALIDATION_ERROR","message":"Missing required fields","details":{"required":["eventTypeCode","aggregateType","aggregateId","eventData"],"received":["eventTypeCode","aggregateType"],"missing":["aggregateId","eventData"]}}}},"invalid_event_type":{"summary":"Invalid Event Type Code","description":"Event type not recognized by the system","value":{"error":{"code":"INVALID_EVENT_TYPE","message":"Invalid event type code","details":{"provided":"custom.unknown.event","validTypes":["project.created","project.updated","task.created","task.assigned"],"suggestion":"Use a predefined event type or register a custom event type first"}}}},"invalid_uuid_format":{"summary":"Invalid UUID Format","description":"Aggregate ID or other UUID field has invalid format","value":{"error":{"code":"INVALID_UUID_FORMAT","message":"Invalid UUID format in aggregateId","details":{"field":"aggregateId","provided":"not-a-valid-uuid","expected":"Valid UUID format (e.g., 123e4567-e89b-12d3-a456-426614174000)"}}}},"payload_too_large":{"summary":"Event Payload Too Large","description":"Event data exceeds maximum allowed size","value":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"Event data payload exceeds maximum size limit","details":{"currentSize":"1.2MB","maxSize":"1MB","suggestion":"Reduce payload size or store large data externally with references"}}}}}}}},"401":{"description":"**Authentication required** - Missing or invalid API key for organization access.\n\nEnsure the `X-API-Key` header contains a valid organization-scoped API key with event publishing permissions.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"AUTHENTICATION_REQUIRED","message":"API key is required for event publishing","details":{"header":"X-API-Key","documentation":"https://docs.a.api.apart.tech/authentication"}}}}}},"403":{"description":"**Insufficient permissions** - API key lacks event publishing permissions or organization access.\n\n**Permission Requirements:**\n- Event publishing permission for the organization\n- Access to the specified aggregate entities\n- Topic publishing permissions for targeted topics\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficient_permissions":{"summary":"Insufficient Event Publishing Permissions","description":"API key lacks permission to publish events","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"API key does not have event publishing permissions","details":{"required":"events:publish","current":["events:read"],"contact":"Contact administrator to grant event publishing permissions"}}}},"entity_access_denied":{"summary":"Entity Access Denied","description":"No access to specified aggregate entity","value":{"error":{"code":"ENTITY_ACCESS_DENIED","message":"No access to specified aggregate entity","details":{"aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","reason":"Entity not found or insufficient permissions"}}}}}}}},"404":{"description":"**Resource not found** - Referenced entities or topics do not exist in the organization.\n\n**Common Causes:**\n- Aggregate ID references non-existent entity\n- Topic IDs in topicIds array don't exist\n- Organization context mismatch\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"aggregate_not_found":{"summary":"Aggregate Entity Not Found","description":"Referenced aggregate entity does not exist","value":{"error":{"code":"AGGREGATE_NOT_FOUND","message":"Aggregate entity not found","details":{"aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","organization":"org-123e4567-e89b-12d3-a456-426614174000"}}}},"topic_not_found":{"summary":"Target Topic Not Found","description":"Specified topic ID does not exist","value":{"error":{"code":"TOPIC_NOT_FOUND","message":"Specified topic not found","details":{"topicId":"topic-nonexistent-12d3-a456-426614174000","availableTopics":["topic-123e4567-e89b-12d3-a456-426614174000"]}}}}}}}},"409":{"description":"**Duplicate event detected** - Event with the same idempotency key already exists.\n\n**Idempotency Protection:** When an idempotency key is provided, duplicate requests return\nthe original event details without creating a new event. This is the expected behavior\nfor reliable integration patterns.\n","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorResponse/properties/error"},"existingEvent":{"$ref":"#/components/schemas/Event"}}},"example":{"error":{"code":"DUPLICATE_EVENT","message":"Event with this idempotency key already exists","details":{"idempotencyKey":"project-create-456e7890-20240215103000","existingEventId":"123e4567-e89b-12d3-a456-426614174000","createdAt":"2024-02-15T10:30:00.000Z"}},"existingEvent":{"id":"123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"project.created","publishingStatus":"PUBLISHED","createdAt":"2024-02-15T10:30:00.000Z"}}}}},"500":{"description":"**Internal server error** - Event creation succeeded but publication to topics failed.\n\n**Partial Success Scenario:** The event is created in the database but publication to\nexternal topics may have failed. Check the event's publication status for details.\n\n**Recovery:** Events with failed publications can be republished using the event ID\nand publication retry endpoints.\n","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorResponse/properties/error"},"event":{"$ref":"#/components/schemas/Event","nullable":true}}},"examples":{"publication_failure":{"summary":"Event Created But Publication Failed","description":"Event stored successfully but failed to publish to topics","value":{"error":{"code":"PUBLICATION_FAILURE","message":"Event created but failed to publish to all topics","details":{"eventId":"123e4567-e89b-12d3-a456-426614174000","failedTopics":["topic-456e4567-e89b-12d3-a456-426614174000"],"error":"Pub/Sub service temporarily unavailable","retryRecommended":true}},"event":{"id":"123e4567-e89b-12d3-a456-426614174000","publishingStatus":"FAILED","publishingError":"Pub/Sub service temporarily unavailable","createdAt":"2024-02-15T10:30:00.000Z"}}},"system_error":{"summary":"Internal System Error","description":"Unexpected system error during event processing","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to publish event due to system error","details":{"error":"Database connection timeout","requestId":"req-123e4567-e89b-12d3-a456-426614174000","support":"Contact support with request ID for assistance"}},"event":null}}}}}}}}},"/api/v1/events/{id}":{"get":{"operationId":"getEvent","summary":"Retrieve detailed information about a specific event","description":"Retrieves comprehensive information about a specific event in the organization's audit trail. \nThis endpoint is essential for event debugging, audit trail investigation, and troubleshooting \nworkflow and integration issues.\n\n## Business Logic\n\nThe event retrieval service provides complete event context including:\n- **Event Metadata**: Core event information (ID, type code, source, timestamps)\n- **Entity Context**: Aggregate and entity identifiers for tracking business objects\n- **Actor Information**: Details about who or what triggered the event\n- **Event Data**: Complete payload with current and previous state (for updates)\n- **Publication Status**: Information about event distribution to topics\n- **Schema Validation**: Event type schema and validation information\n\n## Event Investigation Use Cases\n\nThis endpoint is typically used for:\n- **Debugging Failed Workflows**: Understanding why a workflow stage failed\n- **Audit Trail Analysis**: Investigating changes to business entities\n- **Integration Troubleshooting**: Diagnosing event publication issues\n- **Performance Analysis**: Understanding event processing patterns\n- **Compliance Reporting**: Providing detailed audit information\n\n## Data Enrichment\n\nThe response includes enriched data through related entities:\n- **Event Type Metadata**: Human-readable names, categories, and payload schemas\n- **Publication Details**: Complete publication history across all topics\n- **Topic Information**: Names and categories of publication targets\n\n## Security & Access Control\n\n- Events are strictly organization-scoped for multi-user data isolation\n- Only events belonging to the authenticated organization are accessible\n- API key authentication required for all requests\n- All access attempts are logged for security auditing\n","tags":["Events"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"description":"Unique event identifier (UUID format).\n\n**Investigation Tip**: Event IDs are typically found in:\n- Event list responses from `/api/v1/events`\n- Webhook payloads sent to external systems\n- Application logs during debugging\n- Workflow execution traces\n","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"Event retrieved successfully with complete details and related information.\n\nThe response includes:\n- Complete event metadata and payload\n- Event type schema information\n- Publication status across all configured topics\n- Actor information for audit trail\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"},"examples":{"project_created_event":{"summary":"Project Creation Event","description":"Complete event data for a project creation with schema validation and publication status","value":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"project.created","eventSource":"USER","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","aggregateType":"project","aggregateId":"456e7890-e89b-12d3-a456-426614174000","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174000","eventData":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Q4 Website Redesign","description":"Complete website redesign and launch","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"projectType":"apartment","rooms":3,"size":85}},"previousData":null,"actorId":"user-123","actorType":"USER","actorName":"Lars Andersen","version":"1.0","publishingStatus":"PUBLISHED","publishingError":null,"publishedAt":"2024-02-15T10:35:00.000Z","publishedToTopics":["topic-123e4567-e89b-12d3-a456-426614174000"],"createdAt":"2024-02-15T10:30:00.000Z","idempotencyKey":"project-create-456e7890-20240215103000","eventType":{"name":"Project Created","description":"Triggered when a new project is created","category":"PROJECT_LIFECYCLE","payload_schema":{"type":"object","required":["projectId","name","status"],"properties":{"projectId":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":255}}}},"eventPublications":[{"id":"pub-123e4567-e89b-12d3-a456-426614174000","topic_id":"topic-123e4567-e89b-12d3-a456-426614174000","status":"PUBLISHED","published_at":"2024-02-15T10:35:00.000Z","created_at":"2024-02-15T10:35:00.000Z","topic":{"topic_name":"project-lifecycle-events","category":"BUSINESS_EVENTS"}}]}},"task_update_event":{"summary":"Task Update Event with Previous State","description":"Event showing task status change with previous data for audit trail","value":{"id":"789e0123-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"task.status_changed","eventSource":"USER","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","aggregateType":"task","aggregateId":"321e4567-e89b-12d3-a456-426614174000","entityType":"task","entityId":"321e4567-e89b-12d3-a456-426614174000","eventData":{"taskId":"321e4567-e89b-12d3-a456-426614174000","title":"Prepare site inspection report","status":"COMPLETED","completedAt":"2024-02-15T14:30:00.000Z","assigneeId":"user-456"},"previousData":{"status":"IN_PROGRESS","completedAt":null},"actorId":"user-456","actorType":"USER","actorName":"Anna Eriksson","version":"1.0","publishingStatus":"PUBLISHED","publishingError":null,"publishedAt":"2024-02-15T14:31:00.000Z","publishedToTopics":["topic-456e7890-e89b-12d3-a456-426614174000"],"createdAt":"2024-02-15T14:30:30.000Z","idempotencyKey":null,"eventType":{"name":"Task Status Changed","description":"Triggered when a task status is updated","category":"TASK_LIFECYCLE","payload_schema":{"type":"object","required":["taskId","status"],"properties":{"taskId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["TODO","IN_PROGRESS","COMPLETED","CANCELLED"]}}}},"eventPublications":[{"id":"pub-456e7890-e89b-12d3-a456-426614174000","topic_id":"topic-456e7890-e89b-12d3-a456-426614174000","status":"PUBLISHED","published_at":"2024-02-15T14:31:00.000Z","created_at":"2024-02-15T14:31:00.000Z","topic":{"topic_name":"task-updates","category":"OPERATIONAL_EVENTS"}}]}},"failed_publication_event":{"summary":"Event with Failed Publication","description":"Example of an event with publication failures for debugging integration issues","value":{"id":"654e3210-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","eventTypeCode":"workflow.started","eventSource":"SYSTEM","correlationId":"111fcdeb-51a2-43d7-b456-426614174000","aggregateType":"workflow","aggregateId":"999e4567-e89b-12d3-a456-426614174000","entityType":"workflow","entityId":"999e4567-e89b-12d3-a456-426614174000","eventData":{"workflowId":"999e4567-e89b-12d3-a456-426614174000","templateId":"template-inspection-process","projectId":"456e7890-e89b-12d3-a456-426614174000","status":"ACTIVE","startedAt":"2024-02-15T09:00:00.000Z"},"previousData":null,"actorId":"system","actorType":"SYSTEM","actorName":"Workflow Engine","version":"1.0","publishingStatus":"FAILED","publishingError":"Topic not found: workflow-notifications. Check topic configuration.","publishedAt":null,"publishedToTopics":[],"createdAt":"2024-02-15T09:00:15.000Z","idempotencyKey":"workflow-start-999e4567-20240215090000","eventType":{"name":"Workflow Started","description":"Triggered when a workflow is initiated","category":"WORKFLOW_LIFECYCLE","payload_schema":{"type":"object","required":["workflowId","templateId","status"]}},"eventPublications":[]}}}}}},"400":{"description":"Bad request due to invalid event ID format.\n\n**Common Issues:**\n- Event ID not in valid UUID format\n- Missing or malformed path parameter\n- Invalid characters in event ID\n\n**Resolution Steps:**\n1. Verify the event ID is a valid UUID\n2. Check that the ID matches the format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n3. Ensure the ID was correctly copied from event lists or logs\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_uuid_format":{"summary":"Invalid UUID Format","value":{"error":{"code":"INVALID_EVENT_ID","message":"Event ID must be a valid UUID format","details":{"providedId":"invalid-id-123","expectedFormat":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}}}}}}},"401":{"description":"Authentication failed - API key is missing, invalid, or expired.\n\n**Authentication Requirements:**\n- Valid API key must be provided in X-API-Key header\n- API key must belong to an active organization\n- Key must have sufficient permissions for event access\n\n**Troubleshooting:**\n1. Verify API key is correctly set in request headers\n2. Check that the API key hasn't expired\n3. Ensure the key has event read permissions\n4. Contact your organization admin if issues persist\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_api_key":{"summary":"Missing API Key","value":{"error":{"code":"MISSING_API_KEY","message":"API key is required for authentication","details":{"requiredHeader":"X-API-Key"}}}},"invalid_api_key":{"summary":"Invalid API Key","value":{"error":{"code":"INVALID_API_KEY","message":"The provided API key is invalid or expired","details":{"authenticatedOrganization":null}}}}}}}},"403":{"description":"Access forbidden - insufficient permissions to access event data.\n\n**Access Control:**\n- Events are organization-scoped for security\n- API key must belong to the same organization as the event\n- Some events may have additional access restrictions\n\n**Common Scenarios:**\n- Attempting to access events from another organization\n- API key lacks event read permissions\n- Event contains sensitive data requiring elevated access\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"organization_mismatch":{"summary":"Organization Access Denied","value":{"error":{"code":"ACCESS_DENIED","message":"Access denied to event from different organization","details":{"requestedEventId":"123e4567-e89b-12d3-a456-426614174000","userOrganization":"org-999e4567-e89b-12d3-a456-426614174000"}}}}}}}},"404":{"description":"Event not found in the organization's event store.\n\n**Possible Causes:**\n- Event ID doesn't exist in the system\n- Event belongs to a different organization\n- Event was deleted or archived (rare)\n- Transient database connectivity issues\n\n**Investigation Steps:**\n1. Verify the event ID is correct and complete\n2. Check if the event exists in the events list endpoint\n3. Confirm you're using the correct organization context\n4. Check application logs for recent event creation\n\n**For Debugging:**\n- Use GET /api/v1/events with filters to find related events\n- Check correlation IDs to trace event sequences\n- Review workflow execution logs if event is workflow-related\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"event_not_found":{"summary":"Event Not Found","value":{"error":{"code":"EVENT_NOT_FOUND","message":"Event not found","details":{"eventId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","searchedAt":"2024-02-15T15:30:00.000Z"}}}}}}}},"500":{"description":"Internal server error occurred while retrieving the event.\n\n**Potential Causes:**\n- Database connectivity issues\n- Event data corruption or schema conflicts\n- System resource exhaustion\n- Internal service failures\n\n**Recommended Actions:**\n- Retry the request after a brief delay\n- Check system status and health endpoints\n- Contact support if the issue persists\n- Provide the error correlation ID for faster resolution\n\n**For Developers:**\n- Check application logs for detailed error information\n- Monitor database performance and connectivity\n- Review event data integrity and schema compliance\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"database_connection_error":{"summary":"Database Connection Failed","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to get event","details":{"error":"Database connection timeout","correlationId":"987fcdeb-51a2-43d7-b456-426614174000","timestamp":"2024-02-15T15:30:00.000Z"}}}},"event_data_corruption":{"summary":"Event Data Corruption","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to get event","details":{"error":"Event data schema validation failed","eventId":"123e4567-e89b-12d3-a456-426614174000","schemaVersion":"1.0"}}}}}}}}}}},"/api/v1/events/{id}/publications":{"get":{"operationId":"getEventPublications","tags":["Events"],"summary":"Retrieve event publication status and delivery tracking","description":"**Critical Event Delivery Monitoring** - Provides comprehensive publication status tracking for a specific event across all configured topics.\n\nThis endpoint is essential for monitoring event delivery to external systems, debugging failed integrations, \nand ensuring compliance with audit requirements. It enables real-time visibility into the event-driven \narchitecture's publication pipeline.\n\n## Business Context\n\nEvent publications represent the delivery mechanism for distributing events to external systems, webhooks, \nand other integrated services. Each publication tracks the delivery attempt to a specific topic, providing \ncomplete visibility into the success or failure of event distribution.\n\n**Key Use Cases:**\n- **Integration Monitoring**: Verify successful delivery to CRM systems, external platforms, and external APIs\n- **Debugging Failed Deliveries**: Investigate why webhooks or integrations failed to receive events\n- **Compliance Auditing**: Provide delivery confirmation for regulatory compliance and audit trails\n- **Retry Strategy Planning**: Analyze failure patterns to optimize retry logic and error handling\n- **Performance Monitoring**: Track delivery times and success rates across different topic categories\n- **System Health Checks**: Monitor overall event system reliability and integration health\n\n## Publication Lifecycle\n\nEach publication follows a defined lifecycle with status tracking:\n\n### Publication States\n- **PENDING**: Publication queued but not yet attempted\n- **PUBLISHED**: Successfully delivered to the target topic/system\n- **FAILED**: Delivery failed after all retry attempts exhausted\n- **RETRYING**: Currently retrying after initial failure\n\n### Topic Categories\n- **WEBHOOK**: External webhook endpoints for real-time notifications\n- **INTEGRATION**: Partner system integrations (CRM, external systems)\n- **INTERNAL**: Internal system communication and coordination\n- **ANALYTICS**: Business intelligence and reporting systems\n\n### Delivery Tracking\nEach publication includes:\n- **Attempt Count**: Number of delivery attempts made\n- **Message IDs**: Google Pub/Sub message identifiers for correlation\n- **Error Details**: Specific failure reasons and technical details\n- **Timing Information**: Creation, attempt, and success timestamps\n\n## Integration Scenarios\n\n### Webhook Delivery Confirmation\n```javascript\n// Check if entity update was delivered to external CRM\nconst response = await fetch('/api/v1/events/project-update-123/publications');\nconst delivery = response.publications.find(pub => \n  pub.topicCategory === 'WEBHOOK' && pub.topicName.includes('crm-integration')\n);\nconsole.log(`CRM delivery status: ${delivery.status}`);\n```\n\n### Failed Integration Recovery\n```javascript\n// Identify failed publications for retry\nconst failedPublications = response.publications.filter(pub => \n  pub.status === 'FAILED' && pub.attempts >= 3\n);\n// Trigger manual retry or escalation\n```\n\n### Compliance Reporting\n```javascript\n// Generate audit trail for regulatory compliance\nconst auditRecord = {\n  eventId: response.eventId,\n  deliveryConfirmations: response.publications.map(pub => ({\n    destination: pub.topicName,\n    delivered: pub.status === 'PUBLISHED',\n    timestamp: pub.publishedAt,\n    messageId: pub.pubsubMessageId\n  }))\n};\n```\n","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"**Event identifier** - UUID of the event to retrieve publication status for.\n\nThe event must exist within the authenticated organization's scope. Only events \nbelonging to the current organization will be accessible.\n","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"**Publication status retrieved successfully** - Complete delivery tracking information for the event.\n\nThe response includes the event's overall publishing status plus detailed information for each \ntopic publication, including delivery attempts, success status, error details, and timing data.\n\n**Data Interpretation:**\n- Use `publishingStatus` for overall event delivery health check\n- Check individual `publications` for topic-specific delivery status\n- Monitor `attempts` count for retry strategy effectiveness\n- Use `pubsubMessageId` for correlation with Google Pub/Sub logs\n","content":{"application/json":{"schema":{"type":"object","required":["eventId","eventType","publishingStatus","publications"],"properties":{"eventId":{"type":"string","format":"uuid","description":"Unique identifier of the event","example":"123e4567-e89b-12d3-a456-426614174000"},"eventType":{"type":"string","description":"**Event type code** - Business domain and action that generated this event.\n\nUsed for filtering publications by business context and routing logic.\n","example":"project.updated"},"publishingStatus":{"type":"string","enum":["PENDING","PUBLISHED","FAILED","PARTIAL"],"description":"**Overall publishing status** - Aggregate status across all topic publications.\n\n- **PENDING**: Not yet processed for publication\n- **PUBLISHED**: Successfully delivered to all topics  \n- **FAILED**: Failed to deliver to any topic\n- **PARTIAL**: Some topics succeeded, others failed\n","example":"PUBLISHED"},"publications":{"type":"array","description":"**Per-topic publication details** - Individual delivery status for each configured topic.\n\nEach entry represents an attempt to deliver the event to a specific topic or external system.\n","items":{"type":"object","required":["id","topicId","topicName","topicCategory","status","attempts","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this publication record","example":"pub-456e7890-e89b-12d3-a456-426614174000"},"topicId":{"type":"string","format":"uuid","description":"Identifier of the target Pub/Sub topic","example":"topic-789e4567-e89b-12d3-a456-426614174000"},"topicName":{"type":"string","description":"**Human-readable topic name** - Descriptive name for the target topic or system.\n\nOften includes organization prefix and business domain for easy identification.\n","example":"org-12345678-project-events"},"topicCategory":{"type":"string","enum":["WEBHOOK","INTEGRATION","INTERNAL","ANALYTICS"],"description":"**Topic classification** - Category of the target system for routing and monitoring.\n\n- **WEBHOOK**: External webhook endpoints\n- **INTEGRATION**: Partner system integrations  \n- **INTERNAL**: Internal system communication\n- **ANALYTICS**: Business intelligence systems\n","example":"INTEGRATION"},"status":{"type":"string","enum":["PENDING","PUBLISHED","FAILED","RETRYING"],"description":"**Publication delivery status** - Current state of delivery to this specific topic.\n\n- **PENDING**: Queued for delivery\n- **PUBLISHED**: Successfully delivered\n- **FAILED**: Delivery failed permanently\n- **RETRYING**: Currently retrying after failure\n","example":"PUBLISHED"},"attempts":{"type":"integer","minimum":0,"description":"**Delivery attempt count** - Number of times delivery was attempted.\n\nUsed for monitoring retry effectiveness and identifying persistent failures.\n","example":1},"pubsubMessageId":{"type":"string","nullable":true,"description":"**Google Pub/Sub message identifier** - Unique ID for correlation with Pub/Sub logs.\n\nEssential for debugging delivery issues and tracing messages through the system.\n","example":"2847294857629"},"publishedAt":{"type":"string","format":"date-time","nullable":true,"description":"**Successful delivery timestamp** - When the event was successfully delivered to the topic.\n\nOnly present for successfully delivered publications (status: PUBLISHED).\n","example":"2024-02-15T10:35:00.000Z"},"errorMessage":{"type":"string","nullable":true,"description":"**Detailed error information** - Specific failure reason for failed deliveries.\n\nIncludes technical details for debugging integration issues and connection problems.\n","example":"Connection timeout: Unable to reach webhook endpoint https://crm.example.com/webhook"},"createdAt":{"type":"string","format":"date-time","description":"**Publication record creation timestamp** - When this publication attempt was first created.\n\nUsed for tracking delivery delays and performance monitoring.\n","example":"2024-02-15T10:30:00.000Z"}}}}}},"examples":{"successful_delivery":{"summary":"Successful Event Delivery","description":"Event successfully delivered to all configured topics","value":{"eventId":"123e4567-e89b-12d3-a456-426614174000","eventType":"project.updated","publishingStatus":"PUBLISHED","publications":[{"id":"pub-456e7890-e89b-12d3-a456-426614174000","topicId":"topic-789e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-project-events","topicCategory":"INTEGRATION","status":"PUBLISHED","attempts":1,"pubsubMessageId":"2847294857629","publishedAt":"2024-02-15T10:35:00.000Z","errorMessage":null,"createdAt":"2024-02-15T10:30:00.000Z"},{"id":"pub-567e8901-e89b-12d3-a456-426614174000","topicId":"topic-890e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-webhook-notifications","topicCategory":"WEBHOOK","status":"PUBLISHED","attempts":1,"pubsubMessageId":"2847294857630","publishedAt":"2024-02-15T10:35:01.000Z","errorMessage":null,"createdAt":"2024-02-15T10:30:00.000Z"}]}},"partial_failure":{"summary":"Partial Delivery Failure","description":"Event delivered to some topics but failed on others, requiring investigation","value":{"eventId":"456e7890-e89b-12d3-a456-426614174000","eventType":"task.completed","publishingStatus":"PARTIAL","publications":[{"id":"pub-success-123","topicId":"topic-789e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-task-events","topicCategory":"INTERNAL","status":"PUBLISHED","attempts":1,"pubsubMessageId":"2847294857631","publishedAt":"2024-02-15T14:30:00.000Z","errorMessage":null,"createdAt":"2024-02-15T14:29:55.000Z"},{"id":"pub-failed-456","topicId":"topic-890e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-crm-integration","topicCategory":"INTEGRATION","status":"FAILED","attempts":3,"pubsubMessageId":null,"publishedAt":null,"errorMessage":"Connection timeout: Unable to reach CRM webhook endpoint after 3 attempts","createdAt":"2024-02-15T14:29:55.000Z"}]}},"retry_in_progress":{"summary":"Retry in Progress","description":"Initial delivery failed, system is retrying delivery attempts","value":{"eventId":"789e4567-e89b-12d3-a456-426614174000","eventType":"workflow.started","publishingStatus":"PARTIAL","publications":[{"id":"pub-retry-789","topicId":"topic-901e4567-e89b-12d3-a456-426614174000","topicName":"org-12345678-external-notifications","topicCategory":"WEBHOOK","status":"RETRYING","attempts":2,"pubsubMessageId":null,"publishedAt":null,"errorMessage":"HTTP 503: Service temporarily unavailable","createdAt":"2024-02-15T16:45:00.000Z"}]}}}}}},"401":{"description":"**Authentication required** - Valid API key must be provided in the Authorization header.\n\nThe endpoint requires authentication to access organization-specific event data.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"**Access denied** - API key doesn't have sufficient permissions for event publication monitoring.\n\nContact your administrator to request the necessary permissions for event system access.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"**Event not found** - The specified event does not exist or is not accessible within the organization.\n\n**Common Causes:**\n- Event ID doesn't exist in the system\n- Event belongs to a different organization (access denied)\n- Event was deleted or archived\n- Malformed UUID in the request path\n\n**Troubleshooting Steps:**\n1. Verify the event ID is a valid UUID format\n2. Check if the event exists using the events list endpoint\n3. Confirm you're authenticated with the correct organization\n4. Ensure the event hasn't been deleted or archived\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"event_not_found":{"summary":"Event Not Found","description":"Event does not exist in the organization","value":{"error":{"code":"EVENT_NOT_FOUND","message":"Event not found","details":{"eventId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-456e7890-e89b-12d3-a456-426614174000"}}}}}}}},"500":{"description":"**Internal server error** - Failed to retrieve publication status due to system error.\n\nThis may indicate database connectivity issues, Pub/Sub system problems, or other infrastructure failures.\nThe event and its publications exist but cannot be retrieved at this time.\n\n**Recovery Actions:**\n- Retry the request after a brief delay\n- Check system status and health endpoints\n- Contact support if the issue persists\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"database_error":{"summary":"Database Connection Error","description":"Unable to retrieve publication data due to database issues","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to get event publications","details":{"error":"Connection timeout to database"}}}}}}}}}}},"/api/v1/events/statistics":{"get":{"operationId":"getEventStatistics","summary":"Get comprehensive event publishing statistics and analytics","description":"**Critical system monitoring and performance analysis endpoint** providing comprehensive event publishing statistics and analytics.\n\n## Business Context\n\nThis endpoint is essential for:\n- **System Health Monitoring**: Track overall event processing health and identify bottlenecks\n- **Integration Performance Analysis**: Monitor success rates across different event types and external integrations\n- **Capacity Planning**: Analyze event volume trends for infrastructure scaling decisions\n- **Business Intelligence**: Understanding workflow patterns and system usage across the organization\n- **Troubleshooting**: Identify failing event types and publication issues for rapid response\n\n## Analytics Capabilities\n\n### Event Processing Metrics\n- Total event counts with success/failure breakdown\n- Publishing success rates for reliability monitoring\n- Event type distribution analysis for understanding business patterns\n- Time-based filtering for trend analysis and reporting\n\n### Publication Health Monitoring\nEvents in the system go through a publication process to external topics and integrations.\nThis endpoint tracks:\n- **Publication Success Rate**: Critical metric for integration health\n- **Failed Publications**: Immediate visibility into integration issues\n- **Volume Analysis**: Understanding publication load and scaling requirements\n\n### Business Pattern Analysis\n- **Top Event Types**: Identify most active business processes\n- **Activity Patterns**: Understand peak usage periods and workflow efficiency\n- **Integration Usage**: See which event types are most critical for external systems\n\n## Time Range Analytics\n\n### Default Behavior\nWithout date parameters, returns statistics for the last 30 days, providing a comprehensive\nview of recent system activity while maintaining reasonable query performance.\n\n### Custom Time Ranges\nSpecify `from` and/or `to` parameters for:\n- **Daily Reports**: Single day analysis for detailed investigation\n- **Weekly/Monthly Trends**: Longer-term pattern analysis\n- **Incident Analysis**: Focused time windows around specific events\n- **Performance Baseline**: Historical comparison for capacity planning\n\n## System Monitoring Use Cases\n\n### Real-time Health Dashboards\nUse this endpoint to power monitoring dashboards that track:\n- Current system load and processing capacity\n- Integration health across all connected systems\n- Alert conditions when success rates drop below thresholds\n\n### Performance Optimization\n- Identify high-volume event types for optimization priorities\n- Track the impact of system changes on event processing\n- Monitor seasonal patterns and prepare for peak loads\n\n### Integration Monitoring\n- Track success rates for each event type to identify problematic integrations\n- Monitor publication failures to detect downstream system issues\n- Analyze event patterns to optimize webhook and notification strategies\n\n## Success Metrics Interpretation\n\n### Event Success Rate\nPercentage of events that were successfully processed and marked as PUBLISHED.\n- **Above 95%**: Healthy system operation\n- **90-95%**: Monitor closely, investigate specific failure patterns\n- **Below 90%**: Immediate attention required, likely system or integration issues\n\n### Publication Success Rate\nPercentage of publication attempts that succeeded in delivering to target topics.\nThis metric is critical for integration reliability and may differ from event success rate\nas events can succeed internally but fail to publish to external systems.\n","tags":["Events"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"from","schema":{"type":"string","format":"date-time"},"description":"**Start date for statistics analysis** (ISO 8601 format)\n\nControls the beginning of the time range for analytics. When combined with `to`,\nenables precise time window analysis for:\n- Incident investigation and root cause analysis\n- Performance comparison between different time periods\n- Trend analysis for capacity planning and optimization\n- Historical reporting for business intelligence\n\nIf only `from` is specified, statistics run from this date to the current time.\nIf neither `from` nor `to` are specified, defaults to 30 days ago.\n","example":"2024-01-01T00:00:00.000Z"},{"in":"query","name":"to","schema":{"type":"string","format":"date-time"},"description":"**End date for statistics analysis** (ISO 8601 format)\n\nDefines the end boundary for the analytics time window. Useful for:\n- Historical analysis of specific time periods\n- Comparing performance before and after system changes\n- Generating reports for specific business periods\n- Incident timeline analysis\n\nIf only `to` is specified, statistics run from 30 days prior to this date.\nIf neither `from` nor `to` are specified, defaults to the current time.\n","example":"2024-01-31T23:59:59.999Z"}],"responses":{"200":{"description":"**Comprehensive event publishing statistics and analytics**\n\nReturns detailed metrics about event processing performance, publication success rates,\nand business activity patterns within the specified time range.\n","content":{"application/json":{"schema":{"type":"object","required":["events","publications","topEventTypes"],"properties":{"events":{"type":"object","description":"**Core event processing metrics** providing insight into overall system health\nand event handling performance across all business processes.\n","required":["total","published","failed","successRate"],"properties":{"total":{"type":"integer","minimum":0,"description":"**Total number of events processed** in the specified time range.\n\nThis includes all events regardless of their final status, providing\na complete picture of system activity and business process volume.\n","example":15420},"published":{"type":"integer","minimum":0,"description":"**Number of events successfully published** to their target topics.\n\nThese events completed the full processing pipeline and were delivered\nto downstream systems. This is the primary success metric for event processing.\n","example":14673},"failed":{"type":"integer","minimum":0,"description":"**Number of events that failed to publish** due to system errors,\nintegration issues, or validation failures.\n\nFailed events require investigation and may need reprocessing.\nHigh failure rates indicate system issues that need immediate attention.\n","example":747},"successRate":{"type":"number","format":"float","minimum":0,"maximum":100,"description":"**Event processing success rate as a percentage** (published/total * 100).\n\nKey performance indicator for system health:\n- **95-100%**: Excellent system performance\n- **90-95%**: Good performance, monitor for trends\n- **85-90%**: Concerning, investigate failure patterns\n- **Below 85%**: Critical issues requiring immediate attention\n","example":95.2}}},"publications":{"type":"object","description":"**Publication delivery metrics** tracking the success of event distribution\nto external topics, webhooks, and integration endpoints.\n","required":["total","successful","failed","successRate"],"properties":{"total":{"type":"integer","minimum":0,"description":"**Total number of publication attempts** across all topics and integrations.\n\nThis count may exceed the number of events since each event can be\npublished to multiple topics or destinations.\n","example":23891},"successful":{"type":"integer","minimum":0,"description":"**Number of successful publication deliveries** to target destinations.\n\nSuccessful publications indicate that external systems received\nthe event data and acknowledged receipt.\n","example":22654},"failed":{"type":"integer","minimum":0,"description":"**Number of failed publication attempts** due to network issues,\ndestination unavailability, or authentication problems.\n\nFailed publications may trigger retry mechanisms and require\nmonitoring for pattern analysis.\n","example":1237},"successRate":{"type":"number","format":"float","minimum":0,"maximum":100,"description":"**Publication delivery success rate as a percentage** (successful/total * 100).\n\nCritical metric for integration reliability:\n- **98-100%**: Excellent integration health\n- **95-98%**: Good performance with minor issues\n- **90-95%**: Moderate issues, review integration health\n- **Below 90%**: Significant integration problems requiring investigation\n","example":94.8}}},"topEventTypes":{"type":"array","description":"**Most frequently occurring event types** ranked by volume, providing insights\ninto business activity patterns and system usage across workflows.\n\nLimited to top 10 event types for focused analysis and dashboard display.\n","maxItems":10,"items":{"type":"object","required":["eventType","count"],"properties":{"eventType":{"type":"string","maxLength":100,"description":"**Event type code** identifying the specific business process or system event.\n\nCommon high-volume event types include:\n- `task.created`, `task.updated`: Core task management activities\n- `workflow.started`, `workflow.completed`: Business process execution\n- `project.created`, `project.status_changed`: Project lifecycle events\n- `attachment.uploaded`: File management activities\n","example":"task.created"},"count":{"type":"integer","minimum":1,"description":"**Number of occurrences** of this event type within the analyzed time range.\n\nHigh counts indicate active business processes and may inform:\n- System capacity planning and resource allocation\n- Integration prioritization and optimization efforts\n- Business process analysis and workflow efficiency\n","example":3247}}}}}},"examples":{"healthySystem":{"summary":"Healthy System Performance","description":"Example response showing a well-performing system with high success rates and typical business activity patterns","value":{"events":{"total":15420,"published":14673,"failed":747,"successRate":95.2},"publications":{"total":23891,"successful":22654,"failed":1237,"successRate":94.8},"topEventTypes":[{"eventType":"task.created","count":3247},{"eventType":"task.updated","count":2891},{"eventType":"workflow.started","count":1456},{"eventType":"project.status_changed","count":1203},{"eventType":"task.completed","count":987},{"eventType":"attachment.uploaded","count":856},{"eventType":"workflow.completed","count":743},{"eventType":"project.created","count":567},{"eventType":"task.assigned","count":445},{"eventType":"workflow-stage.completed","count":389}]}},"systemWithIssues":{"summary":"System with Integration Issues","description":"Example showing a system with publication problems that require attention","value":{"events":{"total":8934,"published":7823,"failed":1111,"successRate":87.6},"publications":{"total":14567,"successful":12345,"failed":2222,"successRate":84.7},"topEventTypes":[{"eventType":"task.updated","count":2156},{"eventType":"workflow.started","count":1834},{"eventType":"task.created","count":1567},{"eventType":"attachment.uploaded","count":934},{"eventType":"project.status_changed","count":723}]}},"lowActivityPeriod":{"summary":"Low Activity Period","description":"Example from a quiet period with minimal business activity","value":{"events":{"total":234,"published":231,"failed":3,"successRate":98.7},"publications":{"total":345,"successful":342,"failed":3,"successRate":99.1},"topEventTypes":[{"eventType":"task.updated","count":89},{"eventType":"workflow.completed","count":45},{"eventType":"task.completed","count":34},{"eventType":"project.updated","count":23},{"eventType":"attachment.downloaded","count":12}]}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/entities/{entityType}/{entityId}/follow":{"post":{"tags":["Entity Follow"],"summary":"Follow an entity","description":"Allows user to follow a task, project, or workflow to receive notifications about updates.","operationId":"followEntity","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["task","project","workflow","TASK","PROJECT","WORKFLOW"]},"description":"Type of entity to follow (case-insensitive)","example":"task"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the entity","example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"],"default":"MANUAL","description":"Reason for following the entity"},"metadata":{"type":"object","additionalProperties":true,"description":"Additional metadata for the follow relationship"}}}}}},"responses":{"200":{"description":"Successfully followed the entity","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"]},"entityId":{"type":"string","format":"uuid"},"userId":{"type":"string","format":"uuid"},"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"]},"followedAt":{"type":"string","format":"date-time"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"User is already following this entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Entity Follow"],"summary":"Unfollow an entity","description":"Removes follow relationship, stopping notifications for the entity.","operationId":"unfollowEntity","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["task","project","workflow","TASK","PROJECT","WORKFLOW"]},"description":"Type of entity to unfollow (case-insensitive)","example":"task"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the entity","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"Successfully unfollowed the entity","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Successfully unfollowed entity"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Entity not found or follow relationship does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/entities/{entityType}/{entityId}/followers":{"get":{"tags":["Entity Follow"],"summary":"Get entity followers","description":"Retrieves paginated list of users following an entity with follow metadata.","operationId":"getEntityFollowers","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["task","project","workflow","TASK","PROJECT","WORKFLOW"]},"description":"Type of entity (case-insensitive)","example":"project"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the entity","example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Maximum number of followers to return"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of followers to skip for pagination"}],"responses":{"200":{"description":"List of entity followers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string","format":"uuid"},"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"]},"followedAt":{"type":"string","format":"date-time"},"metadata":{"type":"object","additionalProperties":true}}}},"total":{"type":"integer","description":"Total number of followers"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/users/{userId}/following":{"get":{"tags":["Entity Follow"],"summary":"Get user's followed entities","description":"Retrieves paginated list of entities a user is following, optionally filtered by entity type.","operationId":"getUserFollowing","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"User ID to get following list for","example":"550e8400-e29b-41d4-a716-446655440000"},{"name":"entityType","in":"query","schema":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"]},"description":"Filter by entity type","example":"TASK"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Maximum number of entities to return"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of entities to skip for pagination"}],"responses":{"200":{"description":"List of followed entities","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"]},"entityId":{"type":"string","format":"uuid"},"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"]},"followedAt":{"type":"string","format":"date-time"},"metadata":{"type":"object","additionalProperties":true}}}},"total":{"type":"integer","description":"Total number of followed entities"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/entities/{entityType}/{entityId}/following":{"get":{"tags":["Entity Follow"],"summary":"Check follow status","description":"Checks if a user is following a specific entity and returns follow details if exists.","operationId":"checkFollowStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"path","required":true,"schema":{"type":"string","enum":["task","project","workflow","TASK","PROJECT","WORKFLOW"]},"description":"Type of entity (case-insensitive)","example":"workflow"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the entity","example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"userId","in":"query","schema":{"type":"string","format":"uuid"},"description":"User ID to check (defaults to current user)","example":"550e8400-e29b-41d4-a716-446655440000"}],"responses":{"200":{"description":"Follow status information","content":{"application/json":{"schema":{"type":"object","properties":{"isFollowing":{"type":"boolean","description":"Whether the user is following the entity"},"followDetails":{"type":"object","nullable":true,"properties":{"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"]},"followedAt":{"type":"string","format":"date-time"},"metadata":{"type":"object","additionalProperties":true}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/v1/entities/follow/bulk":{"post":{"tags":["Entity Follow"],"summary":"Bulk follow entities","description":"Follow multiple entities (max 100) in one operation. Idempotent with partial success support.","operationId":"bulkFollowEntities","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entities"],"properties":{"entities":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"],"description":"Type of entity to follow"},"entityId":{"type":"string","format":"uuid","description":"Unique identifier of the entity"}}}},"followReason":{"type":"string","enum":["MANUAL","MENTIONED","ASSIGNED","CREATED"],"default":"MANUAL","description":"Reason for following all entities"}}},"examples":{"followMultipleTasks":{"summary":"Follow multiple tasks","value":{"entities":[{"entityType":"TASK","entityId":"123e4567-e89b-12d3-a456-426614174000"},{"entityType":"TASK","entityId":"456e7890-e89b-12d3-a456-426614174111"}],"followReason":"ASSIGNED"}}}}}},"responses":{"200":{"description":"Bulk follow operation results","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Bulk follow operation completed"},"data":{"type":"object","properties":{"successful":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"}}}},"failed":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"},"error":{"type":"string"}}}},"alreadyFollowing":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/entities/unfollow/bulk":{"post":{"tags":["Entity Follow"],"summary":"Bulk unfollow entities","description":"Unfollow multiple entities (max 100) in one operation. Idempotent with partial success support.","operationId":"bulkUnfollowEntities","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entities"],"properties":{"entities":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"],"description":"Type of entity to unfollow"},"entityId":{"type":"string","format":"uuid","description":"Unique identifier of the entity"}}}}}},"examples":{"unfollowCompletedTasks":{"summary":"Unfollow completed tasks","value":{"entities":[{"entityType":"TASK","entityId":"123e4567-e89b-12d3-a456-426614174000"},{"entityType":"TASK","entityId":"456e7890-e89b-12d3-a456-426614174111"}]}}}}}},"responses":{"200":{"description":"Bulk unfollow operation results","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","example":"Bulk unfollow operation completed"},"data":{"type":"object","properties":{"successful":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"}}}},"failed":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"},"error":{"type":"string"}}}},"notFollowing":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string"},"entityId":{"type":"string"}}}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/v1/tasks/{taskId}/form/action-logs":{"get":{"tags":["Form Action Logs","Tasks"],"summary":"List execution logs for a task","description":"Retrieves form action execution logs for a specific task.","operationId":"listTaskExecutionLogs","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"Task ID","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","description":"Maximum number of logs to return","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","description":"Number of logs to skip","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Execution logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FormActionExecutionLog"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-action-logs":{"get":{"tags":["Form Action Logs"],"summary":"List all execution logs","description":"Retrieves form action execution logs across all tasks with filtering options.\n\n**Filtering Options:**\n- By status (success, failure, pending, timeout, skipped)\n- By action code\n- By task or workflow\n- By date range\n- By recoverability\n","operationId":"listAllExecutionLogs","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"status","in":"query","description":"Filter by execution status","schema":{"type":"string","enum":["success","failure","pending","timeout","skipped"]}},{"name":"action_code","in":"query","description":"Filter by form action code","schema":{"type":"string"}},{"name":"task_id","in":"query","description":"Filter by task ID","schema":{"type":"string","format":"uuid"}},{"name":"workflow_id","in":"query","description":"Filter by workflow ID","schema":{"type":"string","format":"uuid"}},{"name":"is_recoverable","in":"query","description":"Filter by recoverability","schema":{"type":"boolean"}},{"name":"created_after","in":"query","description":"Filter logs created after this date","schema":{"type":"string","format":"date-time"}},{"name":"created_before","in":"query","description":"Filter logs created before this date","schema":{"type":"string","format":"date-time"}},{"name":"limit","in":"query","description":"Maximum number of logs to return","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"offset","in":"query","description":"Number of logs to skip","schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Execution logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FormActionExecutionLog"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-action-logs/{id}":{"get":{"tags":["Form Action Logs"],"summary":"Get execution log details","description":"Retrieves detailed information for a specific execution log.","operationId":"getExecutionLog","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Execution log ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Execution log retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormActionExecutionLog"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Execution log not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-action-logs/{id}/retry":{"post":{"tags":["Form Action Logs"],"summary":"Retry failed execution","description":"Retries a single failed form action execution.\n\n**Constraints:**\n- Can only retry failed or timed-out executions\n- Cannot exceed maximum retry attempts\n- Cannot retry successful or skipped executions\n","operationId":"retryExecution","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Execution log ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Execution marked for retry","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"400":{"description":"Retry not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Execution log not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-action-logs/retry-query":{"post":{"tags":["Form Action Logs"],"summary":"Bulk retry executions by query","description":"Retries multiple failed executions matching specified criteria.\n\n**Use Cases:**\n- Retry all failures for a specific action\n- Retry all failures for a workflow\n- Retry failures within a time range\n","operationId":"bulkRetryExecutions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["failure","timeout"],"default":"failure"},"action_codes":{"type":"array","items":{"type":"string"}},"task_id":{"type":"string","format":"uuid"},"workflow_id":{"type":"string","format":"uuid"},"created_after":{"type":"string","format":"date-time"},"created_before":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Bulk retry completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"retriedCount":{"type":"integer"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-action-logs/batch/{batchId}/retry-all":{"post":{"tags":["Form Action Logs"],"summary":"Retry all failed executions in a batch","description":"Retries all failed executions for a specific batch ID.","operationId":"retryBatchExecutions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"batchId","in":"path","required":true,"description":"Batch ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Batch retry completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"retriedCount":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{formTemplateId}/actions":{"post":{"tags":["Form Actions","Forms"],"summary":"Create form action","description":"Creates a configurable action that executes when forms are submitted or tasks are completed.\n\n**Use Cases:**\n- Webhook notifications on form submission\n- Sync form data to workflow data models\n- Trigger custom events or context actions\n- Automate workflows based on form completion\n\n**Action Types:**\n- **webhook**: HTTP request to external endpoint\n- **workflow_data_sync**: Sync to workflow data instance\n- **event**: Publish custom event\n- **context_action**: Execute context-specific action\n","operationId":"createFormAction","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFormActionRequest"}}}},"responses":{"201":{"description":"Form action created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormAction"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"409":{"description":"Form action with this code already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Form Actions","Forms"],"summary":"List form actions","description":"Retrieves all form actions for a specific form template.\n\n**Use Cases:**\n- View configured actions for a form\n- Filter actions by trigger or status\n- Include deleted actions for audit purposes\n","operationId":"listFormActions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}},{"name":"include_deleted","in":"query","description":"Include deleted actions","schema":{"type":"boolean","default":false}},{"name":"trigger","in":"query","description":"Filter by trigger type","schema":{"type":"string","enum":["on_submit","on_task_complete","on_approved"]}},{"name":"is_enabled","in":"query","description":"Filter by enabled status","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Form actions retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FormAction"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{formTemplateId}/actions/{code}":{"get":{"tags":["Form Actions","Forms"],"summary":"Get form action by code","description":"Retrieves a specific form action by its code.","operationId":"getFormAction","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}},{"name":"code","in":"path","required":true,"description":"Form action code","schema":{"type":"string"}}],"responses":{"200":{"description":"Form action retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormAction"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form action not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Form Actions","Forms"],"summary":"Update form action","description":"Updates an existing form action configuration.","operationId":"updateFormAction","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}},{"name":"code","in":"path","required":true,"description":"Form action code","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFormActionRequest"}}}},"responses":{"200":{"description":"Form action updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormAction"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form action not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Form Actions","Forms"],"summary":"Delete form action","description":"Soft deletes a form action (marks as deleted without removing from database).","operationId":"deleteFormAction","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}},{"name":"code","in":"path","required":true,"description":"Form action code","schema":{"type":"string"}}],"responses":{"200":{"description":"Form action deleted successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form action not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{formTemplateId}/actions/reorder":{"post":{"tags":["Form Actions","Forms"],"summary":"Reorder form actions","description":"Updates the execution order of form actions for a specific trigger.","operationId":"reorderFormActions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["trigger","action_codes"],"properties":{"trigger":{"type":"string","enum":["on_submit","on_task_complete","on_approved"]},"action_codes":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Form actions reordered successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{formTemplateId}/actions/{code}/test":{"post":{"tags":["Form Actions","Forms"],"summary":"Test form action","description":"Tests a form action with mock data without actually persisting results.\n\n**Use Cases:**\n- Validate webhook configuration\n- Test payload mapping\n- Debug action execution\n- Verify conditions and transformations\n","operationId":"testFormAction","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form template ID","schema":{"type":"string","format":"uuid"}},{"name":"code","in":"path","required":true,"description":"Form action code","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"task_id":{"type":"string","format":"uuid","description":"Optional task ID to use for testing"},"mock_form_data":{"type":"object","description":"Mock form submission data"},"mock_entity_data":{"type":"object","description":"Mock entity context data"}}}}}},"responses":{"200":{"description":"Test execution completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{taskId}/form-responses":{"get":{"tags":["Form Responses","Tasks"],"summary":"Get form submission history for a task","description":"Retrieves all form responses (submissions) for a specific task.\nResults are ordered by submission date, most recent first.\n\n**Use Cases:**\n- View all previous form submissions for a task\n- Track form revision history\n- Audit form submission activity\n","operationId":"getTaskFormResponses","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"Task ID","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","description":"Maximum number of responses to return","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","description":"Number of responses to skip","schema":{"type":"integer","minimum":0,"default":0}},{"name":"from_date","in":"query","description":"Filter responses submitted on or after this date","schema":{"type":"string","format":"date-time"}},{"name":"to_date","in":"query","description":"Filter responses submitted on or before this date","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Form responses retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FormResponse"}},"pagination":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of responses"},"limit":{"type":"integer","description":"Maximum responses per page"},"offset":{"type":"integer","description":"Current offset"},"hasMore":{"type":"boolean","description":"Whether there are more responses"}}}}},"examples":{"multipleSubmissions":{"summary":"Task with multiple form submissions","value":{"data":[{"id":"resp-001","task_id":"task-123","form_template_id":"template-456","submitted_at":"2024-01-15T10:30:00Z","submitted_by":"user-789","template_version":"1.2","response_data":{"propertyAddress":"123 Main St","inspectionDate":"2024-01-20","condition":"good"},"created_at":"2024-01-15T10:30:00Z"},{"id":"resp-002","task_id":"task-123","form_template_id":"template-456","submitted_at":"2024-01-10T09:00:00Z","submitted_by":"user-456","template_version":"1.1","response_data":{"propertyAddress":"123 Main St","inspectionDate":"2024-01-15","condition":"fair"},"created_at":"2024-01-10T09:00:00Z"}],"pagination":{"total":2,"limit":20,"offset":0,"hasMore":false}}},"noSubmissions":{"summary":"Task with no form submissions","value":{"data":[],"pagination":{"total":0,"limit":20,"offset":0,"hasMore":false}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{formTemplateId}/responses":{"get":{"tags":["Form Responses","Form Templates"],"summary":"Get all form responses for a template","description":"Retrieves all form responses submitted using a specific form template.\nResults are ordered by submission date, most recent first.\n\n**Use Cases:**\n- Analytics on form template usage\n- Aggregate reporting across all tasks using a template\n- Audit all submissions for a specific form type\n","operationId":"getFormTemplateResponses","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"formTemplateId","in":"path","required":true,"description":"Form Template ID","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","description":"Maximum number of responses to return","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","description":"Number of responses to skip","schema":{"type":"integer","minimum":0,"default":0}},{"name":"from_date","in":"query","description":"Filter responses submitted on or after this date","schema":{"type":"string","format":"date-time"}},{"name":"to_date","in":"query","description":"Filter responses submitted on or before this date","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Form responses retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/FormResponse"},{"type":"object","properties":{"task":{"type":"object","description":"Task summary","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string"}}}}}]}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"}}}}},"examples":{"templateResponses":{"summary":"Responses across multiple tasks","value":{"data":[{"id":"resp-001","task_id":"task-123","form_template_id":"template-456","submitted_at":"2024-01-15T10:30:00Z","submitted_by":"user-789","template_version":"1.2","response_data":{"propertyAddress":"123 Main St","condition":"good"},"task":{"id":"task-123","title":"Inspect 123 Main St","status":"COMPLETED"}},{"id":"resp-002","task_id":"task-789","form_template_id":"template-456","submitted_at":"2024-01-14T14:00:00Z","submitted_by":"user-456","template_version":"1.2","response_data":{"propertyAddress":"456 Oak Ave","condition":"excellent"},"task":{"id":"task-789","title":"Inspect 456 Oak Ave","status":"COMPLETED"}}],"pagination":{"total":2,"limit":20,"offset":0,"hasMore":false}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-responses/{responseId}":{"get":{"tags":["Form Responses"],"summary":"Get a specific form response","description":"Retrieves detailed information for a specific form response.","operationId":"getFormResponse","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"responseId","in":"path","required":true,"description":"Form Response ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Form response retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"allOf":[{"$ref":"#/components/schemas/FormResponse"},{"type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"status":{"type":"string"}}},"form_template":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"}}}}}]}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form response not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates":{"get":{"tags":["FormTemplates","Forms"],"summary":"List form templates","description":"Retrieve form templates for the authenticated organization with optional filtering\nby category, status, and code. This endpoint supports the backend-designed dynamic forms\nsystem for Issue #81 - Dynamic Task Forms.\n\n**Use Cases:**\n- Browse available form templates\n- Fetch a specific template by exact code\n- Filter templates by category (real_estate, maintenance, legal)\n- Find active form templates for workflow creation\n- Template management and administration\n\n**Filtering:**\n- Filter by exact template code for precise lookups\n- Filter by category for specific business domains\n- Filter by active status\n- Search by template name or code (partial match)\n\n**Security:** Only returns form templates for the authenticated organization\n","operationId":"getFormTemplates","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"category","in":"query","description":"Filter by template category","required":false,"schema":{"type":"string","example":"real_estate"}},{"name":"is_active","in":"query","description":"Filter by active status","required":false,"schema":{"type":"boolean","example":true}},{"name":"code","in":"query","description":"Filter by exact template code","required":false,"schema":{"type":"string","example":"property_inspection_v1"}},{"name":"search","in":"query","description":"Search by name or code (partial match)","required":false,"schema":{"type":"string","example":"property"}},{"name":"limit","in":"query","description":"Number of templates to return","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","description":"Number of templates to skip","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Form templates retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FormTemplate"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"}}}}},"example":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174001","code":"property_inspection_v1","name":"Property Inspection Checklist","description":"Comprehensive property inspection form","category":"real_estate","versionMajor":1,"versionMinor":0,"isActive":true,"createdAt":"2024-01-20T10:30:00.000Z"}],"pagination":{"total":12,"limit":20,"offset":0,"hasMore":false}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["FormTemplates","Forms"],"summary":"Create form template","description":"Create a new form template with JSON schema definition for backend-designed\ndynamic forms (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Create reusable form templates for workflows\n- Define Norwegian real estate form structures\n- Build template library for business processes\n- Standardize data collection across organizations\n\n**Form Schema Structure:**\n- JSON schema defining form structure, fields, and validation\n- Translation-ready with key-based labels\n- Support for various field types and constraints\n- Conditional logic and field dependencies\n\n**Security:** Can only create form templates for the authenticated organization\n","operationId":"createFormTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","name","form_schema"],"properties":{"code":{"type":"string","description":"Unique template identifier","example":"property_inspection_v1"},"name":{"type":"string","description":"Human-readable template name","example":"Property Inspection Checklist"},"description":{"type":"string","description":"Template description","example":"Comprehensive property inspection form for Norwegian real estate"},"category":{"type":"string","description":"Template category","example":"real_estate"},"form_schema":{"type":"object","description":"JSON schema defining the form structure","example":{"id":"property_inspection","version":"1.0","titleKey":"form.property.inspection.title","sections":[{"id":"basic_info","titleKey":"section.basic.info.title","fields":[{"id":"property_address","type":"text","labelKey":"field.property.address.label","required":true}]}]}},"metadata":{"type":"object","description":"Additional template metadata"}}},"examples":{"propertyInspection":{"summary":"Norwegian property inspection template","value":{"code":"property_inspection_v1","name":"Property Inspection Checklist","description":"Comprehensive property inspection form for Norwegian real estate","category":"real_estate","form_schema":{"id":"property_inspection","version":"1.0","titleKey":"form.property.inspection.title","sections":[{"id":"basic_info","titleKey":"section.basic.info.title","fields":[{"id":"property_address","type":"text","labelKey":"field.property.address.label","required":true},{"id":"inspection_date","type":"date","labelKey":"field.inspection.date.label","required":true}]},{"id":"condition_assessment","titleKey":"section.condition.assessment.title","fields":[{"id":"overall_condition","type":"select","labelKey":"field.overall.condition.label","required":true,"options":[{"value":"utmerket","labelKey":"option.condition.excellent"},{"value":"god","labelKey":"option.condition.good"},{"value":"tilfredsstillende","labelKey":"option.condition.satisfactory"},{"value":"dårlig","labelKey":"option.condition.poor"}]}]}]}}},"tenantApplication":{"summary":"Tenant application review template","value":{"code":"tenant_application_v1","name":"Tenant Application Review","description":"Form for reviewing tenant applications","category":"real_estate","form_schema":{"id":"tenant_application","version":"1.0","titleKey":"form.tenant.application.title","sections":[{"id":"applicant_info","titleKey":"section.applicant.info.title","fields":[{"id":"applicant_score","type":"number","labelKey":"field.applicant.score.label","required":true,"min":0,"max":100},{"id":"recommendation","type":"select","labelKey":"field.recommendation.label","required":true,"options":[{"value":"approved","labelKey":"option.recommendation.approved"},{"value":"rejected","labelKey":"option.recommendation.rejected"},{"value":"conditional","labelKey":"option.recommendation.conditional"}]}]}]}}}}}}},"responses":{"201":{"description":"Form template created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormTemplate"}}},"example":{"data":{"id":"123e4567-e89b-12d3-a456-426614174001","code":"property_inspection_v1","name":"Property Inspection Checklist","description":"Comprehensive property inspection form","category":"real_estate","versionMajor":1,"versionMinor":0,"isActive":true,"createdAt":"2024-01-20T10:30:00.000Z"}}}}},"400":{"description":"Bad Request - Validation errors or duplicate code","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"duplicateCode":{"summary":"Duplicate template code","value":{"error":{"code":"DUPLICATE_TEMPLATE_CODE","message":"Form template with this code already exists"}}},"validationError":{"summary":"Invalid form schema","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid form schema structure"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{id}":{"get":{"tags":["FormTemplates","Forms"],"summary":"Get form template by ID","description":"Retrieve a specific form template by its ID, including the complete form schema\ndefinition (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Load form template for task creation\n- Preview form template structure\n- Form template editing and management\n- Apply template to workflow stages\n\n**Security:** Can only access form templates belonging to the authenticated organization\n","operationId":"getFormTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Form template retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormTemplate"}}},"example":{"data":{"id":"123e4567-e89b-12d3-a456-426614174001","code":"property_inspection_v1","name":"Property Inspection Checklist","description":"Comprehensive property inspection form for Norwegian real estate","category":"real_estate","versionMajor":1,"versionMinor":0,"isActive":true,"formSchema":{"id":"property_inspection","version":"1.0","titleKey":"form.property.inspection.title","sections":[{"id":"basic_info","titleKey":"section.basic.info.title","fields":[{"id":"property_address","type":"text","labelKey":"field.property.address.label","required":true}]}]},"createdAt":"2024-01-20T10:30:00.000Z"}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FORM_TEMPLATE_NOT_FOUND","message":"Form template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["FormTemplates","Forms"],"summary":"Update form template","description":"Update an existing form template (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Update form schema definitions\n- Modify template metadata\n- Version management (increment version numbers)\n- Activate/deactivate templates\n\n**Versioning:**\n- Consider incrementing version numbers for schema changes\n- Maintain backward compatibility for existing tasks\n- Use is_active flag to manage template lifecycle\n\n**Security:** Can only update form templates belonging to the authenticated organization\n","operationId":"updateFormTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Updated template name"},"description":{"type":"string","description":"Updated template description"},"category":{"type":"string","description":"Updated template category"},"version_major":{"type":"integer","description":"Major version number"},"version_minor":{"type":"integer","description":"Minor version number"},"is_active":{"type":"boolean","description":"Template active status"},"form_schema":{"type":"object","description":"Updated form schema definition"},"metadata":{"type":"object","description":"Updated template metadata"}}},"example":{"name":"Updated Property Inspection Checklist","description":"Enhanced property inspection form with new fields","version_minor":1,"is_active":true}}}},"responses":{"200":{"description":"Form template updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/FormTemplate"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FORM_TEMPLATE_NOT_FOUND","message":"Form template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["FormTemplates","Forms"],"summary":"Delete form template","description":"Delete a form template by its ID (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Remove obsolete form templates\n- Clean up unused templates\n- Template lifecycle management\n\n**⚠️ Warning:** This action is irreversible and may affect:\n- Tasks using this template\n- Workflow templates referencing this form\n- Historical form data\n\n**Alternative:** Consider deactivating templates (is_active = false) instead\nof deletion for data integrity.\n\n**Security:** Can only delete form templates belonging to the authenticated organization\n","operationId":"deleteFormTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Form template deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FORM_TEMPLATE_NOT_FOUND","message":"Form template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/form-templates/{id}/apply-to-task/{taskId}":{"post":{"tags":["FormTemplates","Forms","Tasks"],"summary":"Apply form template to task","description":"Apply a form template to a task by setting the form_template_id foreign key.\n\n**Use Cases:**\n- Apply predefined form templates to tasks\n- Standardize form structure across workflow stages\n- Bulk task form assignment\n- Template-driven task creation\n\n**Behavior:**\n- Sets form_template_id FK on the task to reference the template\n- Updates task updated_by and updated_at fields\n- Does not affect the original template\n- If task already has a different template with responses, returns 409 conflict\n- Use `replace_existing=true` to delete existing responses and apply new template\n\n**Security:** Can only apply templates and modify tasks belonging to the authenticated organization\n","operationId":"applyFormTemplateToTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","description":"Form template ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"taskId","in":"path","description":"Task ID to apply template to","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"replace_existing","in":"query","description":"If true, delete existing form responses when replacing a different template.\nRequired when task already has a different template with responses.\n","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Form template applied to task successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"taskId":{"type":"string","format":"uuid"},"templateId":{"type":"string","format":"uuid"},"templateCode":{"type":"string"},"appliedAt":{"type":"string","format":"date-time"},"previousTemplateId":{"type":"string","format":"uuid","description":"Present when replacing a previous template"},"deletedResponseCount":{"type":"integer","description":"Number of responses deleted when replacing template"}}}}},"examples":{"newApplication":{"summary":"First template application","value":{"data":{"taskId":"789e0123-e89b-12d3-a456-426614174222","templateId":"123e4567-e89b-12d3-a456-426614174001","templateCode":"property_inspection_v1","appliedAt":"2024-01-20T10:30:00.000Z"}}},"replacement":{"summary":"Template replacement with deleted responses","value":{"data":{"taskId":"789e0123-e89b-12d3-a456-426614174222","templateId":"123e4567-e89b-12d3-a456-426614174001","templateCode":"property_inspection_v1","appliedAt":"2024-01-20T10:30:00.000Z","previousTemplateId":"456e7890-e89b-12d3-a456-426614174333","deletedResponseCount":3}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Form template or task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateNotFound":{"summary":"Form template not found","value":{"error":{"code":"FORM_TEMPLATE_NOT_FOUND","message":"Form template not found."}}},"taskNotFound":{"summary":"Task not found","value":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}}}},"409":{"description":"Task already has a different form template with responses","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FORM_TEMPLATE_CONFLICT","message":"Task already has form template 'old_template' with 3 response(s). Use ?replace_existing=true to delete existing responses and apply new template.","details":{"currentTemplateId":"456e7890-e89b-12d3-a456-426614174333","currentTemplateCode":"old_template","responseCount":3}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/organization/portals":{"get":{"tags":["Organization Portals"],"summary":"List organization portals","description":"Retrieves all portal configurations for the organization, sorted by default status then name.","operationId":"listOrganizationPortals","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"includeInactive","in":"query","description":"Include inactive portals in results","required":false,"schema":{"type":"boolean","default":false}},{"name":"page","in":"query","description":"Page number (1-based)","required":false,"schema":{"type":"integer","minimum":1}},{"name":"pageSize","in":"query","description":"Number of results per page","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Portal list retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationPortal"}}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/ServerError"}}},"post":{"tags":["Organization Portals"],"summary":"Create a new organization portal","description":"Creates a portal configuration. Portal codes must be unique, lowercase alphanumeric with underscores, 3-50 chars. Only one default portal allowed.","operationId":"createOrganizationPortal","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["portalCode","portalName"],"properties":{"portalCode":{"type":"string","pattern":"^[a-z0-9_]+$","minLength":3,"maxLength":50,"example":"customer_portal","description":"Portal code (immutable identifier)"},"portalName":{"type":"string","minLength":1,"maxLength":255,"example":"Customer Portal","description":"Human-readable portal name"},"description":{"type":"string","maxLength":1000,"example":"Portal for customer access","description":"Optional portal description"},"isActive":{"type":"boolean","default":true,"description":"Whether the portal is active"},"isDefault":{"type":"boolean","default":false,"description":"Whether this is the default portal"},"metadata":{"type":"object","description":"Optional metadata object"}}}}}},"responses":{"201":{"description":"Portal created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/OrganizationPortal"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"409":{"description":"Portal code already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/api/v1/organization/portals/{portalCode}":{"get":{"tags":["Organization Portals"],"summary":"Get a specific portal","description":"Retrieves portal configuration and metadata by portal code.","operationId":"getOrganizationPortal","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"portalCode","in":"path","required":true,"description":"The portal code identifier","schema":{"type":"string","pattern":"^[a-z0-9_]+$","example":"vendor_portal"}}],"responses":{"200":{"description":"Portal details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/OrganizationPortal"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/ServerError"}}},"put":{"tags":["Organization Portals"],"summary":"Update a portal","description":"Updates portal configuration. Supports partial updates. Setting as default unsets previous default portal.","operationId":"updateOrganizationPortal","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"portalCode","in":"path","required":true,"description":"The portal code identifier","schema":{"type":"string","pattern":"^[a-z0-9_]+$","example":"vendor_portal"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","minProperties":1,"properties":{"portalName":{"type":"string","minLength":1,"maxLength":255,"example":"Updated Customer Portal","description":"Human-readable portal name"},"description":{"type":"string","nullable":true,"maxLength":1000,"example":"Updated portal description","description":"Portal description (null to clear)"},"isActive":{"type":"boolean","description":"Whether the portal is active"},"isDefault":{"type":"boolean","description":"Whether this is the default portal"},"metadata":{"type":"object","nullable":true,"description":"Metadata object (null to clear)"}}}}}},"responses":{"200":{"description":"Portal updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/OrganizationPortal"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/ServerError"}}},"delete":{"tags":["Organization Portals"],"summary":"Delete a portal","description":"Soft deletes a portal (sets as inactive). Returns error if portal is referenced by visibility rules.","operationId":"deleteOrganizationPortal","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"portalCode","in":"path","required":true,"description":"The portal code identifier","schema":{"type":"string","pattern":"^[a-z0-9_]+$","example":"vendor_portal"}}],"responses":{"204":{"description":"Portal deleted successfully"},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"Portal not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Portal is in use and cannot be deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/ServerError"}}}},"/api/v1/organizations/current":{"get":{"tags":["Organizations"],"summary":"Get current organization details","description":"Retrieves comprehensive information about the organization associated with the provided API key.\nThis endpoint is the primary method for applications to identify their organization context and \nretrieve configuration settings that affect system behavior.\n\n## Business Logic\n\nThis endpoint serves as the foundation for multi-tenant data isolation by:\n- Validating the API key against the organization database\n- Returning organization metadata without exposing sensitive credentials\n- Providing feature flags that control system behavior (e.g., calendar integration)\n- Establishing the organization context for all subsequent API operations\n\n## Use Cases\n\n1. **Initial Application Setup**\n   - Verify API key validity on application startup\n   - Cache organization settings for performance\n   - Configure feature toggles based on organization settings\n\n2. **User Interface Customization**\n   - Display organization name in application headers\n   - Show/hide features based on enabled capabilities\n   - Personalize the user experience per organization\n\n3. **Administrative Operations**\n   - Verify organization context before administrative actions\n   - Display current settings in admin panels\n   - Audit organization access patterns\n\n4. **Feature Availability Checks**\n   - Determine if calendar features are available\n   - Check for custom integrations or add-ons\n   - Validate organization-specific limits or quotas\n\n## Security Considerations\n\n- API keys are never returned in the response for security\n- Organization IDs are validated to prevent unauthorized access\n- All requests are logged for security auditing\n- Rate limiting prevents brute force attacks\n\n## Related Endpoints\n\n- `PUT /api/v1/organizations/current` - Update organization settings\n- `GET /api/v1/calendar/auth/status` - Check calendar integration status\n- `GET /api/v1/workflows` - Access organization workflows\n","operationId":"getCurrentOrganization","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Organization details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Organization"}}},"examples":{"basic":{"summary":"Basic organization without optional features","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Startup Inc","calendarFeaturesEnabled":false,"gcpProjectId":"tasks-462013","createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-15T10:30:00.000Z"}}},"enterprise":{"summary":"Enterprise organization with all features enabled","value":{"data":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Enterprise Corp","calendarFeaturesEnabled":true,"gcpProjectId":"tasks-462013","createdAt":"2023-06-01T08:00:00.000Z","updatedAt":"2024-12-01T16:45:30.000Z"}}},"recentlyUpdated":{"summary":"Organization with recent configuration changes","value":{"data":{"id":"789a1234-e89b-12d3-a456-426614174222","name":"Growth Company LLC","calendarFeaturesEnabled":true,"gcpProjectId":"tasks-462013","createdAt":"2024-01-01T00:00:00.000Z","updatedAt":"2024-12-15T14:30:00.000Z"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"summary":"Organization does not exist","value":{"error":{"code":"ORGANIZATION_NOT_FOUND","message":"Organization not found.","details":{"organizationId":"999e9999-e89b-12d3-a456-426614174999","timestamp":"2024-12-15T10:30:00.000Z"}}}},"deleted":{"summary":"Organization has been deleted","value":{"error":{"code":"ORGANIZATION_NOT_FOUND","message":"Organization not found.","details":{"reason":"Organization may have been deleted or suspended"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Organizations"],"summary":"Update current organization settings","description":"Updates configurable settings for the authenticated organization. This endpoint enables\norganizations to modify their configuration dynamically without requiring system administrator\nintervention.\n\n## Business Logic\n\nThe update process follows these business rules:\n\n1. **Partial Updates**: Only fields provided in the request are updated; others remain unchanged\n2. **Validation**: At least one field must be provided for the update to proceed\n3. **Feature Activation**: Enabling calendar features may trigger additional setup processes\n4. **Audit Trail**: All changes are logged with actor information and timestamp\n5. **Event Publishing**: Updates trigger `organization.updated` events for downstream systems\n6. **Transactional**: Updates are atomic - either all changes succeed or none are applied\n\n## Use Cases\n\n1. **Feature Enablement**\n   - Enable calendar integration when organization purchases the add-on\n   - Activate beta features for early access customers\n   - Toggle features based on subscription tier changes\n\n2. **Rebranding Operations**\n   - Update organization name after merger or acquisition\n   - Reflect legal name changes in the system\n   - Customize display name for white-label deployments\n\n3. **Administrative Updates**\n   - Configure organization settings from admin panels\n   - Apply bulk updates via API automation\n   - Migrate organizations to new feature sets\n\n4. **Integration Setup**\n   - Enable calendar features before OAuth flow\n   - Prepare organization for third-party integrations\n   - Configure feature flags for custom workflows\n\n## Validation Rules\n\n- **name**: Optional string, 1-255 characters, cannot be empty if provided\n- **calendarFeaturesEnabled**: Optional boolean, affects access to calendar endpoints\n- **calendarRedirectUri**: Optional HTTPS URL (max 500 chars), for calendar OAuth redirect\n- At least one field must be provided in the request body\n- Organization must exist and be active\n\n## Side Effects\n\n1. **Calendar Feature Enablement**\n   - Enables access to `/api/v1/calendar/*` endpoints\n   - May trigger calendar sync initialization\n   - Affects task scheduling capabilities\n\n2. **Event Publication**\n   - Publishes `organization.updated` event with before/after state\n   - Triggers webhooks configured for organization events\n   - Updates audit log with change details\n\n## Related Endpoints\n\n- `GET /api/v1/organizations/current` - Retrieve current settings\n- `GET /api/v1/calendar/auth/url` - Start calendar OAuth (requires calendar features)\n- `GET /api/v1/events` - Subscribe to organization update events\n","operationId":"updateCurrentOrganization","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationRequest"},"examples":{"enableCalendar":{"summary":"Enable calendar integration features","description":"Activates calendar functionality for the organization","value":{"calendarFeaturesEnabled":true}},"disableCalendar":{"summary":"Disable calendar integration features","description":"Removes access to calendar functionality","value":{"calendarFeaturesEnabled":false}},"updateName":{"summary":"Update organization display name","description":"Changes how the organization name appears in the UI","value":{"name":"Acme Corporation (Europe Division)"}},"setCalendarRedirect":{"summary":"Set calendar OAuth redirect URI","description":"Configure where users are redirected after calendar authorization","value":{"calendarRedirectUri":"https://app.mycompany.com/calendar/auth/success"}},"fullUpdate":{"summary":"Update multiple settings simultaneously","description":"Both name and features can be updated in one request","value":{"name":"Premium Enterprise Customer","calendarFeaturesEnabled":true,"calendarRedirectUri":"https://dashboard.enterprise.com/integrations/calendar"}},"minimalName":{"summary":"Update with minimal name","description":"Name must be at least 1 character","value":{"name":"A"}},"maximalName":{"summary":"Update with maximum length name","description":"Name can be up to 255 characters","value":{"name":"This is a very long organization name that demonstrates the maximum allowed length for organization names in the system which is two hundred and fifty five characters total including spaces and special characters εταιρεία™"}}}}}},"responses":{"200":{"description":"Organization updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Organization"}}},"examples":{"nameUpdated":{"summary":"Organization name successfully updated","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Updated Corporation Name","calendarFeaturesEnabled":false,"gcpProjectId":"tasks-462013","createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-12-15T16:45:30.000Z"}}},"calendarEnabled":{"summary":"Calendar features successfully enabled","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Acme Corporation","calendarFeaturesEnabled":true,"gcpProjectId":"tasks-462013","createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-12-15T16:45:30.000Z"}}},"multipleUpdates":{"summary":"Both name and features updated","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Enterprise Customer LLC","calendarFeaturesEnabled":true,"gcpProjectId":"tasks-462013","createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-12-15T16:45:30.000Z"}}}}}}},"400":{"description":"Bad request - validation error or invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"noFields":{"summary":"No fields provided for update","value":{"error":{"code":"VALIDATION_ERROR","message":"At least one field must be provided for update","details":{"providedFields":[],"requiredFields":["name","calendarFeaturesEnabled"]}}}},"emptyName":{"summary":"Empty name string provided","value":{"error":{"code":"VALIDATION_ERROR","message":"Organization name cannot be empty","details":{"field":"name","constraint":"minLength: 1"}}}},"nameTooLong":{"summary":"Name exceeds maximum length","value":{"error":{"code":"VALIDATION_ERROR","message":"Organization name exceeds maximum length","details":{"field":"name","maxLength":255,"providedLength":300}}}},"invalidBoolean":{"summary":"Invalid boolean value for calendarFeaturesEnabled","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid value for calendarFeaturesEnabled","details":{"field":"calendarFeaturesEnabled","expectedType":"boolean","receivedValue":"yes"}}}},"invalidRedirectUri":{"summary":"Invalid calendar redirect URI format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid calendar redirect URI. Must be a valid HTTPS URL with public hostname and under 500 characters.","details":{"field":"calendarRedirectUri","providedValue":"http://localhost:3000/callback","requirement":"HTTPS URL with public hostname"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Organization not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"summary":"Organization does not exist","value":{"error":{"code":"ORGANIZATION_NOT_FOUND","message":"Organization not found","details":{"organizationId":"999e9999-e89b-12d3-a456-426614174999"}}}},"suspended":{"summary":"Organization is suspended","value":{"error":{"code":"ORGANIZATION_NOT_FOUND","message":"Organization not found","details":{"reason":"Organization access has been suspended"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects":{"get":{"tags":["Projects"],"summary":"List projects with filtering and pagination","description":"Retrieves projects for the authenticated organization. Projects contain tasks, sections, workflows, and attachments.\nSupports filtering by status, owner, entity relationships, dates, and full-text search.\n","operationId":"getProjects","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","schema":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"style":"form","explode":true,"description":"Filter projects by status. Supports multiple values (e.g., ?status=ACTIVE&status=DRAFT)","examples":{"single":{"summary":"Single status","value":"ACTIVE"},"multiple":{"summary":"Multiple statuses","value":["ACTIVE","DRAFT"]}}},{"name":"ownerType","in":"query","schema":{"oneOf":[{"type":"string","enum":["ROLE","POSITION","USER"]},{"type":"array","items":{"type":"string","enum":["ROLE","POSITION","USER"]}}]},"style":"form","explode":true,"description":"Filter projects by owner type. Supports multiple values (e.g., ?ownerType=USER&ownerType=ROLE)","examples":{"single":{"summary":"Single owner type","value":"USER"},"multiple":{"summary":"Multiple owner types","value":["USER","ROLE"]}}},{"name":"ownerId","in":"query","schema":{"type":"string"},"description":"Filter projects by specific owner ID","example":"user-123"},{"name":"workflowId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter projects by associated workflow","example":"456e7890-e89b-12d3-a456-426614174111"},{"name":"entityType","in":"query","schema":{"type":"string"},"description":"Filter projects by external entity type","example":"client"},{"name":"entityId","in":"query","schema":{"type":"string"},"description":"Filter projects by external entity ID","example":"client-456"},{"name":"entities","in":"query","schema":{"type":"array","items":{"type":"string","pattern":"^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+$"},"maxItems":10},"style":"form","explode":true,"description":"Filter projects by multiple entities in 'type:id' format. Maximum 10 entities. Use entityMatchMode to control AND/OR logic.","examples":{"multiple_clients":{"summary":"Multiple clients","value":["client:client-123","client:client-456"]},"mixed_entities":{"summary":"Mixed entity types","value":["client:client-789","campaign:campaign-123"]}}},{"name":"entityMatchMode","in":"query","schema":{"type":"string","enum":["ANY","ALL"],"default":"ANY"},"description":"Match mode for multiple entities. ANY returns projects linked to any entity (OR), ALL returns projects linked to all entities (AND).","example":"ANY"},{"name":"dueDateFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects due after this date (ISO 8601 format)","example":"2024-01-20T00:00:00.000Z"},{"name":"dueDateTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects due before this date (ISO 8601 format)","example":"2024-01-31T23:59:59.999Z"},{"name":"startDateFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects starting after this date (ISO 8601 format)","example":"2024-01-01T00:00:00.000Z"},{"name":"startDateTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects starting before this date (ISO 8601 format)","example":"2024-01-31T23:59:59.999Z"},{"name":"createdFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects created after this date (ISO 8601 format)","example":"2024-01-01T00:00:00.000Z"},{"name":"createdTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter projects created before this date (ISO 8601 format)","example":"2024-01-31T23:59:59.999Z"},{"name":"sortBy","in":"query","schema":{"type":"string","enum":["created_at","updated_at","due_date","start_date","name"]},"description":"Field to sort by","example":"due_date"},{"name":"sortOrder","in":"query","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction (ascending or descending)","example":"desc"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Text search across project name and description","example":"website redesign"},{"name":"portal","in":"query","schema":{"type":"string"},"description":"Portal context for visibility filtering (e.g., customer_portal, partner_portal)","example":"customer_portal"},{"name":"portalUserId","in":"query","schema":{"type":"string"},"description":"User ID in the portal context for visibility filtering","example":"user-123"}],"responses":{"200":{"description":"Projects retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"examples":{"activeProjects":{"summary":"Active projects","value":{"data":[{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Q1 Marketing Campaign","description":"Launch new product marketing campaign across digital channels","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"campaign","entityId":"campaign-q1-2024","ownerId":"user-john-doe","ownerType":"USER","startDate":"2024-01-15T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"budget":50000,"channels":["social","email","web"],"status":"in-progress"},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T16:15:00.000Z"},{"id":"789e0123-e89b-12d3-a456-426614174222","name":"Mobile App Development","description":"Build and launch iOS and Android mobile applications","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"product","entityId":"product-mobile-app","ownerId":"role-engineering-lead","ownerType":"ROLE","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-08-31T23:59:59.999Z","data":{"platforms":["ios","android"],"teamSize":8,"milestone":"beta-testing"},"createdAt":"2024-01-10T09:15:00.000Z","updatedAt":"2024-01-18T11:30:00.000Z"}],"meta":{"total":25,"page":1,"limit":20}}},"clientProjects":{"summary":"Client service delivery projects","value":{"data":[{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Acme Corp Website Redesign","description":"Complete overhaul of corporate website with modern UX","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"client","entityId":"client-acme-corp","ownerId":"user-project-mgr-123","ownerType":"USER","startDate":"2024-01-15T00:00:00.000Z","dueDate":"2024-04-30T23:59:59.999Z","data":{"contractValue":125000,"primaryContact":"john.smith@acmecorp.com","technologies":["react","nodejs","postgresql"]},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T16:15:00.000Z"}],"meta":{"total":8,"page":1,"limit":20}}},"internalProjects":{"summary":"Internal projects","value":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174333","name":"Q1 Strategic Planning","description":"Quarterly strategic planning and goal setting","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":null,"entityId":null,"ownerId":"role-operations-manager","ownerType":"ROLE","startDate":"2024-01-01T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"department":"Operations","priority":"high","category":"planning"},"createdAt":"2024-01-02T08:00:00.000Z","updatedAt":"2024-01-25T14:30:00.000Z"}],"meta":{"total":12,"page":1,"limit":20}}},"empty":{"summary":"No projects found","value":{"data":[],"meta":{"total":0,"page":1,"limit":20}}}}}}},"400":{"description":"Bad Request - Invalid parameters or validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidDateRange":{"summary":"Invalid date range","value":{"error":{"code":"INVALID_DATE_RANGE","message":"Start date must be before end date","details":{"dueDateFrom":"2024-03-01T00:00:00.000Z","dueDateTo":"2024-01-01T00:00:00.000Z"}}}},"invalidPagination":{"summary":"Invalid pagination parameters","value":{"error":{"code":"INVALID_PAGINATION","message":"Page number must be greater than 0","details":{"page":0}}}},"invalidOwnerFilter":{"summary":"Missing owner ID","value":{"error":{"code":"INVALID_FILTER","message":"ownerId is required when ownerType is specified","details":{"ownerType":"USER","ownerId":null}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Projects"],"summary":"Create a new project","description":"Creates a new project container for tasks, workflows, and attachments. Both entityType and entityId must be provided together or both omitted.","operationId":"createProject","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectInput"},"examples":{"marketingCampaign":{"summary":"Marketing campaign project","value":{"name":"Q1 Product Launch","description":"Launch new product with integrated marketing campaign","entityType":"campaign","entityId":"campaign-q1-launch","ownerId":"role-marketing-team","ownerType":"ROLE","startDate":"2024-01-15T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"budget":50000,"channels":["social","email","web"],"targetAudience":"enterprise"}}},"clientProject":{"summary":"Client service project","value":{"name":"Acme Corp Website Redesign","description":"Complete website redesign with modern UX","entityType":"client","entityId":"client-acme-corp","ownerId":"user-project-mgr-123","ownerType":"USER","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-07-31T23:59:59.999Z","data":{"budget":125000,"primaryContact":"john@client.com","deliverables":["design","development","deployment"]}}},"internalProject":{"summary":"Internal project","value":{"name":"Q1 2024 Security Audit","description":"Comprehensive security audit and compliance review","ownerId":"position-ciso","ownerType":"POSITION","startDate":"2024-01-01T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"frameworks":["SOC2","ISO27001"],"budget":75000}}},"minimalProject":{"summary":"Minimal required fields","value":{"name":"Emergency Production Hotfix"}}}}}},"responses":{"201":{"description":"Project created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Project"}}},"example":{"data":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024","description":"Complete overhaul of company website with modern design","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":null,"entityId":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-15T10:30:00.000Z"}}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missingName":{"summary":"Missing required name field","value":{"error":{"code":"VALIDATION_ERROR","message":"Project name is required","details":{"field":"name","value":null}}}},"invalidEntityLink":{"summary":"Incomplete entity linking","value":{"error":{"code":"VALIDATION_ERROR","message":"Both entityType and entityId must be provided together","details":{"entityType":"client","entityId":null}}}},"invalidDateRange":{"summary":"Invalid date configuration","value":{"error":{"code":"INVALID_DATE_RANGE","message":"Due date cannot be before start date","details":{"startDate":"2024-03-01T00:00:00.000Z","dueDate":"2024-02-01T00:00:00.000Z"}}}},"nameTooLong":{"summary":"Name exceeds maximum length","value":{"error":{"code":"VALIDATION_ERROR","message":"Project name cannot exceed 255 characters","details":{"field":"name","maxLength":255,"actualLength":312}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{id}":{"get":{"tags":["Projects"],"summary":"Get specific project details","description":"Retrieves a specific project by ID with optional live context data from integrated external systems (CRM, ERP, etc.)\n","operationId":"getProject","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"},{"name":"includeContext","in":"query","schema":{"type":"boolean","default":true},"description":"Include live context data from external integrations","example":true}],"responses":{"200":{"description":"Project details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Project"}}},"examples":{"projectWithContext":{"summary":"Project with live context data","value":{"data":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Q1 Marketing Campaign","description":"Launch new product marketing campaign across digital channels","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"campaign","entityId":"campaign-q1-2024","ownerId":"user-john-doe","ownerType":"USER","startDate":"2024-01-15T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"budget":50000,"channels":["social","email","web"],"status":"in-progress"},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T16:15:00.000Z","contexts":[{"contextTypeId":"ctx-crm-001","contextTypeName":"CRM System","entityType":"campaign","entityId":"campaign-q1-2024","data":{"leads":247,"conversions":52,"revenue":15600,"status":"active"},"fetchedAt":"2024-01-20T16:15:00.000Z"},{"contextTypeId":"ctx-financial-sys-002","contextTypeName":"Financial System","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174111","data":{"budgetUtilization":45.5,"spentToDate":22750,"approvedBudget":50000},"fetchedAt":"2024-01-20T16:15:00.000Z"}]}}},"projectWithoutContext":{"summary":"Project without context data","value":{"data":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024","description":"Complete overhaul of company website with modern design","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"client","entityId":"client-789","ownerId":"user-project-mgr-123","ownerType":"USER","startDate":"2024-01-15T00:00:00.000Z","dueDate":"2024-04-30T23:59:59.999Z","data":{"budget":125000,"primaryContact":"john.smith@client.com","technologies":["react","nodejs"]},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T16:15:00.000Z","contexts":[]}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Projects"],"summary":"Update an existing project","description":"Updates project properties. Only provided fields are updated (partial update). Data field updates are merged by default.","operationId":"updateProject","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdate"},"examples":{"archiveCompleted":{"summary":"Archive completed project","value":{"status":"ARCHIVED","data":{"completionDate":"2024-03-28","finalBudget":142500,"successMetrics":{"onTime":true,"onBudget":false,"budgetVariance":14.5}}}},"extendDeadline":{"summary":"Extend project deadline","value":{"dueDate":"2024-05-15T23:59:59.999Z","description":"Extended timeline due to additional requirements","data":{"extensionReason":"scope-change","approvedBy":"client-lead"}}},"reassignOwnership":{"summary":"Transfer project to new owner","value":{"ownerId":"user-jane-smith","ownerType":"USER","data":{"previousOwner":"user-john-doe","handoverDate":"2024-02-01"}}},"updateProjectScope":{"summary":"Update project scope","value":{"name":"Q1 Marketing Campaign - Phase 2","description":"Phase 2 campaign with expanded channels","data":{"phase":2,"additionalChannels":["podcast","video"]}}},"reactivateProject":{"summary":"Reactivate archived project","value":{"status":"ACTIVE","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-06-30T23:59:59.999Z","description":"Project reactivated for Phase 2 implementation"}}}}}},"responses":{"200":{"description":"Project updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Project"}}},"example":{"data":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024 - Phase 2","description":"Complete overhaul of company website with modern design","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":null,"entityId":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T16:15:00.000Z"}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Projects"],"summary":"Delete a project","description":"Permanently deletes a project and all associated data (tasks, sections, attachments, workflows). This cannot be undone. Consider archiving instead.","operationId":"deleteProject","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Project deleted successfully. No content is returned.\nThe project and all associated data have been permanently removed.\n"},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/bulk":{"post":{"tags":["Projects"],"summary":"Create multiple projects in bulk","description":"Creates multiple projects in a single transaction. Maximum 100 projects per request. All projects validated before creation (all-or-nothing).","operationId":"bulkCreateProjects","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkCreateProjectsRequest"},"examples":{"campaignProjects":{"summary":"Multiple campaign projects","value":{"projects":[{"name":"Q1 Email Campaign","description":"Email marketing campaign for Q1","entityType":"campaign","entityId":"campaign-email-q1","ownerId":"role-marketing-team","ownerType":"ROLE","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-04-30T23:59:59.999Z","data":{"budget":30000,"channels":["email"]}},{"name":"Q1 Social Campaign","description":"Social media campaign for Q1","entityType":"campaign","entityId":"campaign-social-q1","ownerId":"role-marketing-team","ownerType":"ROLE","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-05-31T23:59:59.999Z","data":{"budget":40000,"channels":["facebook","linkedin","twitter"]}},{"name":"Q1 Content Campaign","description":"Content marketing campaign for Q1","entityType":"campaign","entityId":"campaign-content-q1","ownerId":"role-marketing-team","ownerType":"ROLE","startDate":"2024-02-15T00:00:00.000Z","dueDate":"2024-06-30T23:59:59.999Z","data":{"budget":25000,"channels":["blog","video","podcast"]}}]}},"quarterlyInitiatives":{"summary":"Department quarterly projects","value":{"projects":[{"name":"Q2 2024 - Engineering OKRs","description":"Engineering department objectives and key results for Q2","ownerId":"role-engineering-lead","ownerType":"ROLE","startDate":"2024-04-01T00:00:00.000Z","dueDate":"2024-06-30T23:59:59.999Z","data":{"department":"engineering","quarter":"Q2-2024","objectives":["improve-deployment-speed","reduce-tech-debt","enhance-monitoring"]}},{"name":"Q2 2024 - Sales Targets","description":"Sales team targets and initiatives for Q2","ownerId":"role-sales-director","ownerType":"ROLE","startDate":"2024-04-01T00:00:00.000Z","dueDate":"2024-06-30T23:59:59.999Z","data":{"department":"sales","quarter":"Q2-2024","targetRevenue":3500000,"newAccountsTarget":25}},{"name":"Q2 2024 - Marketing Campaigns","description":"Marketing campaigns and brand initiatives for Q2","ownerId":"role-marketing-manager","ownerType":"ROLE","startDate":"2024-04-01T00:00:00.000Z","dueDate":"2024-06-30T23:59:59.999Z","data":{"department":"marketing","quarter":"Q2-2024","campaigns":["spring-launch","customer-conference","partner-program"],"budget":450000}}]}},"clientOnboarding":{"summary":"Standardized client onboarding projects","value":{"projects":[{"name":"TechCorp - Onboarding Phase 1: Discovery","description":"Initial discovery and requirements gathering","entityType":"client","entityId":"client-techcorp-new","ownerId":"user-account-mgr-sarah","ownerType":"USER","startDate":"2024-02-01T00:00:00.000Z","dueDate":"2024-02-14T23:59:59.999Z","data":{"onboardingPhase":1,"clientSize":"enterprise","estimatedAnnualValue":750000}},{"name":"TechCorp - Onboarding Phase 2: Implementation","description":"System setup and initial implementation","entityType":"client","entityId":"client-techcorp-new","ownerId":"user-impl-lead-john","ownerType":"USER","startDate":"2024-02-15T00:00:00.000Z","dueDate":"2024-03-15T23:59:59.999Z","data":{"onboardingPhase":2,"systemsToIntegrate":["crm","erp","billing"]}},{"name":"TechCorp - Onboarding Phase 3: Training","description":"User training and go-live preparation","entityType":"client","entityId":"client-techcorp-new","ownerId":"user-training-mgr-lisa","ownerType":"USER","startDate":"2024-03-16T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z","data":{"onboardingPhase":3,"usersToTrain":150,"trainingSessions":8}}]}}}}}},"responses":{"201":{"description":"Projects created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}},"example":{"data":[{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Q1 Marketing Campaign","description":"Complete Q1 marketing initiative","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":null,"entityId":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-15T10:30:00.000Z"},{"id":"789e0123-e89b-12d3-a456-426614174222","name":"Q1 Product Development","description":"New product features for Q1","status":"ACTIVE","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":null,"entityId":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-15T10:30:00.000Z"}]}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"emptyList":{"summary":"Empty projects array","value":{"error":{"code":"EMPTY_PROJECTS_ARRAY","message":"At least one project must be provided"}}},"validation":{"summary":"Project validation error","value":{"error":{"code":"VALIDATION_ERROR","message":"Project validation failed","details":{"index":1,"field":"name","value":null}}}},"tooMany":{"summary":"Too many projects","value":{"error":{"code":"TOO_MANY_PROJECTS","message":"Maximum 100 projects allowed per bulk request"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{id}/attachments":{"post":{"tags":["Projects","Attachments"],"summary":"Upload attachment to project","description":"Uploads a file to a project with automatic validation and secure cloud storage. Maximum 100MB per file.","operationId":"uploadProjectAttachment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload"},"externalDocumentId":{"type":"string","description":"External document identifier for integration"}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentResponse"}}},"examples":{"pdfDocument":{"summary":"PDF document upload","value":{"data":{"id":"att-789e0123-e89b-12d3-a456-426614174222","filename":"project-report.pdf","originalFilename":"Q1 Campaign Report 2024.pdf","mimeType":"application/pdf","fileSize":2457600,"uploadedBy":"user-john-doe","uploadedAt":"2024-01-20T14:30:00.000Z","entityType":"project","entityId":"456e7890-e89b-12d3-a456-426614174111","externalDocumentId":"doc-report-2024-001","storageUrl":"gs://tasks-attachments/organizations/123e4567/projects/456e7890/attachments/20240120143000_project-report.pdf","entityContext":{"entityName":"Q1 Marketing Campaign","entityType":"project","project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Q1 Marketing Campaign","status":"ACTIVE","entityType":"campaign","entityId":"campaign-q1-2024"}}}}},"designAsset":{"summary":"Design file upload for client project","value":{"data":{"id":"att-321e6543-e89b-12d3-a456-426614174333","filename":"homepage-mockup-v3.fig","originalFilename":"Acme Corp Homepage Mockup v3.fig","mimeType":"application/octet-stream","fileSize":15678900,"uploadedBy":"user-designer-456","uploadedAt":"2024-01-20T16:45:00.000Z","entityType":"project","entityId":"789e0123-e89b-12d3-a456-426614174222","storageUrl":"gs://tasks-attachments/organizations/123e4567/projects/789e0123/attachments/20240120164500_homepage-mockup-v3.fig","entityContext":{"entityName":"Acme Corp Website Redesign","entityType":"project","project":{"id":"789e0123-e89b-12d3-a456-426614174222","name":"Acme Corp Website Redesign","status":"ACTIVE","entityType":"client","entityId":"client-acme-corp"}}}}}}}}},"400":{"description":"Bad Request - Validation or upload errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"fileTooLarge":{"summary":"File exceeds size limit","value":{"error":{"code":"FILE_TOO_LARGE","message":"File size exceeds maximum allowed size of 100MB","details":{"fileSize":157286400,"maxSize":104857600,"filename":"large-video.mp4"}}}},"invalidFileType":{"summary":"Unsupported file type","value":{"error":{"code":"INVALID_FILE_TYPE","message":"File type not allowed","details":{"mimeType":"application/x-executable","filename":"malicious.exe","allowedTypes":["image/*","application/pdf","application/msword","text/*"]}}}},"missingFile":{"summary":"No file in request","value":{"error":{"code":"MISSING_FILE","message":"No file provided in the request"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found or access denied."}}}}},"413":{"description":"Payload Too Large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"Request payload exceeds maximum size limit"}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Projects","Attachments"],"summary":"List project attachments","description":"Retrieves all files attached to a project with filtering by MIME type, date range, and sorting options. Supports optional signed download URLs.","operationId":"getProjectAttachments","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"},{"in":"query","name":"mimeType","schema":{"type":"string"},"description":"Filter by MIME type (partial match)","example":"image/"},{"in":"query","name":"includeDownloadUrls","schema":{"type":"boolean"},"description":"Include signed download URLs in response (15 min expiry)"},{"in":"query","name":"sortBy","schema":{"type":"string","enum":["created_at","file_size","original_filename"]},"description":"Field to sort by","example":"created_at"},{"in":"query","name":"sortOrder","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction","example":"desc"},{"in":"query","name":"uploadedAfter","schema":{"type":"string","format":"date-time"},"description":"Filter files uploaded after this date","example":"2024-01-01T00:00:00.000Z"},{"in":"query","name":"uploadedBefore","schema":{"type":"string","format":"date-time"},"description":"Filter files uploaded before this date","example":"2024-01-31T23:59:59.999Z"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Project attachments retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentListResponse"}}}}}},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/projects/{id}/attachments/stats":{"get":{"tags":["Projects","Attachments"],"summary":"Get project attachment statistics","description":"Returns analytics about project attachments including total count, storage size, file type distribution, and recent uploads.","operationId":"getProjectAttachmentStats","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Project attachment statistics","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentStatsResponse"}}},"examples":{"campaignProjectStats":{"summary":"Marketing campaign project with diverse attachments","value":{"data":{"entityId":"456e7890-e89b-12d3-a456-426614174111","entityName":"Q1 Marketing Campaign","entityType":"project","statistics":{"totalCount":47,"totalSize":256789012,"averageSize":5463596,"fileTypes":{"application/pdf":{"count":18,"totalSize":125678900,"examples":["campaign-report.pdf","analytics-summary.pdf","creative-brief.pdf"]},"image/jpeg":{"count":23,"totalSize":89012345,"examples":["banner-ad-01.jpg","social-post.jpg","email-header.jpg"]},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"count":4,"totalSize":34567890,"examples":["budget-tracker.xlsx","performance-metrics.xlsx","lead-list.xlsx"]},"application/vnd.openxmlformats-officedocument.wordprocessingml.document":{"count":2,"totalSize":7530877,"examples":["campaign-proposal.docx","content-plan.docx"]}},"recentAttachments":[{"id":"att-recent-001","filename":"final-campaign-report.pdf","mimeType":"application/pdf","fileSize":4567890,"uploadedBy":"user-john-doe","uploadedAt":"2024-01-25T16:30:00.000Z"},{"id":"att-recent-002","filename":"campaign-assets.zip","mimeType":"application/zip","fileSize":45678900,"uploadedBy":"user-jane-smith","uploadedAt":"2024-01-25T14:15:00.000Z"}]},"projectContext":{"projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Q1 Marketing Campaign","projectStatus":"ACTIVE"}}}},"softwareProjectStats":{"summary":"Software development project attachments","value":{"data":{"entityId":"789e0123-e89b-12d3-a456-426614174222","entityName":"Acme Corp Website Redesign","entityType":"project","statistics":{"totalCount":32,"totalSize":67890123,"averageSize":2121566,"fileTypes":{"image/png":{"count":15,"totalSize":23456789,"examples":["homepage-mockup.png","logo-variations.png","icon-set.png"]},"application/pdf":{"count":8,"totalSize":18901234,"examples":["requirements-doc.pdf","wireframes.pdf","style-guide.pdf"]},"application/octet-stream":{"count":5,"totalSize":15678900,"examples":["design-files.sketch","prototype.fig","assets.ai"]},"text/html":{"count":4,"totalSize":9853200,"examples":["prototype-v1.html","demo-site.html","component-library.html"]}},"recentAttachments":[{"id":"att-recent-003","filename":"final-designs-approved.pdf","mimeType":"application/pdf","fileSize":8901234,"uploadedBy":"user-designer-789","uploadedAt":"2024-01-25T11:00:00.000Z"}]},"projectContext":{"projectId":"789e0123-e89b-12d3-a456-426614174222","projectName":"Acme Corp Website Redesign","projectStatus":"ACTIVE"}}}},"emptyProject":{"summary":"Project with no attachments","value":{"data":{"entityId":"987e6543-e89b-12d3-a456-426614174333","entityName":"New Project - Planning Phase","entityType":"project","statistics":{"totalCount":0,"totalSize":0,"averageSize":0,"fileTypes":{},"recentAttachments":[]},"projectContext":{"projectId":"987e6543-e89b-12d3-a456-426614174333","projectName":"New Project - Planning Phase","projectStatus":"ACTIVE"}}}}}}}},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PROJECT_NOT_FOUND","message":"Project not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/pubsub/subscriptions":{"get":{"summary":"List organization Pub/Sub subscriptions","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"topicId","schema":{"type":"string","format":"uuid"},"description":"Filter subscriptions by topic"},{"in":"query","name":"serviceName","schema":{"type":"string"},"description":"Filter subscriptions by service name"},{"in":"query","name":"status","schema":{"type":"string","enum":["ACTIVE","PAUSED","DISABLED","FAILED"]},"description":"Filter by subscription status"},{"in":"query","name":"subscriptionType","schema":{"type":"string","enum":["PUSH","PULL","BIGQUERY_EXPORT","CLOUD_STORAGE_EXPORT"]},"description":"Filter by subscription type"},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of subscriptions to return"},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of subscriptions to skip"}],"responses":{"200":{"description":"List of Pub/Sub subscriptions","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/PubSubSubscription"}},"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}}}}},"post":{"summary":"Create a new Pub/Sub subscription","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["topicId","subscriptionName","subscriptionFullName","serviceName"],"properties":{"topicId":{"type":"string","format":"uuid"},"subscriptionName":{"type":"string"},"subscriptionFullName":{"type":"string"},"serviceName":{"type":"string"},"serviceDescription":{"type":"string"},"subscriptionType":{"type":"string","enum":["PUSH","PULL","BIGQUERY_EXPORT","CLOUD_STORAGE_EXPORT"],"default":"PUSH"},"pushEndpointUrl":{"type":"string"},"pushAuthentication":{"type":"object"},"ackDeadlineSeconds":{"type":"integer","default":600},"messageRetentionDurationHours":{"type":"integer","default":168},"exportDestination":{"type":"string"},"exportSchema":{"type":"object"},"messageFilters":{"type":"object"},"deadLetterTopic":{"type":"string"},"maxDeliveryAttempts":{"type":"integer","default":5},"retryPolicy":{"type":"object"},"enableMessageOrdering":{"type":"boolean","default":false}}}}}},"responses":{"201":{"description":"Subscription created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PubSubSubscription"}}}}}}},"/api/pubsub/subscriptions/{id}":{"get":{"summary":"Get a specific Pub/Sub subscription","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Subscription ID"}],"responses":{"200":{"description":"Subscription details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PubSubSubscription"}}}},"404":{"description":"Subscription not found"}}},"put":{"summary":"Update a Pub/Sub subscription","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Subscription ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"serviceDescription":{"type":"string"},"status":{"type":"string","enum":["ACTIVE","PAUSED","DISABLED","FAILED"]},"pushEndpointUrl":{"type":"string"},"pushAuthentication":{"type":"object"},"ackDeadlineSeconds":{"type":"integer"},"messageRetentionDurationHours":{"type":"integer"},"exportDestination":{"type":"string"},"exportSchema":{"type":"object"},"messageFilters":{"type":"object"},"deadLetterTopic":{"type":"string"},"maxDeliveryAttempts":{"type":"integer"},"retryPolicy":{"type":"object"},"enableMessageOrdering":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Subscription updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PubSubSubscription"}}}}}},"delete":{"summary":"Delete a Pub/Sub subscription","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Subscription ID"}],"responses":{"204":{"description":"Subscription deleted successfully"},"404":{"description":"Subscription not found"}}}},"/api/pubsub/subscriptions/{id}/pull":{"post":{"summary":"Pull messages from a subscription (for PULL type subscriptions)","tags":["Pub/Sub Subscriptions"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Subscription ID"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"maxMessages":{"type":"integer","minimum":1,"maximum":1000,"default":10,"description":"Maximum number of messages to pull"}}}}}},"responses":{"200":{"description":"Messages pulled successfully","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"data":{"type":"object"},"attributes":{"type":"object"},"publishTime":{"type":"string","format":"date-time"},"orderingKey":{"type":"string"}}}},"count":{"type":"integer"}}}}}}}}},"/api/v1/pubsub/topics":{"get":{"summary":"List organization Pub/Sub topics with advanced filtering","description":"Retrieves a paginated list of Pub/Sub topics configured for your organization's event-driven architecture.\n\n## Business Context\n\nPub/Sub topics are central to the platform's event-driven architecture, enabling real-time communication \nbetween services and external integrations. Each topic serves specific business functions:\n\n- **Webhook topics** handle external system notifications (entity updates, client communications)\n- **Integration topics** manage data synchronization with CRM, calendar, and management systems\n- **Internal topics** coordinate internal business processes (workflow state changes, task completions)\n- **Analytics topics** collect business intelligence data for reporting and insights\n\n## Event Routing & Management\n\nTopics are organized by category to enable efficient event routing and subscription management.\nEach topic maintains statistics on message volume, subscription health, and delivery performance.\nUse filtering capabilities to monitor specific topic categories or troubleshoot inactive topics.\n\n## Business Context\n\nIn business operations, topics commonly handle:\n- Entity listing updates from external portals\n- Meeting scheduling and confirmations\n- Legal document processing notifications\n- External record updates and verification\n- Client communication preferences and notifications\n\n## Operational Guidelines\n\n- Monitor subscription counts to ensure proper event distribution\n- Review message statistics to identify high-volume topics requiring scaling\n- Use category filtering to organize topic management by business function\n- Inactive topics should be investigated for configuration or subscription issues\n","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"category","schema":{"type":"string","enum":["webhook","integration","internal","analytics"]},"description":"Filter topics by business category. Categories organize topics by their primary function:\n- `webhook`: External system notifications and callbacks\n- `integration`: Third-party system synchronization (CRM, calendar, external portals)\n- `internal`: Internal business process coordination\n- `analytics`: Business intelligence and reporting data collection\n","example":"webhook"},{"in":"query","name":"isActive","schema":{"type":"boolean"},"description":"Filter by topic activation status. Active topics can publish and receive messages,\nwhile inactive topics are paused for maintenance or configuration updates.\nUse this filter to identify topics requiring attention.\n","example":true},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Maximum number of topics to return per page. Use smaller values for faster responses\nwhen browsing, larger values for bulk operations or reporting.\n","example":20},{"in":"query","name":"offset","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of topics to skip for pagination. Calculate as (page - 1) * limit\nfor page-based navigation.\n","example":0}],"responses":{"200":{"description":"Successfully retrieved list of Pub/Sub topics with subscription information","content":{"application/json":{"schema":{"type":"object","properties":{"topics":{"type":"array","description":"Array of topic objects with their subscription details","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the topic","example":"550e8400-e29b-41d4-a716-446655440000"},"organization_id":{"type":"string","format":"uuid","description":"Organization that owns this topic","example":"123e4567-e89b-12d3-a456-426614174000"},"topic_name":{"type":"string","description":"Short name for the topic","example":"entity-updates"},"topic_full_name":{"type":"string","description":"Full GCP Pub/Sub topic name","example":"projects/tasks-462013/topics/org-123-entity-updates"},"gcp_project_id":{"type":"string","description":"Google Cloud Project ID hosting the topic","example":"tasks-462013"},"description":{"type":"string","nullable":true,"description":"Human-readable description of the topic's purpose","example":"Handles entity listing and event updates from external portals"},"category":{"type":"string","nullable":true,"description":"Business category classification","example":"webhook"},"message_retention_duration_hours":{"type":"integer","description":"Hours to retain messages for redelivery","example":168},"event_types":{"type":"array","description":"Types of events published to this topic","items":{"type":"string"},"example":["ENTITY_UPDATED","EVENT_SCHEDULED","SUBMISSION_RECEIVED"]},"entity_filters":{"type":"object","nullable":true,"description":"JSON filters for message routing","example":{"entity_type":["project","task"]}},"is_active":{"type":"boolean","description":"Whether the topic is currently active","example":true},"last_published_at":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of last message publication","example":"2024-01-15T10:30:00Z"},"total_messages_published":{"type":"string","description":"Total number of messages published (as string due to BigInt serialization)","example":"1247"},"is_consolidated":{"type":"boolean","description":"Whether this topic consolidates multiple event types","example":false},"legacy_topic_id":{"type":"string","format":"uuid","nullable":true,"description":"Previous topic ID if migrated","example":null},"consolidation_strategy":{"type":"string","nullable":true,"description":"Strategy used for topic consolidation","example":null},"migration_status":{"type":"string","description":"Current migration status","example":"NOT_MIGRATED"},"created_at":{"type":"string","format":"date-time","description":"Topic creation timestamp","example":"2024-01-10T08:00:00Z"},"created_by":{"type":"string","description":"User who created the topic","example":"system@apart.tech"},"updated_at":{"type":"string","format":"date-time","description":"Last modification timestamp","example":"2024-01-15T14:22:00Z"},"subscriptions":{"type":"array","description":"Active subscriptions for this topic","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Subscription unique identifier","example":"660e8400-e29b-41d4-a716-446655440001"},"subscription_name":{"type":"string","description":"Short name for the subscription","example":"crm-sync-handler"},"status":{"type":"string","description":"Current subscription status","example":"ACTIVE"},"subscription_type":{"type":"string","description":"Type of subscription (PUSH/PULL)","example":"PUSH"}}}}}}},"total":{"type":"integer","description":"Total number of topics matching the filter criteria","example":87},"limit":{"type":"integer","description":"Number of topics requested per page","example":20},"offset":{"type":"integer","description":"Number of topics skipped for pagination","example":0}}},"examples":{"webhook_topics":{"summary":"Webhook topics for external system integrations","description":"Example webhook topics for external notifications","value":{"topics":[{"id":"550e8400-e29b-41d4-a716-446655440000","organization_id":"123e4567-e89b-12d3-a456-426614174000","topic_name":"entity-updates","topic_full_name":"projects/tasks-462013/topics/org-123-entity-updates","gcp_project_id":"tasks-462013","description":"Handles entity listing updates from external portals","category":"webhook","message_retention_duration_hours":168,"event_types":["ENTITY_UPDATED","ENTITY_UPDATED","EVENT_SCHEDULED"],"entity_filters":{"source":["api","webhook"]},"is_active":true,"last_published_at":"2024-01-15T10:30:00Z","total_messages_published":"1247","is_consolidated":false,"legacy_topic_id":null,"consolidation_strategy":null,"migration_status":"NOT_MIGRATED","created_at":"2024-01-10T08:00:00Z","created_by":"system@apart.tech","updated_at":"2024-01-15T14:22:00Z","subscriptions":[{"id":"660e8400-e29b-41d4-a716-446655440001","subscription_name":"entity-processor","status":"ACTIVE","subscription_type":"PUSH"}]}],"total":15,"limit":20,"offset":0}},"integration_topics":{"summary":"Topics for CRM and calendar integration","description":"Example showing integration topics for third-party system synchronization","value":{"topics":[{"id":"770e8400-e29b-41d4-a716-446655440002","organization_id":"123e4567-e89b-12d3-a456-426614174000","topic_name":"crm-sync","topic_full_name":"projects/tasks-462013/topics/org-123-crm-sync","gcp_project_id":"tasks-462013","description":"Synchronizes client data with external CRM system","category":"integration","message_retention_duration_hours":72,"event_types":["CONTACT_CREATED","CONTACT_CREATED","EVENT_SCHEDULED"],"entity_filters":{"sync_direction":["bidirectional"],"priority":["high","medium"]},"is_active":true,"last_published_at":"2024-01-15T11:45:00Z","total_messages_published":"892","is_consolidated":true,"legacy_topic_id":"550e8400-e29b-41d4-a716-446655440010","consolidation_strategy":"event_type_based","migration_status":"MIGRATED","created_at":"2024-01-08T14:30:00Z","created_by":"admin@realestate.no","updated_at":"2024-01-15T11:45:00Z","subscriptions":[{"id":"880e8400-e29b-41d4-a716-446655440003","subscription_name":"superoffice-sync","status":"ACTIVE","subscription_type":"PUSH"},{"id":"990e8400-e29b-41d4-a716-446655440004","subscription_name":"calendar-integration","status":"ACTIVE","subscription_type":"PULL"}]}],"total":8,"limit":20,"offset":0}},"inactive_topics":{"summary":"Inactive topics requiring attention","description":"Example showing inactive topics that may need troubleshooting","value":{"topics":[{"id":"aa0e8400-e29b-41d4-a716-446655440005","organization_id":"123e4567-e89b-12d3-a456-426614174000","topic_name":"analytics-events","topic_full_name":"projects/tasks-462013/topics/org-123-analytics-events","gcp_project_id":"tasks-462013","description":"Collects user interaction data for business intelligence","category":"analytics","message_retention_duration_hours":720,"event_types":["USER_ACTION","PAGE_VIEW","FEATURE_USAGE"],"entity_filters":null,"is_active":false,"last_published_at":"2024-01-12T16:20:00Z","total_messages_published":"5432","is_consolidated":false,"legacy_topic_id":null,"consolidation_strategy":null,"migration_status":"NOT_MIGRATED","created_at":"2024-01-05T12:00:00Z","created_by":"analytics@apart.tech","updated_at":"2024-01-12T16:20:00Z","subscriptions":[]}],"total":3,"limit":20,"offset":0}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Pub/Sub Topics"],"summary":"Create new Pub/Sub topic for event routing","description":"Creates a new Google Cloud Pub/Sub topic with customized event routing and filtering capabilities.\nThis endpoint establishes dedicated event channels for specific integration patterns and business workflows.\n\n**Business Logic:**\n1. **Validation**: Checks for unique topic names within organization scope\n2. **Google Cloud Integration**: Creates the actual GCP Pub/Sub topic with specified configuration\n3. **Database Registration**: Stores topic metadata and configuration for management\n4. **Event Routing Setup**: Configures event type filtering and entity-based message routing\n5. **Retention Policy**: Applies message retention settings for reliable event delivery\n\n**Integration Scenarios:**\n- **Webhook Integration**: Route external webhook events to internal systems\n- **Workflow Orchestration**: Coordinate multi-stage business processes\n- **Real Estate Events**: Handle property updates, viewing schedules, and transaction events\n- **CRM Synchronization**: Sync customer and lead data with external CRM systems\n- **Document Processing**: Route attachment and document processing events\n\n**Google Cloud Requirements:**\n- Valid GCP project with Pub/Sub API enabled\n- Service account with `pubsub.topics.create` permission\n- Topic naming must follow GCP conventions (lowercase, hyphens allowed)\n\n**Message Retention**: Configurable retention (default 7 days) ensures message durability\n**Entity Filtering**: JSON-based filters enable precise message routing based on content\n","operationId":"createPubSubTopic","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["topicName","topicFullName","gcpProjectId","eventTypes"],"properties":{"topicName":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$","description":"Short identifier for the topic. Must be unique within organization.\nUsed for internal references and topic management.\n","example":"entity-updates"},"topicFullName":{"type":"string","pattern":"^projects\\/[a-z0-9-]+\\/topics\\/[a-z0-9-]+$","description":"Complete Google Cloud Pub/Sub topic identifier.\nFormat: projects/{project-id}/topics/{topic-name}\nMust follow GCP naming conventions.\n","example":"projects/tasks-462013/topics/org-123-entity-updates"},"gcpProjectId":{"type":"string","pattern":"^[a-z0-9-]+$","description":"Google Cloud Project ID hosting the Pub/Sub infrastructure.\nMust have Pub/Sub API enabled and appropriate permissions.\n","example":"tasks-462013"},"description":{"type":"string","maxLength":500,"nullable":true,"description":"Human-readable description of the topic's purpose and use case","example":"Handles entity listing updates, event schedules, and submission notifications from external portals"},"category":{"type":"string","enum":["webhook","workflow","attachment","crm","calendar","consolidated","system"],"nullable":true,"description":"Business category classification for topic organization.\nUsed for filtering and management grouping.\n","example":"webhook"},"messageRetentionDurationHours":{"type":"integer","minimum":1,"maximum":8760,"default":168,"description":"Duration in hours to retain messages for redelivery and recovery.\nDefault is 168 hours (7 days). Maximum is 8760 hours (1 year).\n","example":168},"eventTypes":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"string","pattern":"^[A-Z_]+$"},"description":"Array of event type identifiers that will be published to this topic.\nEvent types must be uppercase with underscores (e.g., 'ENTITY_UPDATED').\n","example":["ENTITY_UPDATED","EVENT_SCHEDULED","SUBMISSION_RECEIVED","AGREEMENT_SIGNED"]},"entityFilters":{"type":"object","nullable":true,"additionalProperties":true,"description":"JSON object defining filters for message routing based on entity properties.\nSupports arrays for multiple values and nested object filtering.\nUsed by subscribers to receive only relevant messages.\n","example":{"property_type":["apartment","house","commercial"],"municipality":["Region-A","Region-A","Region-A"],"price_range":{"min":1000000,"max":5000000}}}}},"examples":{"propertyWebhook":{"summary":"External Portal Webhook Integration","description":"Topic for receiving entity updates from external portals","value":{"topicName":"external-webhook","topicFullName":"projects/tasks-462013/topics/org-123-external-webhook","gcpProjectId":"tasks-462013","description":"Receives property listings, updates, and viewing requests from Finn.no and other external portals","category":"webhook","messageRetentionDurationHours":336,"eventTypes":["ENTITY_UPDATED","ENTITY_UPDATED","ENTITY_UPDATED","EVENT_SCHEDULED"],"entityFilters":{"property_type":["apartment","house"],"municipality":["Region-A","Region-A"],"source":["example.com","provider.com"]}}},"workflowOrchestration":{"summary":"Workflow Orchestration Events","description":"Topic for coordinating complex multi-stage business processes","value":{"topicName":"workflow-orchestration","topicFullName":"projects/tasks-462013/topics/org-123-workflow-orchestration","gcpProjectId":"tasks-462013","description":"Coordinates workflow stage transitions, approvals, and escalations for project acquisition processes","category":"workflow","messageRetentionDurationHours":168,"eventTypes":["WORKFLOW_STARTED","STAGE_COMPLETED","APPROVAL_REQUIRED","WORKFLOW_COMPLETED"],"entityFilters":{"workflow_type":["project-acquisition","legal-review"],"priority":["high","critical"]}}},"crmIntegration":{"summary":"CRM Data Synchronization","description":"Topic for bidirectional CRM system integration","value":{"topicName":"crm-sync","topicFullName":"projects/tasks-462013/topics/org-123-crm-sync","gcpProjectId":"tasks-462013","description":"Synchronizes customer data, leads, and interaction history with external CRM systems like Salesforce or HubSpot","category":"crm","messageRetentionDurationHours":72,"eventTypes":["CONTACT_CREATED","CONTACT_UPDATED","LEAD_QUALIFIED","OPPORTUNITY_CREATED"],"entityFilters":{"contact_type":["buyer","seller","agent"],"lead_source":["website","referral","advertising"]}}}}}}},"responses":{"201":{"description":"Pub/Sub topic created successfully","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/PubSubTopic"},{"type":"object","properties":{"total_messages_published":{"type":"string","description":"Total published messages (BigInt as string)","example":"0"}}}]},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","organization_id":"123e4567-e89b-12d3-a456-426614174000","topic_name":"external-webhook","topic_full_name":"projects/tasks-462013/topics/org-123-external-webhook","gcp_project_id":"tasks-462013","description":"Receives property listings, updates, and viewing requests from Finn.no and other external portals","category":"webhook","message_retention_duration_hours":336,"event_types":["ENTITY_UPDATED","ENTITY_UPDATED","ENTITY_UPDATED","EVENT_SCHEDULED"],"entity_filters":{"property_type":["apartment","house"],"municipality":["Region-A","Region-A"],"source":["example.com","provider.com"]},"is_active":true,"last_published_at":null,"total_messages_published":"0","is_consolidated":false,"legacy_topic_id":null,"consolidation_strategy":null,"migration_status":"NOT_MIGRATED","created_at":"2024-01-15T10:30:00Z","created_by":"api-user","updated_at":"2024-01-15T10:30:00Z","subscriptions":[]}}}},"400":{"description":"Invalid request data or validation errors","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid topic configuration"},"details":{"type":"object","example":{"field":"topicName","issue":"Must contain only lowercase letters, numbers, and hyphens"}}}}}},"examples":{"invalidTopicName":{"summary":"Invalid Topic Name Format","value":{"error":{"code":"VALIDATION_ERROR","message":"Topic name contains invalid characters","details":{"field":"topicName","value":"Property_Updates","expected":"lowercase letters, numbers, and hyphens only"}}}},"invalidGcpProjectId":{"summary":"Invalid GCP Project ID","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid Google Cloud Project ID format","details":{"field":"gcpProjectId","value":"Invalid-Project-ID","expected":"lowercase letters, numbers, and hyphens only"}}}},"missingEventTypes":{"summary":"Missing Required Event Types","value":{"error":{"code":"VALIDATION_ERROR","message":"At least one event type is required","details":{"field":"eventTypes","issue":"Array cannot be empty"}}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"UNAUTHORIZED"},"message":{"type":"string","example":"Valid API key required"}}}}}}}},"403":{"description":"Insufficient permissions for topic creation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"INSUFFICIENT_PERMISSIONS"},"message":{"type":"string","example":"Organization does not have permission to create Pub/Sub topics"},"details":{"type":"object","example":{"required_permission":"pubsub.topics.create","gcp_project":"tasks-462013"}}}}}}}}},"409":{"description":"Topic name already exists","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"TOPIC_ALREADY_EXISTS"},"message":{"type":"string","example":"Topic with name 'entity-updates' already exists"},"details":{"type":"object","example":{"field":"topicName","value":"entity-updates","existing_topic_id":"550e8400-e29b-41d4-a716-446655440000"}}}}}}}}},"500":{"description":"Internal server error during topic creation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"INTERNAL_SERVER_ERROR"},"message":{"type":"string","example":"Failed to create topic"},"details":{"type":"object","example":{"phase":"gcp_topic_creation","gcp_error":"Permission denied on resource project tasks-462013"}}}}}},"examples":{"gcpCreationFailure":{"summary":"Google Cloud Topic Creation Failed","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to create topic","details":{"phase":"gcp_topic_creation","gcp_error":"Topic projects/tasks-462013/topics/org-123-test already exists"}}}},"databaseError":{"summary":"Database Registration Failed","value":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to create topic","details":{"phase":"database_registration","error":"Connection timeout to database"}}}}}}}}}}},"/api/pubsub/topics/{id}":{"get":{"summary":"Get a specific Pub/Sub topic","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Topic ID"}],"responses":{"200":{"description":"Topic details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PubSubTopic"}}}},"404":{"description":"Topic not found"}}},"put":{"summary":"Update a Pub/Sub topic","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Topic ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"category":{"type":"string"},"messageRetentionDurationHours":{"type":"integer"},"eventTypes":{"type":"array","items":{"type":"string"}},"entityFilters":{"type":"object"},"isActive":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Topic updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PubSubTopic"}}}}}},"delete":{"summary":"Delete a Pub/Sub topic","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Topic ID"}],"responses":{"204":{"description":"Topic deleted successfully"},"404":{"description":"Topic not found"}}}},"/api/pubsub/topics/{id}/publish":{"post":{"summary":"Publish a message to a topic","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Topic ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"Message payload"},"attributes":{"type":"object","additionalProperties":{"type":"string"},"description":"Message attributes"},"orderingKey":{"type":"string","description":"Ordering key for message ordering"}}}}}},"responses":{"200":{"description":"Message published successfully","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string"},"topicName":{"type":"string"}}}}}}}}},"/api/pubsub/topics/consolidated":{"post":{"summary":"Create consolidated topics for organization","description":"Creates consolidated topics based on the selected strategy to reduce infrastructure costs","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"strategy":{"type":"string","enum":["SINGLE_TOPIC","CATEGORY_BASED"],"default":"SINGLE_TOPIC","description":"Consolidation strategy to use"},"categories":{"type":"array","items":{"type":"string","enum":["all","workflow","attachment"]},"default":["all"],"description":"Categories to create topics for (only used with CATEGORY_BASED strategy)"},"messageRetentionHours":{"type":"integer","default":168,"description":"Message retention duration in hours"},"enableOrdering":{"type":"boolean","default":true,"description":"Enable message ordering for consolidated topics"}}}}}},"responses":{"201":{"description":"Consolidated topics created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"strategy":{"type":"string"},"topics":{"type":"array","items":{"$ref":"#/components/schemas/PubSubTopic"}},"message":{"type":"string"}}}}}},"400":{"description":"Invalid consolidation configuration"},"409":{"description":"Consolidated topics already exist"}}}},"/api/pubsub/topics/consolidated/status":{"get":{"summary":"Check consolidated topic status for organization","description":"Returns information about consolidated topic setup and recommendations","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Consolidated topic status information","content":{"application/json":{"schema":{"type":"object","properties":{"hasConsolidatedTopics":{"type":"boolean"},"consolidatedTopics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"topicName":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"subscriptionCount":{"type":"integer"},"totalMessages":{"type":"string"}}}},"legacyTopics":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"topicName":{"type":"string"},"category":{"type":"string"},"totalMessages":{"type":"string"}}}},"validation":{"type":"object","properties":{"isValid":{"type":"boolean"},"issues":{"type":"array","items":{"type":"string"}},"recommendations":{"type":"array","items":{"type":"string"}}}},"costSavingsEstimate":{"type":"object","properties":{"currentTopicCount":{"type":"integer"},"projectedTopicCount":{"type":"integer"},"estimatedReduction":{"type":"string"}}}}}}}}}}},"/api/pubsub/topics/usage-stats":{"get":{"summary":"Get topic usage statistics for consolidation planning","description":"Returns detailed usage statistics to help plan topic consolidation","tags":["Pub/Sub Topics"],"security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"days","schema":{"type":"integer","default":30},"description":"Number of days to analyze"}],"responses":{"200":{"description":"Topic usage statistics","content":{"application/json":{"schema":{"type":"object","properties":{"timeRange":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"topicStats":{"type":"array","items":{"type":"object","properties":{"topicId":{"type":"string"},"topicName":{"type":"string"},"category":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"publicationCount":{"type":"integer"},"averageAttempts":{"type":"number"},"totalMessages":{"type":"integer"}}}},"consolidationRecommendations":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/v1/recurring-definitions":{"post":{"summary":"Create a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","sourceType","recurrenceType","startsAt"],"properties":{"name":{"type":"string","maxLength":255},"description":{"type":"string"},"sourceType":{"type":"string","enum":["TASK_TEMPLATE","WORKFLOW_TEMPLATE"]},"taskTemplateId":{"type":"string","format":"uuid"},"workflowTemplateId":{"type":"string","format":"uuid"},"recurrenceType":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","SEMI_ANNUAL","YEARLY","CUSTOM"]},"timezone":{"type":"string","default":"Europe/Oslo"},"timeOfDay":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","default":"09:00"},"dayOfWeek":{"type":"integer","minimum":1,"maximum":7},"dayOfMonth":{"type":"integer","minimum":1,"maximum":31},"monthOfYear":{"type":"integer","minimum":1,"maximum":12},"businessDaysOnly":{"type":"boolean","default":false},"customIntervalDays":{"type":"integer","minimum":1},"instantiationConfig":{"type":"object"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"maxOccurrences":{"type":"integer","minimum":1}}}}}},"responses":{"201":{"description":"Recurring definition created"},"400":{"description":"Validation error"}}},"get":{"summary":"List recurring definitions","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","default":1}},{"in":"query","name":"limit","schema":{"type":"integer","default":20}},{"in":"query","name":"status","schema":{"type":"string","enum":["ACTIVE","PAUSED","COMPLETED","CANCELLED"]}},{"in":"query","name":"sourceType","schema":{"type":"string","enum":["TASK_TEMPLATE","WORKFLOW_TEMPLATE"]}}],"responses":{"200":{"description":"List of recurring definitions"}}}},"/api/v1/recurring-definitions/{id}":{"get":{"summary":"Get a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Recurring definition details"},"404":{"description":"Not found"}}},"patch":{"summary":"Update a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"recurrenceType":{"type":"string","enum":["DAILY","WEEKLY","MONTHLY","QUARTERLY","SEMI_ANNUAL","YEARLY","CUSTOM"]},"timezone":{"type":"string"},"timeOfDay":{"type":"string"},"dayOfWeek":{"type":"integer"},"dayOfMonth":{"type":"integer"},"monthOfYear":{"type":"integer"},"businessDaysOnly":{"type":"boolean"},"customIntervalDays":{"type":"integer"},"instantiationConfig":{"type":"object"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"maxOccurrences":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated recurring definition"},"404":{"description":"Not found"}}},"delete":{"summary":"Cancel (soft-delete) a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Recurring definition cancelled"},"404":{"description":"Not found"}}}},"/api/v1/recurring-definitions/{id}/pause":{"post":{"summary":"Pause a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Recurring definition paused"},"400":{"description":"Invalid status transition"},"404":{"description":"Not found"}}}},"/api/v1/recurring-definitions/{id}/resume":{"post":{"summary":"Resume a paused recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Recurring definition resumed"},"400":{"description":"Invalid status transition"},"404":{"description":"Not found"}}}},"/api/v1/recurring-definitions/{id}/trigger":{"post":{"summary":"Trigger immediate execution of a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Execution result"},"400":{"description":"Invalid status"},"404":{"description":"Not found"}}}},"/api/v1/recurring-definitions/{id}/instances":{"get":{"summary":"List instances (execution history) of a recurring definition","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"page","schema":{"type":"integer","default":1}},{"in":"query","name":"limit","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"List of recurring instances"},"404":{"description":"Definition not found"}}}},"/api/v1/internal/recurring-definitions/process":{"post":{"summary":"Process all due recurring definitions (internal cron endpoint)","tags":["Recurring Definitions"],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Processing results"}}}},"/api/v1/services/register":{"post":{"tags":["Service Registration"],"summary":"Register a new service for automatic event delivery","description":"Registers a new service for automatic onboarding and plug-and-play integration\nwith the task management platform. This creates the required infrastructure\n(Pub/Sub topics and subscriptions) automatically.\n\n**Use Cases:**\n- Service onboarding and integration\n- Automatic Pub/Sub infrastructure provisioning\n- Event subscription management\n- Multi-tenant service isolation\n\n**Auto-Provisioning:**\n- Creates organization-scoped Pub/Sub topics\n- Sets up webhook PUSH subscriptions\n- Configures event routing based on patterns\n","operationId":"registerService","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["serviceName","webhookEndpoint","eventSubscriptions"],"properties":{"serviceName":{"type":"string","description":"Unique service name within organization","example":"letting-service"},"serviceDescription":{"type":"string","description":"Human-readable service description","example":"Property letting and rental management service"},"webhookEndpoint":{"type":"string","format":"uri","description":"HTTPS endpoint to receive events","example":"https://letting-service.com/webhook"},"eventSubscriptions":{"type":"array","items":{"type":"string"},"description":"Event patterns to subscribe to","example":["task.*","workflow.completed","project.created"]},"authenticationMethod":{"type":"string","enum":["NONE","BEARER","APIKEY"],"description":"Webhook authentication method","default":"NONE"},"retryPolicy":{"type":"object","properties":{"maxRetries":{"type":"integer","minimum":1,"maximum":10,"default":5},"backoffMultiplier":{"type":"number","minimum":1,"maximum":3,"default":2}}},"metadata":{"type":"object","description":"Service-specific configuration"}}}}}},"responses":{"201":{"description":"Service registered successfully with infrastructure provisioned","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ServiceRegistrationResponse"}}}}}},"400":{"$ref":"#/components/responses/ValidationError"},"409":{"description":"Service name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/services":{"get":{"tags":["Service Registration"],"summary":"List registered services for organization","description":"Retrieves a paginated list of all services registered for the authenticated organization.\nServices are returned in descending order by creation date (newest first).\n\n**Use Cases:**\n- Service management dashboard\n- Service health monitoring\n- Administrative oversight\n- Integration status review\n","operationId":"getServices","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","description":"Filter by service status","schema":{"type":"string","enum":["PENDING","ACTIVE","PAUSED","FAILED","DEREGISTERED"]}},{"name":"serviceName","in":"query","description":"Filter by service name (partial match)","schema":{"type":"string"}}],"responses":{"200":{"description":"Services retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ServiceResponse"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/services/{serviceId}/status":{"get":{"tags":["Service Registration"],"summary":"Get service health and delivery status","description":"Retrieves detailed health and delivery statistics for a specific service.\nIncludes infrastructure status, delivery metrics, and health check results.\n\n**Use Cases:**\n- Service monitoring and alerting\n- Troubleshooting delivery issues\n- Performance analysis\n- Health dashboard displays\n","operationId":"getServiceStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"description":"Service ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Service status retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ServiceStatusResponse"}}}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/services/{serviceId}/webhook":{"put":{"tags":["Service Registration"],"summary":"Update service webhook configuration","description":"Updates the webhook endpoint and authentication configuration for a service.\nThis will update all related Pub/Sub subscriptions to use the new endpoint.\n\n**Use Cases:**\n- Service endpoint migration\n- Authentication method changes\n- Webhook URL updates\n- Retry policy adjustments\n","operationId":"updateServiceWebhook","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"description":"Service ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhookEndpoint"],"properties":{"webhookEndpoint":{"type":"string","format":"uri","description":"New HTTPS endpoint to receive events"},"authenticationMethod":{"type":"string","enum":["NONE","BEARER","APIKEY"],"description":"Webhook authentication method"},"retryPolicy":{"type":"object","properties":{"maxRetries":{"type":"integer","minimum":1,"maximum":10},"backoffMultiplier":{"type":"number","minimum":1,"maximum":3}}}}}}}},"responses":{"200":{"description":"Webhook configuration updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ServiceResponse"}}}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/services/{serviceId}/events":{"put":{"tags":["Service Registration"],"summary":"Update service event subscriptions","description":"Updates the event subscription patterns for a service. This will modify\nwhich events the service receives and may create new Pub/Sub infrastructure\nif new event categories are added.\n\n**Use Cases:**\n- Adding new event subscriptions\n- Removing unwanted event types\n- Changing event filtering patterns\n- Service capability evolution\n","operationId":"updateServiceEvents","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"description":"Service ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["eventSubscriptions"],"properties":{"eventSubscriptions":{"type":"array","items":{"type":"string"},"description":"New event patterns to subscribe to","example":["task.*","workflow.completed","project.created"]}}}}}},"responses":{"200":{"description":"Event subscriptions updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ServiceResponse"}}}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/services/{serviceId}":{"delete":{"tags":["Service Registration"],"summary":"Deregister service and cleanup infrastructure","description":"Deregisters a service and performs cleanup of associated infrastructure.\nThis will disable Pub/Sub subscriptions and mark the service as deregistered.\n\n**Use Cases:**\n- Service retirement and cleanup\n- Infrastructure resource management\n- Service migration scenarios\n- Cost optimization\n\n**Cleanup Actions:**\n- Marks service as DEREGISTERED\n- Disables Pub/Sub subscriptions\n- Preserves event subscriptions for audit purposes\n","operationId":"deregisterService","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"serviceId","in":"path","required":true,"description":"Service ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Service deregistered successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"message":{"type":"string","example":"Service deregistered successfully"},"serviceId":{"type":"string","format":"uuid"},"serviceName":{"type":"string"}}}}}}}},"404":{"description":"Service not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/webhooks/cronofy/smart-invite":{"post":{"tags":["Webhooks"],"summary":"Handle Smart Invite RSVP callback","description":"Receives RSVP responses from Cronofy Smart Invites.\nUses HMAC-SHA256 signature verification instead of API key authentication.\nThe signature is provided in the 'cronofy-hmac-sha256' header.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartInviteCallback"}}}},"responses":{"200":{"description":"Callback received and processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","example":true}}}}}},"400":{"description":"Invalid smart_invite_id format"},"401":{"description":"Invalid HMAC signature","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"Invalid signature"}}}}}}}}},"/api/v1/calendar/smart-invites/{smartInviteId}/counter-proposal":{"post":{"tags":["Calendar"],"summary":"Handle counter-proposal for Smart Invite","description":"When an attendee proposes a different time via Smart Invite,\nthis endpoint allows accepting or declining that proposal.\n","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"smartInviteId","required":true,"schema":{"type":"string"},"description":"Smart Invite identifier"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CounterProposalAction"}}}},"responses":{"200":{"description":"Counter-proposal action completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"smartInviteId":{"type":"string"},"action":{"type":"string","enum":["accept","decline"]},"message":{"type":"string"}}}}}}}},"400":{"description":"Invalid action"}}}},"/api/v1/stage-definitions":{"get":{"tags":["Stage Definitions"],"summary":"List stage definitions","description":"Retrieves a paginated list of stage definitions for the authenticated organization.\nStage definitions are reusable components that define workflow stages.\n\n**Norwegian Real Estate Use Cases:**\n- Browse available legal review stages\n- View technical assessment definitions\n- List financial analysis stage types\n- Find inspection process stages\n\n**Stage Types:** Includes system and custom stage definitions\n**Filtering:** By category, system stage flag, and assignment requirements\n","operationId":"getStageDefinitions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"category","in":"query","description":"Filter by stage category","schema":{"type":"string"},"example":"legal"},{"name":"isSystemStage","in":"query","description":"Filter by system stage flag","schema":{"type":"boolean"},"example":false},{"name":"requiresAssignment","in":"query","description":"Filter by assignment requirement","schema":{"type":"boolean"},"example":true}],"responses":{"200":{"description":"Stage definitions retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/StageDefinition"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"example":{"data":[{"id":"stage-def-001","code":"legal-review","name":"Legal Due Diligence","description":"Comprehensive legal review of property documents","category":"legal","isSystemStage":false,"canBeSkipped":false,"requiresAssignment":true,"defaultDurationDays":10,"escalationAfterDays":12,"usageCount":15},{"id":"stage-def-002","code":"technical-assessment","name":"Technical Property Assessment","description":"Structural and systems evaluation","category":"technical","isSystemStage":false,"canBeSkipped":true,"requiresAssignment":true,"defaultDurationDays":7,"usageCount":12}],"meta":{"total":25,"page":1,"limit":20}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Stage Definitions"],"summary":"Create stage definition","description":"Creates a new stage definition that can be used in workflow templates.\nStage definitions define reusable workflow components with standardized behavior.\n\n**Norwegian Real Estate Use Cases:**\n- Create legal review stage definition\n- Define technical assessment stage\n- Build financial analysis stage definition\n- Design inspection process stage\n\n**Configuration:** Includes timing, assignment rules, and escalation settings\n**Reusability:** Can be used across multiple workflow templates\n**Assignment Rules:** Supports role-based and rule-based assignment\n","operationId":"createStageDefinition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateStageDefinitionRequest"},"examples":{"legalReview":{"summary":"Legal Review Stage","value":{"code":"legal-review-enhanced","name":"Enhanced Legal Due Diligence","description":"Comprehensive legal review with compliance checks","category":"legal","isSystemStage":false,"canBeSkipped":false,"requiresAssignment":true,"primaryService":"legal-department","defaultDurationDays":12,"escalationAfterDays":15,"autoAssignmentRules":{"defaultRole":"senior-legal-counsel","fallbackRole":"legal-manager","workloadBalancing":true,"skillsRequired":["property-law","compliance"]},"metadata":{"complexity":"high","priority":"critical","documentTypes":["deed","contract","survey","permits"]}}},"technicalAssessment":{"summary":"Technical Assessment Stage","value":{"code":"tech-assessment-detailed","name":"Detailed Technical Assessment","description":"Comprehensive technical evaluation of property systems","category":"technical","canBeSkipped":true,"requiresAssignment":true,"primaryService":"technical-services","defaultDurationDays":5,"escalationAfterDays":7,"autoAssignmentRules":{"defaultRole":"technical-inspector","certificationRequired":true}}}}}}},"responses":{"201":{"description":"Stage definition created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/StageDefinition"}}},"example":{"data":{"id":"stage-def-new-001","code":"legal-review-enhanced","name":"Enhanced Legal Due Diligence","category":"legal","canBeSkipped":false,"requiresAssignment":true,"defaultDurationDays":12}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"422":{"description":"Validation error (duplicate code)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_CODE_EXISTS","message":"A stage definition with this code already exists.","details":{"code":"legal-review-enhanced"}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/stage-definitions/{id}":{"get":{"tags":["Stage Definitions"],"summary":"Get stage definition details","description":"Retrieves detailed information about a specific stage definition,\nincluding usage statistics, assignment rules, and configuration.\n\n**Norwegian Real Estate Use Cases:**\n- Review legal review stage requirements\n- Examine technical assessment parameters\n- Study financial analysis configuration\n- Analyze stage usage across workflows\n\n**Includes:** Complete definition with rules, usage statistics, and related templates\n","operationId":"getStageDefinition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Stage Definition ID","schema":{"type":"string","format":"uuid"},"example":"stage-def-001"}],"responses":{"200":{"description":"Stage definition details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/StageDefinition"}}},"example":{"data":{"id":"stage-def-001","code":"legal-review","name":"Legal Due Diligence","description":"Comprehensive legal review of property documents and contracts","category":"legal","isSystemStage":false,"canBeSkipped":false,"requiresAssignment":true,"primaryService":"legal-department","defaultDurationDays":10,"escalationAfterDays":12,"autoAssignmentRules":{"defaultRole":"legal-counsel","fallbackRole":"senior-legal-counsel","workloadBalancing":true},"metadata":{"complexity":"high","skillsRequired":["contract-law","property-law"],"documentTypes":["deed","contract","survey"]},"workflowTemplateStages":[{"templateName":"Property Acquisition Standard","sequenceOrder":1},{"templateName":"Commercial Property Acquisition","sequenceOrder":2}],"taskTemplates":[{"name":"Review Property Deed","estimatedDuration":120},{"name":"Analyze Purchase Contract","estimatedDuration":180}],"usageStatistics":{"totalUsages":15,"averageDuration":8.5,"completionRate":95}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Stage Definitions"],"summary":"Update stage definition","description":"Updates stage definition properties such as name, description, timing,\nand assignment rules. Cannot modify code after creation.\n\n**Norwegian Real Estate Use Cases:**\n- Update legal review requirements\n- Modify technical assessment duration\n- Change assignment rules for financial analysis\n- Update escalation timing for inspections\n\n**Code Immutability:** Stage code cannot be changed after creation\n**Active Usage:** Changes affect future workflow template usage\n**Assignment Rules:** Can update role-based assignment configuration\n","operationId":"updateStageDefinition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Stage Definition ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStageDefinitionRequest"},"examples":{"updateTiming":{"summary":"Update Stage Timing","value":{"name":"Enhanced Legal Due Diligence - Extended","defaultDurationDays":15,"escalationAfterDays":18}},"updateAssignment":{"summary":"Update Assignment Rules","value":{"autoAssignmentRules":{"defaultRole":"senior-legal-counsel","fallbackRole":"legal-director","workloadBalancing":true,"skillsRequired":["property-law","compliance","international-law"],"certificationRequired":true}}},"updateSkippable":{"summary":"Make Stage Optional","value":{"canBeSkipped":true,"description":"Optional enhanced legal review for low-risk properties"}}}}}},"responses":{"200":{"description":"Stage definition updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/StageDefinition"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"422":{"description":"Validation error (system stage modification)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"SYSTEM_STAGE_IMMUTABLE","message":"System stage definitions cannot be modified."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/stage-definitions/{id}/task-templates":{"put":{"tags":["Stage Definitions"],"summary":"Attach/detach task templates to stage definition","description":"Updates the task templates attached to a stage definition.\nThis endpoint allows batch attachment and detachment of task templates.\n\n**Norwegian Real Estate Use Cases:**\n- Attach document review templates to legal stage\n- Add inspection checklist templates to assessment stage\n- Reuse standard templates across multiple stages\n- Build comprehensive stage workflows from template library\n\n**Options:**\n- Replace all templates: Provide array of task template IDs\n- Add/remove specific templates: Use add/remove arrays\n\n**Validation:**\n- Templates must belong to same organization\n- Templates can only be attached to one stage at a time\n- System stages may have restrictions\n","operationId":"updateStageTaskTemplates","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Stage Definition ID","schema":{"type":"string","format":"uuid"},"example":"stage-def-001"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["taskTemplateIds"],"properties":{"taskTemplateIds":{"type":"array","description":"Replace all task templates with this list","items":{"type":"string","format":"uuid"}}},"additionalProperties":false},{"type":"object","properties":{"add":{"type":"array","description":"Task template IDs to add","items":{"type":"string","format":"uuid"}},"remove":{"type":"array","description":"Task template IDs to remove","items":{"type":"string","format":"uuid"}}},"additionalProperties":false}]},"examples":{"replaceAll":{"summary":"Replace all task templates","value":{"taskTemplateIds":["template-001","template-002","template-003"]}},"addRemove":{"summary":"Add and remove specific templates","value":{"add":["template-004","template-005"],"remove":["template-001"]}}}}}},"responses":{"200":{"description":"Task templates updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["stageDefinitionId","attachedTemplates","changes"],"properties":{"stageDefinitionId":{"type":"string","description":"The stage definition ID"},"attachedTemplates":{"type":"array","description":"Current list of attached task templates","items":{"type":"object","properties":{"id":{"type":"string"},"code":{"type":"string"},"name":{"type":"string"}}}},"changes":{"type":"object","properties":{"added":{"type":"number","description":"Number of templates added"},"removed":{"type":"number","description":"Number of templates removed"},"total":{"type":"number","description":"Total templates attached"}}}}}}},"example":{"data":{"stageDefinitionId":"stage-def-001","attachedTemplates":[{"id":"template-002","code":"review-deed","name":"Review Property Deed"},{"id":"template-003","code":"analyze-contract","name":"Analyze Purchase Contract"},{"id":"template-004","code":"compliance-check","name":"Compliance Verification"}],"changes":{"added":2,"removed":1,"total":3}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templatesNotFound":{"summary":"Templates not found","value":{"error":{"code":"TEMPLATES_NOT_FOUND","message":"Some task templates were not found or don't belong to your organization","details":{"invalidTemplateIds":["template-999"]}}}},"templatesAlreadyAttached":{"summary":"Templates already attached","value":{"error":{"code":"TEMPLATES_ALREADY_ATTACHED","message":"Some task templates are already attached to other stage definitions","details":{"conflictingTemplates":[{"templateId":"template-001","currentStageId":"stage-def-002","currentStageName":"Technical Assessment"}]}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Task Templates","Stage Definitions"],"summary":"Get task templates for a stage definition","description":"Retrieves all task templates associated with a specific stage definition.\nThese templates are automatically used when workflows are instantiated.\n\n**Use Cases:**\n- Display templates for workflow stage configuration\n- Review automated task creation setup\n- Stage definition management interfaces\n- Workflow template validation\n\n**Filtering:** Supports same filtering options as general task template listing\n**Security:** Only returns templates for stage definitions belonging to the authenticated organization\n","operationId":"getStageDefinitionTaskTemplates","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Stage Definition ID","schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"priority","in":"query","schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"description":"Filter by task priority level","example":"HIGH"},{"name":"assigneeType","in":"query","schema":{"type":"string","enum":["ROLE","POSITION"]},"description":"Filter by assignee type","example":"ROLE"}],"responses":{"200":{"description":"Task templates for stage definition retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TaskTemplate"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Stage definition not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_DEFINITION_NOT_FOUND","message":"Stage definition not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{taskTemplateId}/context-triggers":{"post":{"summary":"Create a new task template context trigger","description":"Creates a trigger that executes a context operation when specific task events occur for tasks created from this template.","tags":["Task Template Context Triggers"],"parameters":[{"in":"path","name":"taskTemplateId","required":true,"schema":{"type":"string","format":"uuid"},"description":"The ID of the task template"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["taskTemplateContextId","triggerEvent","operationId"],"properties":{"taskTemplateContextId":{"type":"string","description":"ID of the task template context"},"triggerEvent":{"type":"string","enum":["task.created","task.updated","task.completed"],"description":"Event that triggers this context action"},"operationId":{"type":"string","description":"ID of the context operation to execute"},"executionOrder":{"type":"integer","minimum":0,"default":0,"description":"Order of execution when multiple triggers exist"},"isAsync":{"type":"boolean","default":false,"description":"Whether to execute this trigger asynchronously"},"continueOnFailure":{"type":"boolean","default":true,"description":"Whether to continue processing other triggers if this one fails"},"retryCount":{"type":"integer","minimum":0,"maximum":10,"default":3,"description":"Number of retry attempts on failure"},"retryDelayMs":{"type":"integer","minimum":100,"maximum":60000,"default":1000,"description":"Delay in milliseconds between retry attempts"},"conditionType":{"type":"string","nullable":true,"maxLength":50,"description":"Type of condition to evaluate before executing"},"conditionConfig":{"type":"object","nullable":true,"description":"Configuration for the condition evaluation"}}}}}},"responses":{"201":{"description":"Task template context trigger created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateContextTriggerResponse"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates":{"get":{"tags":["Task Templates"],"summary":"List all task templates for organization","description":"Retrieves a paginated list of task templates belonging to the authenticated organization.\nTask templates define reusable task configurations that can be automatically created\nduring workflow instantiation or used separately.\n\n**Use Cases:**\n- Browse available task templates for workflow stages\n- Task template management interfaces\n- Template library views\n- Administrative task template reviews\n\n**Enhanced Filtering Options:**\n- **Stage Definition**: Filter by specific stage definition\n- **Category**: Filter by template category\n- **Assignment Type**: Filter by assignee type (ROLE, POSITION)\n- **Priority**: Filter by task priority level\n\n**Sorting Options:**\n- Sort by: created_at, updated_at, name, priority, category\n- Sort order: asc (ascending) or desc (descending)\n- Default: newest first (created_at desc)\n\n**Search Functionality:**\n- Text search across task template name and description fields\n- Case-insensitive partial matching\n","operationId":"getTaskTemplates","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"stageDefinitionId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter task templates for specific stage definition","example":"456e7890-e89b-12d3-a456-426614174111"},{"name":"category","in":"query","schema":{"type":"string"},"description":"Filter by template category","example":"inspection"},{"name":"assigneeType","in":"query","schema":{"type":"string","enum":["ROLE","POSITION"]},"description":"Filter by assignee type (only ROLE and POSITION allowed)","example":"ROLE"},{"name":"priority","in":"query","schema":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},"description":"Filter by task priority level","example":"HIGH"},{"name":"sortBy","in":"query","schema":{"type":"string","enum":["created_at","updated_at","name","priority","category"]},"description":"Field to sort by","example":"name"},{"name":"sortOrder","in":"query","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction (ascending or descending)","example":"asc"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Text search across task template name and description","example":"inspection checklist"}],"responses":{"200":{"description":"Task templates retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TaskTemplate"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Task Templates"],"summary":"Create a new task template","description":"Creates a new task template within the authenticated organization.\nTask templates define reusable task configurations that can be automatically\ninstantiated during workflow creation or used separately.\n\n**Use Cases:**\n- Create standardized task definitions for workflow stages\n- Define recurring tasks for specific business processes\n- Build task template libraries for different departments\n- Template-based task automation setup\n\n**Assignment Restrictions:**\n- Only `ROLE` and `POSITION` assignment types are allowed for templates\n- `USER` assignment type is not supported for templates (for reusability)\n\n**Stage Association:**\n- Can be associated with a specific stage definition\n- Stage definition must belong to the authenticated organization\n\n**Auto-generated Fields:**\n- `id`: UUID automatically assigned\n- `organizationId`: Set from API key context\n- `createdAt` / `updatedAt`: Auto-managed timestamps\n","operationId":"createTaskTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateInput"},"examples":{"basicTemplate":{"summary":"Basic task template creation","value":{"code":"inspection-checklist","name":"Property Inspection Checklist","description":"Complete property inspection with standardized checklist","category":"inspection","priority":"HIGH","assigneeType":"ROLE","assigneeId":"property-inspector","estimatedDurationMinutes":120}},"stageTemplate":{"summary":"Template linked to stage definition","value":{"code":"legal-document-review","name":"Legal Document Review","description":"Review and validate all legal documentation","category":"legal","stageDefinitionId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH","assigneeType":"POSITION","assigneeId":"senior-legal-counsel","estimatedDurationMinutes":480,"requiresApproval":true,"approvalAssigneeType":"ROLE","approvalAssigneeId":"legal-manager"}},"complexTemplate":{"summary":"Template with checklist and metadata","value":{"code":"tenant-background-check","name":"Tenant Background Verification","description":"Comprehensive background check for prospective tenants","category":"tenant-management","priority":"MEDIUM","assigneeType":"ROLE","assigneeId":"tenant-screening-specialist","estimatedDurationMinutes":60,"checklistItems":[{"title":"Credit Score Verification","required":true},{"title":"Employment History Check","required":true},{"title":"Previous Landlord References","required":true},{"title":"Criminal Background Check","required":false}],"metadata":{"requiredDocuments":["ID","payslips","bank_statements"],"minimumCreditScore":650}}},"inheritanceOverrideTemplate":{"summary":"Template with assignment inheritance override","value":{"code":"personal-task-review","name":"Personal Task Review","description":"Review task that should always be assigned to workflow owner","category":"review","priority":"HIGH","assigneeType":"ROLE","assigneeId":"reviewer","estimatedDurationMinutes":30,"assignmentInheritanceOverride":{"enabled":true,"strategy":"WORKFLOW_OWNER"}}}}}}},"responses":{"201":{"description":"Task template created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplate"}}}}}},"400":{"description":"Bad Request - Validation errors or invalid references","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validation":{"summary":"Missing required field","value":{"error":{"code":"VALIDATION_ERROR","message":"Task template name is required","details":{"field":"name","value":null}}}},"invalidAssigneeType":{"summary":"Invalid assignee type","value":{"error":{"code":"INVALID_ASSIGNEE_TYPE","message":"Only ROLE and POSITION assignee types are allowed for task templates."}}},"duplicateCode":{"summary":"Duplicate template code","value":{"error":{"code":"DUPLICATE_CODE","message":"A task template with this code already exists."}}},"invalidStageDefinition":{"summary":"Invalid stage definition reference","value":{"error":{"code":"INVALID_STAGE_DEFINITION","message":"Stage definition not found or does not belong to your organization."}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{id}":{"get":{"tags":["Task Templates"],"summary":"Get specific task template details","description":"Retrieves detailed information for a specific task template by its UUID.\nThe task template must belong to the authenticated organization.\n\n**Use Cases:**\n- Display task template details page\n- Load task template context for editing\n- Template configuration reviews\n- Integration with workflow builders\n\n**Includes:** Response includes related stage definition details and usage statistics\n**Security:** Task template access is automatically scoped to the authenticated organization\n","operationId":"getTaskTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Task template details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplate"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Task Templates"],"summary":"Update an existing task template","description":"Updates an existing task template's properties. Only provided fields will be updated;\nomitted fields will retain their current values.\n\n**Use Cases:**\n- Update task template configurations\n- Modify assignment rules and priorities\n- Update checklist items and metadata\n- Refine template descriptions and categories\n\n**Partial Updates:** This endpoint supports partial updates - only include\nfields you want to change in the request body.\n\n**Assignment Restrictions:**\n- Only `ROLE` and `POSITION` assignment types are allowed\n- `USER` assignment type is not supported for templates\n\n**Security:** Can only update task templates belonging to the authenticated organization\n","operationId":"updateTaskTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateUpdate"},"examples":{"basicUpdate":{"summary":"Update basic template properties","value":{"name":"Enhanced Property Inspection Checklist","description":"Updated comprehensive property inspection with new safety requirements","priority":"URGENT"}},"assignmentUpdate":{"summary":"Update assignment configuration","value":{"assigneeType":"POSITION","assigneeId":"senior-property-inspector","estimatedDurationMinutes":180}},"approvalUpdate":{"summary":"Add approval requirements","value":{"requiresApproval":true,"approvalAssigneeType":"ROLE","approvalAssigneeId":"inspection-manager"}},"checklistUpdate":{"summary":"Update checklist items","value":{"checklistItems":[{"title":"Safety Equipment Check","required":true},{"title":"Structural Integrity Assessment","required":true},{"title":"Environmental Compliance Review","required":false}]}},"formTemplateUpdate":{"summary":"Associate a form template","value":{"formTemplateId":"566105cc-986b-4c91-9118-14eeb207e9df"}},"removeFormTemplate":{"summary":"Remove form template association","value":{"formTemplateId":null}}}}}},"responses":{"200":{"description":"Task template updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplate"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Task Templates"],"summary":"Delete a task template","description":"Permanently deletes a task template and all associated data.\nCannot delete templates that have been used to create tasks.\n\n**⚠️ Warning:** This action is irreversible and will delete:\n- The task template record\n- Template configuration and metadata\n\n**Use Cases:**\n- Remove test or draft templates\n- Clean up unused template definitions\n- Delete templates created in error\n\n**Usage Protection:** Cannot delete templates with existing task instances\n**Security:** Can only delete task templates belonging to the authenticated organization\n","operationId":"deleteTaskTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Task template deleted successfully. No content is returned.\nThe task template and all associated data have been permanently removed.\n"},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"409":{"description":"Cannot delete template with existing tasks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TEMPLATE_HAS_TASKS","message":"Cannot delete task template with existing task instances.","details":{"taskCount":5}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{id}/instantiate":{"post":{"tags":["Template Requirements","Task Templates"],"summary":"Instantiate task from template","description":"Create a new standalone task from a template using provided initialization data.\nOnly works with task templates that have standalone_instantiation enabled.\n\n**Process:**\n1. Validate template exists and supports standalone instantiation\n2. Validate initialization data (unless skipValidation = true)\n3. Evaluate creation conditions\n4. Resolve assignee (with override support)\n5. Create task with interpolated data\n6. Publish task created events\n\n**Use Cases:**\n- Create ad-hoc tasks from templates\n- Generate tasks outside workflow context\n- Create standardized maintenance tasks\n- Instantiate inspection or review tasks\n","operationId":"instantiateTaskFromTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam","name":"id","in":"path","required":true,"description":"Task template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskInstantiationRequest"},"examples":{"basicInstantiation":{"summary":"Basic task creation from template","value":{"projectId":"456e7890-e89b-12d3-a456-426614174111","workflowId":"789e0123-e89b-12d3-a456-426614174222","workflowStageId":"987e6543-e89b-12d3-a456-426614174333"}},"customizedInstantiation":{"summary":"Task creation with overrides","value":{"projectId":"456e7890-e89b-12d3-a456-426614174111","title":"Custom Property Inspection - Building A","description":"Specific inspection for Building A with additional safety requirements","priority":"URGENT","dueDate":"2024-01-25T17:00:00.000Z","assigneeType":"USER","assigneeId":"inspector-john-doe","metadata":{"requested_date":"2025-08-15T00:00:00.000Z","building_floor":3,"inspection_type":"annual"}}},"withEntityLinks":{"summary":"Task creation with entity links","value":{"projectId":"456e7890-e89b-12d3-a456-426614174111","entityType":"lead","entityId":"lead-abc-123","entityLinks":[{"entityType":"property","entityId":"prop-001","linkType":"related"},{"entityType":"contact","entityId":"contact-456","linkType":"associated","metadata":{"role":"primary"}}]}}}}}},"responses":{"201":{"description":"Task created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/InstantiationResult"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError","description":"Validation failed or invalid request","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/InstantiationResult"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/code/{code}/instantiate":{"post":{"tags":["Task Templates"],"summary":"Create task from template by code","description":"Creates a new task instance based on the task template identified by its unique code.\nBehaves identically to the ID-based instantiate endpoint but uses the template code\nfor lookup, which is useful for frontend integrations with well-known template codes.\n\n**Use Cases:**\n- Frontend integration with known template codes (e.g. fagansvarlig-approval-person)\n- Stable references that don't change across environments\n- Simplified API usage without needing to look up template IDs\n","operationId":"instantiateTaskTemplateByCode","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"code","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","maxLength":50},"description":"The unique template code within the organization","example":"fagansvarlig-approval-person"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateInstantiationRequest"},"examples":{"basicInstantiation":{"summary":"Basic task creation from template code","value":{"entityType":"lead","entityId":"456e7890-e89b-12d3-a456-426614174111","dueDate":"2026-03-05T23:59:59.000Z","metadata":{"leadId":"456e7890-e89b-12d3-a456-426614174111"}}}}}}},"responses":{"201":{"description":"Task created successfully from template","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template with the specified code was not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{id}/test-resolution":{"post":{"tags":["Task Templates"],"summary":"Test assignee resolution configuration","description":"Tests the assignee resolution configuration of a task template without creating a task.\nThis endpoint is useful for validating resolution configurations and debugging\nassignee resolution issues during template development.\n\n**Use Cases:**\n- Test assignee resolution with sample data\n- Debug resolution configuration issues\n- Validate context data extraction patterns\n- Preview assignee resolution results\n\n**Test Modes:**\n- Use template's existing resolution config\n- Override with test-specific resolution config\n- Test with custom sample context data\n","operationId":"testTaskTemplateResolution","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateTestResolutionRequest"},"examples":{"basicTest":{"summary":"Test with sample context data","value":{"sampleContextData":{"Owner":{"Email":"john.doe@example.com","Name":"John Doe","Role":"PROPERTY_MANAGER"}}}},"withConfigOverride":{"summary":"Test with custom resolution config","value":{"sampleContextData":{"Contacts":[{"Email":"jane.smith@example.com","Role":"SALES_AGENT"}]},"resolutionConfig":{"enabled":true,"contextType":"crm-contact","assigneeField":"Contacts.0.Email","assigneeType":"USER","transform":"EXTRACT_USERNAME"}}}}}}},"responses":{"200":{"description":"Resolution test completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplateResolutionResult"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{id}/preview-instantiation":{"post":{"tags":["Task Templates"],"summary":"Preview task instantiation with assignee resolution","description":"Creates a preview of what a task would look like when instantiated from the template,\nincluding assignee resolution if requested. The task is not actually saved to the database.\n\n**Use Cases:**\n- Preview task creation before actual instantiation\n- Test assignee resolution with real context data\n- Validate task template configuration\n- Show users what will be created\n\n**Preview Features:**\n- Shows resolved assignee information\n- Applies template defaults and overrides\n- Validates project and section references\n- Does not create database records\n","operationId":"previewTaskTemplateInstantiation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplatePreviewInstantiationRequest"},"examples":{"basicPreview":{"summary":"Preview without assignee resolution","value":{"contextData":{},"resolveAssignee":false}},"withResolution":{"summary":"Preview with assignee resolution","value":{"contextData":{"Owner":{"Email":"jane.doe@company.com","Name":"Jane Doe"}},"projectId":"456e7890-e89b-12d3-a456-426614174111","resolveAssignee":true}}}}}},"responses":{"200":{"description":"Task preview generated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplateResolutionResult"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/task-templates/{id}/instantiate-resolved":{"post":{"tags":["Task Templates"],"summary":"Create task with immediate assignee resolution","description":"Creates a new task from the template with immediate assignee resolution.\nThis endpoint combines task creation with assignee resolution in a single operation.\n\n**Use Cases:**\n- Create tasks with context-aware assignee resolution\n- Automate task assignment based on external system data\n- Integrate with CRM/ERP systems for task assignment\n- Workflow automation with dynamic assignee resolution\n\n**Resolution Features:**\n- Uses template's resolution configuration\n- Supports custom context data override\n- Fallback to template defaults on resolution failure\n- Optional waiting for resolution completion\n","operationId":"instantiateTaskTemplateWithResolution","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskTemplateInstantiateResolvedRequest"},"examples":{"basicInstantiation":{"summary":"Create task with context-based resolution","value":{"projectId":"456e7890-e89b-12d3-a456-426614174111","contextEntityId":"property-12345","waitForResolution":true}},"withOverrides":{"summary":"Create task with custom overrides","value":{"projectId":"456e7890-e89b-12d3-a456-426614174111","contextEntityId":"property-12345","contextData":{"Owner":{"Email":"specific.owner@example.com"}},"taskOverrides":{"title":"Custom Property Inspection Task","priority":"HIGH","dueDate":"2024-01-30T17:00:00.000Z"},"waitForResolution":true}}}}}},"responses":{"201":{"description":"Task created successfully with assignee resolution","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TaskTemplateResolutionResult"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_TEMPLATE_NOT_FOUND","message":"Task template not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks":{"get":{"tags":["Tasks"],"summary":"List tasks for organization","description":"Retrieves paginated tasks with filtering, sorting, search, and optional data enrichment","operationId":"getTasks","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"$ref":"#/components/parameters/ProjectIdParam"},{"name":"status","in":"query","schema":{"oneOf":[{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"]},{"type":"array","items":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"]}}]},"style":"form","explode":true,"description":"Filter tasks by status. Supports multiple values (e.g., ?status=PENDING&status=READY)","examples":{"single":{"summary":"Single status","value":"IN_PROGRESS"},"multiple":{"summary":"Multiple statuses","value":["PENDING","READY","IN_PROGRESS"]}}},{"name":"priority","in":"query","schema":{"oneOf":[{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]},{"type":"array","items":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"]}}]},"style":"form","explode":true,"description":"Filter tasks by priority level. Supports multiple values (e.g., ?priority=HIGH&priority=URGENT)","examples":{"single":{"summary":"Single priority","value":"HIGH"},"multiple":{"summary":"Multiple priorities","value":["HIGH","URGENT"]}}},{"name":"completionMode","in":"query","schema":{"oneOf":[{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"]},{"type":"array","items":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"]}}]},"style":"form","explode":true,"description":"Filter tasks by completion mode. INLINE for simple tasks, DETAIL_VIEW for form tasks, EXTERNAL_ACTION for tasks completed by other actions","examples":{"single":{"summary":"Single completion mode","value":"INLINE"},"multiple":{"summary":"Multiple completion modes","value":["INLINE","DETAIL_VIEW"]}}},{"name":"assigneeType","in":"query","schema":{"oneOf":[{"type":"string","enum":["ROLE","POSITION","USER"]},{"type":"array","items":{"type":"string","enum":["ROLE","POSITION","USER"]}}]},"style":"form","explode":true,"description":"Filter tasks by assignee type. Supports multiple values (e.g., ?assigneeType=USER&assigneeType=ROLE)","examples":{"single":{"summary":"Single assignee type","value":"USER"},"multiple":{"summary":"Multiple assignee types","value":["USER","ROLE"]}}},{"name":"assigneeId","in":"query","schema":{"type":"string"},"description":"Filter tasks by specific assignee ID","example":"user-123"},{"name":"workflowId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter tasks belonging to specific workflow","example":"456e7890-e89b-12d3-a456-426614174111"},{"name":"workflowStageId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter tasks in specific workflow stage","example":"789e0123-e89b-12d3-a456-426614174222"},{"name":"workflowTemplateId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter tasks belonging to workflows created from a specific template.\nUseful for finding all tasks related to a particular workflow type\n(e.g., all tasks from onboarding workflows).\n","example":"789e0123-e89b-12d3-a456-426614174222"},{"name":"workflowTemplateIds","in":"query","schema":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":50},"style":"form","explode":true,"description":"Filter tasks by multiple workflow template IDs (supports multiple values).\nReturns tasks from workflows created from any of the specified templates.\nUseful for aggregating tasks across related workflow types.\n","examples":{"multiple_templates":{"summary":"Filter by multiple templates","value":["789e0123-e89b-12d3-a456-426614174222","890f0234-e89b-12d3-a456-426614174333"]}}},{"name":"taskTemplateId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter tasks created from a specific task template.\nUseful for finding all instances of a particular task type.\n","example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"taskTemplateIds","in":"query","schema":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":50},"style":"form","explode":true,"description":"Filter tasks by multiple task template IDs (supports multiple values).\nReturns tasks created from any of the specified task templates.\n","examples":{"multiple_task_templates":{"summary":"Filter by multiple task templates","value":["123e4567-e89b-12d3-a456-426614174000","234f5678-e89b-12d3-a456-426614174111"]}}},{"name":"entityType","in":"query","schema":{"type":"string"},"description":"Filter tasks by external entity type","example":"resource"},{"name":"entityId","in":"query","schema":{"type":"string"},"description":"Filter tasks by external entity ID","example":"resource-456"},{"name":"entities","in":"query","schema":{"type":"array","items":{"type":"string","pattern":"^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+$"},"maxItems":10},"style":"form","explode":true,"description":"Filter tasks by multiple entities (multi-entity filtering). Each entity must be in 'type:id' format.\nMaximum 10 entities. Supports filtering by ANY or ALL entities based on entityMatchMode parameter.\n","examples":{"resource_tasks":{"summary":"Tasks for multiple resources","value":["resource:res-123","resource:res-456"]},"cross_entity_tasks":{"summary":"Tasks spanning multiple entity types","value":["client:client-789","resource:res-123"]}}},{"name":"entityMatchMode","in":"query","schema":{"type":"string","enum":["ANY","ALL"],"default":"ANY"},"description":"Determines how multiple entities are matched when using the 'entities' parameter:\n- ANY: Return tasks linked to any of the specified entities (OR logic)\n- ALL: Return tasks that have links to all specified entities (AND logic, requires EntityLink table)\n","example":"ANY"},{"name":"sourceService","in":"query","schema":{"type":"string"},"description":"Filter tasks by source service (for inter-service coordination)","example":"resource-management"},{"name":"approvalRequired","in":"query","schema":{"type":"boolean"},"description":"Filter tasks by whether they require approval (true) or not (false)","example":true},{"name":"approverId","in":"query","schema":{"type":"string"},"description":"Filter tasks where the current approval step's resolved approver matches this ID.\nTypically used with status=PENDING_APPROVAL to find tasks awaiting a specific approver.\n","example":"42333ad4-a338-4d21-8141-ad316d1327c1"},{"name":"dueDateFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter tasks due after this date (ISO 8601 format)","example":"2024-01-20T00:00:00.000Z"},{"name":"dueDateTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter tasks due before this date (ISO 8601 format)","example":"2024-01-31T23:59:59.999Z"},{"name":"createdFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter tasks created after this date (ISO 8601 format)","example":"2024-01-01T00:00:00.000Z"},{"name":"createdTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter tasks created before this date (ISO 8601 format)","example":"2024-01-31T23:59:59.999Z"},{"name":"sortBy","in":"query","schema":{"type":"string","enum":["created_at","updated_at","due_date","priority","title"]},"description":"Field to sort by","example":"due_date"},{"name":"sortOrder","in":"query","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction (ascending or descending)","example":"desc"},{"name":"search","in":"query","schema":{"type":"string"},"description":"Text search across task title and description","example":"homepage design"},{"name":"portal","in":"query","schema":{"type":"string"},"description":"Portal context for visibility filtering (e.g., client_portal, partner_portal)","example":"client_portal"},{"name":"portalUserId","in":"query","schema":{"type":"string"},"description":"User ID in the portal context for visibility filtering","example":"user-123"},{"name":"linkedEntities","in":"query","schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"Supplementary entity link filtering (comma-separated type:id format)","example":["resource:res-123","client:client-456"]},{"name":"anyEntity","in":"query","schema":{"type":"string"},"description":"Filter tasks linked to any entity type (format type:id)","example":"resource:res-123"},{"name":"hasLinkedType","in":"query","schema":{"type":"string"},"description":"Filter tasks with linked entity of specific type","example":"resource"},{"name":"includeLinks","in":"query","schema":{"type":"boolean","default":false},"description":"Include supplementary entity links in response","example":true},{"name":"includeEntities","in":"query","schema":{"type":"boolean","default":false},"description":"Include entity enrichment data in response metadata","example":true},{"name":"includeContextData","in":"query","schema":{"type":"boolean","default":false},"description":"Include hierarchical context data in response metadata","example":true},{"name":"includeCalendarSummary","in":"query","schema":{"type":"boolean","default":false},"description":"Include lightweight calendar event summaries for tasks. When enabled, each task response includes:\n- Whether the task has an associated calendar event\n- Event timing (start/end times, timezone)\n- RSVP summary (total attendees, accepted, declined, pending responses)\n- Registration summary (confirmed, waitlisted, total party size)\n\n**Performance Considerations:**\n- Maximum 100 tasks allowed when this parameter is enabled\n- Returns only the first/primary event per task\n- Optimized batch loading for minimal performance impact\n\n**Business Value:**\n- View calendar status directly in task lists without additional API calls\n- Monitor RSVP response rates for event-related tasks\n- Track registration confirmations for viewing appointments\n","example":true}],"responses":{"200":{"description":"Tasks retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"examples":{"roleBasedTasks":{"summary":"Tasks assigned to a specific role","value":{"data":[{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Create homepage design mockups","description":"Design 3 different homepage layouts focusing on improved conversion rates","status":"IN_PROGRESS","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":null,"assignmentType":"ROLE","assigneeRole":"ui-designer","assigneePosition":null,"assigneeUserId":null,"estimatedMinutes":480,"dueDate":"2024-01-25T17:00:00.000Z","entityType":"feature","entityId":"feature-456","sourceService":null,"sourceEntityId":null,"workflowId":null,"workflowStageId":null,"completionNotes":null,"completedAt":null,"project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-18T09:45:00.000Z"}],"meta":{"total":5,"page":1,"limit":20}}},"workflowGeneratedTasks":{"summary":"Tasks generated by workflow automation","value":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174555","title":"Resource verification checklist","description":"Complete resource verification process","status":"READY","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"789e0123-e89b-12d3-a456-426614174666","sectionId":null,"assignmentType":"POSITION","assigneeRole":null,"assigneePosition":"quality-inspector","assigneeUserId":null,"estimatedMinutes":120,"dueDate":"2024-01-22T10:00:00.000Z","entityType":"resource","entityId":"resource-204","sourceService":"external-system","sourceEntityId":"contract-renewal-123","workflowId":"456e7890-e89b-12d3-a456-426614174777","workflowStageId":"789e0123-e89b-12d3-a456-426614174888","completionNotes":null,"completedAt":null,"project":{"id":"789e0123-e89b-12d3-a456-426614174666","name":"Resource Management"},"section":null,"createdAt":"2024-01-18T08:00:00.000Z","updatedAt":"2024-01-18T08:00:00.000Z"},{"id":"234e5678-e89b-12d3-a456-426614174666","title":"Review client application","description":"Review and approve or reject client application","status":"BLOCKED","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"789e0123-e89b-12d3-a456-426614174666","sectionId":null,"assignmentType":"ROLE","assigneeRole":"resource-manager","assigneePosition":null,"assigneeUserId":null,"requiresApproval":true,"approvalAssigneeType":"ROLE","approvalAssigneeId":"senior-resource-manager","approvedAt":null,"approvedBy":null,"estimatedMinutes":60,"dueDate":"2024-01-23T17:00:00.000Z","entityType":"resource","entityId":"resource-204","sourceService":"external-system","sourceEntityId":"contract-renewal-123","workflowId":"456e7890-e89b-12d3-a456-426614174777","workflowStageId":"890e1234-e89b-12d3-a456-426614174999","completionNotes":null,"completedAt":null,"project":{"id":"789e0123-e89b-12d3-a456-426614174666","name":"Resource Management"},"section":null,"createdAt":"2024-01-18T08:00:00.000Z","updatedAt":"2024-01-18T09:15:00.000Z"}],"meta":{"total":15,"page":1,"limit":20}}},"userSpecificTasks":{"summary":"Tasks assigned to a specific user","value":{"data":[{"id":"987e6543-e89b-12d3-a456-426614174333","title":"Setup development environment","description":"Configure Docker containers and database schema","status":"COMPLETED","priority":"MEDIUM","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":"321e6547-e89b-12d3-a456-426614174333","assignmentType":"USER","assigneeRole":null,"assigneePosition":null,"assigneeUserId":"user-123","estimatedMinutes":120,"dueDate":null,"entityType":null,"entityId":null,"sourceService":null,"sourceEntityId":null,"workflowId":null,"workflowStageId":null,"completionNotes":"Environment configured successfully. All services running.","completedAt":"2024-01-16T14:30:00.000Z","project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":{"id":"321e6547-e89b-12d3-a456-426614174333","name":"Setup Phase"},"createdAt":"2024-01-12T08:15:00.000Z","updatedAt":"2024-01-16T14:30:00.000Z"}],"meta":{"total":8,"page":1,"limit":20}}},"empty":{"summary":"No tasks found","value":{"data":[],"meta":{"total":0,"page":1,"limit":20}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Tasks"],"summary":"Create a new task","description":"Creates a task within the organization. Tasks can be assigned to roles, positions, or users, and linked to external entities.\n","operationId":"createTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskInput"},"examples":{"basicTask":{"summary":"Basic task creation","value":{"title":"Create homepage design mockups","description":"Design 3 different homepage layouts focusing on improved conversion rates","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH"}},"assignedTask":{"summary":"Task with role assignment","value":{"title":"Implement user authentication","description":"Build secure login/logout functionality with JWT tokens","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":"321e6547-e89b-12d3-a456-426614174333","priority":"HIGH","assignmentType":"ROLE","assigneeRole":"backend-developer","estimatedMinutes":960,"dueDate":"2024-01-30T17:00:00.000Z"}},"linkedTask":{"summary":"Task linked to external entity","value":{"title":"Fix critical bug in payment flow","description":"Resolve issue causing payment failures on mobile devices","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"URGENT","assignmentType":"USER","assigneeUserId":"user-789","estimatedMinutes":240,"entityType":"bug-report","entityId":"bug-12345"}},"minimalTask":{"summary":"Minimal required fields","value":{"title":"Emergency server maintenance","projectId":"456e7890-e89b-12d3-a456-426614174111"}},"subtask":{"summary":"Subtask creation with parent relationship","value":{"title":"Test payment integration","description":"Verify payment flow works with new API","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH","assignmentType":"USER","assigneeUserId":"user-456","parentTaskId":"123e4567-e89b-12d3-a456-426614174000","estimatedMinutes":120}}}}}},"responses":{"201":{"description":"Task created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Create homepage design mockups","description":"Design 3 different homepage layouts focusing on improved conversion rates","status":"PENDING","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":null,"assignmentType":null,"assigneeRole":null,"assigneePosition":null,"assigneeUserId":null,"estimatedMinutes":null,"dueDate":null,"entityType":null,"entityId":null,"project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":null,"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-15T10:30:00.000Z"}}}}},"400":{"description":"Bad Request - Validation errors or invalid references","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validation":{"summary":"Missing required field","value":{"error":{"code":"VALIDATION_ERROR","message":"Task title is required","details":{"field":"title","value":null}}}},"invalidProject":{"summary":"Invalid project reference","value":{"error":{"code":"INVALID_PROJECT","message":"Project not found or does not belong to your organization."}}},"invalidSection":{"summary":"Invalid section reference","value":{"error":{"code":"INVALID_SECTION","message":"Section not found or does not belong to your organization/project."}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}":{"get":{"tags":["Tasks"],"summary":"Get specific task details","description":"Retrieves a single task by ID with optional context and entity enrichment.\n","operationId":"getTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"},{"name":"includeContext","in":"query","description":"Include live context data from integrated systems","schema":{"type":"boolean","default":true},"example":true},{"name":"includeEntities","in":"query","description":"Include cached entity data from external systems","schema":{"type":"boolean","default":false},"example":false},{"name":"includeContextData","in":"query","description":"Include hierarchical context data from workflow system (Issue","schema":{"type":"boolean","default":false},"example":false},{"name":"includeCalendarSummary","in":"query","description":"Include lightweight calendar event summary for this task. Returns:\n- Whether the task has an associated calendar event\n- Event timing (start/end times, timezone, location)\n- RSVP summary (total attendees, accepted, declined, pending)\n- Registration summary (confirmed, waitlisted, total party size)\n\nUseful for displaying calendar status alongside task details.\n","schema":{"type":"boolean","default":false},"example":false},{"name":"includeCalendarEvents","in":"query","description":"Include full calendar event details for this task. Returns complete event records with:\n- All event details (summary, description, location, times, status)\n- Full attendee list with RSVP status\n- Complete registration details for each registrant\n- Smart Invite tracking information\n- Calculated RSVP and registration summaries\n\nUse this for detailed calendar event management UIs. For lighter-weight summary data, use includeCalendarSummary instead.\n","schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"Task details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"examples":{"success":{"summary":"Successful task retrieval","value":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Create homepage design mockups","description":"Design 3 different homepage layouts focusing on improved conversion rates and modern aesthetic","status":"IN_PROGRESS","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":"321e6547-e89b-12d3-a456-426614174333","assignmentType":"ROLE","assigneeRole":"ui-designer","estimatedMinutes":480,"dueDate":"2024-01-25T17:00:00.000Z","entityType":"feature","entityId":"feature-456","project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":{"id":"321e6547-e89b-12d3-a456-426614174333","name":"Design Phase"},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-18T09:45:00.000Z"}}},"withoutSection":{"summary":"Task without section assignment","value":{"data":{"id":"987e6543-e89b-12d3-a456-426614174333","title":"Review project requirements","description":"Conduct thorough review of client requirements and specifications","status":"PENDING","priority":"MEDIUM","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":null,"assignmentType":"USER","assigneeUserId":"user-456","estimatedMinutes":240,"dueDate":null,"entityType":null,"entityId":null,"project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":null,"createdAt":"2024-01-16T14:20:00.000Z","updatedAt":"2024-01-16T14:20:00.000Z"}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Tasks"],"summary":"Update an existing task","description":"Updates a task with partial or complete field changes. Only provided fields are updated.\n","operationId":"updateTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskUpdate"},"examples":{"statusUpdate":{"summary":"Update task status to completed","value":{"status":"COMPLETED"}},"reassignment":{"summary":"Reassign task to specific user","value":{"assignmentType":"USER","assigneeUserId":"user-456","status":"IN_PROGRESS"}},"priorityUpdate":{"summary":"Increase task priority","value":{"priority":"URGENT","dueDate":"2024-01-20T17:00:00.000Z"}},"fullUpdate":{"summary":"Update multiple fields","value":{"title":"Enhanced homepage design mockups","description":"Updated scope: Design 5 different homepage layouts with A/B testing considerations","status":"IN_PROGRESS","priority":"HIGH","assignmentType":"ROLE","assigneeRole":"senior-designer","estimatedMinutes":720,"dueDate":"2024-01-28T17:00:00.000Z"}},"progressUpdate":{"summary":"Update task progress","value":{"description":"Completed 3 of 5 mockup designs. Working on mobile responsive layouts.","status":"IN_PROGRESS"}},"parentTaskUpdate":{"summary":"Set task as subtask of another","value":{"parentTaskId":"123e4567-e89b-12d3-a456-426614174000"}},"removeParentTask":{"summary":"Remove parent task relationship","value":{"parentTaskId":null}}}}}},"responses":{"200":{"description":"Task updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Enhanced homepage design mockups","description":"Updated scope: Design 5 different homepage layouts with A/B testing considerations","status":"IN_PROGRESS","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","sectionId":"321e6547-e89b-12d3-a456-426614174333","assignmentType":"ROLE","assigneeRole":"senior-designer","estimatedMinutes":720,"dueDate":"2024-01-28T17:00:00.000Z","entityType":"feature","entityId":"feature-456","project":{"id":"456e7890-e89b-12d3-a456-426614174111","name":"Website Redesign Q1 2024"},"section":{"id":"321e6547-e89b-12d3-a456-426614174333","name":"Design Phase"},"createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-20T14:45:00.000Z"}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Tasks"],"summary":"Delete a task","description":"Deletes a task by ID. The task is permanently removed from the system.\n","operationId":"deleteTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Task deleted successfully. No content is returned.\nThe task and all associated data have been permanently removed.\n"},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/complete":{"post":{"tags":["Tasks"],"summary":"Complete a task with structured data support","description":"Marks a task as completed with optional completion notes and metadata.\n","operationId":"completeTask","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"completion_notes":{"type":"string","description":"Simple completion notes","example":"Task completed successfully"},"metadata":{"type":"object","description":"Structured completion data","properties":{"completion_form":{"type":"object","description":"Frontend-designed form completion data","properties":{"form_type":{"type":"string","description":"Identifier for the form type","example":"resource_inspection_checklist"},"form_version":{"type":"string","description":"Version of the form","example":2.1},"submitted_at":{"type":"string","format":"date-time","description":"When the form was submitted","example":"2024-01-20T10:30:00Z"},"submitted_by":{"type":"string","description":"Who submitted the form","example":"user-123"},"data":{"type":"object","description":"The structured form data","example":{"overall_condition":"good","checklist_items":[{"item":"electrical_check","status":"passed","notes":"All working"},{"item":"plumbing_check","status":"failed","notes":"Minor leak detected"}],"photos":["attachment-id-1","attachment-id-2"],"recommendations":["Schedule minor plumbing repair"]}}}}}}}},"examples":{"simpleCompletion":{"summary":"Simple task completion","value":{"completion_notes":"Task completed successfully"}},"frontendFormCompletion":{"summary":"Frontend form completion with structured data","value":{"completion_notes":"Property inspection completed","metadata":{"completion_form":{"form_type":"resource_verification_checklist","form_version":2.1,"submitted_at":"2024-01-20T10:30:00Z","submitted_by":"user-123","data":{"overall_condition":"good","checklist_items":[{"item":"electrical_check","status":"passed","notes":"All working"},{"item":"plumbing_check","status":"failed","notes":"Minor leak detected"}],"photos":["attachment-id-1","attachment-id-2"],"recommendations":["Schedule minor plumbing repair"]}}}}},"complexFormCompletion":{"summary":"Complex form with multiple data types","value":{"completion_notes":"Tenant application review completed","metadata":{"completion_form":{"form_type":"client_application_review","form_version":1,"submitted_at":"2024-01-20T14:45:00Z","submitted_by":"user-456","data":{"applicant_score":85,"credit_check_passed":true,"employment_verified":true,"references_contacted":3,"recommendation":"approved","conditions":["First month rent in advance","Security deposit required"],"supporting_documents":["attachment-id-3","attachment-id-4"]}}}}}}}}},"responses":{"200":{"description":"Task completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Resource verification checklist","description":"Complete verification checklist for resource","status":"COMPLETED","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","completionNotes":"Property inspection completed","completedAt":"2024-01-20T10:30:00.000Z","metadata":{"completion_form":{"form_type":"resource_verification_checklist","submitted_at":"2024-01-20T10:30:00Z","data":{"overall_condition":"good","checklist_items":["..."]}}}}}}}},"400":{"description":"Bad Request - Task already completed or validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"alreadyCompleted":{"summary":"Task already completed","value":{"error":{"code":"TASK_ALREADY_COMPLETED","message":"Task is already completed"}}},"invalidFormData":{"summary":"Invalid form completion data","value":{"error":{"code":"INVALID_COMPLETION_DATA","message":"Form completion data validation failed","details":{"field":"form_type","issue":"required"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{workflowIdOrNumber}/tasks/by-code/{templateCode}/complete":{"post":{"tags":["Tasks","Workflows"],"summary":"Complete task by workflow ID/number and template code","description":"Complete a task using workflow identifier (UUID or workflow_number) and task template code,\neliminating the need to track task UUIDs in frontend code.\n\n## Business Context\n\nThis endpoint enables UI-driven task completion where the frontend knows the workflow context\nand the specific task action (template code) but doesn't need to track task IDs.\n\n**Use Case Example:**\nUser navigates to resource details page → automatically complete \"view_resource_details\" task\nwithout needing to look up the task UUID first.\n\n## Key Features\n\n- **Flexible Workflow Identification**: Supports both UUID and workflow_number (e.g., \"WF-2024-001\")\n- **Template Code Lookup**: Uses task template code instead of task UUID\n- **Multi-Tenant Safe**: All operations scoped by organization\n- **Complete Validation**: Full error handling for all edge cases\n\n## Workflow Identifier Formats\n\n- **UUID Format**: `123e4567-e89b-12d3-a456-426614174000`\n- **Workflow Number**: `WF-2024-001`, `WF-2025-123`\n\n## Template-Based Tasks Only\n\nThis endpoint only works for tasks created from templates (tasks with a template_id).\nAd-hoc tasks without templates must use the standard task completion endpoint.\n","operationId":"completeTaskByTemplateCode","parameters":[{"in":"path","name":"workflowIdOrNumber","required":true,"schema":{"type":"string","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|WF-\\d{4}-\\d{3,})$"},"description":"Either workflow UUID or workflow number (e.g., WF-2024-001)","examples":{"uuid":{"value":"123e4567-e89b-12d3-a456-426614174000","summary":"Using workflow UUID"},"workflowNumber":{"value":"WF-2024-001","summary":"Using workflow number"}}},{"in":"path","name":"templateCode","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","minLength":1,"maxLength":50},"description":"Task template code","example":"view_resource_details"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"completion_notes":{"type":"string","maxLength":2000,"description":"Optional notes about task completion"},"metadata":{"type":"object","additionalProperties":true,"description":"Optional metadata including completion_form"}}},"examples":{"simpleCompletion":{"summary":"Simple completion","value":{"completion_notes":"Property viewed successfully"}},"withFormData":{"summary":"Completion with form data","value":{"completion_notes":"Documents verified","metadata":{"completion_form":{"form_type":"document_verification","submitted_by":"user@example.com","submitted_at":"2024-01-15T10:30:00Z","data":{"verified":true,"notes":"All documents in order"}}}}}}}}},"responses":{"200":{"description":"Task completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"task-uuid-here","title":"View Property Details","status":"COMPLETED","completed_at":"2024-01-15T10:30:00Z","template_id":"template-uuid","workflow_id":"workflow-uuid"}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidTemplateCode":{"summary":"Invalid template code format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid template code format"}}},"invalidWorkflowId":{"summary":"Invalid workflow identifier","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid workflow identifier format"}}}}}}},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"description":"Workflow or task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotFound":{"summary":"Workflow not found","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow 'WF-2024-001' not found"}}},"taskNotFound":{"summary":"Task not found","value":{"error":{"code":"TASK_NOT_FOUND","message":"No task found with template code 'view_resource_details' in workflow 'WF-2024-001'"}}},"notTemplateTask":{"summary":"Task not template-based","value":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found - only template-based tasks support code lookup"}}}}}}},"409":{"description":"Task already completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_ALREADY_COMPLETED","message":"Task is already completed"}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{workflowIdOrNumber}/tasks/by-code/{templateCode}/status":{"get":{"tags":["Tasks","Workflows"],"summary":"Get task status by workflow ID/number and template code","description":"Retrieves minimal task status information for UI state management. This endpoint enables\ncomponents to check task completion status without fetching full task details, providing\na lightweight alternative for status checks.\n\n## Lookup Process\n\n1. Resolves workflow by ID (UUID) or workflow number (string identifier)\n2. Finds task within the resolved workflow using the template code\n3. Returns minimal status information: id, status, completed_at, completion_notes\n\n## Use Cases\n\n- UI components that need to display task completion status\n- State management systems checking task progress\n- Conditional rendering based on task completion\n- Lightweight status polling without full task data\n","parameters":[{"in":"path","name":"workflowIdOrNumber","required":true,"schema":{"type":"string"},"description":"Workflow identifier - accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Workflow number string (e.g., \"WF-2024-001\")\n","example":"WF-2024-001"},{"in":"path","name":"templateCode","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$"},"description":"Task template code - unique identifier within the workflow template.\nMust be alphanumeric with underscores and hyphens.\n","example":"view_resource_details"}],"responses":{"200":{"description":"Task status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique task identifier"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","WAITING_FOR_EVENT","FAILED"],"description":"Current task status"},"completed_at":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when task was completed (null if not completed)"},"completion_notes":{"type":"string","nullable":true,"description":"Optional notes added when task was completed"}}}}},"examples":{"completed":{"summary":"Completed task","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440000","status":"COMPLETED","completed_at":"2024-01-15T10:30:00Z","completion_notes":"All documents reviewed and approved"}}},"in_progress":{"summary":"Task in progress","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440001","status":"IN_PROGRESS","completed_at":null,"completion_notes":null}}}}}}},"404":{"description":"Workflow or task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflow_not_found":{"summary":"Workflow not found","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow 'WF-2024-999' not found"}}},"task_not_found":{"summary":"Task not found in workflow","value":{"error":{"code":"TASK_NOT_FOUND","message":"No task found with template code 'INVALID_CODE' in workflow 'WF-2024-001'"}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{workflowIdOrNumber}/tasks/by-code/{templateCode}":{"get":{"tags":["Tasks","Workflows"],"summary":"Get complete task details by workflow ID/number and template code","description":"Returns full task information including optional entity enrichment and context data.\nThis endpoint enables components to retrieve complete task details without tracking UUIDs.\n\n## Key Benefits\n\n- **UUID-Free Access**: Reference tasks by workflow and template code instead of task UUIDs\n- **External Integration**: Ideal for external systems that track workflow numbers and template codes\n- **Workflow-Based UIs**: Simplifies components that navigate workflow stages and tasks\n- **Complete Data**: Returns all task details with optional entity enrichment and context data\n\n## Lookup Process\n\n1. Resolves workflow by ID (UUID) or workflow number (string identifier)\n2. Finds task within the resolved workflow using the template code\n3. Fetches complete task details including relationships and optional context\n4. Optionally enriches with cached entity data from external systems\n5. Optionally includes hierarchical context data from workflow system\n\n## Use Cases\n\n- External integrations that reference tasks by workflow/template codes\n- Workflow-based UI components displaying task details\n- Systems that need full task information without tracking UUIDs\n- Integration scenarios where template codes are the primary reference\n","operationId":"getTaskByTemplateCode","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowIdOrNumber","required":true,"schema":{"type":"string"},"description":"Workflow identifier - accepts either:\n- UUID format (e.g., \"123e4567-e89b-12d3-a456-426614174000\")\n- Workflow number string (e.g., \"WF-2024-001\")\n","example":"WF-2024-001"},{"in":"path","name":"templateCode","required":true,"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$"},"description":"Task template code - unique identifier within the workflow template.\nMust be alphanumeric with underscores and hyphens.\n","example":"view_resource_details"},{"name":"includeContext","in":"query","description":"Include live context data from integrated systems","schema":{"type":"boolean","default":true},"example":true},{"name":"includeEntities","in":"query","description":"Include cached entity data from external systems","schema":{"type":"boolean","default":false},"example":false},{"name":"includeContextData","in":"query","description":"Include hierarchical context data from workflow system","schema":{"type":"boolean","default":false},"example":false}],"responses":{"200":{"description":"Task details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"examples":{"success":{"summary":"Task with full details","value":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Review resource documents","description":"Review all resource documents for accuracy and completeness","status":"IN_PROGRESS","priority":"HIGH","organizationId":"123e4567-e89b-12d3-a456-426614174000","projectId":"456e7890-e89b-12d3-a456-426614174111","workflowId":"321e6547-e89b-12d3-a456-426614174333","workflowStageId":"111e2222-e89b-12d3-a456-426614174444","taskTemplateCode":"view_resource_details","assignmentType":"ROLE","assigneeRole":"resource-manager","estimatedMinutes":60,"dueDate":"2024-01-25T17:00:00.000Z","createdAt":"2024-01-15T10:30:00.000Z","updatedAt":"2024-01-18T09:45:00.000Z"}}}}}}},"404":{"description":"Workflow or task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflow_not_found":{"summary":"Workflow not found","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow 'WF-2024-999' not found"}}},"task_not_found":{"summary":"Task not found in workflow","value":{"error":{"code":"TASK_NOT_FOUND","message":"No task found with template code 'INVALID_CODE' in workflow 'WF-2024-001'"}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/form":{"get":{"tags":["Tasks","Forms"],"summary":"Get task form definition and response data","description":"Retrieve form definition and any existing response data for a specific task.\nUsed for backend-designed dynamic forms with JSON schema definitions.\n\n## Business Logic\n\n### Form System Overview\n\nThe task form system enables dynamic, data-driven forms attached to tasks:\n\n1. **Backend-Designed Forms**\n   - Form definitions stored in task metadata\n   - JSON Schema validation for responses\n   - Field types, validation rules, and UI hints\n   - Version control for form evolution\n\n2. **Form Response Lifecycle**\n   - Initial form load returns definition only\n   - Responses saved via `/form/submit` endpoint\n   - Multiple submissions allowed until task completion\n   - Final submission preserved in completion data\n\n3. **Integration with Task Completion**\n   - Form responses can be part of task completion\n   - Completion locks form from further edits\n   - Historical responses preserved for audit\n\n## Use Cases\n\n### Property Inspection Form\nBackend defines inspection checklist structure\n```json\n{\n  \"taskId\": \"789e0123-e89b-12d3-a456-426614174222\",\n  \"formDefinition\": {\n    \"id\": \"resource-verification-v2\",\n    \"version\": \"2.0\",\n    \"title\": \"Property Inspection Checklist\",\n    \"description\": \"Standard inspection form for rental properties\",\n    \"schema\": {\n      \"type\": \"object\",\n      \"required\": [\"resourceId\", \"verificationDate\", \"overallCondition\"],\n      \"properties\": {\n        \"resourceId\": {\n          \"type\": \"string\",\n          \"title\": \"Property ID\",\n          \"readOnly\": true\n        },\n        \"verificationDate\": {\n          \"type\": \"string\",\n          \"format\": \"date\",\n          \"title\": \"Inspection Date\"\n        },\n        \"overallCondition\": {\n          \"type\": \"string\",\n          \"title\": \"Overall Condition\",\n          \"enum\": [\"excellent\", \"good\", \"fair\", \"poor\"],\n          \"enumNames\": [\"Excellent\", \"Good\", \"Fair\", \"Poor\"]\n        },\n        \"checklistItems\": {\n          \"type\": \"array\",\n          \"title\": \"Inspection Items\",\n          \"items\": {\n            \"type\": \"object\",\n            \"properties\": {\n              \"area\": {\n                \"type\": \"string\",\n                \"enum\": [\"electrical\", \"plumbing\", \"hvac\", \"structural\"]\n              },\n              \"status\": {\n                \"type\": \"string\",\n                \"enum\": [\"passed\", \"failed\", \"needs_attention\"]\n              },\n              \"notes\": {\n                \"type\": \"string\",\n                \"maxLength\": 500\n              }\n            }\n          }\n        }\n      }\n    },\n    \"uiSchema\": {\n      \"resourceId\": {\n        \"ui:widget\": \"hidden\"\n      },\n      \"overallCondition\": {\n        \"ui:widget\": \"radio\"\n      },\n      \"checklistItems\": {\n        \"ui:options\": {\n          \"orderable\": false\n        }\n      }\n    }\n  },\n  \"formResponse\": {\n    \"resourceId\": \"resource-204\",\n    \"verificationDate\": \"2024-01-20\",\n    \"overallCondition\": \"good\",\n    \"checklistItems\": [\n      {\n        \"area\": \"electrical\",\n        \"status\": \"passed\",\n        \"notes\": \"All outlets tested and working\"\n      }\n    ]\n  },\n  \"completionData\": null\n}\n```\n\n### Customer Intake Form\nComplex multi-step form with conditional logic\n```json\n{\n  \"taskId\": \"123e4567-e89b-12d3-a456-426614174333\",\n  \"formDefinition\": {\n    \"id\": \"client-intake\",\n    \"version\": \"1.0\",\n    \"title\": \"New Customer Intake\",\n    \"schema\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"personalInfo\": {\n          \"type\": \"object\",\n          \"title\": \"Personal Information\",\n          \"required\": [\"firstName\", \"lastName\", \"email\"],\n          \"properties\": {\n            \"firstName\": { \"type\": \"string\" },\n            \"lastName\": { \"type\": \"string\" },\n            \"email\": { \"type\": \"string\", \"format\": \"email\" }\n          }\n        },\n        \"accountType\": {\n          \"type\": \"string\",\n          \"title\": \"Account Type\",\n          \"enum\": [\"basic\", \"premium\", \"enterprise\"]\n        }\n      }\n    }\n  },\n  \"formResponse\": null,\n  \"completionData\": null\n}\n```\n\n### No Form Defined\nTask without attached form\n```json\n{\n  \"taskId\": \"456e7890-e89b-12d3-a456-426614174444\",\n  \"formDefinition\": null,\n  \"formResponse\": null,\n  \"completionData\": null\n}\n```\n\n## Form Definition Structure\n\n### JSON Schema Support\n- Standard JSON Schema Draft 7 validation\n- Custom UI hints via uiSchema\n- Conditional logic support\n- File upload references\n- Nested object and array support\n\n### UI Schema Extensions\n- Widget selection (radio, select, textarea)\n- Field ordering and grouping\n- Conditional visibility rules\n- Help text and placeholders\n- Custom validation messages\n\n## Response States\n\n1. **No Form**: All fields null\n2. **Form Only**: Definition present, no responses\n3. **With Response**: Active form with saved data\n4. **Completed**: Form locked with final data\n\n## Localization Support\n\nFuture enhancement for multi-language forms:\n- Pass `locale` parameter for translations\n- Field labels and help text localized\n- Validation messages in user language\n","operationId":"getTaskForm","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task ID","schema":{"type":"string","format":"uuid"},"example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"locale","in":"query","description":"Locale for form field translations (future enhancement)","schema":{"type":"string"},"example":"en-US"}],"responses":{"200":{"description":"Task form data retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"taskId":{"type":"string","format":"uuid","description":"Task identifier"},"formDefinition":{"type":"object","nullable":true,"description":"Form schema and field definitions"},"formResponse":{"type":"object","nullable":true,"description":"Any existing form response data"},"completionData":{"type":"object","nullable":true,"description":"Form data submitted during task completion"}}}}},"example":{"data":{"taskId":"123e4567-e89b-12d3-a456-426614174000","formDefinition":{"id":"resource-verification-form","version":"1.0","fields":["..."]},"formResponse":null,"completionData":null}}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/form/submit":{"post":{"tags":["Tasks","Forms"],"summary":"Submit form response for backend-designed dynamic forms","description":"Submit a form response for a task with backend-designed dynamic forms.\nThis endpoint validates the form response against the form definition schema\nand stores the response data in the task metadata (Issue #81).\n\n## Business Logic\n\n### Submission Process\n\n1. **Pre-validation**\n   - Verify task exists and has form definition\n   - Check task is not completed (forms locked after completion)\n   - Validate user has permission to submit\n\n2. **Schema Validation**\n   - Validate response against JSON Schema\n   - Check required fields are present\n   - Validate data types and formats\n   - Apply custom validation rules\n   - Return detailed error messages\n\n3. **Data Storage**\n   - Store response in task metadata\n   - Preserve submission timestamp\n   - Track submitter identity\n   - Maintain version history\n\n4. **Event Publishing**\n   - `form.submitted` event with complete data\n   - Task update notifications\n   - Workflow progression triggers\n\n### Multiple Submissions\n\n- Allows multiple saves before task completion\n- Each submission overwrites previous\n- History preserved in audit log\n- Final submission locked on task completion\n\n## Use Cases\n\n### Property Inspection Submission\nReviewer completes resource checklist\n```json\n{\n  \"response\": {\n    \"resourceId\": \"resource-204\",\n    \"verificationDate\": \"2024-01-20\",\n    \"overallCondition\": \"good\",\n    \"checklistItems\": [\n      {\n        \"area\": \"electrical\",\n        \"status\": \"passed\",\n        \"notes\": \"All outlets tested, GFCI functioning\"\n      },\n      {\n        \"area\": \"plumbing\",\n        \"status\": \"needs_attention\",\n        \"notes\": \"Kitchen faucet has slow drip\"\n      },\n      {\n        \"area\": \"hvac\",\n        \"status\": \"passed\",\n        \"notes\": \"System running efficiently, filter changed\"\n      },\n      {\n        \"area\": \"structural\",\n        \"status\": \"passed\",\n        \"notes\": \"No visible damage or concerns\"\n      }\n    ],\n    \"photos\": [\"attachment-123\", \"attachment-456\"],\n    \"recommendations\": \"Schedule plumbing repair for kitchen faucet\"\n  },\n  \"submittedBy\": \"inspector-789\"\n}\n```\n\n### Customer Intake Submission\nAgent completes client information\n```json\n{\n  \"response\": {\n    \"personalInfo\": {\n      \"firstName\": \"John\",\n      \"lastName\": \"Doe\",\n      \"email\": \"john.doe@example.com\",\n      \"phone\": \"+47 123 45 678\"\n    },\n    \"accountType\": \"premium\",\n    \"preferences\": {\n      \"language\": \"en\",\n      \"contactMethod\": \"email\",\n      \"marketingOptIn\": true\n    },\n    \"identityVerification\": {\n      \"method\": \"bankid\",\n      \"verified\": true,\n      \"verifiedAt\": \"2024-01-20T10:30:00Z\"\n    }\n  },\n  \"submittedBy\": \"agent-456\"\n}\n```\n\n### Partial Save\nSave progress on complex form\n```json\n{\n  \"response\": {\n    \"section1\": {\n      \"field1\": \"value1\",\n      \"field2\": \"value2\"\n    },\n    \"_draft\": true,\n    \"_lastSaved\": \"2024-01-20T14:30:00Z\"\n  },\n  \"submittedBy\": \"user-123\"\n}\n```\n\n## Validation Examples\n\n### Required Field Missing\n```json\n{\n  \"response\": {\n    \"resourceId\": \"resource-204\"\n    // Missing required verificationDate\n  }\n}\n// Returns: 400 - \"verificationDate is required\"\n```\n\n### Invalid Format\n```json\n{\n  \"response\": {\n    \"email\": \"not-an-email\"\n  }\n}\n// Returns: 400 - \"email must be valid email format\"\n```\n\n### Schema Constraint Violation\n```json\n{\n  \"response\": {\n    \"rating\": 11  // Max is 10\n  }\n}\n// Returns: 400 - \"rating must be less than or equal to 10\"\n```\n\n## Best Practices\n\n### Frontend Implementation\n1. Save drafts periodically to prevent data loss\n2. Validate on client before submission\n3. Handle validation errors gracefully\n4. Show submission confirmation\n5. Prevent edits after task completion\n\n### Data Structure\n1. Use consistent field names\n2. Reference attachments by ID\n3. Include metadata like timestamps\n4. Structure for easy processing\n5. Consider versioning needs\n\n## Response Format\n\nSuccess returns submission details:\n- Task ID\n- Submission timestamp\n- Submitter identity\n- Complete form response\n\nValidation errors return:\n- Error code and message\n- Field-level validation details\n- Schema path for nested errors\n","operationId":"submitTaskForm","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["response"],"properties":{"response":{"type":"object","description":"The form response data","additionalProperties":true},"submittedBy":{"type":"string","description":"User who submitted the form","example":"user-123"}}},"example":{"response":{"resource_location":"123 Main Street, Oslo","inspection_date":"2024-01-20","overall_condition":"god","notes":"Property in good condition"},"submittedBy":"user-123"}}}},"responses":{"200":{"description":"Form submitted successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"taskId":{"type":"string","format":"uuid"},"submittedAt":{"type":"string","format":"date-time"},"submittedBy":{"type":"string"},"formResponse":{"type":"object"}}}}},"example":{"data":{"taskId":"789e0123-e89b-12d3-a456-426614174222","submittedAt":"2024-01-20T10:30:00.000Z","submittedBy":"user-123","formResponse":{"resource_location":"123 Main Street, Oslo","overall_condition":"god"}}}}}},"400":{"description":"Bad Request - Form validation errors or no form definition","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"noFormDefinition":{"summary":"No form definition found","value":{"error":{"code":"NO_FORM_DEFINITION","message":"Task does not have a form definition"}}},"validationError":{"summary":"Form validation failed","value":{"error":{"code":"FORM_VALIDATION_ERROR","message":"Form response validation failed","details":{"validationErrors":["resource_location: Required field missing"]}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/form/validate":{"post":{"tags":["Tasks","Forms"],"summary":"Validate form response without submitting","description":"Validates form response data against the task's form definition schema\nwithout actually submitting or storing the response (Issue #81).\n\n**Use Cases:**\n- Client-side form validation before submission\n- Form development and testing\n- Validation rule verification\n- User feedback on form errors before submission\n\n**Validation Process:**\n- Checks form response against form definition schema\n- Validates required fields, data types, and constraints\n- Returns detailed validation errors for correction\n\n**Security:** Can only validate forms for tasks belonging to the authenticated organization\n","operationId":"validateTaskForm","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["response"],"properties":{"response":{"type":"object","description":"The form response data to validate","additionalProperties":true}}},"example":{"response":{"resource_location":"123 Main Street, Oslo","inspection_date":"2024-01-20","overall_condition":"god"}}}}},"responses":{"200":{"description":"Validation completed (may contain errors)","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the form response is valid"},"errors":{"type":"array","items":{"type":"string"},"description":"Validation error messages (if any)"}}}}},"examples":{"validForm":{"summary":"Valid form response","value":{"data":{"valid":true,"errors":[]}}},"invalidForm":{"summary":"Invalid form response","value":{"data":{"valid":false,"errors":["resource_location: Required field missing","inspection_date: Invalid date format"]}}}}}}},"400":{"description":"Bad Request - No form definition found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"NO_FORM_DEFINITION","message":"Task does not have a form definition"}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/bulk":{"post":{"tags":["Tasks"],"summary":"Create multiple tasks in bulk with dependencies","description":"Creates multiple tasks in a single operation with optional dependencies.\n","operationId":"bulkCreateTasks","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkCreateTasksRequest"},"examples":{"simpleTasks":{"summary":"Create multiple tasks without dependencies","value":{"tasks":[{"title":"Design mockups","description":"Create initial design mockups","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH"},{"title":"Implement frontend","description":"Build the frontend components","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"MEDIUM"},{"title":"Testing and QA","description":"Test the implemented features","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH"}]}},"tasksWithDependencies":{"summary":"Create tasks with dependency relationships","value":{"tasks":[{"title":"Design mockups","description":"Create initial design mockups","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH","tempId":"design-task"},{"title":"Implement frontend","description":"Build the frontend components","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"MEDIUM","tempId":"frontend-task"},{"title":"Testing and QA","description":"Test the implemented features","projectId":"456e7890-e89b-12d3-a456-426614174111","priority":"HIGH","tempId":"testing-task"}],"dependencies":[{"dependentTempId":"frontend-task","dependentType":"task","prerequisiteTempId":"design-task","prerequisiteType":"task","constraintType":"HARD","relationType":"FINISH_TO_START"},{"dependentTempId":"testing-task","dependentType":"task","prerequisiteTempId":"frontend-task","prerequisiteType":"task","constraintType":"HARD","relationType":"FINISH_TO_START"}]}},"mixedDependencies":{"summary":"Mix of new tasks and existing task dependencies","value":{"tasks":[{"title":"New Task 1","description":"This depends on an existing task","projectId":"456e7890-e89b-12d3-a456-426614174111","tempId":"new-task-1"},{"title":"New Task 2","description":"This depends on New Task 1","projectId":"456e7890-e89b-12d3-a456-426614174111","tempId":"new-task-2"}],"dependencies":[{"dependentTempId":"new-task-1","dependentType":"task","prerequisiteId":"789e0123-e89b-12d3-a456-426614174222","prerequisiteType":"task","constraintType":"HARD"},{"dependentTempId":"new-task-2","dependentType":"task","prerequisiteTempId":"new-task-1","prerequisiteType":"task","constraintType":"HARD"}]}}}}}},"responses":{"201":{"description":"Tasks created successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"dependencies":{"type":"array","items":{"$ref":"#/components/schemas/DependencyResponse"}}}}}}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"emptyList":{"summary":"Empty tasks array","value":{"error":{"code":"EMPTY_TASKS_ARRAY","message":"At least one task must be provided"}}},"validation":{"summary":"Task validation error","value":{"error":{"code":"VALIDATION_ERROR","message":"Task validation failed","details":{"index":1,"field":"title","value":null}}}},"invalidProject":{"summary":"Invalid project reference","value":{"error":{"code":"INVALID_PROJECT","message":"Project not found for task at index 2"}}},"circularDependency":{"summary":"Circular dependency detected","value":{"error":{"code":"CIRCULAR_DEPENDENCY_DETECTED","message":"Circular dependency detected in task relationships","details":{"cycle":["task-1","task-2","task-3","task-1"]}}}},"tooMany":{"summary":"Too many tasks","value":{"error":{"code":"TOO_MANY_TASKS","message":"Maximum 100 tasks allowed per bulk request"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/attachments":{"post":{"tags":["Tasks","Attachments"],"summary":"Upload attachment to task","description":"Upload a file attachment directly to a specific task.\nThe task must belong to the authenticated organization.\n\n## Business Logic\n\n### Upload Process\n\n1. **Validation**\n   - Verify task exists and belongs to organization\n   - Check file size limits (default: 100MB)\n   - Validate file type restrictions if configured\n   - Verify storage quota not exceeded\n\n2. **File Processing**\n   - Generate unique storage path\n   - Preserve original filename\n   - Extract file metadata (size, type)\n   - Scan for security threats (if enabled)\n\n3. **Storage**\n   - Upload to Google Cloud Storage\n   - Organization-scoped bucket structure\n   - Generate secure access URLs\n   - Create thumbnail if image\n\n4. **Database Record**\n   - Create attachment record\n   - Link to task and project\n   - Store metadata and references\n   - Update task modification time\n\n5. **Event Publishing**\n   - `attachment.uploaded` event\n   - Task update notification\n   - Storage quota update\n\n## Use Cases\n\n### Design Task Mockups\nUpload UI/UX design files\n```\nPOST /api/v1/tasks/design-task-123/attachments\nContent-Type: multipart/form-data\n\nfile: homepage-mockup-v2.figma\n```\nCommon files: .figma, .sketch, .png, .jpg, .pdf\n\n### Development Task Code\nAttach code snippets or configs\n```\nPOST /api/v1/tasks/dev-task-456/attachments\nContent-Type: multipart/form-data\n\nfile: database-schema.sql\nexternalDocumentId: \"github-pr-789\"\n```\nCommon files: .sql, .json, .yaml, .txt, .md\n\n### Property Inspection Photos\nUpload inspection evidence\n```\nPOST /api/v1/tasks/inspection-task-789/attachments\nContent-Type: multipart/form-data\n\nfile: kitchen-leak-photo.jpg\n```\nCommon files: .jpg, .png, .heic, .mp4\n\n### Contract Documents\nAttach legal documents\n```\nPOST /api/v1/tasks/contract-task-101/attachments\nContent-Type: multipart/form-data\n\nfile: lease-agreement-draft.pdf\nexternalDocumentId: \"docusign-envelope-123\"\n```\nCommon files: .pdf, .docx, .doc\n\n## File Handling Details\n\n### Size Limits\n- Default: 100MB per file\n- Configurable per organization\n- Total storage quota enforced\n- Large file handling via resumable uploads\n\n### Supported Types\n- Images: jpg, png, gif, webp, heic\n- Documents: pdf, doc, docx, xls, xlsx\n- Design: figma, sketch, psd, ai\n- Code: txt, json, xml, yaml, sql\n- Archives: zip, tar, gz\n- Media: mp4, mov, mp3\n\n### Storage Structure\n```\n/organizations/{orgId}/tasks/{taskId}/attachments/{timestamp}-{filename}\n```\n- Organization isolation\n- Task-specific folders\n- Timestamp prevents collisions\n- Original filename preserved\n\n### Security\n- Files scanned for malware\n- Executable files blocked\n- Access URLs expire after 7 days\n- Direct bucket access prevented\n\n## Response Details\n\n### Success Response\n- Attachment ID and metadata\n- Secure download URL (temporary)\n- File size and type information\n- Task and project context\n- Upload timestamp\n\n### Entity Context\nResponse includes:\n- Task name and ID\n- Project name and ID\n- Organization context\n- Related entity information\n\n## Integration Features\n\n### External Document ID\n- Link to external systems\n- Track document sources\n- Enable cross-references\n- Support audit trails\n\nExamples:\n- `github-pr-123` - GitHub pull request\n- `jira-ticket-456` - Jira issue\n- `docusign-789` - DocuSign envelope\n- `gdrive-file-abc` - Google Drive file\n\n## Best Practices\n\n### File Organization\n1. Use descriptive filenames\n2. Include version numbers\n3. Add date prefixes for chronology\n4. Group related files\n\n### Performance\n1. Compress large files before upload\n2. Use appropriate image formats\n3. Consider PDF for documents\n4. Batch uploads when possible\n\n### Security\n1. Scan files before upload\n2. Avoid sensitive data in filenames\n3. Use external IDs for tracking\n4. Implement retention policies\n","operationId":"uploadTaskAttachment","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload"},"externalDocumentId":{"type":"string","description":"External document identifier for integration"}}}}}},"responses":{"201":{"description":"Attachment uploaded successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentResponse"}}},"examples":{"imageUpload":{"summary":"Design mockup image uploaded","value":{"data":{"id":"att-123e4567-e89b-12d3-a456-426614174000","filename":"homepage-mockup-v2.png","originalFilename":"homepage-mockup-v2.png","mimeType":"image/png","fileSize":2458624,"storageKey":"organizations/org-123/tasks/task-456/attachments/1706620800000-homepage-mockup-v2.png","downloadUrl":"https://storage.googleapis.com/tasks-attachments/signed-url-expires-in-7-days","externalDocumentId":null,"organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"task","entityId":"789e0123-e89b-12d3-a456-426614174222","entityContext":{"entityName":"Create homepage design mockups","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"createdAt":"2024-01-30T12:00:00.000Z","updatedAt":"2024-01-30T12:00:00.000Z"}}},"documentUpload":{"summary":"Contract PDF with external reference","value":{"data":{"id":"att-234e5678-e89b-12d3-a456-426614174111","filename":"lease-agreement-v3-final.pdf","originalFilename":"lease-agreement-v3-final.pdf","mimeType":"application/pdf","fileSize":854321,"storageKey":"organizations/org-123/tasks/task-789/attachments/1706620900000-lease-agreement-v3-final.pdf","downloadUrl":"https://storage.googleapis.com/tasks-attachments/signed-url-expires-in-7-days","externalDocumentId":"docusign-envelope-abc123","organizationId":"123e4567-e89b-12d3-a456-426614174000","entityType":"task","entityId":"890e1234-e89b-12d3-a456-426614174333","entityContext":{"entityName":"Review and sign lease agreement","entityType":"task","projectId":"789e0123-e89b-12d3-a456-426614174666","projectName":"Property Management - Building A"},"createdAt":"2024-01-30T12:01:40.000Z","updatedAt":"2024-01-30T12:01:40.000Z"}}}}}}},"400":{"description":"Bad Request - Validation error or file too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"fileTooLarge":{"summary":"File exceeds size limit","value":{"error":{"code":"FILE_TOO_LARGE","message":"File size exceeds maximum allowed size of 100MB","details":{"fileSize":157286400,"maxSize":104857600}}}},"invalidFileType":{"summary":"File type not allowed","value":{"error":{"code":"INVALID_FILE_TYPE","message":"File type not allowed","details":{"mimeType":"application/x-executable","filename":"malicious.exe"}}}},"noFile":{"summary":"No file provided","value":{"error":{"code":"NO_FILE_PROVIDED","message":"No file was provided in the request"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found or access denied."}}}}},"413":{"description":"Payload Too Large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"PAYLOAD_TOO_LARGE","message":"Request entity too large"}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"get":{"tags":["Tasks","Attachments"],"summary":"List task attachments","description":"Retrieve all attachments for a specific task with enhanced filtering and pagination.\nResponse includes task and project context with enhanced attachment metadata.\n\n## Business Logic\n\n### Retrieval Process\n\n1. **Validation**\n   - Verify task exists and belongs to organization\n   - Check user has access to task\n   - Validate query parameters\n\n2. **Query Building**\n   - Apply MIME type filters\n   - Apply date range filters\n   - Set sorting criteria\n   - Configure pagination\n\n3. **URL Generation**\n   - Generate signed URLs if requested\n   - URLs expire after 15 minutes\n   - Direct bucket access prevented\n   - Secure token-based access\n\n4. **Context Enhancement**\n   - Include task name and details\n   - Add project information\n   - Provide organization context\n   - Include upload metadata\n\n## Use Cases\n\n### Task File Gallery\nDisplay all attachments for a task\n```\nGET /api/v1/tasks/task-123/attachments?includeDownloadUrls=true\n```\nShows all files with download links\n\n### Image Gallery View\nFilter only image attachments\n```\nGET /api/v1/tasks/task-123/attachments?mimeType=image/&sortBy=created_at&sortOrder=desc\n```\nReturns only images, newest first\n\n### Document Management\nList PDF documents for review\n```\nGET /api/v1/tasks/task-123/attachments?mimeType=application/pdf&includeDownloadUrls=true\n```\nReturns PDFs with download links\n\n### Recent Uploads\nGet files uploaded in last week\n```\nGET /api/v1/tasks/task-123/attachments?uploadedAfter=2024-01-23T00:00:00Z\n```\nReturns recent attachments only\n\n### Large File Check\nFind large attachments\n```\nGET /api/v1/tasks/task-123/attachments?sortBy=file_size&sortOrder=desc&limit=10\n```\nReturns 10 largest files\n\n## Filtering Options\n\n### MIME Type Filtering\n- Partial match supported\n- `image/` matches all images\n- `application/pdf` exact match\n- `text/` matches all text files\n\n### Date Range Filtering\n- `uploadedAfter`: Inclusive start date\n- `uploadedBefore`: Inclusive end date\n- ISO 8601 format required\n- UTC timezone assumed\n\n### Sorting Options\n- `created_at`: Upload timestamp\n- `file_size`: File size in bytes\n- `original_filename`: Alphabetical\n\n## Response Format\n\n### Attachment List\n- Array of attachment objects\n- Each includes full metadata\n- Optional download URLs\n- File type and size info\n\n### Entity Context\n- Task ID and name\n- Project ID and name\n- Organization scope\n- Related entity info\n\n### Pagination\n- Total count included\n- Page-based navigation\n- Configurable page size\n- Maximum 100 per page\n\n## Security Features\n\n### Access Control\n- Organization-scoped access\n- Task-level permissions\n- No direct bucket access\n- Signed URL expiration\n\n### URL Security\n- Time-limited access (15 min)\n- Single-use tokens\n- IP restriction capable\n- Audit trail logging\n","operationId":"getTaskAttachments","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"},{"in":"query","name":"mimeType","schema":{"type":"string"},"description":"Filter by MIME type (partial match)","example":"image/"},{"in":"query","name":"includeDownloadUrls","schema":{"type":"boolean"},"description":"Include signed download URLs in response (15 min expiry)"},{"in":"query","name":"sortBy","schema":{"type":"string","enum":["created_at","file_size","original_filename"]},"description":"Field to sort by","example":"created_at"},{"in":"query","name":"sortOrder","schema":{"type":"string","enum":["asc","desc"]},"description":"Sort direction","example":"desc"},{"in":"query","name":"uploadedAfter","schema":{"type":"string","format":"date-time"},"description":"Filter files uploaded after this date","example":"2024-01-01T00:00:00.000Z"},{"in":"query","name":"uploadedBefore","schema":{"type":"string","format":"date-time"},"description":"Filter files uploaded before this date","example":"2024-01-31T23:59:59.999Z"},{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Task attachments retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentListResponse"}}},"examples":{"multipleAttachments":{"summary":"Task with multiple attachments","value":{"data":{"attachments":[{"id":"att-123e4567-e89b-12d3-a456-426614174000","filename":"homepage-mockup-v2.png","originalFilename":"homepage-mockup-v2.png","mimeType":"image/png","fileSize":2458624,"downloadUrl":"https://storage.googleapis.com/tasks-attachments/signed-url-1","entityContext":{"entityName":"Create homepage design mockups","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"createdAt":"2024-01-28T10:00:00.000Z"},{"id":"att-234e5678-e89b-12d3-a456-426614174111","filename":"homepage-mockup-v3.png","originalFilename":"homepage-mockup-v3.png","mimeType":"image/png","fileSize":2654321,"downloadUrl":"https://storage.googleapis.com/tasks-attachments/signed-url-2","entityContext":{"entityName":"Create homepage design mockups","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"createdAt":"2024-01-29T14:30:00.000Z"},{"id":"att-345e6789-e89b-12d3-a456-426614174222","filename":"design-requirements.pdf","originalFilename":"design-requirements.pdf","mimeType":"application/pdf","fileSize":854321,"downloadUrl":"https://storage.googleapis.com/tasks-attachments/signed-url-3","entityContext":{"entityName":"Create homepage design mockups","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"createdAt":"2024-01-27T09:15:00.000Z"}],"entityContext":{"entityId":"789e0123-e89b-12d3-a456-426614174222","entityName":"Create homepage design mockups","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"pagination":{"page":1,"limit":20,"total":3,"hasMore":false}}}},"emptyList":{"summary":"Task with no attachments","value":{"data":{"attachments":[],"entityContext":{"entityId":"890e1234-e89b-12d3-a456-426614174333","entityName":"Review project requirements","entityType":"task","projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"},"pagination":{"page":1,"limit":20,"total":0,"hasMore":false}}}}}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/attachments/stats":{"get":{"tags":["Tasks","Attachments"],"summary":"Get task attachment statistics","description":"Get comprehensive statistics about attachments for a specific task.\nIncludes file type breakdown, size analysis, and recent activity.\n\n## Business Logic\n\n### Statistics Calculation\n\n1. **Aggregation**\n   - Count total attachments\n   - Sum total file sizes\n   - Group by MIME type\n   - Identify recent uploads\n\n2. **File Type Analysis**\n   - Group attachments by MIME type\n   - Calculate count per type\n   - Sum sizes per type\n   - Sort by frequency\n\n3. **Recent Activity**\n   - Get last 5 attachments\n   - Include full metadata\n   - Sort by upload date\n   - Include download URLs\n\n4. **Storage Metrics**\n   - Total storage used\n   - Average file size\n   - Largest attachment\n   - Storage trends\n\n## Use Cases\n\n### Task Dashboard Widget\nQuick overview of task attachments\n```\nGET /api/v1/tasks/task-123/attachments/stats\n```\nShows summary statistics for UI widget\n\n### Storage Quota Check\nMonitor storage usage per task\n```\nGET /api/v1/tasks/task-456/attachments/stats\n```\nCheck if task using excessive storage\n\n### File Type Analysis\nUnderstand attachment patterns\n```\nGET /api/v1/tasks/task-789/attachments/stats\n```\nAnalyze predominant file types\n\n### Activity Monitoring\nTrack recent attachment activity\n```\nGET /api/v1/tasks/task-101/attachments/stats\n```\nSee latest uploads at a glance\n\n## Statistics Breakdown\n\n### Total Metrics\n- `totalAttachments`: Count of all files\n- `totalFileSize`: Sum in bytes\n- `averageFileSize`: Mean file size\n- `largestFileSize`: Maximum file size\n\n### File Type Breakdown\nFor each MIME type:\n- `mimeType`: Type identifier\n- `count`: Number of files\n- `totalSize`: Combined size\n- `percentage`: % of total files\n\n### Recent Attachments\nLast 5 uploads with:\n- Full attachment details\n- Upload timestamps\n- File metadata\n- Download URLs (optional)\n\n### Context Information\n- Task name and ID\n- Project association\n- Organization scope\n- Related entities\n\n## Performance\n\n- Cached for 5 minutes\n- Single aggregation query\n- Indexed for performance\n- Lightweight response\n\n## Example Insights\n\nFrom statistics you can determine:\n- Is task documentation-heavy?\n- Are images predominant?\n- Recent activity level\n- Storage optimization needs\n- File organization patterns\n","operationId":"getTaskAttachmentStats","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"200":{"description":"Task attachment statistics","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/EntityAttachmentStatsResponse"}}},"example":{"data":{"entityId":"789e0123-e89b-12d3-a456-426614174222","entityName":"Create homepage design mockups","entityType":"task","statistics":{"totalAttachments":12,"totalFileSize":45678901,"fileTypeBreakdown":[{"mimeType":"image/png","count":8,"totalSize":35678901},{"mimeType":"application/pdf","count":3,"totalSize":8500000},{"mimeType":"text/plain","count":1,"totalSize":1500000}],"recentAttachments":[{"id":"att-latest-123","filename":"final-design-v5.png","mimeType":"image/png","fileSize":3456789,"createdAt":"2024-01-30T15:30:00.000Z"},{"id":"att-latest-456","filename":"design-feedback.pdf","mimeType":"application/pdf","fileSize":1234567,"createdAt":"2024-01-30T14:20:00.000Z"}]},"projectContext":{"projectId":"456e7890-e89b-12d3-a456-426614174111","projectName":"Website Redesign Q1 2024"}}}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{taskId}/resolve-assignee":{"post":{"tags":["Tasks"],"summary":"Manually trigger assignee resolution for a task","description":"Triggers the assignee resolution process for a specific task. This endpoint allows manual\nresolution of task assignees from external context data when automatic resolution during\nworkflow instantiation is not sufficient or needs to be re-triggered.\n\n## Business Logic\n\nThe resolution process:\n1. **Validates task ownership** - Ensures the task belongs to the authenticated organization\n2. **Checks resolution configuration** - Verifies the task template has assignee resolution enabled\n3. **Fetches external data** - Uses existing context integration to get data from external systems\n4. **Applies resolution strategy** - Extracts assignee information based on configured strategy\n5. **Updates task assignee** - Sets the new assignee and marks the task as resolved from context\n\n## Resolution Strategies\n\n- **FIELD_MAPPING**: Direct field extraction from external data (e.g., \"Owner.Email\")\n- **LOOKUP_TABLE**: Map external values to internal assignees using predefined table\n\n## Context Requirements\n\nThe task must have:\n- A template with `assignee_resolution_config` enabled\n- Associated entity contexts that match the configured context type\n- Accessible external data in the configured external system\n\n## Response Details\n\nSuccess response includes:\n- Resolution status and details\n- Updated task information with new assignee\n- Previous and new assignee information for audit purposes\n\n## Use Cases\n\n- **Re-trigger resolution** after external data changes\n- **Manual resolution** for tasks created outside workflow instantiation\n- **Recovery from failures** when automatic resolution failed during workflow creation\n- **Testing and validation** of assignee resolution configurations\n","operationId":"resolveTaskAssignee","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"The unique identifier of the task to resolve assignee for","schema":{"type":"string","format":"uuid"},"example":"789e0123-e89b-12d3-a456-426614174222"}],"responses":{"200":{"description":"Assignee resolution completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["success","message","task","resolution"],"properties":{"success":{"type":"boolean","description":"Whether the resolution was successful","example":true},"message":{"type":"string","description":"Human-readable result message","example":"Assignee resolved successfully from Salesforce opportunity owner"},"task":{"type":"object","required":["id","title","assignee_type","assignee_id","assignee_resolved_from_context","assignee_resolved_at"],"properties":{"id":{"type":"string","format":"uuid","example":"789e0123-e89b-12d3-a456-426614174222"},"title":{"type":"string","example":"Review sales contract"},"assignee_type":{"type":"string","enum":["USER","ROLE","POSITION"],"example":"USER"},"assignee_id":{"type":"string","example":"john.doe@company.com"},"assignee_name":{"type":"string","nullable":true,"example":"john.doe@company.com"},"assignee_resolved_from_context":{"type":"boolean","example":true},"assignee_resolved_at":{"type":"string","format":"date-time","example":"2024-01-30T15:30:00.000Z"}}},"resolution":{"type":"object","required":["contextType","strategy"],"properties":{"contextType":{"type":"string","description":"The context type used for resolution","example":"salesforce"},"strategy":{"type":"string","description":"The resolution strategy applied","example":"FIELD_MAPPING"},"previousAssignee":{"type":"object","nullable":true,"properties":{"type":{"type":"string","example":"ROLE"},"id":{"type":"string","example":"sales-team"},"name":{"type":"string","nullable":true,"example":null}}},"newAssignee":{"type":"object","properties":{"type":{"type":"string","example":"USER"},"id":{"type":"string","example":"john.doe@company.com"},"name":{"type":"string","example":"john.doe@company.com"}}}}}}}}},"example":{"data":{"success":true,"message":"Assignee resolved successfully from Salesforce opportunity owner","task":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Review sales contract","assignee_type":"USER","assignee_id":"john.doe@company.com","assignee_name":"john.doe@company.com","assignee_resolved_from_context":true,"assignee_resolved_at":"2024-01-30T15:30:00.000Z"},"resolution":{"contextType":"salesforce","strategy":"FIELD_MAPPING","previousAssignee":{"type":"ROLE","id":"sales-team","name":null},"newAssignee":{"type":"USER","id":"john.doe@company.com","name":"john.doe@company.com"}}}}}}},"400":{"description":"Resolution configuration error or invalid request","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["success","message","reason"],"properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"Assignee resolution not possible"},"reason":{"type":"string","enum":["NO_RESOLUTION_CONFIG","RESOLUTION_DISABLED","NO_MATCHING_CONTEXT","NO_EXTERNAL_DATA","NO_ASSIGNEE_VALUE"],"example":"NO_MATCHING_CONTEXT"},"details":{"type":"string","example":"Task template does not have assignee resolution configured or it is disabled"}}}}},"example":{"data":{"success":false,"message":"Assignee resolution not possible","reason":"NO_MATCHING_CONTEXT","details":"No context found matching the configured context type \"salesforce\""}}}}},"404":{"description":"Task not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found or access denied."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{taskId}/event-listener":{"get":{"summary":"Get task event listener status","description":"Retrieves the event listener configuration and status for a task","tags":["Tasks"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"taskId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the task"}],"responses":{"200":{"description":"Task event listener status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"eventKey":{"type":"string"},"listenerType":{"type":"string","enum":["BLOCKING","NON_BLOCKING"]},"listenerStatus":{"type":"string","enum":["WAITING","RECEIVED","TIMEOUT","CANCELLED"]},"autoComplete":{"type":"boolean"},"eventReceivedAt":{"type":"string","format":"date-time","nullable":true},"timeoutAt":{"type":"string","format":"date-time","nullable":true},"eventPayload":{"type":"object","nullable":true}}}}}}}},"404":{"description":"Task not found or no event listener configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/tasks/{taskId}/calendar-events/{eventId}/registrations":{"get":{"tags":["Tasks","Calendar"],"summary":"Get calendar event registrations for a task","description":"Retrieves detailed registration list for a specific calendar event associated with a task.\nReturns paginated registrations with summary statistics.\n\n## Response Includes\n- Event summary (title, time, location)\n- Paginated registration list with full details\n- Registration summary (counts by status and RSVP)\n- Check-in statistics\n- Total party size\n\n## Use Cases\n- Event management dashboards\n- Registration reporting\n- Attendance tracking\n- Capacity planning\n","operationId":"getTaskEventRegistrations","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"taskId","in":"path","required":true,"description":"Task ID","schema":{"type":"string","format":"uuid"}},{"name":"eventId","in":"path","required":true,"description":"Calendar event ID","schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","description":"Page number for pagination","schema":{"type":"integer","minimum":1,"default":1}},{"name":"perPage","in":"query","description":"Number of registrations per page","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Registrations retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"event":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventId":{"type":"string"},"summary":{"type":"string"},"startTime":{"type":"string","format":"date-time"},"endTime":{"type":"string","format":"date-time"},"location":{"type":"string","nullable":true}}},"registrations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"displayName":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"partySize":{"type":"integer"},"status":{"type":"string","enum":["confirmed","waitlisted","cancelled","declined"]},"registrationSource":{"type":"string","enum":["api","public_link","manual","import"]},"registeredAt":{"type":"string","format":"date-time"},"waitlistPosition":{"type":"integer","nullable":true},"checkedIn":{"type":"boolean"},"checkedInAt":{"type":"string","format":"date-time","nullable":true},"smartInviteId":{"type":"string","nullable":true},"rsvpStatus":{"type":"string","nullable":true},"rsvpUpdatedAt":{"type":"string","format":"date-time","nullable":true},"rsvpComment":{"type":"string","nullable":true}}}},"summary":{"type":"object","properties":{"total":{"type":"integer"},"byStatus":{"type":"object","properties":{"confirmed":{"type":"integer"},"waitlisted":{"type":"integer"},"cancelled":{"type":"integer"},"declined":{"type":"integer"}}},"byRsvp":{"type":"object","properties":{"accepted":{"type":"integer"},"declined":{"type":"integer"},"tentative":{"type":"integer"},"pending":{"type":"integer"}}},"totalPartySize":{"type":"integer"},"checkedInCount":{"type":"integer"}}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"perPage":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}}}}}}}}},"404":{"description":"Task or calendar event not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/tasks/{id}/submit-for-approval":{"post":{"tags":["Tasks"],"summary":"Submit task for approval","description":"Submits a task into the approval workflow. The task must be in READY, IN_PROGRESS,\nor RETURNED status. All required checklist items must be completed or answered before\nsubmission. Once submitted, the task status changes to PENDING_APPROVAL and the\napproval chain begins processing.\n","operationId":"submitTaskForApproval","security":[{"apiKey":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"The task ID","example":"789e0123-e89b-12d3-a456-426614174222"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"comment":{"type":"string","maxLength":2000,"description":"Optional comment to include with the submission","example":"Ready for review - all checklist items completed"}}},"example":{"comment":"Ready for review - all checklist items completed"}}}},"responses":{"200":{"description":"Task submitted for approval successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Resource verification checklist","status":"PENDING_APPROVAL","organizationId":"123e4567-e89b-12d3-a456-426614174000"}}}}},"400":{"description":"Bad Request - Task not in valid status or required checklist items incomplete","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidStatus":{"summary":"Task not in submittable status","value":{"error":{"code":"INVALID_STATUS","message":"Task must be in READY, IN_PROGRESS, or RETURNED status to submit for approval."}}},"checklistIncomplete":{"summary":"Required checklist items not completed","value":{"error":{"code":"CHECKLIST_INCOMPLETE","message":"All required checklist items must be completed before submission."}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/approve":{"post":{"tags":["Tasks"],"summary":"Approve current approval step","description":"Approves the current step in the task's approval chain. Only the designated approver\nfor the current step or an organization admin can approve. If this is the last step\nin the approval chain, the task is automatically completed.\n","operationId":"approveTask","security":[{"apiKey":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"The task ID","example":"789e0123-e89b-12d3-a456-426614174222"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"comment":{"type":"string","maxLength":2000,"description":"Optional comment to include with the approval","example":"Looks good, approved."},"checklist":{"type":"array","maxItems":50,"description":"Step-level checklist responses. Required when the current approval step\nhas a checklist with required items. Array length must match step checklist length.\n","items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string"},"required":{"type":"boolean"},"answer":{"type":"string","enum":["YES","NO"]},"completed":{"type":"boolean"},"comment":{"type":"string"}}}}}},"example":{"comment":"Looks good, approved.","checklist":[{"title":"Is the document signed?","required":true,"answer":"YES"},{"title":"Is the owner verified?","required":true,"answer":"YES"}]}}}},"responses":{"200":{"description":"Approval step completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Resource verification checklist","status":"COMPLETED","organizationId":"123e4567-e89b-12d3-a456-426614174000","approvedAt":"2024-01-20T14:00:00.000Z","approvedBy":"user-456"}}}}},"400":{"description":"Bad Request - Task not in PENDING_APPROVAL status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_STATUS","message":"Task must be in PENDING_APPROVAL status to approve."}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - Not the designated approver for the current step","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"NOT_AUTHORIZED_APPROVER","message":"You are not authorized to approve this step."}}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/return":{"post":{"tags":["Tasks"],"summary":"Return task for correction","description":"Returns a task to the submitter for correction. Increments the return count\nand records the reason in the task's return history. The task status changes\nto RETURNED, allowing the assignee to make corrections and resubmit.\n","operationId":"returnTask","security":[{"apiKey":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"The task ID","example":"789e0123-e89b-12d3-a456-426614174222"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":2000,"description":"The reason for returning the task","example":"Missing documentation for item 3 on the checklist."},"comment":{"type":"string","maxLength":2000,"description":"Optional additional comment","example":"Please also double-check the dates."},"checklist":{"type":"array","maxItems":50,"description":"Partial step-level checklist responses. Saves progress without validation.\nUseful for recording which items were reviewed before returning.\n","items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string"},"required":{"type":"boolean"},"answer":{"type":"string","enum":["YES","NO"]},"completed":{"type":"boolean"},"comment":{"type":"string"}}}}}},"example":{"reason":"Missing documentation for item 3 on the checklist.","comment":"Please also double-check the dates.","checklist":[{"title":"Is the document signed?","required":true,"answer":"NO"},{"title":"Is the owner verified?","required":true}]}}}},"responses":{"200":{"description":"Task returned for correction successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Resource verification checklist","status":"RETURNED","returnCount":1,"organizationId":"123e4567-e89b-12d3-a456-426614174000"}}}}},"400":{"description":"Bad Request - Task not in PENDING_APPROVAL status or missing reason","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidStatus":{"summary":"Task not in approvable status","value":{"error":{"code":"INVALID_STATUS","message":"Task must be in PENDING_APPROVAL status to return."}}},"missingReason":{"summary":"Reason is required","value":{"error":{"code":"VALIDATION_ERROR","message":"Reason is required when returning a task."}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - Not authorized to return this task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"NOT_AUTHORIZED_APPROVER","message":"You are not authorized to return this task."}}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TASK_NOT_FOUND","message":"Task not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/{id}/reject":{"post":{"tags":["Tasks"],"summary":"Reject task (terminal)","description":"Terminally rejects a task that is pending approval. Unlike return (which\nmoves the task to RETURNED so the submitter can correct and resubmit),\nreject is a final decision: the task status changes to REJECTED and the\ntask cannot be resubmitted for approval. The reason is recorded on the\ncurrent approval step. Used by fagansvarlig to decline (avvist) a control.\n","operationId":"rejectTask","security":[{"apiKey":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"The task ID","example":"789e0123-e89b-12d3-a456-426614174222"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["reason"],"properties":{"reason":{"type":"string","minLength":1,"maxLength":2000,"description":"The reason for rejecting the task","example":"Control does not meet compliance requirements; rejected."},"comment":{"type":"string","maxLength":2000,"description":"Optional additional comment"},"checklist":{"type":"array","maxItems":50,"description":"Partial step-level checklist responses. Saves progress without validation.\n","items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string"},"required":{"type":"boolean"},"answer":{"type":"string","enum":["YES","NO"]},"completed":{"type":"boolean"},"comment":{"type":"string"}}}}}},"example":{"reason":"Control does not meet compliance requirements; rejected."}}}},"responses":{"200":{"description":"Task rejected successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Task"}}},"example":{"data":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Resource verification checklist","status":"REJECTED","organizationId":"123e4567-e89b-12d3-a456-426614174000"}}}}},"400":{"description":"Bad Request - Task not in PENDING_APPROVAL status or missing reason","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - Not authorized to reject this task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Task not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/tasks/reports/approval-activity":{"get":{"tags":["Tasks","Reports"],"summary":"Get approval activity report","description":"Returns approval activity grouped by assignee or submitter for a given date range.\nUseful for spot-check coverage tracking and monitoring approval workflow efficiency.\nResults are limited to 5000 tasks; narrow the date range if the limit is reached.\nDefaults to the current calendar month when date parameters are omitted.\n","operationId":"getApprovalActivityReport","security":[{"apiKey":[]}],"parameters":[{"in":"query","name":"templateCode","schema":{"type":"string"},"description":"Filter by a single task template code (back-compat). Combine with templateCodes if needed.","example":"weekly-inspection"},{"in":"query","name":"templateCodes","schema":{"type":"string"},"description":"Comma-separated list of task template codes to include (OR'd together).\nCodes that do not resolve are ignored; a 404 is returned only when none resolve.\n","example":"fag-kon-oppdrag-priv,fag-kon-oppdrag-naering,fag-kon-leie-priv,fag-kon-leie-naering"},{"in":"query","name":"from","schema":{"type":"string","format":"date"},"description":"Start date for the report range (ISO 8601). Defaults to the first day of the current month.","example":"2024-01-01"},{"in":"query","name":"to","schema":{"type":"string","format":"date"},"description":"End date for the report range (ISO 8601). Defaults to the last day of the current month.","example":"2024-01-31"},{"in":"query","name":"groupBy","schema":{"type":"string","enum":["assignee","submitter"],"default":"assignee"},"description":"Group report results by assignee or submitter"},{"in":"query","name":"groupByPeriod","schema":{"type":"string","enum":["quarter","month","year"]},"description":"Bucket results by time period. When set, one row is returned per\ngroup (assignee/submitter) × period, each carrying a `period` label\n(e.g. \"2026-Q1\", \"2026-01\", \"2026\"). When omitted, a single aggregate\nper group is returned over the whole date range.\n"}],"responses":{"200":{"description":"Approval activity report generated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"dateRange":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}},"groupBy":{"type":"string","enum":["assignee","submitter"]},"groupByPeriod":{"type":"string","enum":["quarter","month","year"],"description":"Present only when period bucketing was requested"},"groups":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"The assignee or submitter identifier"},"period":{"type":"string","description":"Period label (e.g. \"2026-Q1\"); present only when groupByPeriod is set"},"totalSubmissions":{"type":"integer"},"totalReturns":{"type":"integer"},"totalApproved":{"type":"integer"},"totalPending":{"type":"integer"},"totalReturned":{"type":"integer"},"totalDeclined":{"type":"integer","description":"Count of terminally rejected (avvist) tasks"},"returnReasons":{"type":"array","items":{"type":"object","properties":{"taskId":{"type":"string","format":"uuid"},"taskTitle":{"type":"string"},"step":{"type":"integer"},"stepLabel":{"type":"string"},"reason":{"type":"string"},"returnedBy":{"type":"string"},"returnedAt":{"type":"string","format":"date-time"}}}}}}},"summary":{"type":"object","properties":{"totalTasks":{"type":"integer"},"totalReturns":{"type":"integer"},"totalApproved":{"type":"integer"},"totalPending":{"type":"integer"},"totalReturned":{"type":"integer"},"totalDeclined":{"type":"integer","description":"Count of terminally rejected (avvist) tasks"}}},"warning":{"type":"string","description":"Present when results are truncated"}}}}},"example":{"data":{"dateRange":{"from":"2024-01-01T00:00:00.000Z","to":"2024-01-31T23:59:59.999Z"},"groupBy":"assignee","groups":[{"key":"user-123","totalSubmissions":10,"totalReturns":2,"totalApproved":7,"totalPending":1,"totalReturned":2,"totalDeclined":0,"returnReasons":[{"taskId":"789e0123-e89b-12d3-a456-426614174222","taskTitle":"Weekly inspection","step":1,"stepLabel":"Manager Review","reason":"Missing documentation","returnedBy":"user-456","returnedAt":"2024-01-15T10:00:00.000Z"}]}],"summary":{"totalTasks":10,"totalReturns":2,"totalApproved":7,"totalPending":1,"totalReturned":2,"totalDeclined":0}}}}}},"400":{"description":"Bad Request - Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidGroupBy":{"summary":"Invalid groupBy value","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid groupBy value. Allowed values: assignee, submitter."}}},"invalidDate":{"summary":"Invalid date format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid date format for \"from\" parameter. Use ISO 8601 format (e.g., 2024-01-01)."}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-templates/{id}/requirements":{"get":{"tags":["Template Requirements","Workflow Templates"],"summary":"Get workflow template requirements","description":"Discover the initialization requirements for a workflow template, including\nschema definitions, validation rules, form templates, and supported entity types.\nThis enables frontend applications to dynamically generate forms for workflow creation.\n\n**Business Value:**\n- Dynamic form generation for workflow instantiation\n- Validation rules discovery for client-side validation\n- Context requirements identification\n- Entity type compatibility checking\n\n**Use Cases:**\n- Build dynamic workflow creation forms\n- Validate user input before submission\n- Display entity type compatibility\n- Generate context-aware interfaces\n","operationId":"getWorkflowTemplateRequirements","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440001"}],"responses":{"200":{"description":"Template requirements retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TemplateRequirements"}}}}}},"404":{"description":"Workflow template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Workflow template not found"}}}}}}}},"/api/v1/task-templates/{id}/requirements":{"get":{"tags":["Template Requirements","Task Templates"],"summary":"Get task template requirements","description":"Discover the initialization requirements for a task template, including\nschema definitions, validation rules, form templates, and supported contexts.\nThis enables frontend applications to dynamically generate forms for task creation.\n\n**Business Value:**\n- Dynamic form generation for standalone task creation\n- Context requirements discovery\n- Assignee resolution configuration\n- Validation rules for task instantiation\n\n**Use Cases:**\n- Build task creation forms outside workflows\n- Generate context-aware task interfaces\n- Validate task instantiation data\n- Display assignee resolution options\n","operationId":"getTaskTemplateRequirements","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task template ID","schema":{"type":"string","format":"uuid"},"example":"550e8400-e29b-41d4-a716-446655440002"}],"responses":{"200":{"description":"Template requirements retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/TemplateRequirements"}}}}}},"404":{"description":"Task template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Task template not found"}}}}}}}},"/api/v1/workflow-templates/{id}/validate":{"post":{"tags":["Template Requirements","Workflow Templates"],"summary":"Validate workflow instantiation data","description":"Validate initialization data against workflow template requirements before\ninstantiation. This performs schema validation, business rule validation,\nand context validation without creating the actual workflow.\n\n**Validation Types:**\n- JSON Schema validation against template requirements\n- JSONLogic business rule validation\n- Entity type compatibility checking\n- Context data validation\n- Assignee resolution validation\n\n**Use Cases:**\n- Real-time form validation in frontend\n- Pre-submission validation\n- Context-aware error messaging\n- User guidance during form completion\n","operationId":"validateWorkflowInstantiation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationRequest"}}}},"responses":{"200":{"description":"Validation completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ValidationResponse"}}}}}}}}},"/api/v1/task-templates/{id}/validate":{"post":{"tags":["Template Requirements","Task Templates"],"summary":"Validate task instantiation data","description":"Validate initialization data against task template requirements before\ninstantiation. This performs schema validation, business rule validation,\nand context validation without creating the actual task.\n","operationId":"validateTaskInstantiation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationRequest"}}}},"responses":{"200":{"description":"Validation completed","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/ValidationResponse"}}}}}}}}},"/api/v1/workflow-templates/{id}/preview":{"post":{"tags":["Template Requirements","Workflow Templates"],"summary":"Preview workflow instantiation","description":"Generate a preview of what will be created when instantiating a workflow\nfrom the template with given initialization data. This provides a detailed\nbreakdown of stages, tasks, and estimated timelines without creating actual entities.\n\n**Preview Information:**\n- Workflow structure and metadata\n- Stage breakdown with sequence and dependencies\n- Task estimates per stage\n- Duration estimates and timelines\n- Assignee resolution preview\n- Warnings and recommendations\n\n**Use Cases:**\n- Show users what will be created before confirmation\n- Workflow planning and estimation\n- Resource allocation preview\n- Timeline estimation for project planning\n","operationId":"previewWorkflowInstantiation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewRequest"}}}},"responses":{"200":{"description":"Preview generated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/InstantiationPreview"}}}}}}}}},"/api/v1/task-templates/{id}/preview":{"post":{"tags":["Template Requirements","Task Templates"],"summary":"Preview task instantiation","description":"Generate a preview of what will be created when instantiating a task\nfrom the template with given initialization data.\n","operationId":"previewTaskInstantiation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Task template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewRequest"}}}},"responses":{"200":{"description":"Preview generated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/InstantiationPreview"}}}}}}}}},"/api/v1/workflow-templates/{id}/instantiate":{"post":{"tags":["Workflow Templates","Workflow Templates"],"summary":"Create workflow instance from template","description":"Creates a new workflow instance by instantiating an approved workflow template with\ncustomizable parameters. This endpoint serves as the primary mechanism for converting\nreusable workflow templates into active business process instances.\n\n## Business Logic: Template Instantiation Process\n\n**Template Validation:**\n- Verifies template exists and belongs to the authenticated organization\n- Ensures template is active (`isActive: true`) and available for instantiation\n- Validates template is within its validity date range (`validFrom` - `validUntil`)\n- Confirms template has at least one configured stage for process execution\n\n**Workflow Creation Process:**\n1. **Template Analysis**: Extracts all template stages with their configurations\n2. **Workflow Generation**: Creates new workflow with auto-generated workflow number (`WF-YYYY-NNN`)\n3. **Stage Instantiation**: Copies all template stages to workflow with default assignments\n4. **Task Generation**: Creates tasks from task templates associated with each stage\n5. **Context Application**: Applies provided context data for business-specific customization\n6. **Event Configuration**: Sets up event publishing if template has event topic configured\n\n**Stage Copying Logic:**\n- All template stages are copied in sequence order with their original configuration\n- Default assignee types and IDs are preserved from template stage definitions\n- Duration overrides from template stages are applied as due dates\n- Milestone, blocking, and optional flags are maintained from template\n- Entry and exit conditions are preserved for stage transition logic\n\n**Customization Capabilities:**\n- **Workflow Owner**: Override default ownership with specific role, position, or user\n- **Due Date**: Set overall workflow completion deadline\n- **Context Data**: Provide business-specific data for template variable substitution\n- **Entity Linking**: Associate workflow with external business entities\n\n## Norwegian Real Estate Industry Applications\n\n**Property Acquisition Workflows:**\n- Commercial property due diligence with legal, technical, and financial assessment stages\n- Residential acquisition processes with inspection, valuation, and closing coordination\n- Investment property analysis with market research and ROI calculation stages\n\n**Tenant Management Workflows:**\n- Corporate tenant onboarding with document collection, background verification, and lease execution\n- Residential tenant processing with application review, reference checks, and move-in coordination\n- Tenant renewal processes with lease negotiation, condition assessment, and contract updates\n\n**Property Maintenance Workflows:**\n- Scheduled maintenance programs with inspection, contractor assignment, and completion verification\n- Emergency repair processes with urgent response, damage assessment, and restoration stages\n- Compliance maintenance with regulatory inspection, documentation, and certification stages\n\n**Business Process Automation:**\n- Standardized workflow execution with consistent stage progression and validation\n- Role-based task assignment with automatic notification and escalation\n- Document management integration with stage-specific file collection and approval\n- External system integration through context data and event publishing\n\n## Template Validation Rules\n\n**Template Availability:**\n- Template must have `isActive: true` status\n- Current date must be within template validity range\n- Template must belong to the authenticated organization\n- Template must have at least one configured stage\n\n**Request Validation:**\n- Workflow name is required and must be unique within organization\n- Entity type and ID are required for business entity association\n- Owner type and ID are required for workflow ownership assignment\n- Due date must be in the future if provided\n- Context data must be valid JSON if provided\n\n**Business Rules:**\n- Workflow number is auto-generated in format `WF-YYYY-NNN`\n- Initial workflow status is set to `DRAFT` for configuration review\n- All stages start in `PENDING` status awaiting activation (unless `startAtStage` is used)\n- When `startAtStage` is provided, all stages before the target stage are created as `COMPLETED`\n- Event publishing configuration inherits from template settings\n- Total stages count reflects all copied template stages\n","operationId":"instantiateWorkflowTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow template to instantiate.\nMust be a valid UUID of an active template that belongs to\nthe authenticated organization.\n","schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440001"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstantiateWorkflowRequest"},"examples":{"basic":{"summary":"Basic workflow instantiation","value":{"initializationData":{"property_address":"123 Main St, Oslo, Norway","acquisition_type":"purchase","budget":5000000},"entityType":"property_acquisition","entityId":"deal-oslo-001","workflowName":"Property Acquisition - 123 Main St","workflowDescription":"Commercial property acquisition workflow","ownerType":"USER","ownerId":"user-456"}},"withEntityLinks":{"summary":"Workflow with entity links (Issue","value":{"initializationData":{"property_address":"Trondheim Waterfront Complex","acquisition_type":"purchase","budget":25000000},"entityType":"property_acquisition","entityId":"deal-trondheim-001","workflowName":"Trondheim Waterfront Acquisition","ownerType":"POSITION","ownerId":"acquisition_manager","entityLinks":[{"entityType":"property","entityId":"prop-trondheim-waterfront-001","linkType":"related","metadata":{"role":"subject_property"}},{"entityType":"client","entityId":"buyer-corp-investment-as","linkType":"related","metadata":{"role":"buyer","contact_priority":"high"}},{"entityType":"client","entityId":"seller-bergen-holding","linkType":"related","metadata":{"role":"seller"}}]}},"withContextData":{"summary":"Workflow with context-based assignment","value":{"initializationData":{"property_id":"prop-789","inspection_date":"2024-03-15"},"entityType":"property_inspection","entityId":"inspection-789","contextData":{"assigned_inspector":"inspector-001","regional_manager":"manager-002"},"ownerType":"USER","ownerId":"user-123"}},"commercial-property-acquisition":{"summary":"Commercial Property Acquisition - High Value","description":"Large-scale commercial property acquisition in Trondheim with multiple\nassessment stages, environmental review, and regulatory compliance.\n","value":{"name":"Trondheim Waterfront Commercial Complex Acquisition","description":"Acquisition of prime waterfront commercial development with mixed-use potential, including environmental impact assessment and zoning compliance verification","entityType":"property_acquisition","entityId":"trondheim-waterfront-2024-001","ownerType":"ROLE","ownerId":"senior-acquisition-manager","dueDate":"2024-09-30T23:59:59.000Z","context":{"propertyValue":85000000,"propertyType":"commercial-mixed-use","location":"Trondheim Waterfront District, Norway","urgencyLevel":"high","environmentalReview":true,"zoningSensitive":true,"financingApproved":true,"currency":"NOK","stakeholders":["city-planning","environmental-agency","port-authority"]},"entityLinks":[{"entityType":"property","entityId":"prop-trondheim-waterfront-001","linkType":"related","metadata":{"role":"subject_property","property_class":"commercial"}},{"entityType":"client","entityId":"client-corp-investment-as","linkType":"related","metadata":{"role":"buyer","contact_priority":"high","legal_entity":"Trondheim Corporate Investment AS"}},{"entityType":"client","entityId":"client-bergen-holding","linkType":"related","metadata":{"role":"seller","legal_entity":"Bergen Waterfront Holding AS"}}]}},"residential-tenant-onboarding":{"summary":"Premium Residential Tenant Onboarding","description":"High-end residential tenant onboarding for luxury apartment with\nextensive background verification and move-in coordination.\n","value":{"name":"Premium Tenant Onboarding - Aker Brygge Penthouse","description":"Luxury residential tenant onboarding with enhanced verification and white-glove move-in services","entityType":"residential_tenant_onboarding","entityId":"aker-brygge-penthouse-5a","ownerType":"USER","ownerId":"ingrid.nielsen@apart.no","dueDate":"2024-04-15T17:00:00.000Z","context":{"tenantType":"executive","apartmentSize":"180 sqm","monthlyRent":42000,"securityDeposit":126000,"leaseStartDate":"2024-04-01","leaseDuration":"24 months","premiumServices":true,"parkingSpaces":2,"storageUnit":true,"currency":"NOK"}}},"maintenance-inspection-cycle":{"summary":"Annual Property Inspection Workflow","description":"Comprehensive annual inspection workflow for multi-unit residential\nproperty with compliance documentation and tenant coordination.\n","value":{"name":"Annual Inspection - Grünerløkka Residential Complex","description":"Comprehensive annual property inspection with safety compliance verification and tenant impact assessment","entityType":"property_maintenance","entityId":"grunerlokka-residential-block-c","ownerType":"POSITION","ownerId":"property-maintenance-supervisor","dueDate":"2024-06-30T16:00:00.000Z","context":{"propertyType":"residential-complex","unitCount":48,"buildingAge":15,"lastInspectionDate":"2023-06-15","tenantNotificationRequired":true,"complianceDocumentation":["fire-safety","electrical","plumbing","hvac"],"inspectionType":"comprehensive","estimatedDuration":"5 days"}}},"financial-approval-workflow":{"summary":"Capital Expenditure Approval Process","description":"Multi-stage financial approval workflow for major renovation project\nwith budget analysis and stakeholder sign-off requirements.\n","value":{"name":"Major Renovation Approval - Bygdøy Office Building","description":"Financial approval process for comprehensive office building renovation including budget analysis and board approval","entityType":"financial_approval","entityId":"bygdoy-office-renovation-2024","ownerType":"ROLE","ownerId":"financial-controller","dueDate":"2024-05-31T17:00:00.000Z","context":{"projectBudget":12500000,"approvalThreshold":"board-level","renovationType":"comprehensive","projectDuration":"8 months","impactAssessment":"high","requiresPermits":true,"currency":"NOK","stakeholders":["board-of-directors","property-management","legal-counsel"]},"taskCreationStrategyOverride":"ON_STAGE_START"}},"deal-with-separate-assignee-entity":{"summary":"Deal Workflow with Separate Assignee Entity","description":"Deal closing workflow where the workflow is about a deal/transaction,\nbut assignees (roles like property-manager) are resolved against the\nproperty linked to that deal. This demonstrates the assignee entity\nseparation feature.\n","value":{"name":"Deal Closing - 123 Main St Property Sale","description":"Closing workflow for property sale deal with assignees resolved from the property's role assignments","entityType":"deal","entityId":"deal-789-main-st-sale","assigneeEntityType":"property","assigneeEntityId":"prop-123-main-st","ownerType":"USER","ownerId":"deal-coordinator@apart.no","assigneeType":"ROLE","assigneeId":"property-manager","dueDate":"2024-08-15T17:00:00.000Z","context":{"dealType":"sale","dealValue":4500000,"propertyAddress":"123 Main Street, Oslo","buyerName":"Nordic Investments AS","sellerName":"Oslo Property Holdings","closingType":"standard","currency":"NOK"}}},"start-at-stage-import":{"summary":"Import Partially Complete Workflow (Start at Stage)","description":"Imports a workflow that is already partially complete from an external system.\nThe startAtStage parameter specifies the stage to begin at, and all prior\nstages (and their tasks) are automatically created as COMPLETED.\n","value":{"name":"Imported Tenant Onboarding - Already Screened","description":"Tenant onboarding imported from legacy system, screening already completed","entityType":"tenant_onboarding","entityId":"tenant-import-2024-042","ownerType":"USER","ownerId":"property-manager@apart.no","startAtStage":"lease-signing","context":{"importedFrom":"legacy-system","importDate":"2024-06-15","screeningCompletedExternally":true}}}}},"multipart/form-data":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"string","description":"JSON string of WorkflowInstantiationRequest","example":"{\"initializationData\":{\"property_address\":\"123 Main St\"},\"entityType\":\"property_acquisition\",\"entityId\":\"deal-001\",\"workflowName\":\"Property Acquisition\",\"ownerType\":\"USER\",\"ownerId\":\"user-123\"}"},"attachments":{"type":"array","maxItems":10,"items":{"type":"string","format":"binary","description":"File to attach (max 100MB per file)"}}}},"encoding":{"attachments":{"contentType":"application/octet-stream"}},"examples":{"withAttachments":{"summary":"Workflow with attachments","description":"Create workflow and attach initial documents","value":{"data":"{\"initializationData\":{\"property_address\":\"Oslo Business Center\"},\"entityType\":\"property_acquisition\",\"entityId\":\"deal-002\",\"workflowName\":\"Oslo Acquisition\",\"ownerType\":\"USER\",\"ownerId\":\"user-456\",\"entityLinks\":[{\"entityType\":\"property\",\"entityId\":\"prop-002\",\"linkType\":\"related\"}]}","attachments":["contract.pdf","property-photo.jpg"]}}}}},"description":"Workflow instantiation request with customization parameters.\nProvides the specific configuration for the new workflow instance\nincluding ownership, timeline, and business context data.\n"},"responses":{"201":{"description":"Workflow instance created successfully from template. Returns the complete\nworkflow configuration with all instantiated stages, task assignments,\nand business context. The workflow is initially created in DRAFT status\nfor review and configuration before activation.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow","description":"Complete workflow instance with stages and configuration"}}},"examples":{"success":{"summary":"Successful workflow creation","value":{"data":{"success":true,"workflow":{"id":"550e8400-e29b-41d4-a716-446655440001","workflowNumber":"WF-2024-001","name":"Property Acquisition - 123 Main St","status":"ACTIVE","createdAt":"2024-01-15T10:30:00Z"},"created":{"workflowCount":1,"stageCount":3,"taskCount":12},"errors":[],"warnings":[]}}},"withEntityLinks":{"summary":"Workflow with entity links","description":"Created workflow with multiple entity relationships (Issue","value":{"data":{"success":true,"workflow":{"id":"550e8400-e29b-41d4-a716-446655440002","workflowNumber":"WF-2024-015","name":"Trondheim Waterfront Acquisition","status":"ACTIVE","createdAt":"2024-02-01T09:00:00Z"},"created":{"workflowCount":1,"stageCount":5,"taskCount":18},"errors":[],"warnings":[]}}},"withAttachments":{"summary":"Workflow created with attachments","value":{"data":{"success":true,"workflow":{"id":"550e8400-e29b-41d4-a716-446655440003","workflowNumber":"WF-2024-023","name":"Oslo Business Center Acquisition","status":"ACTIVE","createdAt":"2024-02-10T14:30:00Z"},"created":{"workflowCount":1,"stageCount":4,"taskCount":15,"attachmentCount":2},"attachments":[{"id":"att-456","originalFilename":"contract.pdf","fileSize":2048576,"mimeType":"application/pdf","downloadUrl":"https://storage.googleapis.com/bucket/contract.pdf?X-Goog-Algorithm=..."},{"id":"att-789","originalFilename":"property-photo.jpg","fileSize":1048576,"mimeType":"image/jpeg","downloadUrl":"https://storage.googleapis.com/bucket/photo.jpg?X-Goog-Algorithm=..."}],"errors":[],"warnings":[]}}},"property-acquisition-created":{"summary":"Commercial Property Acquisition Workflow Created","description":"Successfully created commercial property acquisition workflow with\nall template stages instantiated and ready for execution.\n","value":{"data":{"id":"workflow-789e0123-e89b-12d3-a456-426614174333","organizationId":"550e8400-e29b-41d4-a716-446655440000","workflowNumber":"WF-2024-087","templateId":"550e8400-e29b-41d4-a716-446655440001","name":"Trondheim Waterfront Commercial Complex Acquisition","description":"Acquisition of prime waterfront commercial development with mixed-use potential","status":"DRAFT","entityType":"property_acquisition","entityId":"trondheim-waterfront-2024-001","ownerType":"ROLE","ownerId":"senior-acquisition-manager","dueDate":"2024-09-30T23:59:59.000Z","totalStages":6,"completedStages":0,"progressPercentage":0,"publishEvents":true,"eventTopicId":"550e8400-e29b-41d4-a716-446655440010","context":{"propertyValue":85000000,"propertyType":"commercial-mixed-use","location":"Trondheim Waterfront District, Norway","urgencyLevel":"high","environmentalReview":true},"template":{"id":"550e8400-e29b-41d4-a716-446655440001","code":"property-acquisition-commercial-v2","name":"Commercial Property Acquisition v2.1","category":"real-estate"},"workflowStages":[{"id":"stage-001","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440201","stageCode":"legal-due-diligence","stageName":"Legal Due Diligence Review","sequenceOrder":1,"status":"PENDING","isMilestone":false,"isBlocking":true,"isOptional":false,"assignedToType":"ROLE","assignedToId":"legal-counsel","dueDate":"2024-03-15T17:00:00.000Z"},{"id":"stage-002","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440202","stageCode":"technical-assessment","stageName":"Technical Property Assessment","sequenceOrder":2,"status":"PENDING","isMilestone":true,"isBlocking":true,"isOptional":false,"assignedToType":"ROLE","assignedToId":"technical-assessor","dueDate":"2024-03-25T17:00:00.000Z"},{"id":"stage-003","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440203","stageCode":"environmental-review","stageName":"Environmental Impact Assessment","sequenceOrder":3,"status":"PENDING","isMilestone":false,"isBlocking":false,"isOptional":true,"assignedToType":"USER","assignedToId":"environmental-specialist","dueDate":"2024-04-05T17:00:00.000Z"}],"createdAt":"2024-02-28T10:30:00.000Z","createdBy":"api-user@apart.no","updatedAt":"2024-02-28T10:30:00.000Z","updatedBy":"api-user@apart.no"}}},"tenant-onboarding-created":{"summary":"Tenant Onboarding Workflow Created","description":"Successfully created residential tenant onboarding workflow with\nstreamlined digital processing stages.\n","value":{"data":{"id":"workflow-456e7890-e89b-12d3-a456-426614174555","organizationId":"550e8400-e29b-41d4-a716-446655440000","workflowNumber":"WF-2024-088","templateId":"550e8400-e29b-41d4-a716-446655440002","name":"Premium Tenant Onboarding - Aker Brygge Penthouse","description":"Luxury residential tenant onboarding with enhanced verification","status":"DRAFT","entityType":"residential_tenant_onboarding","entityId":"aker-brygge-penthouse-5a","ownerType":"USER","ownerId":"ingrid.nielsen@apart.no","dueDate":"2024-04-15T17:00:00.000Z","totalStages":4,"completedStages":0,"progressPercentage":0,"publishEvents":true,"context":{"tenantType":"executive","apartmentSize":"180 sqm","monthlyRent":42000,"premiumServices":true},"template":{"id":"550e8400-e29b-41d4-a716-446655440002","code":"tenant-onboarding-residential-v1","name":"Residential Tenant Onboarding v1.3","category":"tenant-management"},"workflowStages":[{"id":"stage-011","stageName":"Document Collection & Verification","sequenceOrder":1,"status":"PENDING","assignedToType":"SYSTEM","assignedToId":"document-processor"},{"id":"stage-012","stageName":"Background Check & Credit Assessment","sequenceOrder":2,"status":"PENDING","assignedToType":"SERVICE","assignedToId":"background-check-service"}],"createdAt":"2024-02-28T11:15:00.000Z","createdBy":"api-user@apart.no"}}},"deal-with-assignee-entity-created":{"summary":"Deal Workflow with Separate Assignee Entity Created","description":"Successfully created deal workflow where assignees are resolved\nagainst a different entity (property) than the workflow's primary\nentity (deal).\n","value":{"data":{"id":"workflow-deal-789-e89b-12d3-a456-426614174789","organizationId":"550e8400-e29b-41d4-a716-446655440000","workflowNumber":"WF-2024-089","templateId":"550e8400-e29b-41d4-a716-446655440003","name":"Deal Closing - 123 Main St Property Sale","description":"Closing workflow for property sale deal with assignees resolved from the property's role assignments","status":"DRAFT","entityType":"deal","entityId":"deal-789-main-st-sale","assigneeEntityType":"property","assigneeEntityId":"prop-123-main-st","ownerType":"USER","ownerId":"deal-coordinator@apart.no","dueDate":"2024-08-15T17:00:00.000Z","totalStages":3,"completedStages":0,"progressPercentage":0,"publishEvents":true,"context":{"dealType":"sale","dealValue":4500000,"propertyAddress":"123 Main Street, Oslo","currency":"NOK"},"template":{"id":"550e8400-e29b-41d4-a716-446655440003","code":"deal-closing-v1","name":"Deal Closing Workflow v1.0","category":"deals"},"workflowStages":[{"id":"stage-d01","stageName":"Document Preparation","sequenceOrder":1,"status":"PENDING","assignedToType":"POSITION","assignedToId":"user-resolved-from-property-manager-role"}],"createdAt":"2024-02-28T14:00:00.000Z","createdBy":"api-user@apart.no","updatedAt":"2024-02-28T14:00:00.000Z","updatedBy":"api-user@apart.no"}}}}}}},"400":{"description":"Bad request due to invalid input parameters. Common issues include\nmissing required fields, invalid data types, or malformed UUID values.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/InstantiationResult"}},"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing-required-fields":{"summary":"Missing Required Fields","description":"Request missing required workflow instantiation parameters","value":{"error":{"code":"VALIDATION_ERROR","message":"ownerType and ownerId are required to instantiate a workflow.","details":{"missingFields":["ownerType","ownerId"],"providedFields":["name","entityType","entityId"]}}}},"invalid-owner-type":{"summary":"Invalid Owner Type","description":"Provided owner type is not supported","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid ownerType. Must be one of: ROLE, POSITION, USER","details":{"field":"ownerType","providedValue":"GROUP","allowedValues":["ROLE","POSITION","USER"]}}}},"invalid-due-date":{"summary":"Invalid Due Date","description":"Due date is in the past or has invalid format","value":{"error":{"code":"VALIDATION_ERROR","message":"Due date must be in the future and in ISO 8601 format","details":{"field":"dueDate","providedValue":"2023-12-31T23:59:59.000Z","currentDate":"2024-02-28T10:30:00.000Z"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - insufficient permissions to instantiate workflows from\nthis template or access the specified template category.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FORBIDDEN","message":"Insufficient permissions to instantiate workflows from this template category","details":{"templateCategory":"financial","requiredRole":"financial-manager","userRole":"property-manager"}}}}}},"404":{"description":"Template not found or does not belong to the authenticated organization.\nThe template ID may be invalid or the template may have been deleted.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"template-not-found":{"summary":"Template Not Found","description":"Specified template does not exist or is not accessible","value":{"error":{"code":"NOT_FOUND","message":"Workflow template not found or does not belong to your organization.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440999","organizationId":"550e8400-e29b-41d4-a716-446655440000"}}}}}}}},"422":{"description":"Unprocessable Entity - template exists but cannot be instantiated due to\nbusiness rule violations such as inactive status or invalid date ranges.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"template-inactive":{"summary":"Template Not Active","description":"Template is inactive and cannot be used for new workflows","value":{"error":{"code":"TEMPLATE_NOT_ACTIVE","message":"Cannot create workflow from inactive template.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","templateStatus":"inactive","deactivatedDate":"2024-01-15T10:00:00.000Z"}}}},"template-expired":{"summary":"Template Validity Expired","description":"Template is outside its valid date range","value":{"error":{"code":"TEMPLATE_VALIDITY_EXPIRED","message":"Template is not valid for current date.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","validFrom":"2023-01-01","validUntil":"2023-12-31","currentDate":"2024-02-28"}}}},"template-no-stages":{"summary":"Template Has No Stages","description":"Template cannot be instantiated without configured stages","value":{"error":{"code":"TEMPLATE_CONFIGURATION_INVALID","message":"Template must have at least one stage to be instantiated.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","stageCount":0,"requiredMinimum":1}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/translations":{"get":{"tags":["Translations","Forms"],"summary":"Get translations with filtering","description":"Retrieve translations for the authenticated organization with optional filtering\nby namespace and locale. This endpoint supports the multi-language form system\nfor Issue #81 - Dynamic Task Forms.\n\n**Use Cases:**\n- Load form translations for specific locale\n- Bulk translation management\n- Form rendering with localized labels\n- Translation completeness checking\n\n**Filtering:**\n- Filter by namespace (e.g., 'forms.customer.onboarding')\n- Filter by locale (e.g., 'nb-NO', 'en-US')\n- Combine filters for specific form translations\n\n**Security:** Only returns translations for the authenticated organization\n","operationId":"getTranslations","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"namespace","in":"query","description":"Filter by translation namespace","required":false,"schema":{"type":"string","example":"forms.customer.onboarding"}},{"name":"locale","in":"query","description":"Filter by locale","required":false,"schema":{"type":"string","example":"nb-NO"}},{"name":"key","in":"query","description":"Filter by translation key","required":false,"schema":{"type":"string","example":"title"}},{"name":"limit","in":"query","description":"Number of translations to return","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000,"default":100}},{"name":"offset","in":"query","description":"Number of translations to skip","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Translations retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Translation"}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"hasMore":{"type":"boolean"}}}}},"example":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174001","namespace":"forms.customer.onboarding","key":"title","locale":"nb-NO","value":"Kunderegistrering","context":"Title for customer onboarding form","createdAt":"2024-01-20T10:30:00.000Z"}],"pagination":{"total":45,"limit":100,"offset":0,"hasMore":false}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"post":{"tags":["Translations","Forms"],"summary":"Create or update translation","description":"Create a new translation or update an existing one if the combination\nof namespace, key, and locale already exists (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Add new form translations\n- Update existing translation values\n- Batch translation imports\n- Multi-language form localization\n\n**Upsert Behavior:**\n- Creates new translation if namespace+key+locale combination doesn't exist\n- Updates existing translation if combination already exists\n- Maintains audit trail with created_by and updated_by\n\n**Security:** Can only create translations for the authenticated organization\n","operationId":"createTranslation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["namespace","key","locale","value"],"properties":{"namespace":{"type":"string","description":"Translation namespace (hierarchical)","example":"forms.customer.onboarding"},"key":{"type":"string","description":"Translation key","example":"title"},"locale":{"type":"string","description":"Locale code","example":"nb-NO"},"value":{"type":"string","description":"Translated text","example":"Kunderegistrering"},"context":{"type":"string","description":"Context for translators","example":"Title for customer onboarding form"}}},"examples":{"norwegianFormTitle":{"summary":"Norwegian form title","value":{"namespace":"forms.customer.onboarding","key":"title","locale":"nb-NO","value":"Kunderegistrering","context":"Title for customer onboarding form"}},"englishFormTitle":{"summary":"English form title","value":{"namespace":"forms.customer.onboarding","key":"title","locale":"en-US","value":"Customer Onboarding","context":"Title for customer onboarding form"}},"fieldLabel":{"summary":"Field label translation","value":{"namespace":"forms.customer.onboarding","key":"field.companyName.label","locale":"nb-NO","value":"Firmanavn","context":"Label for company name field"}}}}}},"responses":{"200":{"description":"Translation created or updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Translation"}}},"example":{"data":{"id":"123e4567-e89b-12d3-a456-426614174001","namespace":"forms.customer.onboarding","key":"title","locale":"nb-NO","value":"Kunderegistrering","context":"Title for customer onboarding form","createdAt":"2024-01-20T10:30:00.000Z","updatedAt":"2024-01-20T10:30:00.000Z"}}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"VALIDATION_ERROR","message":"Invalid translation data","details":{"field":"locale","issue":"Invalid locale format"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/translations/{id}":{"put":{"tags":["Translations","Forms"],"summary":"Update translation by ID","description":"Update an existing translation by its ID (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Correct translation values\n- Update translation context\n- Refine form localizations\n- Bulk translation updates\n\n**Security:** Can only update translations belonging to the authenticated organization\n","operationId":"updateTranslation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string","description":"Updated translated text","example":"Oppdatert kunderegistrering"},"context":{"type":"string","description":"Updated context for translators","example":"Updated title for customer onboarding form"}}},"example":{"value":"Oppdatert kunderegistrering","context":"Updated title for customer onboarding form"}}}},"responses":{"200":{"description":"Translation updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Translation"}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Translation not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TRANSLATION_NOT_FOUND","message":"Translation not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Translations","Forms"],"summary":"Delete translation","description":"Delete a translation by its ID (Issue #81 - Dynamic Task Forms).\n\n**Use Cases:**\n- Remove obsolete translations\n- Clean up duplicate translations\n- Manage translation lifecycle\n\n**⚠️ Warning:** This action is irreversible\n\n**Security:** Can only delete translations belonging to the authenticated organization\n","operationId":"deleteTranslation","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/UuidPathParam"}],"responses":{"204":{"description":"Translation deleted successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Translation not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TRANSLATION_NOT_FOUND","message":"Translation not found."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/translations/bulk":{"post":{"tags":["Translations","Forms"],"summary":"Bulk import translations","description":"Bulk import multiple translations at once (Issue #81 - Dynamic Task Forms).\nThis endpoint supports efficient translation management for large form sets.\n\n**Use Cases:**\n- Import translations from external translation services\n- Bulk form localization\n- Initial multi-language content setup\n- Migration from existing translation systems\n\n**Behavior:**\n- Uses upsert logic (create new, update existing)\n- Processes all translations in a single transaction\n- Returns summary of operations performed\n\n**Security:** Can only import translations for the authenticated organization\n","operationId":"bulkImportTranslations","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["translations"],"properties":{"translations":{"type":"array","items":{"type":"object","required":["namespace","key","locale","value"],"properties":{"namespace":{"type":"string"},"key":{"type":"string"},"locale":{"type":"string"},"value":{"type":"string"},"context":{"type":"string"}}}}}},"example":{"translations":[{"namespace":"forms.customer.onboarding","key":"title","locale":"nb-NO","value":"Kunderegistrering","context":"Form title"},{"namespace":"forms.customer.onboarding","key":"title","locale":"en-US","value":"Customer Onboarding","context":"Form title"},{"namespace":"forms.customer.onboarding","key":"field.companyName.label","locale":"nb-NO","value":"Firmanavn","context":"Company name field label"}]}}}},"responses":{"200":{"description":"Bulk import completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"created":{"type":"integer","description":"Number of new translations created"},"updated":{"type":"integer","description":"Number of existing translations updated"},"total":{"type":"integer","description":"Total number of translations processed"},"errors":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer"},"error":{"type":"string"}}},"description":"Any validation errors encountered"}}}}},"example":{"data":{"created":15,"updated":3,"total":18,"errors":[]}}}}},"400":{"description":"Bad Request - Validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/mentions":{"get":{"tags":["Users"],"summary":"Get all mentions for a specific user","description":"Retrieves paginated list of entities (tasks, projects, workflows) where user was mentioned in comments.","operationId":"getUserMentions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"userId","in":"query","required":true,"description":"User ID to fetch mentions for","schema":{"type":"string","example":"550e8400-e29b-41d4-a716-446655440000"}},{"name":"unreadOnly","in":"query","description":"Filter to only show unread mentions","schema":{"type":"boolean","default":false}},{"name":"entityType","in":"query","description":"Filter by entity type (TASK, PROJECT, WORKFLOW)","schema":{"type":"string","enum":["TASK","PROJECT","WORKFLOW"],"example":"TASK"}},{"name":"page","in":"query","description":"Page number for pagination","schema":{"type":"integer","minimum":1,"default":1}},{"name":"limit","in":"query","description":"Number of items per page","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"sortBy","in":"query","description":"Sort field","schema":{"type":"string","enum":["followed_at","created_at"],"default":"followed_at"}},{"name":"sortOrder","in":"query","description":"Sort order","schema":{"type":"string","enum":["asc","desc"],"default":"desc"}}],"responses":{"200":{"description":"User mentions retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"entity_type":{"type":"string","example":"TASK"},"entity_id":{"type":"string","format":"uuid"},"followed_at":{"type":"string","format":"date-time"},"followed_by":{"type":"string","description":"User ID who mentioned you"},"follow_reason":{"type":"string","example":"MENTIONED"},"is_read":{"type":"boolean","description":"Whether the mention has been marked as read"},"read_at":{"type":"string","format":"date-time","nullable":true,"description":"When the mention was marked as read"},"entity":{"type":"object","nullable":true,"description":"Details of the mentioned entity (null if entity was deleted)","properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string","description":"For tasks"},"name":{"type":"string","description":"For projects/workflows"},"status":{"type":"string"}}},"entity_status":{"type":"string","enum":["ACTIVE","DELETED"],"description":"Whether the referenced entity still exists (ACTIVE) or has been deleted (DELETED)"},"mention_metadata":{"type":"object","description":"Metadata about the mention including comment author","properties":{"comment_id":{"type":"string","format":"uuid","description":"ID of the comment where mention occurred"},"comment_author":{"type":"string","description":"ID of the user who authored the comment"},"comment_author_name":{"type":"string","description":"Name of the comment author"},"comment_content":{"type":"string","description":"Content of the comment where mention occurred (truncated to 500 chars). Contains raw user:{uuid} patterns for frontend rendering."},"mentioned_by":{"type":"string","description":"User ID who mentioned you"},"mentioned_at":{"type":"string","format":"date-time","description":"When the mention occurred"},"target_type":{"type":"string","description":"Type of entity where comment was made (task, project, workflow, workflow_stage)"},"target_id":{"type":"string","format":"uuid","description":"ID of the specific entity where comment was made"},"total_mentions":{"type":"integer","description":"Total number of times mentioned on this entity"},"all_mentions":{"type":"array","description":"Array of all mention events on this entity","items":{"type":"object","properties":{"mentionedBy":{"type":"string"},"mentionedAt":{"type":"string","format":"date-time"},"commentId":{"type":"string","format":"uuid"},"commentAuthor":{"type":"string"},"commentAuthorName":{"type":"string"},"commentContent":{"type":"string","description":"Content of the comment (truncated to 500 chars)"},"targetType":{"type":"string"},"targetId":{"type":"string","format":"uuid"}}}}}}}}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"unread":{"type":"integer","description":"Count of unread mentions"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}},"examples":{"taskMentions":{"summary":"User mentioned in tasks","value":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174000","entity_type":"TASK","entity_id":"789e0123-e89b-12d3-a456-426614174222","followed_at":"2024-01-15T10:30:00.000Z","followed_by":"user-456","follow_reason":"MENTIONED","entity":{"id":"789e0123-e89b-12d3-a456-426614174222","title":"Review design mockups","status":"in_progress"},"entity_status":"ACTIVE","mention_metadata":{"comment_id":"abc12345-e89b-12d3-a456-426614174000","comment_author":"user-456","comment_author_name":"Jane Doe","comment_content":"Hey user:{550e8400-e29b-41d4-a716-446655440000} can you review the lease terms before Friday?","mentioned_by":"user-456","mentioned_at":"2024-01-15T10:30:00.000Z","total_mentions":1,"all_mentions":[{"mentionedBy":"user-456","mentionedAt":"2024-01-15T10:30:00.000Z","commentId":"abc12345-e89b-12d3-a456-426614174000","commentContent":"Hey user:{550e8400-e29b-41d4-a716-446655440000} can you review the lease terms before Friday?"}]}}],"meta":{"total":15,"page":1,"limit":20}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/mentions/mark-read":{"post":{"tags":["Users"],"summary":"Mark specific mentions as read","description":"Marks one or more mentions as read for a user by creating read status records.","operationId":"markMentionsAsRead","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId","mentionIds"],"properties":{"userId":{"type":"string","description":"User ID who is marking mentions as read"},"mentionIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of EntityFollow IDs to mark as read"}}},"examples":{"single":{"summary":"Mark single mention as read","value":{"userId":"550e8400-e29b-41d4-a716-446655440000","mentionIds":["123e4567-e89b-12d3-a456-426614174000"]}},"multiple":{"summary":"Mark multiple mentions as read","value":{"userId":"550e8400-e29b-41d4-a716-446655440000","mentionIds":["123e4567-e89b-12d3-a456-426614174000","789e0123-e89b-12d3-a456-426614174222"]}}}}}},"responses":{"200":{"description":"Mentions marked as read successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"markedCount":{"type":"integer","description":"Number of mentions marked as read"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/mentions/mark-all-read":{"post":{"tags":["Users"],"summary":"Mark all mentions as read for a user","description":"Marks all unread mentions as read for a user at once.","operationId":"markAllMentionsAsRead","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["userId"],"properties":{"userId":{"type":"string","description":"User ID who is marking all mentions as read"}}},"example":{"userId":"550e8400-e29b-41d4-a716-446655440000"}}}},"responses":{"200":{"description":"All mentions marked as read successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"markedCount":{"type":"integer","description":"Number of mentions marked as read"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/users/mentions/unread-count":{"get":{"tags":["Users"],"summary":"Get unread mention count for a user","description":"Returns unread mention count for a user, optionally grouped by entity type.","operationId":"getUnreadMentionCount","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"userId","in":"query","required":true,"description":"User ID to get unread count for","schema":{"type":"string"}}],"responses":{"200":{"description":"Unread count retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"count":{"type":"integer","description":"Total unread mention count"},"byEntityType":{"type":"object","description":"Unread counts grouped by entity type","properties":{"TASK":{"type":"integer"},"PROJECT":{"type":"integer"},"WORKFLOW":{"type":"integer"}}}}}}},"example":{"data":{"count":8,"byEntityType":{"TASK":5,"PROJECT":2,"WORKFLOW":1}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/entity-types/{code}/resolved-view-schema":{"get":{"summary":"Get resolved view schema for an entity type","description":"Resolves the view schema for an entity type. Returns the explicitly\nconfigured schema if one exists, otherwise returns a minimal fallback.\nWhen entity data is available, the fallback auto-infers field widgets.\n\nOptionally accepts context IDs to apply hierarchical overrides from\nworkflow templates, stages, and task templates. Overrides are merged\nin order: EntityType → WorkflowTemplate → WorkflowStage → TaskTemplate.\n","tags":["Entity Types"],"parameters":[{"name":"code","in":"path","required":true,"description":"Entity type code","schema":{"type":"string","example":"contract"}},{"name":"workflowTemplateId","in":"query","required":false,"description":"Workflow template ID for context overrides","schema":{"type":"string","format":"uuid"}},{"name":"workflowStageId","in":"query","required":false,"description":"Workflow template stage ID for context overrides","schema":{"type":"string","format":"uuid"}},{"name":"taskTemplateId","in":"query","required":false,"description":"Task template ID for context overrides","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Resolved view schema","content":{"application/json":{"schema":{"type":"object","properties":{"schema":{"type":"object","description":"The view schema configuration"},"base":{"type":"string","enum":["entity-type","auto-inferred"],"description":"How the schema was resolved"},"overrides":{"type":"array","items":{"type":"string","enum":["workflow-template","workflow-stage","task-template"]},"description":"Override levels that were applied"},"resolvedAt":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid query parameter format"},"404":{"description":"Entity type not found"}}}},"/api/v1/entity-types/{id}/validate-view-schema":{"post":{"summary":"Validate a view schema with optional coverage analysis","description":"Validates the structural correctness of a view schema and optionally\nanalyzes how well it covers the actual entity data fields. If no\nsampleData is provided in the request body, the endpoint attempts\nto fetch a recent cached entry for the entity type to use as sample data.\n\nCoverage analysis identifies:\n- **uncoveredFields**: data fields not referenced by any fieldConfig\n- **phantomFields**: fieldConfigs referencing paths not in the sample data\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"Entity type UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["viewSchema"],"properties":{"viewSchema":{"type":"object","description":"The view schema to validate","properties":{"version":{"type":"string","enum":["1.0"]},"fieldConfigs":{"type":"array","items":{"type":"object"}},"layout":{"type":"object"},"fallback":{"type":"object"}}},"sampleData":{"type":"object","description":"Optional sample data for coverage analysis. If omitted, uses cached entity data."}}}}}},"responses":{"200":{"description":"Validation result with optional coverage analysis","content":{"application/json":{"schema":{"type":"object","properties":{"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}}}},"coverage":{"type":"object","properties":{"configuredFields":{"type":"integer"},"sampleDataFields":{"type":"integer"},"uncoveredFields":{"type":"array","items":{"type":"string"}},"phantomFields":{"type":"array","items":{"type":"string"}}}}}}}}},"400":{"description":"Missing required viewSchema in request body"},"404":{"description":"Entity type not found"}}}},"/api/v1/entity-types/{id}/discover-fields":{"get":{"summary":"Discover available fields for an entity type","description":"Inspects cached entity data and returns all discoverable fields with\ninferred widget suggestions. Cross-references with the existing view\nschema to show what is already configured vs. what is available.\n\nThis endpoint powers the View Schema Builder UI, providing field\ndiscovery, widget inference, and existing configuration context.\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"Entity type UUID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Field discovery result","content":{"application/json":{"schema":{"type":"object","properties":{"entityTypeId":{"type":"string","format":"uuid"},"entityTypeCode":{"type":"string"},"sampleDataAvailable":{"type":"boolean"},"fields":{"type":"array","items":{"type":"object"}},"currentSchema":{"type":"object"}}}}}},"404":{"description":"Entity type not found"}}}},"/api/v1/entity-types/{id}/preview-view-schema":{"post":{"summary":"Preview a draft view schema without saving","description":"Accepts a draft view schema, validates it, and returns the resolved\nschema with coverage analysis. Does NOT save the schema — saving\nis done via PUT /api/v1/entity-types/:id.\n","tags":["Entity Types"],"parameters":[{"name":"id","in":"path","required":true,"description":"Entity type UUID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["viewSchema"],"properties":{"viewSchema":{"type":"object","description":"The draft view schema to preview"}}}}}},"responses":{"200":{"description":"Preview result with resolved schema and coverage","content":{"application/json":{"schema":{"type":"object","properties":{"resolved":{"type":"object","properties":{"schema":{"type":"object"},"base":{"type":"string","enum":["entity-type"]},"resolvedAt":{"type":"string","format":"date-time"}}},"validation":{"type":"object"}}}}}},"400":{"description":"Invalid request body"},"404":{"description":"Entity type not found"}}}},"/api/v1/view-schema-options":{"get":{"summary":"Get available view schema configuration options","description":"Returns all available widget types, layout templates, conditional\noperators, and fallback strategies. Static reference endpoint so\nthe frontend doesn't need to hardcode these values.\n","tags":["View Schema"],"responses":{"200":{"description":"Available configuration options","content":{"application/json":{"schema":{"type":"object","properties":{"widgetTypes":{"type":"array","items":{"type":"object"}},"layoutTemplates":{"type":"array","items":{"type":"object"}},"conditionalOperators":{"type":"array","items":{"type":"object"}},"fallbackStrategies":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/visibility/grant":{"post":{"tags":["Visibility"],"summary":"Grant visibility for an entity","description":"Grants visibility for an entity to a user on a portal with optional expiration and child entity inclusion.","operationId":"grantVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityType","entityId","portalCode","userId"],"properties":{"entityType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"],"description":"Type of entity to grant visibility for","example":"PROJECT"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},"portalCode":{"type":"string","description":"Portal code where visibility is granted","example":"customer_portal"},"userId":{"type":"string","description":"ID of the user being granted visibility","example":"user-123"},"expiresAt":{"type":"string","format":"date-time","description":"Optional expiration date for visibility","example":"2024-12-31T23:59:59Z"},"metadata":{"type":"object","description":"Optional metadata for the visibility grant","example":{"reason":"Customer request","approvedBy":"manager-456"}},"includeChildren":{"type":"boolean","description":"Whether to grant visibility to child entities (e.g., tasks in a project)","default":false,"example":true}}}}}},"responses":{"201":{"description":"Visibility granted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityVisibilityResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/revoke":{"post":{"tags":["Visibility"],"summary":"Revoke visibility for an entity","description":"Revokes previously granted visibility from a user on a portal.","operationId":"revokeVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityType","entityId","portalCode","userId"],"properties":{"entityType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"],"description":"Type of entity to revoke visibility for","example":"PROJECT"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},"portalCode":{"type":"string","description":"Portal code where visibility is revoked","example":"customer_portal"},"userId":{"type":"string","description":"ID of the user whose visibility is revoked","example":"user-123"},"reason":{"type":"string","description":"Optional reason for revoking visibility","example":"Project completed"}}}}}},"responses":{"200":{"description":"Visibility revoked successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Visibility revoked successfully"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/bulk-grant":{"post":{"tags":["Visibility"],"summary":"Grant visibility for multiple entities or users","description":"Grants visibility for multiple entities to multiple users in bulk (simple or advanced mode).","operationId":"bulkGrantVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityType","entityIds","portalCode","userIds"],"properties":{"grants":{"type":"array","description":"Advanced mode - grant different entity types with individual settings","items":{"type":"object","properties":{"entityType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"]},"entityId":{"type":"string","format":"uuid"},"includeChildren":{"type":"boolean","default":false}}}},"entityType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"],"description":"Simple mode - type of entities to grant visibility for","example":"TASK"},"entityIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Simple mode - IDs of the entities","example":["550e8400-e29b-41d4-a716-446655440000","650e8400-e29b-41d4-a716-446655440001"]},"portalCode":{"type":"string","required":true,"description":"Portal code where visibility is granted","example":"partner_portal"},"userId":{"type":"string","description":"Single user ID (alternative to userIds)","example":"user-123"},"userIds":{"type":"array","items":{"type":"string"},"description":"IDs of the users being granted visibility","example":["user-123","user-456"]},"expiresAt":{"type":"string","format":"date-time","description":"Optional expiration date for visibility"},"metadata":{"type":"object","description":"Optional metadata for the visibility grants"},"includeChildren":{"type":"boolean","description":"Simple mode - whether to grant visibility to child entities","default":false}}}}}},"responses":{"201":{"description":"Visibility granted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"granted":{"type":"integer","description":"Number of visibility records created","example":4},"entityIds":{"type":"array","items":{"type":"string"},"description":"IDs of entities granted visibility"},"userIds":{"type":"array","items":{"type":"string"},"description":"IDs of users granted visibility"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/check":{"get":{"tags":["Visibility"],"summary":"Check if a user has visibility for an entity","description":"Checks if user has active (non-expired) visibility for an entity on a portal.","operationId":"checkVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"query","required":true,"schema":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"]},"description":"Type of entity to check","example":"PROJECT"},{"name":"entityId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the entity","example":"550e8400-e29b-41d4-a716-446655440000"},{"name":"portalCode","in":"query","required":true,"schema":{"type":"string"},"description":"Portal code to check visibility for","example":"customer_portal"},{"name":"userId","in":"query","required":true,"schema":{"type":"string"},"description":"ID of the user to check","example":"user-123"}],"responses":{"200":{"description":"Visibility check result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"hasVisibility":{"type":"boolean","description":"Whether the user has visibility","example":true}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/entities":{"get":{"tags":["Visibility"],"summary":"Get all visible entities for a user","description":"Retrieves entity IDs of specific type visible to user on a portal.","operationId":"getVisibleEntities","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"entityType","in":"query","required":true,"schema":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION","TASK"]},"description":"Type of entities to retrieve","example":"TASK"},{"name":"portalCode","in":"query","required":true,"schema":{"type":"string"},"description":"Portal code to check visibility for","example":"customer_portal"},{"name":"userId","in":"query","required":true,"schema":{"type":"string"},"description":"ID of the user","example":"user-123"},{"name":"includeExpired","in":"query","schema":{"type":"boolean","default":false},"description":"Include expired visibility records"}],"responses":{"200":{"description":"List of visible entity IDs","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"entityIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of visible entities","example":["550e8400-e29b-41d4-a716-446655440000","650e8400-e29b-41d4-a716-446655440001"]},"count":{"type":"integer","description":"Number of visible entities","example":2}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/sync-inheritance":{"post":{"tags":["Visibility"],"summary":"Sync inherited visibility from parent to children","description":"Propagates visibility from parent entity to its children (e.g., project to tasks).","operationId":"syncInheritedVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["parentType","parentId"],"properties":{"parentType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION"],"description":"Type of parent entity","example":"PROJECT"},"parentId":{"type":"string","format":"uuid","description":"ID of the parent entity","example":"550e8400-e29b-41d4-a716-446655440000"}}}}}},"responses":{"200":{"description":"Inheritance synced successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Visibility inheritance synced successfully"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/bulk-sync-inheritance":{"post":{"tags":["Visibility"],"summary":"Bulk sync inherited visibility for multiple parents","description":"Propagates visibility from multiple parent entities to their children in one operation.","operationId":"bulkSyncInheritedVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["parents"],"properties":{"parents":{"type":"array","items":{"type":"object","properties":{"parentType":{"type":"string","enum":["WORKFLOW","PROJECT","SECTION"],"description":"Type of parent entity"},"parentId":{"type":"string","format":"uuid","description":"ID of the parent entity"}}},"example":[{"parentType":"PROJECT","parentId":"550e8400-e29b-41d4-a716-446655440000"},{"parentType":"WORKFLOW","parentId":"650e8400-e29b-41d4-a716-446655440001"}]}}}}}},"responses":{"200":{"description":"Bulk inheritance sync completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"synced":{"type":"integer","description":"Number of parent entities synced","example":2}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/job-status":{"get":{"tags":["Visibility"],"summary":"Get background job status","description":"Returns status of visibility cleanup background job (running state and processing status).","operationId":"getVisibilityJobStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Job status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"cleanupJob":{"type":"object","properties":{"running":{"type":"boolean","description":"Whether the job scheduler is running","example":true},"processing":{"type":"boolean","description":"Whether the job is currently processing","example":false},"intervalHours":{"type":"number","description":"How often the job runs (in hours)","example":1}}}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/visibility/cleanup-expired":{"post":{"tags":["Visibility"],"summary":"Clean up expired visibility records","description":"Removes all expired visibility records for the organization (maintenance task).","operationId":"cleanupExpiredVisibility","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Cleanup completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"cleaned":{"type":"integer","description":"Number of expired records removed","example":15}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/webhooks":{"post":{"summary":"Register a calendar webhook","description":"Register a new webhook for calendar events and task notifications","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"},"examples":{"taskWebhook":{"summary":"Task events webhook","value":{"endpoint":"https://myapp.com/webhooks/tasks","events":["task.created","task.updated","task.completed"],"config":{"retryPolicy":{"maxRetries":3,"backoffMultiplier":2},"timeout":5000,"verifySSL":true}}}}}}},"responses":{"201":{"description":"Webhook registered successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookRegistration"}}}}}},"400":{"description":"Invalid webhook configuration"},"401":{"description":"Authentication required"}}},"get":{"summary":"List webhooks","description":"List all webhooks for the authenticated organization","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"active","schema":{"type":"boolean"},"description":"Filter by active status"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Webhooks retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookRegistration"}},"meta":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/PaginationInfo"}}}}}}}}}}},"/api/v1/webhooks/{webhookId}":{"get":{"summary":"Get webhook details","description":"Get details of a specific webhook","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook details retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookRegistration"}}}}}},"404":{"description":"Webhook not found"}}},"put":{"summary":"Update webhook configuration","description":"Update webhook endpoint, events, or configuration","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"config":{"type":"object"},"active":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Webhook updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookRegistration"}}}}}},"404":{"description":"Webhook not found"}}},"delete":{"summary":"Delete webhook","description":"Delete a webhook registration","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/webhooks/{webhookId}/secret":{"post":{"summary":"Generate new webhook secret","description":"Generate a new secret for webhook signature verification","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"New secret generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"secret":{"type":"string","description":"New webhook secret"}}}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/webhooks/validate":{"post":{"summary":"Validate webhook signature","description":"Validate webhook signature for incoming requests","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["payload","signature","secret"],"properties":{"payload":{"type":"string","description":"Raw webhook payload"},"signature":{"type":"string","description":"Webhook signature to verify"},"secret":{"type":"string","description":"Webhook secret for verification"}}}}}},"responses":{"200":{"description":"Signature validation result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"valid":{"type":"boolean"},"error":{"type":"string"}}}}}}}}}}},"/api/v1/webhooks/{webhookId}/history":{"get":{"summary":"Get webhook delivery history","description":"Get delivery history and logs for a specific webhook","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"status","schema":{"type":"string","enum":["pending","success","failed","retrying"]},"description":"Filter by delivery status"},{"in":"query","name":"eventType","schema":{"type":"string"},"description":"Filter by event type"},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Webhook delivery history retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryLog"}},"meta":{"type":"object","properties":{"pagination":{"$ref":"#/components/schemas/PaginationInfo"}}}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/webhooks/{webhookId}/retry/{deliveryId}":{"post":{"summary":"Retry webhook delivery","description":"Retry a failed webhook delivery","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"path","name":"deliveryId","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Webhook delivery retry initiated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Webhook or delivery not found"}}}},"/api/v1/webhooks/{webhookId}/stats":{"get":{"summary":"Get webhook statistics","description":"Get delivery statistics for a specific webhook","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"timeframe","schema":{"type":"string","enum":["24h","7d","30d","90d"],"default":"30d"},"description":"Time period for statistics"}],"responses":{"200":{"description":"Webhook statistics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"totalDeliveries":{"type":"integer"},"successfulDeliveries":{"type":"integer"},"failedDeliveries":{"type":"integer"},"averageResponseTime":{"type":"number"},"successRate":{"type":"number"},"timeframe":{"type":"string"}}}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/webhooks/{webhookId}/toggle":{"post":{"summary":"Toggle webhook status","description":"Enable or disable a webhook","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"webhookId","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["active"],"properties":{"active":{"type":"boolean","description":"Whether webhook should be active"}}}}}},"responses":{"200":{"description":"Webhook status updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookRegistration"}}}}}},"404":{"description":"Webhook not found"}}}},"/api/v1/webhooks/events":{"get":{"summary":"Get available event types","description":"Get list of available webhook event types","tags":["Webhooks"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Available event types retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"}}}}}}}}}}}},"/api/v1/workflows/conditions/test":{"post":{"summary":"Test a JSONLogic condition against sample context","description":"Evaluates a JSONLogic condition against provided context data to test its behavior.\nUseful for debugging conditions during workflow template design.\n","tags":["Workflows","Conditions"],"security":[{"apartAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["condition","context"],"properties":{"condition":{"type":"object","description":"JSONLogic condition to test","example":{"==":[{"var":"workflow.status"},"ACTIVE"]}},"context":{"type":"object","description":"Sample context data for evaluation","properties":{"workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"ACTIVE"},"entityType":{"type":"string","example":"customer"},"entityId":{"type":"string","example":"CUST-123"},"totalStages":{"type":"integer","example":5},"completedStages":{"type":"integer","example":2}}},"stage":{"type":"object","properties":{"code":{"type":"string","example":"approval"},"status":{"type":"string","example":"PENDING"},"isOptional":{"type":"boolean","example":false}}},"custom":{"type":"object","example":{"priority":"high","customer_type":"premium"}}}},"options":{"type":"object","properties":{"skipCache":{"type":"boolean","default":false},"timeoutMs":{"type":"integer","minimum":10,"maximum":1000,"default":100}}}}},"examples":{"simple_equality":{"summary":"Simple equality check","value":{"condition":{"==":[{"var":"workflow.status"},"ACTIVE"]},"context":{"workflow":{"status":"ACTIVE"}}}},"complex_condition":{"summary":"Complex condition with multiple checks","value":{"condition":{"and":[{"==":[{"var":"workflow.status"},"ACTIVE"]},{">":[{"var":"workflow.completedStages"},0]},{"in":[{"var":"custom.priority"},["high","urgent"]]}]},"context":{"workflow":{"status":"ACTIVE","completedStages":2},"custom":{"priority":"high"}}}}}}}},"responses":{"200":{"description":"Condition test results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the test was successful"},"evaluation":{"type":"object","description":"Condition evaluation result","properties":{"success":{"type":"boolean"},"result":{"type":"boolean","description":"Condition evaluation result"},"evaluationTimeMs":{"type":"number"},"error":{"type":"string"}}},"validation":{"type":"object","description":"Condition validation result","properties":{"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"operators":{"type":"array","items":{"type":"string"}},"complexity":{"type":"integer"},"maxDepth":{"type":"integer"}}},"suggestions":{"type":"array","items":{"type":"string"},"description":"Optimization suggestions"}}}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Insufficient permissions"},"500":{"description":"Server error"}}}},"/api/v1/workflows/conditions/validate":{"post":{"summary":"Validate JSONLogic condition syntax and complexity","description":"Validates a JSONLogic condition for syntax correctness, security, and performance.\nReturns detailed information about operators used, complexity metrics, and warnings.\n","tags":["Workflows","Conditions"],"security":[{"apartAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["condition"],"properties":{"condition":{"type":"object","description":"JSONLogic condition to validate","example":{"and":[{"==":[{"var":"customer.type"},"premium"]},{">":[{"var":"order.amount"},1000]}]}}}},"examples":{"simple_condition":{"summary":"Simple condition","value":{"condition":{"==":[{"var":"status"},"active"]}}},"complex_condition":{"summary":"Complex nested condition","value":{"condition":{"or":[{"and":[{"==":[{"var":"type"},"premium"]},{">":[{"var":"amount"},1000]}]},{"in":[{"var":"category"},["vip","enterprise"]]}]}}}}}}},"responses":{"200":{"description":"Validation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether validation was successful"},"validation":{"type":"object","properties":{"valid":{"type":"boolean","description":"Whether the condition is valid"},"errors":{"type":"array","items":{"type":"string"},"description":"Validation errors"},"warnings":{"type":"array","items":{"type":"string"},"description":"Performance warnings"},"operators":{"type":"array","items":{"type":"string"},"description":"JSONLogic operators used"},"complexity":{"type":"integer","description":"Condition complexity score"},"maxDepth":{"type":"integer","description":"Maximum nesting depth"}}}}}}}},"400":{"description":"Invalid request data"},"401":{"description":"Unauthorized"},"403":{"description":"Insufficient permissions"},"500":{"description":"Server error"}}}},"/api/v1/workflows/conditions/operators":{"get":{"summary":"Get available JSONLogic operators and their descriptions","description":"Returns a list of all supported JSONLogic operators with descriptions and examples.\nUseful for building condition editors and documentation.\n","tags":["Workflows","Conditions"],"security":[{"apartAuth":[]}],"responses":{"200":{"description":"Available operators","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"operators":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of operator names to descriptions","example":{"==":"Equal - loose equality comparison","and":"Logical AND - all conditions must be true","or":"Logical OR - at least one condition must be true","in":"Check if value exists in array","var":"Access variable from context"}},"categories":{"type":"object","description":"Operators grouped by category","properties":{"logical":{"type":"array","items":{"type":"string"},"example":["and","or","not"]},"comparison":{"type":"array","items":{"type":"string"},"example":["==","!=",">","<",">=","<="]},"arithmetic":{"type":"array","items":{"type":"string"},"example":["+","-","*","/","%"]}}},"examples":{"type":"object","description":"Example conditions for common use cases","properties":{"customer_type_check":{"type":"object","example":{"condition":{"==":[{"var":"customer.type"},"premium"]},"description":"Check if customer type is premium"}},"workflow_progress":{"type":"object","example":{"condition":{">":[{"var":"workflow.progressPercentage"},50]},"description":"Check if workflow is more than 50% complete"}}}}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Insufficient permissions"},"500":{"description":"Server error"}}}},"/api/v1/workflow-data-instances":{"post":{"tags":["Workflow Data Instances"],"summary":"Create workflow data instance","description":"Creates a new data instance for a workflow using a schema","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workflowId","schemaId","data"],"properties":{"workflowId":{"type":"string","format":"uuid","description":"ID of the workflow"},"schemaId":{"type":"string","format":"uuid","description":"ID of the data schema"},"data":{"type":"object","description":"Structured data conforming to schema","additionalProperties":true}}}}}},"responses":{"201":{"description":"Instance created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"schemaId":{"type":"string"},"currentData":{"type":"object"},"validationState":{"type":"object"}}}}}}}},"400":{"description":"Data validation failed"},"404":{"description":"Schema or workflow not found"},"409":{"description":"Instance already exists"},"500":{"description":"Internal server error"}}},"get":{"tags":["Workflow Data Instances"],"summary":"List workflow data instances","description":"Retrieves all data instances for a specific workflow","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Filter by workflow ID"}],"responses":{"200":{"description":"List of instances retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"schemaId":{"type":"string"},"currentData":{"type":"object"}}}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"workflowId":{"type":"string"}}}}}}}},"400":{"description":"Missing required parameters"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-instances/{id}":{"get":{"tags":["Workflow Data Instances"],"summary":"Get workflow data instance by ID","description":"Retrieves a specific data instance with its current data and validation state","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Instance ID"}],"responses":{"200":{"description":"Instance retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"id":{"type":"string"},"workflowId":{"type":"string"},"schemaId":{"type":"string"},"currentData":{"type":"object"},"validationState":{"type":"object"},"lastValidated":{"type":"string","format":"date-time"},"checksum":{"type":"string"}}}}}}}},"404":{"description":"Instance not found"},"500":{"description":"Internal server error"}}},"put":{"tags":["Workflow Data Instances"],"summary":"Update workflow data instance","description":"Updates the data in an instance and validates against schema","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Instance ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"Updated data conforming to schema","additionalProperties":true}}}}}},"responses":{"200":{"description":"Instance updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"400":{"description":"Data validation failed"},"404":{"description":"Instance not found"},"500":{"description":"Internal server error"}}},"delete":{"tags":["Workflow Data Instances"],"summary":"Delete workflow data instance","description":"Deletes a data instance and its history","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Instance ID"}],"responses":{"204":{"description":"Instance deleted successfully"},"404":{"description":"Instance not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-instances/{id}/validate":{"post":{"tags":["Workflow Data Instances"],"summary":"Validate workflow data instance","description":"Validates instance data against its schema rules","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Instance ID"}],"responses":{"200":{"description":"Validation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"isValid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"rule":{"type":"string"},"message":{"type":"string"}}}},"warnings":{"type":"array","items":{"type":"object"}},"lastValidated":{"type":"string","format":"date-time"},"validatedBy":{"type":"string"}}}}}}}},"404":{"description":"Instance not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-instances/{id}/history":{"get":{"tags":["Workflow Data Instances"],"summary":"Get instance history","description":"Retrieves the complete history of changes for a data instance","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Instance ID"}],"responses":{"200":{"description":"History retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"version":{"type":"integer"},"data":{"type":"object"},"changedAt":{"type":"string","format":"date-time"},"changedBy":{"type":"string"},"changes":{"type":"object"}}}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"instanceId":{"type":"string"}}}}}}}},"404":{"description":"Instance not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-instances/validate-data":{"post":{"tags":["Workflow Data Instances"],"summary":"Validate data against schema","description":"Validates data against a schema without creating an instance","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["schemaId","data"],"properties":{"schemaId":{"type":"string","format":"uuid","description":"ID of the schema to validate against"},"data":{"type":"object","description":"Data to validate","additionalProperties":true}}}}}},"responses":{"200":{"description":"Validation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"isValid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}},"validatedAt":{"type":"string","format":"date-time"}}}}}}}},"404":{"description":"Schema not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-schemas":{"post":{"tags":["Workflow Data Schemas"],"summary":"Create a new workflow data schema","description":"Creates a schema definition for structured data within workflows","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["schemaCode","schemaVersion","entityDefinitions"],"properties":{"schemaCode":{"type":"string","description":"Unique identifier code for the schema","example":"PROPERTY_INSPECTION"},"schemaVersion":{"type":"string","description":"Semantic version of the schema","example":"1.0.0"},"workflowTemplateId":{"type":"string","format":"uuid","description":"Optional workflow template association"},"entityDefinitions":{"type":"array","description":"Entity structure definitions","items":{"type":"object","properties":{"name":{"type":"string"},"fields":{"type":"array"}}}},"validationRules":{"type":"array","description":"JSONLogic validation rules"},"computedFields":{"type":"array","description":"Computed field formulas"},"stateTransitions":{"type":"object","description":"Workflow state rules"}}}}}},"responses":{"201":{"description":"Schema created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"400":{"description":"Schema validation failed"},"409":{"description":"Schema already exists"},"500":{"description":"Internal server error"}}},"get":{"tags":["Workflow Data Schemas"],"summary":"List workflow data schemas","description":"Retrieves all schemas with optional filtering","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"query","name":"workflowTemplateId","schema":{"type":"string","format":"uuid"},"description":"Filter by workflow template ID"},{"in":"query","name":"schemaCode","schema":{"type":"string"},"description":"Filter by schema code"},{"in":"query","name":"isActive","schema":{"type":"boolean"},"description":"Filter by active status"},{"in":"query","name":"createdAfter","schema":{"type":"string","format":"date-time"},"description":"Filter schemas created after date"},{"in":"query","name":"createdBefore","schema":{"type":"string","format":"date-time"},"description":"Filter schemas created before date"}],"responses":{"200":{"description":"List of schemas retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object","properties":{"count":{"type":"integer"}}}}}}}},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-schemas/{id}":{"get":{"tags":["Workflow Data Schemas"],"summary":"Get workflow data schema by ID","description":"Retrieves a specific schema definition by its ID","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Schema ID"}],"responses":{"200":{"description":"Schema retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"404":{"description":"Schema not found"},"500":{"description":"Internal server error"}}},"put":{"tags":["Workflow Data Schemas"],"summary":"Update workflow data schema","description":"Updates an existing schema definition","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Schema ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entityDefinitions":{"type":"array","description":"Updated entity definitions"},"validationRules":{"type":"array","description":"Updated validation rules"},"computedFields":{"type":"array","description":"Updated computed fields"},"stateTransitions":{"type":"object","description":"Updated state transitions"},"isActive":{"type":"boolean","description":"Active status"}}}}}},"responses":{"200":{"description":"Schema updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"}}}}}},"400":{"description":"Validation failed"},"404":{"description":"Schema not found"},"500":{"description":"Internal server error"}}},"delete":{"tags":["Workflow Data Schemas"],"summary":"Delete workflow data schema","description":"Deletes a schema definition if no active instances exist","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Schema ID"}],"responses":{"204":{"description":"Schema deleted successfully"},"404":{"description":"Schema not found"},"409":{"description":"Schema has active instances"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-schemas/{id}/migrate":{"post":{"tags":["Workflow Data Schemas"],"summary":"Migrate schema version","description":"Migrates a schema to a new version with data transformation","security":[{"ApiKeyAuth":[]}],"parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Schema ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["newVersion"],"properties":{"newVersion":{"type":"string","description":"Target version for migration","example":"2.0.0"},"migrations":{"type":"array","description":"Migration operations","items":{"type":"object","properties":{"type":{"type":"string","enum":["add_field","remove_field","rename_field","transform_field"]},"entity":{"type":"string"},"field":{"type":"object"}}}}}}}}},"responses":{"200":{"description":"Schema migrated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object"},"message":{"type":"string"}}}}}},"404":{"description":"Schema not found"},"409":{"description":"Migration error"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-data-schemas/validate":{"post":{"tags":["Workflow Data Schemas"],"summary":"Validate schema definition","description":"Validates a schema definition without persisting it","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["entityDefinitions"],"properties":{"entityDefinitions":{"type":"array","description":"Entity definitions to validate","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"Validation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"isValid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object"}},"warnings":{"type":"array","items":{"type":"object"}},"validatedAt":{"type":"string","format":"date-time"}}}}}}}},"500":{"description":"Internal server error"}}}},"/api/v1/workflows/{workflowId}/children":{"get":{"summary":"Get child workflows","description":"Retrieves all child workflows for a parent workflow in a hierarchical structure.\nReturns empty array if workflow has no children.\n\nOptionally includes aggregated progress metrics for all children when\nincludeProgress=true query parameter is provided.\n","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Parent workflow ID"},{"in":"query","name":"includeProgress","schema":{"type":"boolean","default":false},"description":"Include aggregated family progress metrics"}],"responses":{"200":{"description":"Child workflows retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"parent":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"}}},"children":{"type":"array","items":{"type":"object"}},"familyProgress":{"type":"object","nullable":true,"properties":{"totalChildren":{"type":"integer"},"completedChildren":{"type":"integer"},"averageProgress":{"type":"number"},"childProgress":{"type":"array"},"lastCalculated":{"type":"string","format":"date-time"}}},"totalChildren":{"type":"number"},"workflowId":{"type":"string","format":"uuid"}}}}}}}},"404":{"description":"Workflow not found"}}}},"/api/v1/workflows/{workflowId}/parent":{"get":{"summary":"Get parent workflow","description":"Retrieves the parent workflow for a child workflow in a hierarchical structure.\nReturns null if workflow has no parent (i.e., is a root workflow).\n","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Child workflow ID"}],"responses":{"200":{"description":"Parent workflow retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"parent":{"type":"object","nullable":true},"child":{"type":"object"},"workflowId":{"type":"string","format":"uuid"},"isRoot":{"type":"boolean"}}}}}}}},"404":{"description":"Workflow not found"}}}},"/api/v1/workflows/{workflowId}/family":{"get":{"summary":"Get complete workflow family tree","description":"Retrieves the complete family tree structure for a workflow, including all ancestors and descendants.\nAlways returns the root workflow and complete hierarchy, regardless of which workflow ID is provided.\n\nUseful for displaying organizational charts, breadcrumb navigation, and understanding\nthe complete context of a workflow within its family.\n","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Any workflow ID within the family tree"},{"in":"query","name":"maxDepth","schema":{"type":"integer","default":10,"minimum":1,"maximum":10},"description":"Maximum depth to traverse in the hierarchy"},{"in":"query","name":"includeProgress","schema":{"type":"boolean","default":false},"description":"Include aggregated family progress metrics"}],"responses":{"200":{"description":"Workflow family tree retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"root":{"type":"object","description":"The root workflow of the family"},"allWorkflows":{"type":"array","description":"Flat array of all workflows in family","items":{"type":"object"}},"depth":{"type":"integer","description":"Maximum depth of the tree"},"totalCount":{"type":"integer","description":"Total number of workflows in family"},"hierarchy":{"type":"object","description":"Nested tree structure"},"familyProgress":{"type":"object","nullable":true,"description":"Aggregated progress for root workflow"}}}}}}}},"404":{"description":"Workflow not found"}}}},"/api/v1/workflows/{workflowId}/stages":{"get":{"tags":["Workflow Stages"],"summary":"List workflow stages","description":"Retrieves all stages for a specific workflow, ordered by sequence.\nIncludes stage status, assignments, timing, and completion details.\n\n**Norwegian Real Estate Use Cases:**\n- Monitor property acquisition stage progress\n- Track tenant onboarding step completion\n- View maintenance workflow stage status\n- Audit stage execution timeline\n\n**Stage Information:** Full stage details including assignments, timing, and external integrations\n**Ordering:** Stages returned in sequential workflow order\n","operationId":"getWorkflowStages","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"description":"Workflow ID","schema":{"type":"string","format":"uuid"},"example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"status","in":"query","description":"Filter by stage status","schema":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"]},"example":"IN_PROGRESS"}],"responses":{"200":{"description":"Workflow stages retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowStage"}}}},"example":{"data":[{"id":"456e7890-e89b-12d3-a456-426614174000","stageCode":"legal-review","stageName":"Legal Due Diligence","sequenceOrder":1,"status":"COMPLETED","assignedToType":"ROLE","assignedToId":"legal-counsel","assignedToName":"Legal Department","startedAt":"2024-01-15T09:00:00.000Z","completedAt":"2024-01-20T17:30:00.000Z","durationMinutes":7350,"completionNotes":"All legal documents reviewed. Clear title confirmed."},{"id":"789e0123-e89b-12d3-a456-426614174000","stageCode":"technical-assessment","stageName":"Technical Assessment","sequenceOrder":2,"status":"IN_PROGRESS","assignedToType":"ROLE","assignedToId":"technical-manager","startedAt":"2024-01-21T08:00:00.000Z","dueDate":"2024-01-28T17:00:00.000Z"}]}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}":{"get":{"tags":["Workflow Stages"],"summary":"Get workflow stage details","description":"Retrieves detailed information about a specific workflow stage,\nincluding stage definition, tasks, timing, and completion details.\n\n**Norwegian Real Estate Use Cases:**\n- Review legal due diligence stage details\n- Monitor technical assessment progress\n- Check financial analysis completion\n- Audit stage execution timeline\n\n**Includes:** Stage definition, associated tasks, timing metrics, and external service integrations\n","operationId":"getWorkflowStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"},"example":"456e7890-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"Workflow stage details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowStage"}}},"example":{"data":{"id":"456e7890-e89b-12d3-a456-426614174000","workflowId":"123e4567-e89b-12d3-a456-426614174000","stageCode":"legal-review","stageName":"Legal Due Diligence","sequenceOrder":1,"status":"COMPLETED","isMilestone":true,"isBlocking":true,"isOptional":false,"assignedToType":"ROLE","assignedToId":"legal-counsel","assignedToName":"Legal Department","scheduledAt":"2024-01-15T09:00:00.000Z","startedAt":"2024-01-15T09:00:00.000Z","completedAt":"2024-01-20T17:30:00.000Z","dueDate":"2024-01-22T17:00:00.000Z","durationMinutes":7350,"completionNotes":"All legal documents reviewed. Clear title confirmed.","context":{"documentsReviewed":15,"legalIssuesFound":0,"approvalStatus":"approved"},"stageDefinition":{"code":"legal-review","name":"Legal Due Diligence","description":"Comprehensive legal review of property documents","canBeSkipped":false,"requiresAssignment":true},"tasks":[{"id":"task-001","name":"Review property deed","status":"COMPLETED","priority":"HIGH"}]}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Workflow Stages"],"summary":"Update workflow stage","description":"Updates workflow stage properties such as status, assignment, scheduling,\nand completion details. Validates status transitions and business rules.\n\n**Norwegian Real Estate Use Cases:**\n- Assign legal review to specific counsel\n- Update technical assessment due date\n- Change stage status based on external factors\n- Add completion notes and context\n\n**Status Transitions:** Validates business rules for status changes\n**Assignment Updates:** Allows reassignment with proper validation\n**Context Updates:** Supports adding stage-specific business data\n","operationId":"updateWorkflowStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowStageRequest"},"examples":{"assignStage":{"summary":"Assign Stage to Team Member","value":{"assignedToType":"USER","assignedToId":"maria.hansen@apart.no","assignedToName":"Maria Hansen","scheduledAt":"2024-01-25T09:00:00.000Z","dueDate":"2024-01-30T17:00:00.000Z"}},"updateStatus":{"summary":"Mark Stage as In Progress","value":{"status":"IN_PROGRESS"}},"completeStage":{"summary":"Complete Stage with Notes","value":{"status":"COMPLETED","completionNotes":"Technical assessment completed. Property meets all requirements."}}}}}},"responses":{"200":{"description":"Workflow stage updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowStage"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"422":{"description":"Invalid status transition or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_STATUS_TRANSITION","message":"Cannot change stage status from COMPLETED to IN_PROGRESS."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/start":{"post":{"tags":["Workflow Stages"],"summary":"Start workflow stage","description":"Starts a workflow stage by changing status to IN_PROGRESS and optionally\nassigning it to a team member. Validates that stage is ready to start.\n\n**Norwegian Real Estate Use Cases:**\n- Begin legal due diligence review\n- Start technical property assessment\n- Initiate financial analysis stage\n\n**Validation:** Ensures stage is in READY or PENDING status\n**Assignment:** Optionally assigns stage to specific team member\n**Timing:** Records start timestamp for duration tracking\n","operationId":"startWorkflowStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartWorkflowStageRequest"},"example":{"assignedToType":"USER","assignedToId":"erik.nordahl@apart.no","assignedToName":"Erik Nordahl"}}}},"responses":{"200":{"description":"Workflow stage started successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowStage"}}}}}},"400":{"description":"Stage cannot be started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_ALREADY_STARTED","message":"Stage is already in progress or completed."}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/complete":{"post":{"tags":["Workflow Stages"],"summary":"Complete workflow stage","description":"Completes a workflow stage by changing status to COMPLETED and recording\ncompletion timestamp and notes. Automatically advances workflow to next stage.\n\n**Auto-Advancement Feature:**\nWhen `rules.autoAdvance` is enabled in the workflow template, stages can be\nautomatically completed when all associated tasks are finished. This provides\nseamless workflow progression without manual intervention.\n\n**Norwegian Real Estate Use Cases:**\n- Complete legal due diligence with findings\n- Finish technical assessment with report\n- Close financial analysis with recommendations\n\n**Validation:** Ensures stage is in progress or ready\n**Progression:** Automatically starts next stage if applicable\n**Documentation:** Records completion notes for audit trail\n**Auto-Advance:** Tasks completion triggers automatic stage advancement when enabled\n","operationId":"completeWorkflowStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteWorkflowStageRequest"},"example":{"completionNotes":"Legal review completed successfully. All documents verified and approved. No legal issues identified."}}}},"responses":{"200":{"description":"Workflow stage completed successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowStage"}}}}}},"400":{"description":"Stage cannot be completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_NOT_STARTED","message":"Cannot complete stage that has not been started."}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/skip":{"post":{"tags":["Workflow Stages"],"summary":"Skip workflow stage","description":"Skips a workflow stage by changing status to SKIPPED with a required reason.\nOnly optional stages or stages that allow skipping can be skipped.\n\n**Norwegian Real Estate Use Cases:**\n- Skip optional environmental assessment for certain properties\n- Skip additional inspections for recently inspected properties\n- Skip certain legal checks for internal transfers\n\n**Validation:** Ensures stage can be skipped based on definition\n**Reason Required:** Must provide business justification for skipping\n**Progression:** Automatically advances to next stage if applicable\n","operationId":"skipWorkflowStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkipWorkflowStageRequest"},"example":{"skipReason":"Property environmental assessment not required for this type of commercial building."}}}},"responses":{"200":{"description":"Workflow stage skipped successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowStage"}}}}}},"400":{"description":"Stage cannot be skipped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_CANNOT_BE_SKIPPED","message":"This stage is required and cannot be skipped."}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/scheduled-transition":{"get":{"tags":["Workflow Stages"],"summary":"Get scheduled transition details","description":"Retrieves scheduled transition information for a workflow stage,\nincluding the calculated transition date and configuration.\n\n**Norwegian Real Estate Use Cases:**\n- Check when legal review will auto-complete\n- Monitor scheduled inspection transitions\n- View automatic stage progression timeline\n","operationId":"getScheduledTransition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Scheduled transition details retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"stageId":{"type":"string","format":"uuid"},"scheduledTransitionAt":{"type":"string","format":"date-time"},"autoTransitionType":{"type":"string","enum":["DATE_BASED","DURATION_BASED"]},"autoTransitionProcessed":{"type":"boolean"},"currentStatus":{"type":"string"}}}}}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"put":{"tags":["Workflow Stages"],"summary":"Update scheduled transition","description":"Updates or sets a scheduled transition date for a workflow stage.\nCan be used to reschedule automatic transitions or set custom dates.\n\n**Norwegian Real Estate Use Cases:**\n- Reschedule automatic inspection based on availability\n- Adjust legal review completion based on holidays\n- Override calculated transition dates for special cases\n","operationId":"updateScheduledTransition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scheduledTransitionAt":{"type":"string","format":"date-time","description":"New scheduled transition date"}}},"example":{"scheduledTransitionAt":"2024-02-01T09:00:00.000Z"}}}},"responses":{"200":{"description":"Scheduled transition updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"},"scheduledTransitionAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Workflow Stages"],"summary":"Cancel scheduled transition","description":"Cancels a scheduled automatic transition for a workflow stage.\nThe stage will remain in its current state and require manual progression.\n\n**Norwegian Real Estate Use Cases:**\n- Cancel automatic completion when manual review needed\n- Stop scheduled transition due to external dependencies\n- Override automation for critical decision points\n","operationId":"cancelScheduledTransition","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Scheduled transition cancelled successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/process-scheduled-transitions":{"post":{"tags":["Workflow Stages"],"summary":"Process scheduled transitions","description":"Manually trigger processing of scheduled transitions that are due.\nThis endpoint is typically called by a cron job or admin action.\n\n**Norwegian Real Estate Use Cases:**\n- Manual trigger for scheduled transitions during maintenance\n- Force immediate processing of due transitions\n- Admin override for batch processing\n","operationId":"processScheduledTransitions","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"responses":{"200":{"description":"Scheduled transitions processed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"processed":{"type":"integer","description":"Number of transitions processed successfully"},"failed":{"type":"integer","description":"Number of transitions that failed"},"errors":{"type":"array","items":{"type":"object","properties":{"stageId":{"type":"string"},"error":{"type":"string"}}}}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/child-workflow":{"get":{"tags":["Workflow Stages"],"summary":"Get child workflow created by stage","description":"Retrieves the child workflow that was created by a WORKFLOW-type stage.\nReturns 404 if the stage hasn't created a child workflow or if the stage is not a WORKFLOW-type stage.\n\n**Norwegian Real Estate Use Cases:**\n- Check if a legal review stage has spawned a child workflow\n- Verify child workflow creation for multi-level processes\n- Monitor nested workflow hierarchies\n","operationId":"getStageChildWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Child workflow details retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}}}}},"404":{"description":"Stage not found or has not created a child workflow","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"CHILD_WORKFLOW_NOT_FOUND","message":"This stage has not created a child workflow."}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-stages/{id}/recurrence":{"get":{"tags":["Workflow Stages"],"summary":"Get recurrence status for a RECURRING stage","description":"Retrieves the recurrence status for a RECURRING stage type.\n\n**Norwegian Real Estate Use Cases:**\n- Monitor compliance check schedule\n- View remaining recurrence cycles\n- Check next scheduled task creation\n\n**Status Information:** Next recurrence date, end date, and task count\n","operationId":"getStageRecurrenceStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Recurrence status retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"nextRecurrenceAt":{"type":"string","format":"date-time","nullable":true},"recurrenceEndsAt":{"type":"string","format":"date-time","nullable":true},"recurrenceTaskCount":{"type":"integer"},"isActive":{"type":"boolean"}}}}}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}},"patch":{"tags":["Workflow Stages"],"summary":"Update recurrence end date for early termination","description":"Updates the recurrence end date for a RECURRING stage type.\nSetting the end date to the past or now will immediately terminate the recurrence.\n\n**Norwegian Real Estate Use Cases:**\n- Terminate compliance monitoring when relationship ends\n- Adjust recurring check schedule\n- End periodic reviews early\n\n**Validation:** Only works for IN_PROGRESS stages\n","operationId":"updateStageRecurrenceEndDate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["endDate"],"properties":{"endDate":{"type":"string","format":"date-time","description":"New recurrence end date"},"reason":{"type":"string","maxLength":500,"description":"Optional reason for the change"}}},"example":{"endDate":"2024-12-31T23:59:59.000Z","reason":"Customer relationship terminated"}}}},"responses":{"200":{"description":"Recurrence end date updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Invalid request or stage state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{workflowId}/stages/{stageId}/transition":{"post":{"tags":["Workflow Stages"],"summary":"Transition to a specific stage","description":"Performs a non-linear transition to a specific target stage. Supports forward\n(skipping intermediate stages), backward (re-entering previous stages), and\nterminate (early termination via global target) transitions.\n\nFor FORWARD/BACKWARD: The current stage must have `allowed_next_stages` configured\nthat includes the target stage's stage_code.\n\nFor TERMINATE: Stages with `is_global_target=true` can be transitioned to from any\nstage, bypassing `allowed_next_stages` validation. If the global target has\n`stage_type=COMPLETION`, the workflow completes normally (orderly completion).\nOtherwise, all open tasks are cancelled and the workflow is set to CANCELLED\n(early termination).\n\nStage re-entry behavior is controlled by the target stage's `stage_reentry_behavior`:\n- `LEAVE_TASKS`: Tasks are left as-is\n- `RESET_TASKS`: Tasks are reset to PENDING\n- `CREATE_FRESH_TASKS`: Old tasks are marked, new tasks created from template\n","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"The target stage ID to transition to"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["actor","actorType","actorName"],"properties":{"actor":{"type":"string","maxLength":255},"actorType":{"type":"string","enum":["USER","SYSTEM","SERVICE","AUTOMATION"]},"actorName":{"type":"string","maxLength":255},"reason":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"Transition completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"fromStageId":{"type":"string","format":"uuid"},"toStageId":{"type":"string","format":"uuid"},"transitionType":{"type":"string","enum":["FORWARD","BACKWARD","TERMINATE"]},"resetStageIds":{"type":"array","items":{"type":"string","format":"uuid"}},"workflowCompleted":{"type":"boolean"},"terminationType":{"type":"string","enum":["ORDERLY_COMPLETION","EARLY_TERMINATION"],"description":"Present only for TERMINATE transitions"}}}}}}}},"400":{"description":"Invalid request"},"404":{"description":"Workflow or stage not found"},"422":{"description":"Transition not allowed"}}}},"/api/v1/workflows/{workflowId}/transition-history":{"get":{"tags":["Workflow Stages"],"summary":"Get workflow transition history","description":"Returns the history of stage transitions for a workflow, ordered by most recent first.","parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"}},{"in":"query","name":"page","schema":{"type":"integer","minimum":1,"default":1}},{"in":"query","name":"limit","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Transition history retrieved successfully"},"404":{"description":"Workflow not found"}}}},"/api/v1/workflows/{workflowId}/parallel-status":{"get":{"tags":["Workflow Stages"],"summary":"Get parallel execution status","description":"Returns the parallel execution status for a workflow, including\nactive branches, completion status per branch, and join condition progress.\n","operationId":"getParallelStatus","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Parallel status retrieved successfully"},"404":{"$ref":"#/components/responses/NotFoundError"}}}},"/api/v1/workflow-templates":{"get":{"tags":["Workflow Templates"],"summary":"List workflow templates","description":"Retrieves a paginated list of workflow templates for the authenticated organization.\nWorkflow templates serve as reusable blueprints for creating standardized business processes\nwith predefined stages, rules, and configurations.\n\n## Business Logic: Template Management\n\n**Template Lifecycle:**\n- Templates define reusable workflow structures with versioned configurations\n- Each template contains ordered stages with specific business rules and validation\n- Version control (major.minor) allows for template evolution while maintaining backwards compatibility\n- Active/inactive status controls template availability for new workflow instantiation\n- Usage statistics track template effectiveness and adoption rates\n\n**Template Categories:**\n- `real-estate`: Property acquisition, sales, and management processes\n- `tenant-management`: Onboarding, renewals, and offboarding workflows\n- `maintenance`: Property maintenance, inspection, and repair processes\n- `compliance`: Regulatory, legal, and audit workflows\n- `financial`: Budgeting, approval, and payment processes\n- `marketing`: Campaign execution and lead nurturing workflows\n\n**Norwegian Real Estate Industry Applications:**\n- **Property Acquisition**: Multi-stage due diligence, legal review, and closing processes\n- **Tenant Onboarding**: Document collection, background checks, lease signing, and move-in coordination\n- **Maintenance Workflows**: Inspection scheduling, contractor coordination, and completion verification\n- **Compliance Management**: Regulatory reporting, safety inspections, and audit trails\n- **Rental Management**: Lease renewals, rent adjustments, and tenant communications\n\n**Template Configuration Features:**\n- **Stage Definitions**: Ordered sequence of workflow steps with dependencies\n- **Business Rules**: Auto-advancement, parallel processing, and validation logic\n- **Assignment Logic**: Default role, position, or user assignments for each stage\n- **Duration Management**: Expected completion times and escalation triggers\n- **Event Publishing**: Integration with notification and external systems\n- **Metadata Storage**: Custom properties for template categorization and behavior\n\n**Usage Analytics:**\n- Stage count indicates template complexity and resource requirements\n- Workflow count shows template adoption and business value\n- Version tracking enables process improvement and compliance auditing\n","operationId":"getWorkflowTemplates","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"category","in":"query","description":"Filter templates by business category. Categories help organize templates\nby business function and enable role-based access control.\n","schema":{"type":"string","enum":["real-estate","tenant-management","maintenance","compliance","financial","marketing"]},"examples":{"real-estate":{"value":"real-estate","summary":"Property-related workflows"},"tenant-management":{"value":"tenant-management","summary":"Tenant lifecycle processes"},"maintenance":{"value":"maintenance","summary":"Property maintenance workflows"}}},{"name":"isActive","in":"query","description":"Filter by template active status. Only active templates can be used\nto create new workflow instances. Inactive templates remain accessible\nfor existing workflows but cannot spawn new instances.\n","schema":{"type":"boolean"},"examples":{"active-only":{"value":true,"summary":"Show only active templates"},"inactive-only":{"value":false,"summary":"Show only inactive templates"},"all-templates":{"summary":"Show all templates (default)"}}},{"name":"code","in":"query","description":"Filter templates by unique template code. Returns at most one template\nsince codes are unique per organization.\n","schema":{"type":"string"},"examples":{"move-in":{"value":"move_in","summary":"Filter by move-in workflow template"},"property-acquisition":{"value":"property-acquisition-commercial-v2","summary":"Filter by property acquisition template"}}}],"responses":{"200":{"description":"Workflow templates retrieved successfully. Returns paginated list of templates\nwith complete configuration details, stage information, and usage statistics.\n","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowTemplate"},"description":"Array of workflow templates with complete details"},"meta":{"$ref":"#/components/schemas/PaginationMeta","description":"Pagination metadata for result set navigation"}}},"examples":{"property-acquisition-templates":{"summary":"Property Acquisition Templates","description":"Templates for various property acquisition scenarios","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440001","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"property-acquisition-commercial-v2","name":"Commercial Property Acquisition v2.1","description":"Enhanced commercial property acquisition process with digital due diligence and compliance automation","category":"real-estate","versionMajor":2,"versionMinor":1,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"rules":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":false,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true},"metadata":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor"],"complianceLevel":"enhanced"},"stageCount":7,"workflowCount":23,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440010","topicName":"property-acquisition-events"},"createdAt":"2024-01-15T09:00:00.000Z","createdBy":"system@apart.no","updatedAt":"2024-01-20T14:30:00.000Z","updatedBy":"admin@apart.no"},{"id":"550e8400-e29b-41d4-a716-446655440002","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"property-acquisition-residential","name":"Residential Property Acquisition","description":"Streamlined acquisition process for residential properties with standard due diligence","category":"real-estate","versionMajor":1,"versionMinor":3,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"rules":{"autoAdvance":true,"requireAllStages":false,"allowParallelStages":true,"maxDurationDays":45,"approvalRequired":false},"metadata":{"complexity":"medium","averageDuration":"35 days","targetEntityTypes":["residential_property"],"requiredRoles":["acquisition_specialist"]},"stageCount":5,"workflowCount":67,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440011","topicName":"residential-acquisition-events"},"createdAt":"2024-01-10T08:30:00.000Z","createdBy":"template.admin@apart.no","updatedAt":"2024-01-18T16:45:00.000Z","updatedBy":"process.manager@apart.no"}],"meta":{"total":35,"page":1,"limit":20}}},"tenant-management-templates":{"summary":"Tenant Management Templates","description":"Templates for tenant lifecycle management processes","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440003","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"tenant-onboarding-corporate-v3","name":"Corporate Tenant Onboarding v3.0","description":"Digital-first onboarding process for corporate tenants with automated background checks and document processing","category":"tenant-management","versionMajor":3,"versionMinor":0,"isActive":true,"validFrom":"2024-02-01","validUntil":null,"publishEvents":true,"rules":{"autoAdvance":false,"requireAllStages":true,"digitalFirst":true,"backgroundCheckRequired":true,"maxDurationDays":14},"metadata":{"complexity":"medium","averageDuration":"10 days","targetEntityTypes":["corporate_tenant"],"requiredRoles":["tenant_coordinator","background_specialist"],"automationLevel":"high"},"stageCount":6,"workflowCount":12,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440012","topicName":"tenant-onboarding-events"},"createdAt":"2024-02-01T10:00:00.000Z","createdBy":"tenant.admin@apart.no","updatedAt":"2024-02-01T10:00:00.000Z","updatedBy":"tenant.admin@apart.no"},{"id":"550e8400-e29b-41d4-a716-446655440004","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"tenant-renewal-standard","name":"Standard Lease Renewal Process","description":"Automated lease renewal workflow with rent adjustment calculations and documentation updates","category":"tenant-management","versionMajor":2,"versionMinor":2,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"rules":{"autoAdvance":true,"requireAllStages":false,"rentCalculationEnabled":true,"maxDurationDays":30},"metadata":{"complexity":"low","averageDuration":"21 days","targetEntityTypes":["lease_renewal"],"requiredRoles":["lease_manager"],"automationLevel":"high"},"stageCount":4,"workflowCount":156,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440013","topicName":"lease-renewal-events"},"createdAt":"2024-01-05T12:00:00.000Z","createdBy":"lease.admin@apart.no","updatedAt":"2024-01-25T09:30:00.000Z","updatedBy":"lease.manager@apart.no"}],"meta":{"total":18,"page":1,"limit":20}}},"maintenance-templates":{"summary":"Maintenance and Inspection Templates","description":"Templates for property maintenance and inspection workflows","value":{"data":[{"id":"550e8400-e29b-41d4-a716-446655440005","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"annual-inspection-comprehensive","name":"Comprehensive Annual Property Inspection","description":"Detailed annual inspection workflow covering safety, maintenance, and compliance requirements","category":"maintenance","versionMajor":1,"versionMinor":4,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"rules":{"autoAdvance":false,"requireAllStages":true,"inspectionRequired":true,"photosRequired":true,"maxDurationDays":21},"metadata":{"complexity":"high","averageDuration":"18 days","targetEntityTypes":["property_inspection"],"requiredRoles":["inspection_coordinator","maintenance_specialist"],"complianceLevel":"regulatory"},"stageCount":8,"workflowCount":89,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440014","topicName":"inspection-events"},"createdAt":"2024-01-01T08:00:00.000Z","createdBy":"maintenance.admin@apart.no","updatedAt":"2024-01-15T11:20:00.000Z","updatedBy":"inspection.manager@apart.no"}],"meta":{"total":12,"page":1,"limit":20}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError","description":"Bad request due to invalid query parameters such as:\n- Invalid pagination parameters (page < 1, limit > 100)\n- Invalid boolean value for isActive parameter\n- Unsupported category value\n"},"401":{"$ref":"#/components/responses/UnauthorizedError","description":"Authentication failed. This occurs when:\n- API key is missing or invalid\n- Bearer token has expired or is malformed\n- User lacks access to organization resources\n"},"500":{"$ref":"#/components/responses/InternalServerError","description":"Internal server error occurred during template retrieval.\nThis may be due to database connectivity issues or\nunexpected system errors during query processing.\n"}}},"post":{"tags":["Workflow Templates"],"summary":"Create comprehensive workflow template with advanced configuration","description":"Creates a new workflow template that serves as a reusable blueprint for consistent business process automation.\nThis endpoint establishes the foundation for standardized workflow execution with sophisticated configuration rules,\nevent publishing capabilities, versioning control, and metadata management essential for enterprise-grade\nbusiness process orchestration.\n\n## Business Logic\n\n**Template Blueprint Creation:**\nThe endpoint creates a comprehensive workflow template that defines the structure, rules, and behavior patterns\nfor all workflow instances created from this template. Templates encapsulate business process knowledge,\nensuring consistent execution across multiple workflow instantiations while providing flexibility through\nconfiguration overrides and rule-based customization.\n\n**Code Uniqueness Validation:**\nTemplate codes must be unique within the organization scope to prevent conflicts and ensure reliable template\nidentification. The system validates code uniqueness before creation, maintaining referential integrity\nacross the template management system.\n\n**Version Control Management:**\nTemplates support semantic versioning with major and minor version numbers, enabling controlled evolution\nof business processes. Version management supports template lifecycle planning, change impact analysis,\nand backward compatibility maintenance for existing workflow instances.\n\n**Configuration Rules Framework:**\nTemplates define comprehensive rule sets governing workflow behavior including auto-advancement policies,\nstage completion requirements, parallel processing capabilities, duration limits, approval mechanisms,\nand digital-first preferences. These rules establish the operational framework for all derived workflows.\n\n**Event Publishing Integration:**\nTemplates can be configured for automatic event publishing to Google Pub/Sub topics, enabling real-time\nworkflow monitoring, external system integration, and business intelligence data collection. Event publishing\nsupports distributed architectures and microservices integration patterns.\n\n**Metadata Management:**\nTemplates support rich metadata structures for business context storage including complexity indicators,\nduration estimates, target entity types, required roles, compliance levels, and automation preferences.\nMetadata enhances template discoverability and supports intelligent workflow routing.\n\n## Norwegian Real Estate Applications\n\n**Property Acquisition Templates:**\n- Create comprehensive acquisition process templates with legal due diligence, technical inspection, financial analysis, and regulatory compliance stages\n- Define parallel processing for independent verification activities while maintaining sequential dependencies for critical path activities\n- Establish approval workflows for acquisition committee reviews and stakeholder sign-offs\n- Configure event publishing for acquisition milestone tracking and portfolio management system integration\n\n**Tenant Management Templates:**\n- Build standardized onboarding templates with document verification, background checks, lease preparation, and move-in coordination stages\n- Design lease renewal templates with rent calculation, negotiation, documentation update, and tenant communication workflows\n- Create tenant exit templates with inspection scheduling, damage assessment, deposit processing, and unit preparation stages\n- Implement tenant service request templates with priority routing, vendor assignment, and completion verification\n\n**Property Maintenance Templates:**\n- Develop preventive maintenance templates with inspection scheduling, vendor coordination, work execution, and quality verification\n- Create emergency response templates with immediate assessment, contractor dispatch, temporary solutions, and permanent repairs\n- Design seasonal maintenance templates with preparation activities, execution schedules, and completion validation\n- Build compliance inspection templates with regulatory requirements, documentation standards, and remediation workflows\n\n**Investment Management Templates:**\n- Create portfolio analysis templates with market research, financial modeling, risk assessment, and investment decision stages\n- Design property valuation templates with comparable analysis, income approach calculations, and market condition assessments\n- Build renovation project templates with scope definition, contractor selection, execution monitoring, and completion certification\n- Implement asset disposition templates with market preparation, marketing execution, negotiation management, and transaction closure\n\n## Template Configuration Features\n\n**Rule-Based Workflow Control:**\nTemplates define sophisticated rule systems controlling workflow execution patterns including automatic stage advancement,\ncompletion requirements, parallel processing permissions, and escalation triggers. Rules provide intelligent workflow\nautomation while maintaining necessary human oversight and approval points.\n\n**Flexible Versioning Strategy:**\nTemplates support both major and minor version increments enabling controlled evolution of business processes.\nMajor versions indicate significant structural changes while minor versions represent incremental improvements,\nsupporting change management and backward compatibility strategies.\n\n**Event-Driven Architecture Integration:**\nTemplates can be configured to publish events to specific Pub/Sub topics, enabling real-time workflow monitoring,\nexternal system notifications, and business intelligence data collection. Event publishing supports distributed\nsystem architectures and microservices integration patterns.\n\n**Validity Period Management:**\nTemplates support configurable validity periods with start and end dates, enabling time-based template lifecycle\nmanagement. This feature supports regulatory compliance, seasonal business processes, and controlled template\nretirement strategies.\n\n**Rich Metadata Framework:**\nTemplates support comprehensive metadata structures including business complexity indicators, average duration\nestimates, target entity type specifications, required role definitions, and automation level preferences.\nMetadata enhances template management and supports intelligent workflow routing decisions.\n\n## Security & Access Control\n\nTemplates are automatically scoped to the authenticated organization ensuring complete data isolation in the\nmulti-tenant environment. All template operations respect organizational boundaries and access control policies.\n","operationId":"createWorkflowTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","name","validFrom"],"properties":{"code":{"type":"string","minLength":3,"maxLength":100,"pattern":"^[a-z0-9-]+$","description":"Unique template identifier within organization scope. Must contain only lowercase letters,\nnumbers, and hyphens. Used for template reference and API operations.\n","example":"commercial-property-acquisition-v2"},"name":{"type":"string","minLength":3,"maxLength":255,"description":"Human-readable template name for display purposes. Should clearly describe the business\nprocess or workflow purpose for easy identification and management.\n","example":"Commercial Property Acquisition Process v2.1"},"description":{"type":"string","maxLength":1000,"description":"Detailed template description explaining the business purpose, key stages, and expected\noutcomes. Supports markdown formatting for rich documentation.\n","example":"Comprehensive acquisition process for commercial properties including legal due diligence, technical inspection, financial analysis, and regulatory compliance with enhanced digital documentation and parallel processing capabilities."},"category":{"type":"string","enum":["real-estate","tenant-management","maintenance","legal","financial","operations","compliance"],"description":"Template category for organizational and filtering purposes. Categories help organize\ntemplates by business domain and support role-based access control.\n","example":"real-estate"},"versionMajor":{"type":"integer","minimum":1,"maximum":999,"default":1,"description":"Major version number for significant structural changes. Increment when making breaking\nchanges to template structure, stages, or fundamental behavior.\n","example":2},"versionMinor":{"type":"integer","minimum":0,"maximum":999,"default":0,"description":"Minor version number for incremental improvements and non-breaking changes.\nIncrement for feature additions, rule refinements, or metadata updates.\n","example":1},"validFrom":{"type":"string","format":"date","description":"Template activation date in ISO 8601 format (YYYY-MM-DD). Template becomes available\nfor workflow creation from this date. Cannot be in the past for new templates.\n","example":"2024-01-01"},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Template expiration date in ISO 8601 format (YYYY-MM-DD). Template becomes unavailable\nfor new workflow creation after this date. Existing workflows remain unaffected. Null means no expiration.\n","example":"2024-12-31"},"publishEvents":{"type":"boolean","default":true,"description":"Enable automatic event publishing to Google Pub/Sub for workflows created from this template.\nEvents support real-time monitoring, external integrations, and business intelligence.\n","example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Optional specific Pub/Sub topic ID for event publishing. If not provided, events are\npublished to the organization's default workflow topic.\n","example":"550e8400-e29b-41d4-a716-446655440020"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Optional form template ID for collecting initialization data when instantiating workflows.\nLinks to a FormTemplate that defines the schema and validation rules for data collection.\n","example":"650e8400-f29c-51e5-b817-556655441234"},"rules":{"type":"object","description":"Configuration rules governing workflow behavior for all instances created from this template.\nRules define automation level, completion requirements, and processing patterns.\n","properties":{"autoAdvance":{"type":"boolean","default":false,"description":"Automatically advance to next stage when current stage is completed"},"requireAllStages":{"type":"boolean","default":true,"description":"Require completion of all stages for workflow completion"},"allowParallelStages":{"type":"boolean","default":false,"description":"Allow multiple stages to be active simultaneously"},"maxDurationDays":{"type":"integer","minimum":1,"maximum":3650,"description":"Maximum allowed workflow duration in days"},"approvalRequired":{"type":"boolean","default":false,"description":"Require explicit approval for workflow progression"},"digitalFirst":{"type":"boolean","default":false,"description":"Prioritize digital processes over manual ones"},"escalationEnabled":{"type":"boolean","default":true,"description":"Enable automatic escalation for overdue stages"},"notificationEnabled":{"type":"boolean","default":true,"description":"Enable automatic notifications for stage transitions"}},"example":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":false,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true}},"taskCreationStrategy":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"default":"UPFRONT","description":"Defines when tasks are created for workflow stages:\n- **UPFRONT**: Create all tasks immediately upon workflow instantiation (default)\n- **ON_STAGE_START**: Create tasks only when a stage transitions to IN_PROGRESS\n- **HYBRID**: Mixed approach based on per-stage configuration\n","example":"UPFRONT"},"assignmentInheritanceStrategy":{"type":"object","description":"Strategy for dynamically assigning tasks during workflow instantiation.\nEnables flexible task assignment based on workflow context, owner, or template defaults.\n","properties":{"mode":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","HYBRID"],"required":true,"description":"Assignment inheritance mode:\n- **WORKFLOW_OWNER**: All tasks assigned to workflow owner (personal workflows)\n- **STAGE_DEFAULT**: Tasks inherit from stage default assignee\n- **CONTEXT_BASED**: Tasks assigned based on initialization data\n- **TEMPLATE_DEFINED**: Keep original template assignments (default)\n- **HYBRID**: Mix strategies with rules by task code/role\n","example":"WORKFLOW_OWNER"},"rules":{"type":"object","description":"Rules for HYBRID mode - define per-task or per-role strategies","properties":{"byTaskCode":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"]},"description":"Override mode by specific task codes","example":{"approval-task":"WORKFLOW_OWNER","review-task":"STAGE_DEFAULT"}},"byRole":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"]},"description":"Override mode by assignee roles/types","example":{"manager":"WORKFLOW_OWNER","reviewer":"STAGE_DEFAULT"}},"fallback":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"],"description":"Fallback mode when no specific rule matches","example":"TEMPLATE_DEFINED"}}},"contextMapping":{"type":"object","description":"Context mapping configuration for CONTEXT_BASED mode","properties":{"source":{"type":"string","enum":["initializationData","entityContext"],"description":"Source of context data","example":"initializationData"},"field":{"type":"string","description":"Field name in the context data","example":"assignedUserId"},"type":{"type":"string","enum":["USER","POSITION"],"description":"Type of assignment target","example":"USER"}}}},"example":{"mode":"WORKFLOW_OWNER"}},"metadata":{"type":"object","description":"Rich metadata for template classification, analysis, and intelligent routing.\nSupports custom properties for business-specific requirements.\n","properties":{"complexity":{"type":"string","enum":["low","medium","high","critical"],"description":"Business process complexity level"},"averageDuration":{"type":"string","description":"Typical workflow completion time (human-readable)"},"targetEntityTypes":{"type":"array","items":{"type":"string"},"description":"List of entity types this template is designed for"},"requiredRoles":{"type":"array","items":{"type":"string"},"description":"List of organizational roles required for workflow execution"},"complianceLevel":{"type":"string","enum":["basic","standard","enhanced","regulatory"],"description":"Compliance and audit requirements level"},"automationLevel":{"type":"string","enum":["manual","semi-automated","automated","fully-automated"],"description":"Level of process automation"},"industry":{"type":"string","description":"Industry or business domain for template specialization"},"tags":{"type":"array","items":{"type":"string"},"description":"Custom tags for template organization and discovery"}},"example":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property","investment_property"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor","financial_analyst"],"complianceLevel":"enhanced","automationLevel":"semi-automated","industry":"commercial_real_estate","tags":["acquisition","due_diligence","investment"]}}}},"examples":{"commercial-property-acquisition":{"summary":"Commercial Property Acquisition Template","description":"Comprehensive template for commercial property acquisition with enhanced due diligence,\nregulatory compliance, and parallel processing capabilities. Designed for high-value\ncommercial real estate transactions requiring multiple stakeholder coordination.\n","value":{"code":"commercial-property-acquisition-v2","name":"Commercial Property Acquisition Process v2.1","description":"Enhanced commercial property acquisition process with digital due diligence, parallel inspections, and compliance automation for efficient high-value transaction management.","category":"real-estate","versionMajor":2,"versionMinor":1,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"eventTopicId":"550e8400-e29b-41d4-a716-446655440020","rules":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":true,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true},"metadata":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property","office_building","retail_space"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor","financial_analyst"],"complianceLevel":"enhanced","automationLevel":"semi-automated","industry":"commercial_real_estate","tags":["acquisition","due_diligence","high_value"]}}},"tenant-onboarding-standard":{"summary":"Standardized Tenant Onboarding Template","description":"Streamlined tenant onboarding template with digital document processing, automated\nbackground checks, and integrated lease preparation. Optimized for residential\nproperty management with high-volume tenant processing.\n","value":{"code":"tenant-onboarding-digital-v3","name":"Digital Tenant Onboarding Process v3.0","description":"Fully digital tenant onboarding with automated document verification, integrated background screening, electronic lease signing, and seamless move-in coordination.","category":"tenant-management","versionMajor":3,"versionMinor":0,"validFrom":"2024-02-01","validUntil":"2024-12-31","publishEvents":true,"rules":{"autoAdvance":true,"requireAllStages":true,"allowParallelStages":true,"maxDurationDays":14,"approvalRequired":false,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true},"metadata":{"complexity":"medium","averageDuration":"10 days","targetEntityTypes":["residential_tenant","corporate_tenant"],"requiredRoles":["leasing_agent","property_manager","background_specialist"],"complianceLevel":"standard","automationLevel":"automated","industry":"residential_real_estate","tags":["onboarding","digital","automated"]}}},"preventive-maintenance-annual":{"summary":"Annual Preventive Maintenance Template","description":"Comprehensive annual maintenance template covering all critical building systems,\nsafety inspections, and regulatory compliance requirements. Designed for\nmulti-property portfolio management with vendor coordination.\n","value":{"code":"preventive-maintenance-annual-v1","name":"Annual Preventive Maintenance Program","description":"Comprehensive annual maintenance program covering HVAC systems, electrical infrastructure, plumbing, safety equipment, and building envelope with integrated vendor management and compliance tracking.","category":"maintenance","versionMajor":1,"versionMinor":2,"validFrom":"2024-01-01","publishEvents":true,"rules":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":true,"maxDurationDays":45,"approvalRequired":false,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true},"assignmentInheritanceStrategy":{"mode":"WORKFLOW_OWNER"},"metadata":{"complexity":"high","averageDuration":"35 days","targetEntityTypes":["building_maintenance","system_inspection"],"requiredRoles":["maintenance_coordinator","facility_manager","system_specialist"],"complianceLevel":"regulatory","automationLevel":"semi-automated","industry":"property_management","tags":["maintenance","inspection","compliance","annual"]}}},"lease-renewal-automated":{"summary":"Automated Lease Renewal Template","description":"Highly automated lease renewal template with market rate analysis, tenant\ncommunication, negotiation support, and document generation. Optimized for\nhigh-volume lease portfolio management.\n","value":{"code":"lease-renewal-automated-v2","name":"Automated Lease Renewal Process v2.3","description":"Fully automated lease renewal workflow with market analysis, rent optimization, automated tenant communications, electronic document generation, and seamless lease execution.","category":"tenant-management","versionMajor":2,"versionMinor":3,"validFrom":"2024-01-15","publishEvents":true,"rules":{"autoAdvance":true,"requireAllStages":false,"allowParallelStages":false,"maxDurationDays":30,"approvalRequired":false,"digitalFirst":true,"escalationEnabled":false,"notificationEnabled":true},"metadata":{"complexity":"medium","averageDuration":"21 days","targetEntityTypes":["lease_renewal","rent_adjustment"],"requiredRoles":["lease_manager","revenue_analyst"],"complianceLevel":"standard","automationLevel":"fully-automated","industry":"residential_real_estate","tags":["renewal","automated","high_volume"]}}}}}}},"responses":{"201":{"description":"Workflow template created successfully with complete configuration.\nReturns the fully configured template ready for workflow instantiation with all\nrules, metadata, versioning, and event publishing settings properly established.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowTemplate","description":"Complete workflow template with all configuration details and system-generated fields"}}},"examples":{"commercial-acquisition-created":{"summary":"Commercial Property Acquisition Template Created","description":"Successfully created commercial property acquisition template with advanced configuration,\nparallel processing capabilities, and comprehensive metadata for enterprise-grade\nreal estate transaction management.\n","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440001","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"commercial-property-acquisition-v2","name":"Commercial Property Acquisition Process v2.1","description":"Enhanced commercial property acquisition process with digital due diligence, parallel inspections, and compliance automation for efficient high-value transaction management.","category":"real-estate","versionMajor":2,"versionMinor":1,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"eventTopicId":"550e8400-e29b-41d4-a716-446655440020","rules":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":true,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true},"metadata":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property","office_building","retail_space"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor","financial_analyst"],"complianceLevel":"enhanced","automationLevel":"semi-automated","industry":"commercial_real_estate","tags":["acquisition","due_diligence","high_value"]},"stageCount":0,"workflowCount":0,"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440020","topicName":"commercial-acquisition-events"},"createdAt":"2024-01-15T10:30:00.000Z","createdBy":"acquisition.manager@apart.no","updatedAt":"2024-01-15T10:30:00.000Z","updatedBy":"acquisition.manager@apart.no"}}},"tenant-onboarding-created":{"summary":"Tenant Onboarding Template Created","description":"Successfully created digital tenant onboarding template with automated processing,\ndocument verification, and integrated background screening for efficient\nhigh-volume tenant management.\n","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440002","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"tenant-onboarding-digital-v3","name":"Digital Tenant Onboarding Process v3.0","description":"Fully digital tenant onboarding with automated document verification, integrated background screening, electronic lease signing, and seamless move-in coordination.","category":"tenant-management","versionMajor":3,"versionMinor":0,"isActive":true,"validFrom":"2024-02-01","validUntil":"2024-12-31","publishEvents":true,"eventTopicId":null,"rules":{"autoAdvance":true,"requireAllStages":true,"allowParallelStages":true,"maxDurationDays":14,"approvalRequired":false,"digitalFirst":true,"escalationEnabled":true,"notificationEnabled":true},"metadata":{"complexity":"medium","averageDuration":"10 days","targetEntityTypes":["residential_tenant","corporate_tenant"],"requiredRoles":["leasing_agent","property_manager","background_specialist"],"complianceLevel":"standard","automationLevel":"automated","industry":"residential_real_estate","tags":["onboarding","digital","automated"]},"stageCount":0,"workflowCount":0,"eventTopic":null,"createdAt":"2024-02-01T09:15:00.000Z","createdBy":"leasing.admin@apart.no","updatedAt":"2024-02-01T09:15:00.000Z","updatedBy":"leasing.admin@apart.no"}}}}}}},"400":{"$ref":"#/components/responses/BadRequestError","description":"Bad request due to invalid input data such as:\n- Invalid template code format (must be lowercase alphanumeric with hyphens)\n- Invalid date formats or date range constraints\n- Invalid version numbers (must be positive integers)\n- Invalid category values or enum constraints\n- Missing required fields or empty values\n- Invalid rule combinations or configuration conflicts\n"},"401":{"$ref":"#/components/responses/UnauthorizedError","description":"Authentication failed. This occurs when:\n- API key is missing, invalid, or expired\n- Bearer token has expired or is malformed\n- User lacks sufficient permissions for template creation\n- Organization access is restricted or suspended\n"},"403":{"description":"Forbidden. Insufficient permissions for workflow template creation.\nUser lacks the required role or permissions to create templates in this organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User lacks permission to create workflow templates.","details":{"requiredPermission":"template:create","userRole":"viewer"}}}}}},"422":{"description":"Validation error due to business rule violations such as:\n- Template code already exists within the organization\n- Invalid date ranges (validFrom in past, validUntil before validFrom)\n- Invalid rule combinations or conflicting configuration settings\n- Referenced event topic does not exist or is inactive\n- Metadata constraints violation or invalid enum values\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"duplicate-code":{"summary":"Duplicate Template Code","value":{"error":{"code":"TEMPLATE_CODE_EXISTS","message":"A workflow template with this code already exists in your organization.","details":{"code":"commercial-property-acquisition-v2","existingTemplateId":"550e8400-e29b-41d4-a716-446655440001"}}}},"invalid-date-range":{"summary":"Invalid Date Range","value":{"error":{"code":"INVALID_DATE_RANGE","message":"Template validity end date must be after the start date.","details":{"validFrom":"2024-01-01","validUntil":"2023-12-31"}}}},"invalid-topic":{"summary":"Invalid Event Topic","value":{"error":{"code":"INVALID_EVENT_TOPIC","message":"The specified event topic does not exist or is not accessible.","details":{"eventTopicId":"550e8400-e29b-41d4-a716-446655440099"}}}},"rule-conflict":{"summary":"Rule Configuration Conflict","value":{"error":{"code":"RULE_CONFIGURATION_CONFLICT","message":"Cannot enable auto-advance when approval is required.","details":{"conflictingRules":["autoAdvance","approvalRequired"]}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-templates/{id}":{"get":{"tags":["Workflow Templates"],"summary":"Get comprehensive workflow template details","description":"Retrieves complete detailed information about a specific workflow template, providing the foundational blueprint\nfor business process automation. This endpoint returns the full template structure including all stage definitions,\nconfiguration rules, event publishing settings, and versioning information essential for template analysis,\nconfiguration review, and workflow instantiation preparation.\n\n## Business Logic\n\n**Template Structure Analysis:**\nThe endpoint provides complete visibility into template architecture, returning all stages with their sequence\norder, dependencies, and configuration overrides. This is essential for understanding process flow complexity,\nidentifying bottlenecks, and planning workflow optimizations.\n\n**Configuration Management:**\nReturns comprehensive rule sets governing workflow behavior including auto-advancement settings, stage requirements,\nparallel processing capabilities, duration limits, and approval mechanisms. These rules directly impact workflow\nexecution patterns and resource allocation strategies.\n\n**Version Control & Lifecycle:**\nProvides complete versioning information with major/minor version tracking, validity periods, and activation status.\nCritical for template governance, change management, and ensuring compliance with organizational standards.\n\n**Event Integration:**\nReturns event topic configuration for real-time workflow monitoring and integration with external systems.\nEssential for building responsive business process ecosystems.\n\n## Norwegian Real Estate Applications\n\n**Property Acquisition Analysis:**\n- Review complete acquisition template structure with legal, technical, and financial due diligence stages\n- Analyze stage dependencies and parallel processing opportunities\n- Examine approval workflows and compliance requirements\n- Study duration estimates and resource allocation patterns\n\n**Tenant Management Configuration:**\n- Examine onboarding process templates with document verification stages\n- Review lease management workflow structures\n- Analyze maintenance request processing templates\n- Study tenant communication and engagement workflows\n\n**Maintenance & Operations:**\n- Review preventive maintenance scheduling templates\n- Examine emergency response workflow structures\n- Analyze vendor management and procurement processes\n- Study compliance and inspection workflow templates\n\n**Template Instantiation Planning:**\n- Understand complete stage sequence for new workflow creation\n- Review configuration overrides and customization options\n- Analyze resource requirements and role assignments\n- Plan integration with existing business systems\n\n## Key Response Features\n\n**Complete Stage Definitions:**\nAll workflow template stages returned in sequence order with complete configuration including milestone markers,\nblocking behavior, optional flags, duration estimates, assignee defaults, and entry/exit conditions.\n\n**Template Configuration Rules:**\nComprehensive rule set including auto-advancement settings, stage completion requirements, parallel processing\ncapabilities, maximum duration limits, approval requirements, and digital-first preferences.\n\n**Version & Validity Information:**\nComplete versioning with major/minor numbers, validity date ranges, activation status, and template lifecycle state.\n\n**Event Publishing Settings:**\nEvent topic configuration for real-time workflow monitoring, external system integration, and business intelligence.\n\n**Usage Analytics:**\nStage count metrics and workflow instance statistics for template utilization analysis and optimization planning.\n\n## Security & Access Control\n\nTemplates are automatically filtered by organization scope ensuring data isolation. Only templates belonging to\nthe authenticated organization are accessible, maintaining multi-tenant security boundaries.\n","operationId":"getWorkflowTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique workflow template identifier. Must be a valid UUID belonging to the authenticated organization.\nUse this ID for template analysis, configuration review, or workflow instantiation operations.\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"example":"550e8400-e29b-41d4-a716-446655440001"}],"responses":{"200":{"description":"Workflow template details retrieved successfully with complete configuration.\nReturns comprehensive template information including all stages, rules, versioning,\nand event publishing settings essential for business process analysis and workflow creation.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowTemplate","description":"Complete workflow template with all stages and configuration details"}}},"examples":{"commercial-property-acquisition":{"summary":"Commercial Property Acquisition Template","description":"Comprehensive commercial property acquisition template with enhanced due diligence,\ncompliance automation, and digital-first approach. Includes 7 sequential stages\nwith blocking dependencies and approval requirements.\n","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440001","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"property-acquisition-commercial-v2","name":"Commercial Property Acquisition v2.1","description":"Enhanced commercial property acquisition process with digital due diligence and compliance automation","category":"real-estate","versionMajor":2,"versionMinor":1,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"eventTopicId":"550e8400-e29b-41d4-a716-446655440010","rules":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":false,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true},"metadata":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor"],"complianceLevel":"enhanced"},"stageCount":7,"workflowCount":23,"workflowTemplateStages":[{"id":"550e8400-e29b-41d4-a716-446655440101","templateId":"550e8400-e29b-41d4-a716-446655440001","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440201","sequenceOrder":1,"isMilestone":false,"isBlocking":true,"isOptional":false,"defaultAssigneeType":"role","defaultAssigneeId":"legal_counsel","overrideDurationDays":14,"overrideEscalationDays":21,"entryConditions":{"requiresDocuments":["purchase_agreement","property_deed"],"approvalRequired":false},"exitConditions":{"documentsVerified":true,"legalClearance":true},"createdAt":"2024-01-15T09:00:00.000Z"},{"id":"550e8400-e29b-41d4-a716-446655440102","templateId":"550e8400-e29b-41d4-a716-446655440001","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440202","sequenceOrder":2,"isMilestone":true,"isBlocking":true,"isOptional":false,"defaultAssigneeType":"role","defaultAssigneeId":"technical_assessor","overrideDurationDays":10,"overrideEscalationDays":15,"entryConditions":{"previousStageComplete":true,"accessPermission":true},"exitConditions":{"technicalReportComplete":true,"structuralAssessment":"approved"},"createdAt":"2024-01-15T09:00:00.000Z"},{"id":"550e8400-e29b-41d4-a716-446655440103","templateId":"550e8400-e29b-41d4-a716-446655440001","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440203","sequenceOrder":3,"isMilestone":false,"isBlocking":false,"isOptional":true,"defaultAssigneeType":"user","defaultAssigneeId":"environmental_specialist","overrideDurationDays":7,"overrideEscalationDays":10,"entryConditions":{"environmentalRiskAssessment":"required"},"exitConditions":{"environmentalClearance":true},"createdAt":"2024-01-15T09:00:00.000Z"}],"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440010","topicName":"property-acquisition-events"},"createdAt":"2024-01-15T09:00:00.000Z","createdBy":"system@apart.no","updatedAt":"2024-01-20T14:30:00.000Z","updatedBy":"admin@apart.no"}}},"tenant-onboarding-residential":{"summary":"Residential Tenant Onboarding Template","description":"Streamlined residential tenant onboarding template with digital document processing,\nautomated background checks, and lease activation. Designed for efficiency with\nparallel stage processing and optional approval workflows.\n","value":{"data":{"id":"550e8400-e29b-41d4-a716-446655440002","organizationId":"550e8400-e29b-41d4-a716-446655440000","code":"tenant-onboarding-residential-v1","name":"Residential Tenant Onboarding v1.3","description":"Streamlined onboarding process for residential tenants with digital document processing and automated verification","category":"tenant-management","versionMajor":1,"versionMinor":3,"isActive":true,"validFrom":"2024-01-01","validUntil":null,"publishEvents":true,"eventTopicId":"550e8400-e29b-41d4-a716-446655440011","rules":{"autoAdvance":true,"requireAllStages":false,"allowParallelStages":true,"maxDurationDays":14,"approvalRequired":false,"digitalFirst":true},"metadata":{"complexity":"medium","averageDuration":"7 days","targetEntityTypes":["residential_lease"],"requiredRoles":["leasing_agent"],"automationLevel":"high"},"stageCount":5,"workflowCount":142,"workflowTemplateStages":[{"id":"550e8400-e29b-41d4-a716-446655440104","templateId":"550e8400-e29b-41d4-a716-446655440002","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440204","sequenceOrder":1,"isMilestone":false,"isBlocking":false,"isOptional":false,"defaultAssigneeType":"system","defaultAssigneeId":"document_processor","overrideDurationDays":1,"overrideEscalationDays":2,"entryConditions":{"applicationReceived":true},"exitConditions":{"documentsUploaded":true,"initialValidation":"passed"},"createdAt":"2024-01-10T08:30:00.000Z"},{"id":"550e8400-e29b-41d4-a716-446655440105","templateId":"550e8400-e29b-41d4-a716-446655440002","stageDefinitionId":"550e8400-e29b-41d4-a716-446655440205","sequenceOrder":2,"isMilestone":true,"isBlocking":false,"isOptional":false,"defaultAssigneeType":"service","defaultAssigneeId":"background_check_service","overrideDurationDays":3,"overrideEscalationDays":5,"entryConditions":{"consentProvided":true},"exitConditions":{"backgroundCheckComplete":true,"creditScoreAcceptable":true},"createdAt":"2024-01-10T08:30:00.000Z"}],"eventTopic":{"id":"550e8400-e29b-41d4-a716-446655440011","topicName":"tenant-onboarding-events"},"createdAt":"2024-01-10T08:30:00.000Z","createdBy":"template.admin@apart.no","updatedAt":"2024-01-25T11:45:00.000Z","updatedBy":"process.manager@apart.no"}}}}}}},"400":{"description":"Bad request due to invalid template ID format or malformed parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_TEMPLATE_ID","message":"Template ID must be a valid UUID format","details":{"providedId":"invalid-id-format","expectedFormat":"UUID v4 (8-4-4-4-12 hexadecimal digits)"}}}}}},"401":{"description":"Authentication required. Valid API key or bearer token must be provided in request headers.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"AUTHENTICATION_REQUIRED","message":"Valid authentication credentials required to access workflow templates","details":{"supportedMethods":["API Key","Bearer Token"]}}}}}},"403":{"description":"Access forbidden. Template exists but belongs to different organization or user lacks necessary permissions.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"ACCESS_DENIED","message":"Insufficient permissions to access this workflow template","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","reason":"Template belongs to different organization"}}}}}},"404":{"description":"Workflow template not found. Template with specified ID does not exist in the authenticated organization\nor has been permanently deleted.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Workflow template not found or access denied","details":{"templateId":"550e8400-e29b-41d4-a716-446655440999","organizationId":"550e8400-e29b-41d4-a716-446655440000","suggestions":["Verify template ID is correct","Check if template was recently deleted","Ensure template belongs to your organization"]}}}}}},"500":{"description":"Internal server error occurred while retrieving template details. Database connectivity issues,\nservice unavailability, or unexpected system errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"Failed to retrieve workflow template due to system error","details":{"timestamp":"2024-01-20T14:30:00.000Z","correlationId":"req_550e8400e29b41d4a716446655440001","retryAfter":"30 seconds"}}}}}}}},"put":{"tags":["Workflow Templates"],"summary":"Update comprehensive workflow template properties and configuration","description":"Updates modifiable properties of a workflow template including metadata, configuration rules, event settings,\nand activation status. This endpoint enables template refinement, lifecycle management, and operational control\nwhile preserving template identity and versioning integrity. All updates maintain backward compatibility with\nexisting workflow instances and respect organizational data isolation.\n\n## Business Logic & Template Management\n\n**Template Property Updates:**\nModifies template metadata including name, description, and category classification for improved organization\nand searchability. These changes apply immediately to template discovery but do not affect existing workflow\ninstances, ensuring operational continuity while enabling template evolution.\n\n**Configuration Rule Management:**\nUpdates template-specific rules governing workflow behavior including auto-advancement settings, stage completion\nrequirements, parallel processing capabilities, duration limits, approval mechanisms, and digital-first preferences.\nThese rules apply to new workflow instances created after the update, with existing workflows retaining their\noriginal configuration.\n\n**Activation & Lifecycle Control:**\nManages template availability through activation status and validity period updates. Deactivating templates\nprevents new workflow creation while preserving existing workflows. Validity period adjustments support\nplanned template retirement and seasonal business processes.\n\n**Event Publishing Configuration:**\nUpdates event publication settings and topic assignments for real-time workflow monitoring and system integration.\nChanges to event configuration affect new workflows and ongoing event streams for existing workflows.\n\n**Immutable Field Protection:**\nTemplate code, version numbers (major/minor), creation timestamp, and organization ID remain immutable to preserve\ntemplate identity, ensure audit trail integrity, and maintain workflow instance relationships. Validation date\n(valid_from) is also immutable to maintain version chronology.\n\n## Norwegian Real Estate Applications\n\n**Property Acquisition Template Evolution:**\n- Update acquisition process descriptions to reflect regulatory changes\n- Modify due diligence rules based on market conditions and compliance requirements\n- Adjust approval workflows for different property value thresholds\n- Configure parallel processing for legal and technical reviews\n- Update event notifications for stakeholder communication\n\n**Tenant Management Process Refinement:**\n- Enhance onboarding templates with additional verification requirements\n- Update lease management rules for new contract types\n- Modify maintenance request processing based on tenant feedback\n- Adjust auto-advancement settings for routine vs. complex maintenance\n- Configure event publishing for tenant communication systems\n\n**Maintenance & Operations Optimization:**\n- Update preventive maintenance schedules based on seasonal requirements\n- Modify emergency response templates with updated vendor contacts\n- Adjust compliance templates for regulatory changes\n- Configure duration limits based on service level agreements\n- Update approval requirements for cost thresholds\n\n**Template Lifecycle Management:**\n- Deactivate outdated templates during system transitions\n- Update validity periods for seasonal business processes\n- Modify event configurations for new integration requirements\n- Adjust categories for improved template organization\n- Update metadata for better template discovery\n\n## Key Update Capabilities\n\n**Metadata & Organization:**\nUpdate template name, description, and category for improved discoverability and organizational alignment.\nChanges support template library management and user experience enhancement.\n\n**Business Rules Configuration:**\nComprehensive rule updates including auto-advancement behavior, stage completion requirements, parallel\nprocessing enablement, maximum duration constraints, approval workflows, and digital-first processing preferences.\n\n**Activation & Availability Control:**\nManage template availability through activation status changes and validity period adjustments. Support\nplanned template retirement and controlled template deployment.\n\n**Event Integration Management:**\nConfigure event publishing settings and topic assignments for real-time monitoring and system integration.\nEnable or disable event streams and update topic routing.\n\n**Custom Metadata Extension:**\nUpdate custom metadata fields for organization-specific template attributes and integration requirements.\nSupport flexible template categorization and business-specific configurations.\n\n## Validation & Business Constraints\n\n**Event Topic Validation:**\nWhen updating event topic assignments, the system validates topic existence and organizational ownership.\nTopics must belong to the same organization as the template to ensure data isolation and access control.\n\n**Validity Period Constraints:**\nValid until dates must not precede the template's valid from date to maintain chronological consistency.\nThe system enforces logical date relationships to prevent template availability conflicts.\n\n**Immutable Field Protection:**\nAttempts to modify template code, version numbers, creation timestamps, or organization ID are ignored\nto preserve template identity and audit trail integrity. Only mutable properties are processed.\n\n**Organization Data Isolation:**\nAll updates are scoped to the authenticated organization. Templates can only be updated by users with\nappropriate permissions within the template's owning organization.\n","operationId":"updateWorkflowTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow template to update. Must be a valid UUID\nbelonging to a template within the authenticated organization.\n","schema":{"type":"string","format":"uuid"},"example":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowTemplateRequest"},"examples":{"updateMetadata":{"summary":"Update Template Metadata","description":"Update template name, description, and category for improved organization\nand discoverability in the template library.\n","value":{"name":"Commercial Property Acquisition - Enhanced Due Diligence","description":"Comprehensive acquisition process with enhanced legal and technical due diligence requirements for commercial properties above 50M NOK","category":"real-estate-acquisition","metadata":{"propertyTypes":["office","retail","industrial"],"valuationThreshold":"50000000","jurisdiction":"norway"}}},"deactivateTemplate":{"summary":"Deactivate Template with End Date","description":"Deactivate a template to prevent new workflow creation while setting\nan explicit end date for planned template retirement.\n","value":{"isActive":false,"validUntil":"2024-12-31","metadata":{"retirementReason":"Replaced by enhanced template v2.0","replacementTemplateId":"b1ffcd22-8d1c-4ef9-aa7e-7cc0ce491b22"}}},"updateBusinessRules":{"summary":"Update Template Business Rules","description":"Modify template configuration rules to adjust workflow behavior\nfor new business requirements and process optimizations.\n","value":{"rules":{"autoAdvance":false,"requireAllStages":true,"maxDurationDays":120,"approvalRequired":true,"allowParallelProcessing":true,"digitalFirstPreferred":true,"escalationThresholdDays":7,"approvalValueThreshold":1000000},"metadata":{"rulesVersion":"2.1","lastReviewDate":"2024-01-15"}}},"updateEventConfiguration":{"summary":"Update Event Publishing Settings","description":"Configure event publishing and topic assignments for real-time\nworkflow monitoring and system integration capabilities.\n","value":{"publishEvents":true,"eventTopicId":"c2ggde33-9e2d-4ffa-bb8f-8dd1df592c33","metadata":{"eventTypes":["workflow.stage.completed","workflow.milestone.reached"],"notificationChannels":["slack","email","webhook"]}}},"comprehensiveUpdate":{"summary":"Comprehensive Template Update","description":"Example of updating multiple template properties simultaneously\nincluding metadata, rules, event settings, and lifecycle management.\n","value":{"name":"Residential Property Acquisition - Winter 2024","description":"Seasonal acquisition process optimized for Q4 2024 market conditions with enhanced financing and inspection workflows","category":"real-estate-seasonal","isActive":true,"validUntil":"2025-03-31","rules":{"autoAdvance":true,"requireAllStages":false,"maxDurationDays":90,"approvalRequired":false,"allowParallelProcessing":true,"seasonalAdjustments":true,"weatherDependentStages":["exterior-inspection","roof-assessment"]},"publishEvents":true,"eventTopicId":"d3hhef44-af3e-4ggb-cc9g-9ee2eg693d44","metadata":{"season":"winter","marketConditions":"buyer-favorable","inspectionProviders":["nordic-inspect","cold-weather-experts"],"financingPartners":["dnb","sparebank1","handelsbanken"]}}}}}}},"responses":{"200":{"description":"Workflow template updated successfully. Returns the complete updated template\nwith all current properties, configuration rules, and relationship data.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowTemplate"}}},"examples":{"updatedTemplate":{"summary":"Successfully Updated Template","value":{"data":{"id":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11","organizationId":"org-123e4567-e89b-12d3-a456-426614174000","code":"commercial-acquisition-v1","name":"Commercial Property Acquisition - Enhanced Due Diligence","description":"Comprehensive acquisition process with enhanced legal and technical due diligence requirements","category":"real-estate-acquisition","versionMajor":1,"versionMinor":2,"isActive":true,"validFrom":"2024-01-01","validUntil":"2024-12-31","rules":{"autoAdvance":false,"requireAllStages":true,"maxDurationDays":120,"approvalRequired":true,"allowParallelProcessing":true},"publishEvents":true,"eventTopicId":"c2ggde33-9e2d-4ffa-bb8f-8dd1df592c33","metadata":{"propertyTypes":["office","retail"],"jurisdiction":"norway"},"createdAt":"2024-01-01T10:00:00.000Z","createdBy":"admin@company.no","updatedAt":"2024-02-15T14:30:00.000Z","updatedBy":"manager@company.no"}}}}}}},"400":{"description":"Bad request due to invalid template ID format, malformed request body,\nor invalid property values that violate business constraints.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidTemplateId":{"summary":"Invalid Template ID Format","value":{"error":{"code":"INVALID_TEMPLATE_ID","message":"Template ID must be a valid UUID format.","details":{"providedId":"invalid-id-format","expectedFormat":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}}}},"invalidPropertyValue":{"summary":"Invalid Property Value","value":{"error":{"code":"INVALID_PROPERTY_VALUE","message":"Template name cannot be empty or exceed 255 characters.","details":{"field":"name","providedLength":300,"maxLength":255}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - Insufficient permissions to update the workflow template.\nUser may lack template management permissions or the template may belong\nto a different organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficientPermissions":{"summary":"Insufficient Template Management Permissions","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User does not have permission to update workflow templates.","details":{"requiredPermission":"workflow_templates:update","userPermissions":["workflow_templates:read"]}}}},"crossOrganizationAccess":{"summary":"Cross-Organization Access Denied","value":{"error":{"code":"CROSS_ORGANIZATION_ACCESS_DENIED","message":"Cannot update template belonging to different organization.","details":{"templateOrganization":"org-other-456","userOrganization":"org-123e4567"}}}}}}}},"404":{"description":"Workflow template not found. The specified template ID does not exist\nor does not belong to the authenticated organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateNotFound":{"summary":"Template Not Found","value":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Workflow template not found or does not belong to your organization.","details":{"templateId":"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11","organizationId":"org-123e4567-e89b-12d3-a456-426614174000"}}}}}}}},"422":{"description":"Unprocessable Entity - Validation errors due to business rule violations,\ninvalid date relationships, missing required dependencies, or constraint conflicts.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidValidUntilDate":{"summary":"Invalid Valid Until Date","value":{"error":{"code":"INVALID_VALID_UNTIL_DATE","message":"Valid until date cannot be before valid from date.","details":{"validFrom":"2024-01-01","validUntil":"2023-12-31","constraint":"validUntil >= validFrom"}}}},"eventTopicNotFound":{"summary":"Event Topic Not Found","value":{"error":{"code":"EVENT_TOPIC_NOT_FOUND","message":"Event topic not found or does not belong to your organization.","details":{"eventTopicId":"c2ggde33-9e2d-4ffa-bb8f-8dd1df592c33","organizationId":"org-123e4567-e89b-12d3-a456-426614174000"}}}},"immutableFieldModification":{"summary":"Attempted Immutable Field Modification","value":{"error":{"code":"IMMUTABLE_FIELD_MODIFICATION","message":"Cannot modify immutable template fields after creation.","details":{"immutableFields":["code","versionMajor","versionMinor","validFrom","organizationId"],"attemptedFields":["code","versionMajor"],"solution":"These fields are set during template creation and cannot be changed"}}}},"activeTemplateConstraint":{"summary":"Active Template Constraint Violation","value":{"error":{"code":"ACTIVE_TEMPLATE_CONSTRAINT","message":"Cannot set valid until date in the past for active templates.","details":{"currentDate":"2024-02-15","requestedValidUntil":"2024-02-01","templateStatus":"active","solution":"Deactivate template first or set future valid until date"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Workflow Templates"],"summary":"Delete workflow template permanently","description":"Permanently deletes a workflow template and all associated configuration in a cascading operation.\nThis is a **destructive operation** that cannot be undone and includes comprehensive usage validation.\n\n## ⚠️ Critical Warning\n\nThis action is **irreversible** and will permanently delete:\n- The template record and all metadata\n- All workflow template stages and configurations\n- Template rules and validation settings\n- Event publishing configuration\n- Version history and template lineage\n- Any template-specific settings and customizations\n\n## Business Logic\n\n### Pre-deletion Validation Process\n\n1. **Template Existence Verification**\n   - Confirms template exists within authenticated organization\n   - Validates template ID format and ownership\n   - Ensures multi-tenant security boundaries\n\n2. **Usage Protection Analysis**\n   - Scans for active workflow instances (DRAFT, ACTIVE, ON_HOLD)\n   - Counts total workflows created from this template\n   - Prevents deletion if any workflows exist (regardless of status)\n   - Protects business process continuity and data integrity\n\n3. **Cascade Impact Assessment**\n   - Identifies all template stages for deletion\n   - Reviews template configuration dependencies\n   - Validates organizational permissions for template management\n\n### Deletion Process\n\n1. **Security Validation**\n   - Organization-scoped access control enforcement\n   - Template ownership verification\n   - Administrative permission validation\n   - Audit context preparation for compliance\n\n2. **Usage Constraint Enforcement**\n   - **Blocking Rule**: Templates with ANY workflow instances cannot be deleted\n   - Includes completed, cancelled, and archived workflows\n   - Returns 409 Conflict with detailed workflow count\n   - Protects against accidental deletion of production templates\n\n3. **Cascade Deletion Operations**\n   - **Template Stages**: All associated workflow stages removed\n   - **Template Rules**: Business rules and validation settings deleted\n   - **Configuration Data**: Event publishing settings and custom configurations\n   - **Version Data**: Template versioning information and history\n   - **Metadata**: All template-specific metadata and properties\n\n4. **System Integration Cleanup**\n   - Remove template references from system catalogs\n   - Clear template cache entries\n   - Update organizational template metrics\n   - Maintain referential integrity across the platform\n\n5. **Audit Trail and Compliance**\n   - Log deletion operation with full context\n   - Record template details for compliance requirements\n   - Track user and organizational context for audit\n   - Maintain deletion timestamp and reasoning\n\n## Usage Protection Rules\n\n### Templates Cannot Be Deleted If:\n- **Active Workflows**: Any workflows in DRAFT, ACTIVE, or ON_HOLD status exist\n- **Historical Workflows**: Any completed or cancelled workflows were created from template\n- **System Templates**: Templates marked as system-required or protected\n- **Template Dependencies**: Other templates inherit from or reference this template\n\n### Protection Rationale:\n- **Business Continuity**: Prevents disruption of active business processes\n- **Data Integrity**: Maintains workflow-template relationships for reporting\n- **Audit Compliance**: Preserves template definitions for completed workflows\n- **Operational Safety**: Prevents accidental deletion of production templates\n\n## Use Cases\n\n### Development and Testing Cleanup\nRemove templates created during development cycles\n```\nDELETE /api/v1/workflow-templates/test-template-123\n```\n**Prerequisites**: No workflows created from template\n**Best for**: Development environments, prototype templates\n\n### Draft Template Removal\nClean up templates created but never used\n```\nDELETE /api/v1/workflow-templates/draft-property-process-456\n```\n**Alternative**: Keep as inactive template for future reference\n\n### Duplicate Template Cleanup\nRemove accidentally created template duplicates\n```\nDELETE /api/v1/workflow-templates/duplicate-lease-process-789\n```\n**Warning**: Verify no workflows were created from the duplicate\n\n### Template Consolidation\nRemove outdated templates when consolidating processes\n```\n// First ensure no workflows exist\nGET /api/v1/workflows?templateId=old-template-id\n// Then delete if count is 0\nDELETE /api/v1/workflow-templates/old-template-id\n```\n**Alternative**: Mark as inactive instead of deleting\n\n## Norwegian Real Estate Scenarios\n\n### Property Management Template Cleanup\n- Remove test tenant screening templates\n- Clean up experimental maintenance workflow templates\n- Delete duplicate property inspection templates\n- Remove obsolete lease agreement templates\n\n### Compliance and Regulatory Updates\n- Replace outdated compliance templates (after migration)\n- Remove templates that no longer meet regulatory requirements\n- Clean up deprecated due diligence templates\n\n## Recommended Alternatives\n\n### 1. Deactivate Instead of Delete\nPreserves template for historical reference while hiding from active use\n```json\nPUT /api/v1/workflow-templates/{id}\n{\n  \"isActive\": false,\n  \"validUntil\": \"2024-12-31T23:59:59Z\",\n  \"deactivationReason\": \"Superseded by new template version\"\n}\n```\n**Benefits**: Maintains audit trail, allows reactivation, preserves workflow history\n\n### 2. Template Versioning\nCreate new version instead of deleting old one\n```json\nPOST /api/v1/workflow-templates\n{\n  \"basedOnTemplateId\": \"existing-template-id\",\n  \"versionMajor\": 2,\n  \"versionMinor\": 0,\n  \"name\": \"Updated Template Name\"\n}\n```\n**Benefits**: Maintains version history, allows gradual migration\n\n### 3. Template Migration\nMigrate existing workflows to new template before deletion\n```json\nPOST /api/v1/workflows/migrate-template\n{\n  \"fromTemplateId\": \"old-template-id\",\n  \"toTemplateId\": \"new-template-id\",\n  \"preserveStageProgress\": true\n}\n```\n**Benefits**: Preserves active workflows, enables safe template removal\n\n## Security Considerations\n\n- **Organization Isolation**: Templates can only be deleted within authenticated organization\n- **Permission Validation**: Requires administrative or template management permissions\n- **Audit Logging**: All deletion attempts logged for security and compliance\n- **Data Protection**: Cascade deletion ensures no orphaned data remains\n- **Rollback Prevention**: No rollback mechanism - deletion is permanent\n\n## Error Scenarios and Recovery\n\n### Template Has Active Workflows (409 Conflict)\n**Scenario**: Attempting to delete template with existing workflow instances\n**Resolution**: \n1. Complete or cancel all active workflows\n2. Archive completed workflows if historical data not needed\n3. Consider template deactivation instead of deletion\n\n### Template Not Found (404 Not Found)\n**Scenario**: Template ID doesn't exist or belongs to different organization\n**Resolution**: Verify template ID and organization context\n\n### Insufficient Permissions (403 Forbidden)\n**Scenario**: User lacks template management permissions\n**Resolution**: Request administrative access or use service account\n\n### System Constraint Violation (500 Internal Server Error)\n**Scenario**: Database constraints prevent deletion\n**Resolution**: Contact support - may indicate data integrity issue\n","operationId":"deleteWorkflowTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique workflow template identifier for permanent deletion. Must be a valid UUID \nbelonging to the authenticated organization. This template will be permanently removed\nalong with all stages, rules, and configuration data.\n\n**Warning**: Deletion is irreversible - ensure this is the correct template.\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"example":"550e8400-e29b-41d4-a716-446655440001"}],"responses":{"204":{"description":"Workflow template deleted successfully. The template and all associated configuration\nhave been permanently removed from the system. This includes all template stages,\nbusiness rules, event configuration, and metadata.\n\n**Note**: This operation cannot be undone. The template no longer exists in the system.\n"},"400":{"description":"Invalid request parameters or malformed template ID.\nCommon causes include invalid UUID format or missing required parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidUuid":{"summary":"Invalid template ID format","value":{"error":{"code":"INVALID_UUID","message":"Template ID must be a valid UUID format.","details":{"parameter":"id","provided":"invalid-template-id","expected":"UUID format (e.g., 550e8400-e29b-41d4-a716-446655440001)"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Insufficient permissions to delete workflow templates.\nTemplate deletion requires administrative or template management permissions\nwithin the authenticated organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficientPermissions":{"summary":"User lacks template deletion permissions","value":{"error":{"code":"FORBIDDEN","message":"Insufficient permissions to delete workflow templates.","details":{"required":"template:delete","userPermissions":["template:read","template:create"],"action":"Request administrative access or use service account"}}}}}}}},"404":{"description":"Workflow template not found or not accessible within the authenticated organization.\nThe template may not exist, may belong to a different organization, or may have\nalready been deleted.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateNotFound":{"summary":"Template does not exist","value":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Workflow template not found or not accessible.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","organizationId":"550e8400-e29b-41d4-a716-446655440000","suggestion":"Verify template ID and ensure it belongs to your organization"}}}}}}}},"409":{"description":"Cannot delete template due to existing workflow instances. Templates that have been\nused to create workflows cannot be deleted to maintain data integrity and business\nprocess continuity. This includes workflows in any status (active, completed, cancelled).\n\n**Resolution Options:**\n1. Complete or cancel all workflows created from this template\n2. Use template deactivation instead of deletion\n3. Create a new template version if updates are needed\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateHasWorkflows":{"summary":"Template has existing workflow instances","value":{"error":{"code":"TEMPLATE_HAS_WORKFLOWS","message":"Cannot delete template with existing workflow instances.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","templateName":"Property Acquisition Process v2.1","totalWorkflowCount":12,"activeWorkflowCount":3,"completedWorkflowCount":8,"cancelledWorkflowCount":1,"workflowStatusBreakdown":{"ACTIVE":2,"ON_HOLD":1,"COMPLETED":8,"CANCELLED":1},"recommendation":"Consider deactivating the template instead of deleting","alternativeEndpoint":"PUT /api/v1/workflow-templates/{id} with isActive: false"}}}},"templateHasActiveWorkflows":{"summary":"Template has active workflow instances","value":{"error":{"code":"TEMPLATE_HAS_ACTIVE_WORKFLOWS","message":"Cannot delete template with active workflow instances.","details":{"templateId":"550e8400-e29b-41d4-a716-446655440001","activeWorkflowCount":5,"activeWorkflowIds":["workflow-123","workflow-456","workflow-789","workflow-abc","workflow-def"],"recommendation":"Complete or cancel active workflows before deletion"}}}}}}}},"500":{"description":"Internal server error during template deletion process. This may indicate\ndatabase constraints, system connectivity issues, or unexpected application errors.\nThe template deletion has been rolled back and no changes were made.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"databaseConstraintError":{"summary":"Database constraint violation","value":{"error":{"code":"CONSTRAINT_VIOLATION","message":"Database constraint prevents template deletion.","details":{"constraint":"foreign_key_workflow_template_stages","action":"Contact support - may indicate data integrity issue"}}}},"systemError":{"summary":"Unexpected system error","value":{"error":{"code":"INTERNAL_ERROR","message":"An unexpected error occurred during template deletion.","details":{"operationId":"delete-template-op-12345","timestamp":"2024-01-20T10:30:45Z","action":"Please try again or contact support if the issue persists"}}}}}}}}}}},"/api/v1/workflow-templates/{id}/builder-view":{"get":{"tags":["Workflow Templates"],"summary":"Get fully denormalized workflow template tree for builder UI","description":"Returns a complete workflow template with all nested data needed by the workflow builder UI\nin a single request. This eliminates the N+1 problem of fetching task templates, form templates,\nform actions, and completion actions separately per stage.\n\nThe response flattens `stage_definition.task_templates` directly onto each stage for cleaner\nfrontend consumption, and includes a `_summary` object with computed counts.\n","operationId":"getWorkflowTemplateBuilderView","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"}],"responses":{"200":{"description":"Full workflow template tree for the builder","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"Workflow template with nested stages, task templates, form templates, form actions, and completion actions","properties":{"_summary":{"type":"object","properties":{"stage_count":{"type":"integer","example":6},"total_task_count":{"type":"integer","example":12},"total_form_count":{"type":"integer","example":8}}}}}}}}}},"404":{"description":"Workflow template not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-templates/{id}/stages/{stageId}/task-templates":{"put":{"tags":["Workflow Templates"],"summary":"Set task template associations for a workflow template stage","description":"Replaces all task template associations for a specific workflow template stage.\nThis allows per-stage customization of which task templates are used, independent\nof the shared stage definition. Supports ordering, required flags, and delay configuration.\n","operationId":"setWorkflowTemplateStageTaskTemplates","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template stage ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["taskTemplates"],"properties":{"taskTemplates":{"type":"array","items":{"type":"object","required":["task_template_id"],"properties":{"task_template_id":{"type":"string","format":"uuid"},"order":{"type":"integer","minimum":0,"default":0},"is_required":{"type":"boolean","default":true},"delay_days":{"type":"integer","minimum":0,"default":0}}}}}}}}},"responses":{"200":{"description":"Task template associations updated","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"stageId":{"type":"string","format":"uuid"},"taskTemplates":{"type":"array","items":{"type":"object"}},"changes":{"type":"object","properties":{"total":{"type":"integer"}}}}}}}}}},"400":{"description":"Validation error"},"404":{"description":"Template or stage not found"},"500":{"description":"Internal server error"}}},"get":{"tags":["Workflow Templates"],"summary":"Get task template associations for a workflow template stage","description":"Returns task templates associated with a workflow template stage.\nIf per-stage overrides exist, returns those. Otherwise falls back to\nthe stage definition's task templates. The `source` field indicates which.\n","operationId":"getWorkflowTemplateStageTaskTemplates","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template ID"},{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"Workflow template stage ID"}],"responses":{"200":{"description":"Task template associations","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"stageId":{"type":"string","format":"uuid"},"source":{"type":"string","enum":["override","stage_definition"]},"taskTemplates":{"type":"array","items":{"type":"object"}}}}}}}}},"404":{"description":"Stage not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-templates/{id}/stages":{"post":{"tags":["Workflow Templates"],"summary":"Add stage to workflow template","description":"Adds a new stage definition to an existing workflow template.\nThe stage will be added at the specified sequence order, and existing stages\nat or after that order will be shifted to accommodate the new stage.\n\n## Stage Types\n\nThis endpoint supports two primary stage types:\n\n### TASK Stage (Default)\nCreates tasks from task templates when the stage is activated. This is the standard\nbehavior for workflow stages and is used for most business processes.\n\n**Use Cases:**\n- Document collection and verification\n- Approval workflows with human reviewers\n- Quality checks and inspections\n- Manual data entry or processing\n\n### WORKFLOW Stage\nInstantiates a child workflow from a referenced workflow template when activated.\nThis enables complex nested workflows and process orchestration.\n\n**Use Cases:**\n- Trigger property inspection workflow during acquisition\n- Launch tenant background check sub-process\n- Initiate maintenance request workflow during property handover\n- Start parallel approval workflows for different stakeholders\n\n**Parent-Child Behavior:**\n- `waitForCompletion: true` - Parent stage waits for child workflow to complete (blocking)\n- `waitForCompletion: false` - Parent stage completes immediately after instantiation (fire-and-forget)\n\n## Norwegian Real Estate Examples\n\n**Property Acquisition Process:**\n1. Initial Review (TASK stage) - Basic document verification\n2. Property Inspection (WORKFLOW stage) - Launches detailed inspection workflow with waitForCompletion=true\n3. Legal Due Diligence (TASK stage) - Legal team review\n4. Background Checks (WORKFLOW stage) - Parallel tenant verification with waitForCompletion=false\n5. Final Approval (TASK stage) - Management sign-off\n\n**Validation Rules:**\n- Stage definition must exist and belong to organization\n- For WORKFLOW stages, referencedWorkflowTemplateId is required\n- Referenced workflow template must exist and be active\n- Circular workflow references are prevented\n- Sequence order automatically adjusted for conflicts\n","operationId":"addStageToTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stageDefinitionId","sequenceOrder"],"properties":{"stageDefinitionId":{"type":"string","format":"uuid","description":"Stage definition to add to template"},"sequenceOrder":{"type":"integer","minimum":1,"description":"Position in template sequence"},"isMilestone":{"type":"boolean","default":false,"description":"Mark stage as milestone"},"isBlocking":{"type":"boolean","default":true,"description":"Stage blocks workflow progression"},"isOptional":{"type":"boolean","default":false,"description":"Stage can be skipped"},"defaultAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Default assignment type"},"defaultAssigneeId":{"type":"string","description":"Default assignee identifier"},"overrideDurationDays":{"type":"integer","minimum":1,"description":"Override default stage duration"},"overrideEscalationDays":{"type":"integer","minimum":1,"description":"Override default escalation timing"},"entryConditions":{"type":"object","description":"Conditions for stage entry"},"exitConditions":{"type":"object","description":"Conditions for stage completion"},"startOnWorkflowStart":{"type":"boolean","default":false,"description":"When true, stage automatically transitions to IN_PROGRESS when workflow starts,\nenabling parallel execution. When false (default), stage remains PENDING until\nmanually started or auto-advanced by workflow progression.\n"},"stageType":{"type":"string","enum":["TASK","WORKFLOW"],"default":"TASK","description":"Stage behavior type:\n- TASK: Creates tasks from task templates (default)\n- WORKFLOW: Instantiates child workflow from referenced template\n"},"referencedWorkflowTemplateId":{"type":"string","format":"uuid","description":"Required when stageType is WORKFLOW.\nID of workflow template to instantiate as child workflow.\nMust reference an existing, active workflow template.\n"},"waitForCompletion":{"type":"boolean","default":true,"description":"For WORKFLOW stages only:\n- true: Parent stage waits for child workflow completion (blocking)\n- false: Parent stage completes immediately (fire-and-forget)\n"},"allowedNextStages":{"type":"array","items":{"type":"string"},"default":[],"description":"Stage definition codes that this stage can transition to.\nWhen empty (default), linear sequence_order progression is used.\nEnables non-linear transitions including backward movement.\n"},"stageReentryBehavior":{"type":"string","enum":["LEAVE_TASKS","RESET_TASKS","CREATE_FRESH_TASKS"],"default":"LEAVE_TASKS","description":"How tasks are handled when re-entering this stage during backward transitions:\n- LEAVE_TASKS: Leave existing tasks as-is (default)\n- RESET_TASKS: Reset tasks to PENDING status\n- CREATE_FRESH_TASKS: Mark old tasks, create new tasks from template\n"},"maxReentryCount":{"type":"integer","minimum":1,"nullable":true,"description":"Maximum times this stage can be re-entered (null = unlimited)"},"isGlobalTarget":{"type":"boolean","default":false,"description":"When true, this stage can be transitioned to from any stage (bypasses allowed_next_stages)"}}},"examples":{"taskStage":{"summary":"TASK stage - Standard task creation","value":{"stageDefinitionId":"550e8400-e29b-41d4-a716-446655440030","sequenceOrder":1,"stageType":"TASK","isMilestone":true,"isBlocking":true,"defaultAssigneeType":"ROLE","defaultAssigneeId":"property-manager","overrideDurationDays":5}},"workflowStageBlocking":{"summary":"WORKFLOW stage - Blocking child workflow","description":"Parent stage waits for property inspection workflow to complete","value":{"stageDefinitionId":"550e8400-e29b-41d4-a716-446655440031","sequenceOrder":2,"stageType":"WORKFLOW","referencedWorkflowTemplateId":"550e8400-e29b-41d4-a716-446655440099","waitForCompletion":true,"isMilestone":true,"isBlocking":true}},"workflowStageFireAndForget":{"summary":"WORKFLOW stage - Fire-and-forget","description":"Triggers background check workflow without waiting","value":{"stageDefinitionId":"550e8400-e29b-41d4-a716-446655440032","sequenceOrder":3,"stageType":"WORKFLOW","referencedWorkflowTemplateId":"550e8400-e29b-41d4-a716-446655440098","waitForCompletion":false,"isBlocking":false,"isOptional":true}},"parallelStage":{"summary":"Parallel execution stage","description":"Stage that starts immediately when workflow starts for parallel execution","value":{"stageDefinitionId":"550e8400-e29b-41d4-a716-446655440033","sequenceOrder":1,"stageType":"TASK","startOnWorkflowStart":true,"isMilestone":false,"isBlocking":true,"defaultAssigneeType":"ROLE","defaultAssigneeId":"legal-team"}}}}}},"responses":{"201":{"description":"Stage added to template successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowTemplateStage"}}}}}},"400":{"description":"Bad request - Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missingReferencedTemplate":{"summary":"Missing referencedWorkflowTemplateId for WORKFLOW stage","value":{"error":{"code":"VALIDATION_ERROR","message":"referencedWorkflowTemplateId is required when stageType is WORKFLOW"}}},"invalidStageType":{"summary":"Invalid stage type value","value":{"error":{"code":"VALIDATION_ERROR","message":"stageType must be one of: TASK, WORKFLOW"}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateNotFound":{"summary":"Workflow template not found","value":{"error":{"code":"NOT_FOUND","message":"Workflow template not found"}}},"stageDefinitionNotFound":{"summary":"Stage definition not found","value":{"error":{"code":"NOT_FOUND","message":"Stage definition not found"}}},"referencedTemplateNotFound":{"summary":"Referenced workflow template not found","value":{"error":{"code":"NOT_FOUND","message":"Referenced workflow template not found or inactive"}}}}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"circularReference":{"summary":"Circular workflow reference detected","value":{"error":{"code":"VALIDATION_ERROR","message":"Circular workflow reference detected - this would create an infinite loop"}}},"duplicateStage":{"summary":"Stage already exists in template","value":{"error":{"code":"DUPLICATE_STAGE","message":"Stage definition already exists in this template"}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-templates/{id}/stages/{stageId}":{"put":{"tags":["Workflow Templates"],"summary":"Update template stage configuration","description":"Updates stage-specific configuration within a workflow template,\nincluding overrides, assignments, sequence order modifications, and stage type settings.\n\n## Updatable Fields\n\n**Stage Type Configuration:**\n- Can update stageType, referencedWorkflowTemplateId, and waitForCompletion\n- When changing to WORKFLOW type, referencedWorkflowTemplateId becomes required\n- Circular workflow references are validated and prevented\n\n**Stage Behavior:**\n- Sequence order changes trigger automatic reordering of other stages\n- Assignment and duration overrides modify template-specific settings only\n- Entry and exit conditions control stage activation and completion logic\n\n## Norwegian Real Estate Use Cases\n\n**Convert TASK to WORKFLOW Stage:**\n- Upgrade simple inspection stage to comprehensive inspection workflow\n- Convert manual approval to automated approval workflow\n\n**Modify WORKFLOW Stage Behavior:**\n- Change from blocking to fire-and-forget for background processes\n- Update referenced template to use newer version of sub-workflow\n- Adjust wait behavior based on business requirements\n\n**Standard Updates:**\n- Adjust inspection stage duration for complex properties\n- Update assignee for compliance review stages\n- Modify blocking behavior for optional approval stages\n","operationId":"updateTemplateStage","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Template ID","schema":{"type":"string","format":"uuid"}},{"name":"stageId","in":"path","required":true,"description":"Workflow Template Stage ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sequenceOrder":{"type":"integer","minimum":1,"description":"New position in template sequence"},"isMilestone":{"type":"boolean","description":"Mark stage as milestone"},"isBlocking":{"type":"boolean","description":"Stage blocks workflow progression"},"isOptional":{"type":"boolean","description":"Stage can be skipped"},"defaultAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Default assignment type"},"defaultAssigneeId":{"type":"string","description":"Default assignee identifier"},"overrideDurationDays":{"type":"integer","minimum":1,"description":"Override default stage duration"},"overrideEscalationDays":{"type":"integer","minimum":1,"description":"Override default escalation timing"},"entryConditions":{"type":"object","description":"Conditions for stage entry"},"exitConditions":{"type":"object","description":"Conditions for stage completion"},"stageType":{"type":"string","enum":["TASK","WORKFLOW"],"description":"Change stage behavior type.\nWhen changing to WORKFLOW, must provide referencedWorkflowTemplateId.\n"},"referencedWorkflowTemplateId":{"type":"string","format":"uuid","description":"Update the workflow template reference for WORKFLOW stages.\nRequired when stageType is WORKFLOW.\n"},"waitForCompletion":{"type":"boolean","description":"For WORKFLOW stages, control parent-child completion behavior.\n"},"allowedNextStages":{"type":"array","items":{"type":"string"},"description":"Stage definition codes that this stage can transition to.\nWhen empty, linear sequence_order progression is used (default behavior).\n"},"stageReentryBehavior":{"type":"string","enum":["LEAVE_TASKS","RESET_TASKS","CREATE_FRESH_TASKS"],"description":"How tasks are handled when re-entering this stage.\nLEAVE_TASKS (default): Tasks left as-is.\nRESET_TASKS: Tasks reset to PENDING.\nCREATE_FRESH_TASKS: Old tasks marked, new tasks created from template.\n"},"maxReentryCount":{"type":"integer","minimum":1,"nullable":true,"description":"Maximum number of re-entries allowed (null = unlimited)"},"isGlobalTarget":{"type":"boolean","description":"When true, this stage can be transitioned to from any stage (bypasses allowed_next_stages)"}}},"examples":{"updateTaskStage":{"summary":"Update TASK stage configuration","value":{"sequenceOrder":2,"isMilestone":false,"isBlocking":true,"overrideDurationDays":7,"defaultAssigneeType":"USER","defaultAssigneeId":"inspection.coordinator@apart.no"}},"convertToWorkflowStage":{"summary":"Convert TASK stage to WORKFLOW stage","value":{"stageType":"WORKFLOW","referencedWorkflowTemplateId":"550e8400-e29b-41d4-a716-446655440099","waitForCompletion":true,"isBlocking":true}},"updateWorkflowReference":{"summary":"Update referenced workflow template","value":{"referencedWorkflowTemplateId":"550e8400-e29b-41d4-a716-446655440088","waitForCompletion":false}}}}}},"responses":{"200":{"description":"Template stage updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/WorkflowTemplateStage"}}}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Template or stage not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error (invalid sequence order)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Workflow Templates"],"summary":"Remove stage from workflow template","description":"Removes a stage definition from a workflow template and automatically\nadjusts sequence orders of remaining stages. Validates that no active\nworkflows depend on this stage before removal.\n\n**Norwegian Real Estate Use Cases:**\n- Remove obsolete compliance stages from updated templates\n- Delete optional approval stages that cause delays\n- Remove testing stages from production templates\n\n**Safety Checks:** Prevents removal if active workflows use this stage\n**Sequence Management:** Automatically adjusts remaining stage orders\n","operationId":"removeStageFromTemplate","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Template ID","schema":{"type":"string","format":"uuid"}},{"name":"stageId","in":"path","required":true,"description":"Workflow Template Stage ID","schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Stage removed from template successfully"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Template or stage not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Cannot remove stage with active workflow dependencies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"STAGE_HAS_ACTIVE_WORKFLOWS","message":"Cannot remove stage with active workflow instances.","details":{"activeWorkflowCount":3}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-templates/{id}/stages/reorder":{"put":{"tags":["Workflow Templates"],"summary":"Reorder template stages","description":"Performs bulk reordering of all stages within a workflow template.\nProvide an array of stage IDs in the desired sequence order.\nThis operation is atomic - either all stages are reordered or none.\n\n**Norwegian Real Estate Use Cases:**\n- Optimize property acquisition process flow based on experience\n- Reorder tenant onboarding steps for better efficiency\n- Adjust maintenance workflow sequence for critical path optimization\n\n**Atomic Operation:** All stages reordered in single transaction\n**Validation:** Ensures all provided stage IDs belong to template\n","operationId":"reorderTemplateStages","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Workflow Template ID","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["stageIds"],"properties":{"stageIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of stage IDs in desired order","minItems":1}}},"example":{"stageIds":["stage-id-003","stage-id-001","stage-id-004","stage-id-002"]}}}},"responses":{"200":{"description":"Template stages reordered successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowTemplateStage"}}}},"example":{"data":[{"id":"stage-id-003","sequenceOrder":1,"stageName":"Technical Assessment"},{"id":"stage-id-001","sequenceOrder":2,"stageName":"Legal Due Diligence"},{"id":"stage-id-004","sequenceOrder":3,"stageName":"Financial Review"},{"id":"stage-id-002","sequenceOrder":4,"stageName":"Final Approval"}]}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Template not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation error (missing stages, invalid stage IDs)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INVALID_STAGE_IDS","message":"Some stage IDs do not belong to this template.","details":{"invalidStageIds":["stage-id-999"]}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows":{"get":{"tags":["Workflows"],"summary":"List all workflows for organization","description":"List workflows with filtering, sorting, and pagination. Supports multi-entity filtering, status filtering, portal visibility, and optional hierarchy/entity enrichment.","operationId":"getWorkflows","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/PageParam"},{"$ref":"#/components/parameters/LimitParam"},{"name":"status","in":"query","description":"Filter workflows by current status (supports multiple values).","schema":{"oneOf":[{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"]},{"type":"array","items":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"]}}]},"style":"form","explode":true,"examples":{"single":{"summary":"Single status","value":"ACTIVE"},"multiple":{"summary":"Multiple statuses","value":["ACTIVE","ON_HOLD"]}}},{"name":"entityType","in":"query","description":"Filter by the type of business entity the workflow relates to.\nCommon entity types:\n- customer_onboarding: Customer onboarding workflows\n- order_fulfillment: Order processing workflows\n- support_ticket: Repair and support workflows\n- inspection: Regular inspection workflows\n- contract_renewal: Contract renewal workflows\n","schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","maxLength":100},"example":"customer_onboarding"},{"name":"entityId","in":"query","description":"Filter by specific entity ID. This is typically a unique identifier for the\nbusiness object (customer ID, order ID, ticket ID, etc.).\nOften combined with entityType for precise filtering.\n","schema":{"type":"string","maxLength":50},"example":"cust-acme-001"},{"name":"entities","in":"query","schema":{"type":"array","items":{"type":"string","pattern":"^[a-zA-Z0-9_-]+:[a-zA-Z0-9_-]+$"},"maxItems":10},"style":"form","explode":true,"description":"Filter workflows by multiple entities (multi-entity filtering). Each entity must be in 'type:id' format.\nMaximum 10 entities. Ideal for portfolio-wide views and cross-entity workflow analysis.\n","examples":{"customer_portfolio":{"summary":"Multiple customer workflows","value":["customer:cust-001","customer:cust-002"]},"order_fulfillment":{"summary":"Cross-entity order workflows","value":["order:ord-123","customer:cust-001","contract:contract-456"]}}},{"name":"entityMatchMode","in":"query","schema":{"type":"string","enum":["ANY","ALL"],"default":"ANY"},"description":"Determines how multiple entities are matched when using the 'entities' parameter:\n- ANY: Return workflows linked to any of the specified entities (OR logic) - most common use case\n- ALL: Return workflows that have links to all specified entities (AND logic, requires EntityLink table)\n","example":"ANY"},{"name":"ownerType","in":"query","description":"Filter by the type of workflow owner assignment:\n- ROLE: Assigned to a role (e.g., account_manager, support_manager)\n- POSITION: Assigned to a position in the organization\n- USER: Assigned to a specific user\nSupports multiple values (e.g., ?ownerType=ROLE&ownerType=USER).\n","schema":{"oneOf":[{"type":"string","enum":["ROLE","POSITION","USER"]},{"type":"array","items":{"type":"string","enum":["ROLE","POSITION","USER"]}}]},"style":"form","explode":true,"examples":{"single":{"summary":"Single owner type","value":"ROLE"},"multiple":{"summary":"Multiple owner types","value":["ROLE","USER"]}}},{"name":"ownerId","in":"query","description":"Filter by owner ID. The meaning depends on ownerType:\n- For ROLE: The role identifier (e.g., \"account_manager\")\n- For POSITION: The position ID in your organization\n- For USER: The user's unique identifier\nMust be used with ownerType for meaningful results.\n","schema":{"type":"string","maxLength":50},"example":"account_manager"},{"name":"dueDateFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter workflows due after or on this date (inclusive).\nUse ISO 8601 format. Useful for finding upcoming deadlines.\n","example":"2024-01-20T00:00:00.000Z"},{"name":"dueDateTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter workflows due before or on this date (inclusive).\nUse ISO 8601 format. Combine with dueDateFrom for date ranges.\n","example":"2024-01-31T23:59:59.999Z"},{"name":"createdFrom","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter workflows created after or on this date (inclusive).\nUse ISO 8601 format. Useful for finding recently created workflows.\n","example":"2024-01-01T00:00:00.000Z"},{"name":"createdTo","in":"query","schema":{"type":"string","format":"date-time"},"description":"Filter workflows created before or on this date (inclusive).\nUse ISO 8601 format. Combine with createdFrom for date ranges.\n","example":"2024-01-31T23:59:59.999Z"},{"name":"sortBy","in":"query","schema":{"type":"string","enum":["created_at","updated_at","due_date","name"],"default":"created_at"},"description":"Field to sort results by:\n- created_at: When the workflow was created (default)\n- updated_at: Last modification time\n- due_date: Workflow deadline\n- name: Alphabetical by workflow name\n","example":"due_date"},{"name":"sortOrder","in":"query","schema":{"type":"string","enum":["asc","desc"],"default":"desc"},"description":"Sort direction:\n- asc: Ascending order (oldest first, A-Z)\n- desc: Descending order (newest first, Z-A) - default\n","example":"asc"},{"name":"search","in":"query","schema":{"type":"string","maxLength":255},"description":"Free text search across workflow name and description.\nCase-insensitive partial matching. Useful for finding workflows\nby entity name, description, or other searchable text.\n","example":"acme customer"},{"name":"templateId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter workflows by the template they were created from.\nUseful for finding all instances of a specific workflow type\n(e.g., all customer onboarding workflows using the same template).\n","example":"789e0123-e89b-12d3-a456-426614174222"},{"name":"templateIds","in":"query","schema":{"type":"array","items":{"type":"string","format":"uuid"},"maxItems":50},"style":"form","explode":true,"description":"Filter workflows by multiple template IDs (supports multiple values).\nReturns workflows created from any of the specified templates.\nUseful for aggregating workflow metrics across related workflow types\nor viewing workflows from a subset of templates.\nNote: Cannot be combined with templateId - use one or the other.\n","examples":{"multiple_templates":{"summary":"Filter by multiple templates","value":["789e0123-e89b-12d3-a456-426614174222","890f0234-e89b-12d3-a456-426614174333"]}}},{"name":"portal","in":"query","schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","maxLength":50},"description":"Portal context for visibility filtering. Used to restrict workflows\nvisible to external users in customer or partner portals.\nCommon values: customer_portal, partner_portal, vendor_portal\n","example":"customer_portal"},{"name":"portalUserId","in":"query","schema":{"type":"string","maxLength":255},"description":"User ID within the portal context. Required when portal parameter\nis provided. This ensures users only see workflows they have\npermission to access in the portal.\n","example":"customer-user-456"},{"name":"linkType","in":"query","schema":{"type":"string","enum":["PARENT_CHILD","SIBLING","REFERENCE","BIDIRECTIONAL"]},"description":"Filter workflows by link type. Returns workflows that have links of the specified type.\n- PARENT_CHILD: Workflows in a parent-child relationship\n- SIBLING: Workflows that are siblings\n- REFERENCE: Workflows with reference links\n- BIDIRECTIONAL: Workflows with bidirectional links\n","example":"PARENT_CHILD"},{"name":"parentId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter workflows that are children of the specified parent workflow.\nReturns only direct children of the given parent.\n","example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"childId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter workflows that are parents of the specified child workflow.\nReturns the parent workflow(s) of the given child.\n","example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"rootOnly","in":"query","schema":{"type":"boolean","default":false},"description":"When true, returns only root workflows (workflows with no parent).\nUseful for displaying top-level workflows in a hierarchical view.\n","example":true},{"name":"includeHierarchy","in":"query","schema":{"type":"boolean","default":false},"description":"When true, enriches each workflow with hierarchy information including parent, children, siblings, depth, and isRoot flag.","example":false},{"name":"includeEntities","in":"query","schema":{"type":"boolean","default":false},"description":"Include enriched entity data from external systems for each workflow.","example":false},{"name":"includeContextData","in":"query","schema":{"type":"boolean","default":false},"description":"Include hierarchical context data for each workflow.","example":false}],"responses":{"200":{"description":"Workflows retrieved successfully","content":{"application/json":{"schema":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","description":"Array of workflow objects with full details","items":{"type":"object","required":["id","organizationId","workflowNumber","name","status","entityType","entityId","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow identifier"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this workflow"},"workflowNumber":{"type":"string","description":"Human-readable workflow number (e.g., WF-2024-001)"},"name":{"type":"string","description":"Workflow display name"},"description":{"type":"string","nullable":true,"description":"Detailed workflow description"},"status":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"],"description":"Current workflow status"},"entityType":{"type":"string","description":"Type of entity this workflow is for"},"entityId":{"type":"string","description":"ID of the entity this workflow is for"},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"Template this workflow was created from"},"currentStageId":{"type":"string","format":"uuid","nullable":true,"description":"Currently active stage"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of owner assignment"},"ownerId":{"type":"string","nullable":true,"description":"ID of the assigned owner"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Workflow deadline"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"When workflow execution began"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When workflow was completed"},"totalStages":{"type":"integer","description":"Total number of stages in workflow"},"completedStages":{"type":"integer","description":"Number of completed stages"},"progressPercentage":{"type":"number","format":"float","description":"Completion percentage (0-100)"},"context":{"type":"object","nullable":true,"description":"Custom workflow context data"},"metadata":{"type":"object","nullable":true,"description":"Additional workflow metadata"},"publishEvents":{"type":"boolean","description":"Whether this workflow publishes events"},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic for workflow events"},"createdAt":{"type":"string","format":"date-time","description":"Workflow creation timestamp"},"createdBy":{"type":"string","description":"User who created the workflow"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp"},"updatedBy":{"type":"string","description":"User who last updated the workflow"},"template":{"type":"object","nullable":true,"description":"Workflow template details","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string","description":"Template code identifier"},"name":{"type":"string","description":"Template display name"},"description":{"type":"string","nullable":true},"category":{"type":"string","nullable":true}}},"currentStage":{"type":"object","nullable":true,"description":"Currently active stage details","properties":{"id":{"type":"string","format":"uuid"},"stageName":{"type":"string"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"]},"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true},"assignedToId":{"type":"string","nullable":true},"assignedToName":{"type":"string","nullable":true},"dueDate":{"type":"string","format":"date-time","nullable":true}}},"workflowStages":{"type":"array","description":"All stages in the workflow","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"stageName":{"type":"string"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"]},"sequenceOrder":{"type":"integer","description":"Stage position in workflow"}}}}}}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}},"examples":{"customerOnboardingWorkflows":{"summary":"Customer onboarding workflows","description":"Example showing active customer onboarding workflows with various stages","value":{"data":[{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-001","name":"Customer Onboarding - ACME Corp","description":"Complete customer onboarding for ACME Corporation","status":"ACTIVE","entityType":"customer_onboarding","entityId":"cust-acme-001","templateId":"789e0123-e89b-12d3-a456-426614174222","currentStageId":"abc12345-e89b-12d3-a456-426614174333","ownerType":"ROLE","ownerId":"sales_manager","dueDate":"2024-03-15T17:00:00.000Z","startedAt":"2024-01-10T09:00:00.000Z","completedAt":null,"totalStages":8,"completedStages":3,"progressPercentage":37.5,"context":{"accountType":"enterprise","contractValue":45000000,"currency":"NOK","partnerRef":"DNB-2024-0156"},"metadata":{"priorityLevel":"medium","budgetApproved":true},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-10T08:30:00.000Z","createdBy":"john.smith@company.com","updatedAt":"2024-01-25T14:15:00.000Z","updatedBy":"john.smith@company.com","template":{"id":"789e0123-e89b-12d3-a456-426614174222","code":"customer-onboarding-standard","name":"Standard Customer Onboarding Process","description":"Complete onboarding workflow including verification and setup","category":"business_operations"},"currentStage":{"id":"abc12345-e89b-12d3-a456-426614174333","stageName":"Technical Evaluation","status":"IN_PROGRESS","assignedToType":"USER","assignedToId":"auditor-234","assignedToName":"Alex Johnson","dueDate":"2024-01-30T17:00:00.000Z"},"workflowStages":[{"id":"stage-001","stageName":"Initial Assessment","status":"COMPLETED","sequenceOrder":1},{"id":"stage-002","stageName":"Budget Approval","status":"COMPLETED","sequenceOrder":2},{"id":"stage-003","stageName":"Legal Review","status":"COMPLETED","sequenceOrder":3},{"id":"abc12345-e89b-12d3-a456-426614174333","stageName":"Technical Evaluation","status":"IN_PROGRESS","sequenceOrder":4},{"id":"stage-005","stageName":"Contract Negotiation","status":"PENDING","sequenceOrder":5},{"id":"stage-006","stageName":"Final Approval","status":"PENDING","sequenceOrder":6},{"id":"stage-007","stageName":"Contract Signing","status":"PENDING","sequenceOrder":7},{"id":"stage-008","stageName":"Account Registration","status":"PENDING","sequenceOrder":8}]},{"id":"234e5678-e89b-12d3-a456-426614175000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-002","name":"Enterprise Customer Setup - GlobalTech","description":"Enterprise customer setup for GlobalTech Inc","status":"ACTIVE","entityType":"customer_onboarding","entityId":"ord-12345","templateId":"789e0123-e89b-12d3-a456-426614174222","currentStageId":"bcd23456-e89b-12d3-a456-426614174444","ownerType":"USER","ownerId":"user-567","dueDate":"2024-02-28T17:00:00.000Z","startedAt":"2024-01-05T10:00:00.000Z","completedAt":null,"totalStages":8,"completedStages":5,"progressPercentage":62.5,"context":{"accountType":"standard","units":12,"contractValue":85000000,"currency":"NOK"},"metadata":{"activeUsers":"92%","establishedYear":1925,"lastUpgrade":2018},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-05T09:00:00.000Z","createdBy":"maria.hansen@company.com","updatedAt":"2024-01-26T11:30:00.000Z","updatedBy":"maria.hansen@company.com","template":{"id":"789e0123-e89b-12d3-a456-426614174222","code":"customer-onboarding-standard","name":"Standard Customer Onboarding Process","description":"Complete onboarding workflow including verification and setup","category":"business_operations"},"currentStage":{"id":"bcd23456-e89b-12d3-a456-426614174444","stageName":"Contract Negotiation","status":"IN_PROGRESS","assignedToType":"ROLE","assignedToId":"senior_negotiator","assignedToName":"Senior Negotiator","dueDate":"2024-01-28T17:00:00.000Z"},"workflowStages":[{"id":"stage-101","stageName":"Initial Assessment","status":"COMPLETED","sequenceOrder":1},{"id":"stage-102","stageName":"Budget Approval","status":"COMPLETED","sequenceOrder":2},{"id":"stage-103","stageName":"Legal Review","status":"COMPLETED","sequenceOrder":3},{"id":"stage-104","stageName":"Technical Evaluation","status":"COMPLETED","sequenceOrder":4},{"id":"bcd23456-e89b-12d3-a456-426614174444","stageName":"Contract Negotiation","status":"IN_PROGRESS","sequenceOrder":5},{"id":"stage-106","stageName":"Final Approval","status":"PENDING","sequenceOrder":6},{"id":"stage-107","stageName":"Contract Signing","status":"PENDING","sequenceOrder":7},{"id":"stage-108","stageName":"Account Registration","status":"PENDING","sequenceOrder":8}]}],"meta":{"total":47,"page":1,"limit":20}}},"orderFulfillmentWorkflows":{"summary":"Order fulfillment workflows","description":"Example showing workflows for processing orders","value":{"data":[{"id":"345e6789-e89b-12d3-a456-426614176000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-015","name":"Sales Order Processing - Order #12345","description":"Processing and fulfillment for sales order #12345","status":"ACTIVE","entityType":"order_fulfillment","entityId":"customer-789","templateId":"890f0234-e89b-12d3-a456-426614174555","currentStageId":"cde34567-e89b-12d3-a456-426614174666","ownerType":"POSITION","ownerId":"operations_coordinator","dueDate":"2024-02-01T12:00:00.000Z","startedAt":"2024-01-20T09:00:00.000Z","completedAt":null,"totalStages":6,"completedStages":2,"progressPercentage":33.33,"context":{"customerId":"account-456","accountNumber":"3B","contractStartDate":"2024-02-01","recurringRevenue":18500,"securityDeposit":55500},"metadata":{"userCount":3,"additionalServices":false,"storageIncluded":true},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-20T08:00:00.000Z","createdBy":"admin@company.com","updatedAt":"2024-01-25T16:45:00.000Z","updatedBy":"coordinator@company.com","template":{"id":"890f0234-e89b-12d3-a456-426614174555","code":"order-fulfillment-standard","name":"Standard Order Fulfillment","description":"Complete order processing including verification and delivery","category":"order_management"},"currentStage":{"id":"cde34567-e89b-12d3-a456-426614174666","stageName":"Agreement Preparation","status":"IN_PROGRESS","assignedToType":"ROLE","assignedToId":"contract_administrator","assignedToName":"Lease Administrator","dueDate":"2024-01-27T17:00:00.000Z"},"workflowStages":[{"id":"stage-201","stageName":"Application Review","status":"COMPLETED","sequenceOrder":1},{"id":"stage-202","stageName":"Verification Check","status":"COMPLETED","sequenceOrder":2},{"id":"cde34567-e89b-12d3-a456-426614174666","stageName":"Agreement Preparation","status":"IN_PROGRESS","sequenceOrder":3},{"id":"stage-204","stageName":"Contract Signing","status":"PENDING","sequenceOrder":4},{"id":"stage-205","stageName":"Delivery Inspection","status":"PENDING","sequenceOrder":5},{"id":"stage-206","stageName":"Access Provisioning","status":"PENDING","sequenceOrder":6}]}],"meta":{"total":12,"page":1,"limit":20}}},"supportWorkflows":{"summary":"Maintenance request workflows","description":"Example showing support and repair workflows","value":{"data":[{"id":"456e7890-e89b-12d3-a456-426614177000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-032","name":"Critical Support Ticket Resolution","description":"Critical system issue requiring immediate resolution","status":"ACTIVE","entityType":"support_ticket","entityId":"ticket-2024-156","templateId":"901a1345-e89b-12d3-a456-426614174666","currentStageId":"def45678-e89b-12d3-a456-426614174777","ownerType":"ROLE","ownerId":"support_manager","dueDate":"2024-01-26T18:00:00.000Z","startedAt":"2024-01-25T08:30:00.000Z","completedAt":null,"totalStages":5,"completedStages":1,"progressPercentage":20,"context":{"priority":"HIGH_PRIORITY","customerId":"facility-a-001","accountNumber":"5C","ticketCategory":"system_issue","submittedBy":"customer-5c"},"metadata":{"estimatedBudget":15000,"technicianAssigned":"Tech Support Inc","supportContractApplicable":false},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-25T08:00:00.000Z","createdBy":"customer@portal.com","updatedAt":"2024-01-25T09:15:00.000Z","updatedBy":"support@company.com","template":{"id":"901a1345-e89b-12d3-a456-426614174666","code":"emergency-support","name":"Emergency Support Process","description":"Fast-track support workflow for critical issues","category":"support"},"currentStage":{"id":"def45678-e89b-12d3-a456-426614174777","stageName":"Technician Dispatch","status":"IN_PROGRESS","assignedToType":"ROLE","assignedToId":"support_coordinator","assignedToName":"Maintenance Coordinator","dueDate":"2024-01-25T12:00:00.000Z"},"workflowStages":[{"id":"stage-301","stageName":"Issue Assessment","status":"COMPLETED","sequenceOrder":1},{"id":"def45678-e89b-12d3-a456-426614174777","stageName":"Technician Dispatch","status":"IN_PROGRESS","sequenceOrder":2},{"id":"stage-303","stageName":"Issue Resolution","status":"PENDING","sequenceOrder":3},{"id":"stage-304","stageName":"Quality Inspection","status":"PENDING","sequenceOrder":4},{"id":"stage-305","stageName":"Customer Sign-off","status":"PENDING","sequenceOrder":5}]}],"meta":{"total":8,"page":1,"limit":20}}},"filteredByDueDate":{"summary":"Workflows filtered by due date","description":"Example showing workflows due within a specific date range","value":{"data":[{"id":"567e8901-e89b-12d3-a456-426614178000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-045","name":"Annual Quality Audit","description":"Mandatory Q1 2024 quality audit","status":"ACTIVE","entityType":"quality_audit","entityId":"audit-q1-2024","templateId":"a12b2456-e89b-12d3-a456-426614174777","currentStageId":"ef012345-e89b-12d3-a456-426614174888","ownerType":"POSITION","ownerId":"quality_manager","dueDate":"2024-01-31T17:00:00.000Z","startedAt":"2024-01-15T09:00:00.000Z","completedAt":null,"totalStages":4,"completedStages":1,"progressPercentage":25,"context":{"auditType":"quality_assurance","quarter":"Q1-2024","facilityCount":15,"certificationBody":"Regulatory Body"},"metadata":{"lastAuditDate":"2023-10-15","criticalFindingsFound":0,"minorFindingsFound":3},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-10T10:00:00.000Z","createdBy":"system@company.com","updatedAt":"2024-01-20T14:30:00.000Z","updatedBy":"quality@company.com","template":{"id":"a12b2456-e89b-12d3-a456-426614174777","code":"quarterly-quality-audit","name":"Quarterly Quality Audit","description":"Standardized quality audit workflow","category":"quality"},"currentStage":{"id":"ef012345-e89b-12d3-a456-426614174888","stageName":"Auditor Scheduling","status":"IN_PROGRESS","assignedToType":"USER","assignedToId":"user-quality-01","assignedToName":"Jane Smith","dueDate":"2024-01-25T17:00:00.000Z"},"workflowStages":[{"id":"stage-401","stageName":"Preparation","status":"COMPLETED","sequenceOrder":1},{"id":"ef012345-e89b-12d3-a456-426614174888","stageName":"Auditor Scheduling","status":"IN_PROGRESS","sequenceOrder":2},{"id":"stage-403","stageName":"Site Audits","status":"PENDING","sequenceOrder":3},{"id":"stage-404","stageName":"Report Submission","status":"PENDING","sequenceOrder":4}]}],"meta":{"total":3,"page":1,"limit":20}}}}}}},"400":{"description":"Bad request - Invalid query parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidDateFormat":{"summary":"Invalid date format","value":{"error":{"code":"INVALID_DATE_FORMAT","message":"Invalid date format for parameter 'dueDateFrom'. Use ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ)","details":{"parameter":"dueDateFrom","value":"2024-01-20","expectedFormat":"ISO 8601"}}}},"invalidEnumValue":{"summary":"Invalid enum value","value":{"error":{"code":"INVALID_ENUM_VALUE","message":"Invalid value for parameter 'status'. Must be one of: DRAFT, ACTIVE, ON_HOLD, COMPLETED, CANCELLED, ARCHIVED","details":{"parameter":"status","value":"RUNNING","allowedValues":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"]}}}},"invalidPagination":{"summary":"Invalid pagination parameters","value":{"error":{"code":"INVALID_PAGINATION","message":"Page number must be greater than 0","details":{"parameter":"page","value":0,"minValue":1}}}}}}}},"401":{"description":"Unauthorized - Invalid or missing authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"UNAUTHORIZED","message":"Invalid or missing API key","details":{"suggestion":"Ensure you're including a valid API key in the X-API-Key header"}}}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"You don't have permission to view workflows with portal visibility filtering","details":{"requiredPermission":"workflows:read:portal","yourPermissions":["workflows:read"]}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"An unexpected error occurred while retrieving workflows","details":{"requestId":"req-123456","timestamp":"2024-01-25T10:30:00.000Z"}}}}}}}},"post":{"tags":["Workflows"],"summary":"Create a new workflow instance","description":"Creates a new workflow instance for the authenticated organization. This is the primary\nentry point for initiating business processes in the system.\n\n## Business Logic Overview\n\n**Workflow Creation Process:**\n1. **Validation** - Validates required fields (name, entityType, entityId) and optional template access\n2. **Number Generation** - Auto-generates workflow number in format WF-YYYY-### (e.g., WF-2024-001)\n3. **Template Processing** - If templateId provided, validates template access and creates stages\n4. **Entity Linking** - Links workflow to specified business entity for context and tracking\n5. **Owner Assignment** - Assigns workflow ownership based on role, position, or specific user\n6. **Stage Creation** - Auto-generates workflow stages from template with proper sequencing\n\n**Template-Based vs Standalone Workflows:**\n- **Template-Based**: Automatically creates pre-defined stages with default assignments and sequencing\n- **Standalone**: Creates workflow without stages (can be added manually later)\n\n**Entity Types and Business Context:**\nWorkflows are always linked to business entities to provide context and enable proper data organization:\n- `customer_onboarding` - Customer onboarding and acquisition processes\n- `order_fulfillment` - Order processing and fulfillment\n- `support_ticket` - Customer support and issue resolution workflows\n- `quality_audit` - Regular or condition-based quality inspections\n- `contract_renewal` - Contract renewal processes\n- `business_project` - New development or transformation projects\n\n**Owner Assignment Types:**\n- `ROLE` - Assigned to organizational role (e.g., \"account-manager\", \"onboarding-specialist\")\n- `POSITION` - Assigned to specific position (e.g., \"regional-manager\", \"auditor-regional\")\n- `USER` - Assigned to specific user by ID or email address\n\n**Context Data Usage:**\nThe context field allows storing business-specific data that travels with the workflow:\n- Entity details (value, type, location, size)\n- Financial information (budget, approved amounts, currency)\n- Timeline constraints (move-in dates, completion deadlines)\n- Stakeholder information (brokers, contractors, inspectors)\n\n## Integration Points\n\n**Multi-Organization Data Isolation:**\nAll workflows are automatically scoped to the authenticated organization, ensuring complete data isolation.\n\n**Event Publication:**\nWorkflow creation publishes events to organization's Pub/Sub topic for real-time integration with external systems.\n\n**Audit Trail:**\nAll workflow operations are logged with complete audit context including actor, timestamp, and change details.\n\n## Norwegian Real Estate Use Cases\n\n- **Customer Onboarding**: Multi-stage customer acquisition with verification, approval, and legal processes\n- **Order Processing**: Complete order processing including verification, approval, and fulfillment\n- **Maintenance Workflows**: Structured support request handling from report to completion\n- **Quality Audits**: Periodic or condition-based quality assessments\n- **Lease Management**: Renewal processes, rent adjustments, and lease modifications\n- **Development Projects**: Construction and renovation project management\n","operationId":"createWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","entityType","entityId"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable workflow name. Should be descriptive and include key identifying\ninformation like entity identifier, customer name, or project reference.\n","example":"Customer Onboarding - ACME Corp - Strandgaten 15"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed description of the workflow purpose, scope, and any special requirements.\nThis is displayed to users and included in workflow reports.\n","example":"Complete customer onboarding process for enterprise client in downtown area."},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"Optional workflow template ID. When provided, the workflow will be created with\nall stages from the template, including default assignments and sequencing.\nTemplate must be active and accessible to the organization.\n","example":"789e0123-e89b-12d3-a456-426614174222"},"entityType":{"type":"string","enum":["customer_onboarding","order_fulfillment","support_ticket","quality_audit","contract_renewal","business_project","due_diligence","contract_management"],"description":"Type of business entity this workflow is for. This determines the workflow's\nbusiness context and affects available template options and integration points.\n","example":"customer_onboarding"},"entityId":{"type":"string","minLength":1,"maxLength":255,"description":"Unique identifier for the business entity. This can be an internal system ID,\nexternal reference number, or business-meaningful identifier like property address.\n","example":"manhattan-broadway-15-001"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of workflow owner assignment:\n- ROLE: Assigned to organizational role (flexible, multiple people)\n- POSITION: Assigned to specific position (single person per location/function)\n- USER: Assigned to specific individual user\n","example":"ROLE"},"ownerId":{"type":"string","nullable":true,"description":"Owner identifier based on ownerType:\n- For ROLE: Role name (e.g., \"account-manager\", \"onboarding-specialist\")\n- For POSITION: Position identifier (e.g., \"regional-manager-northeast\")\n- For USER: User ID or email address\n","example":"acquisition-manager"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Optional workflow completion deadline. When set, affects stage scheduling\nand provides deadline tracking for the entire workflow process.\n","example":"2024-12-31T23:59:59.000Z"},"context":{"type":"object","nullable":true,"description":"Business-specific context data that travels with the workflow. This data is\npreserved throughout the workflow lifecycle and can be updated as the process\nprogresses. Common fields include financial data, property details, and stakeholder information.\n","additionalProperties":true,"example":{"accountType":"enterprise","contractValue":45000000,"currency":"NOK","facilitySize":2500,"location":"New York, NY","partnerRef":"DNB-2024-0156","urgencyLevel":"normal","specialRequirements":["environmental_assessment","heritage_approval"]}},"entityLinks":{"type":"array","maxItems":20,"nullable":true,"description":"Optional entity links to create alongside the workflow. Enables atomic creation\nof workflows with multiple entity relationships in a single API call. Useful for\nmulti-party deals, complex property transactions, and workflows involving multiple\nstakeholders or properties. Maximum 20 entity links per workflow.\n","items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","minLength":1,"maxLength":100,"description":"Type of the entity to link to (e.g., 'property', 'client', 'tenant', 'vendor',\n'contractor', 'inspector'). This identifies the category of the linked entity.\n","example":"property"},"entityId":{"type":"string","minLength":1,"maxLength":50,"description":"Unique identifier of the entity to link to. This can be an internal system ID,\nexternal reference, or business identifier.\n","example":"acct-001"},"linkType":{"type":"string","enum":["related","reference","associated"],"default":"related","nullable":true,"description":"Type of relationship between the workflow and the linked entity:\n- **related**: General relationship, most common use case\n- **reference**: Entity is referenced but not directly involved\n- **associated**: Entity is associated but with weaker coupling\n","example":"related"},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Optional metadata for the entity link. Can include role information,\nrelationship details, or context-specific data.\n","example":{"role":"buyer","stakeholderType":"primary"}}}}}}},"examples":{"templateBasedPropertyAcquisition":{"summary":"Template-Based Customer Onboarding","description":"Creates workflow from template with automatic stage generation for complex property acquisition","value":{"name":"Customer Onboarding - ACME Corp - Strandgaten 15","description":"Complete customer onboarding process for enterprise client in downtown area.","templateId":"789e0123-e89b-12d3-a456-426614174222","entityType":"customer_onboarding","entityId":"manhattan-broadway-15-001","ownerType":"ROLE","ownerId":"acquisition-manager","dueDate":"2024-12-31T23:59:59.000Z","context":{"accountType":"enterprise","contractValue":45000000,"currency":"NOK","facilitySize":2500,"location":"New York, NY","partnerRef":"DNB-2024-0156","urgencyLevel":"high","specialRequirements":["environmental_assessment","heritage_approval"],"budgetApproved":true,"maxBudget":50000000}}},"standaloneMaintenanceWorkflow":{"summary":"Standalone Maintenance Workflow","description":"Creates workflow without template for custom support process","value":{"name":"Emergency Heating System Repair - Frogner Complex","description":"Urgent repair of central heating system affecting multiple units","entityType":"support_ticket","entityId":"frogner-heating-emergency-001","ownerType":"POSITION","ownerId":"support-supervisor-regional","dueDate":"2024-02-15T17:00:00.000Z","context":{"priority":"emergency","affectedUnits":24,"estimatedBudget":125000,"contractor":"Regional HVAC Services","serviceArea":"heating_ventilation"}}},"tenantOnboardingWithUser":{"summary":"Order Processing - User Assigned","description":"Creates tenant onboarding workflow assigned to specific user","value":{"name":"New Order Processing - Order #4B Frogner","description":"Complete order processing for new customer including background verification and contract signing","templateId":"456e7890-e89b-12d3-a456-426614174333","entityType":"order_fulfillment","entityId":"frogner-apt-4b-tenant-001","ownerType":"USER","ownerId":"maria.hansen@apart.no","context":{"apartmentId":"frogner-apt-4b","customerType":"standard","contractStartDate":"2024-03-01","recurringRevenue":18500,"currency":"NOK","securityDeposit":37000,"leaseDuration":12,"backgroundCheckRequired":true}}},"propertyInspectionWorkflow":{"summary":"Scheduled Quality Inspection","description":"Creates workflow for routine property inspection with specific timeline","value":{"name":"Q1 2024 Quality Inspection - Commercial Building Trondheim","description":"Quarterly inspection of commercial property including structural, electrical, and safety systems","templateId":"123e4567-e89b-12d3-a456-426614174444","entityType":"quality_audit","entityId":"trondheim-commercial-q1-2024","ownerType":"ROLE","ownerId":"property-inspector","dueDate":"2024-03-31T17:00:00.000Z","context":{"auditType":"quarterly","buildingType":"enterprise","totalArea":5200,"lastAuditDate":"2023-12-15","focusAreas":["structural","electrical","hvac","safety"],"tenantNotificationRequired":true}}},"multiPartyDealWorkflow":{"summary":"Multi-Party Deal Workflow with Entity Links","description":"Creates property acquisition workflow with multiple linked entities (property, buyer, seller) in single atomic operation","value":{"name":"Customer Onboarding - HQ Building","description":"Multi-party property acquisition with buyer, seller, and property entity relationships","templateId":"prop-acquisition-template-id","entityType":"deal","entityId":"deal-123","ownerType":"ROLE","ownerId":"acquisition-manager","dueDate":"2024-12-31T23:59:59.000Z","context":{"dealType":"customer_onboarding","totalValue":45000000,"currency":"NOK"},"entityLinks":[{"entityType":"property","entityId":"acct-001","linkType":"related","metadata":{"address":"Storgata 15, Oslo","accountType":"enterprise"}},{"entityType":"client","entityId":"buyer-456","linkType":"related","metadata":{"role":"buyer","stakeholderType":"primary"}},{"entityType":"client","entityId":"seller-789","linkType":"related","metadata":{"role":"seller"}}]}},"propertyInspectionWithMultipleProperties":{"summary":"Quality Inspection Workflow with Multiple Properties","description":"Creates inspection workflow linked to multiple properties, inspector, and property manager","value":{"name":"Q1 2024 Portfolio Inspection - Oslo Properties","description":"Quarterly inspection covering multiple properties in Oslo portfolio","templateId":"inspection-template-id","entityType":"inspection","entityId":"insp-q1-2024-oslo","ownerType":"ROLE","ownerId":"chief-inspector","dueDate":"2024-03-31T17:00:00.000Z","context":{"auditType":"quarterly","portfolioId":"oslo-commercial-portfolio"},"entityLinks":[{"entityType":"property","entityId":"acct-001","linkType":"related","metadata":{"address":"Storgata 15, Oslo","inspectionPriority":"high"}},{"entityType":"property","entityId":"prop-oslo-002","linkType":"related","metadata":{"address":"Drammensveien 45, Oslo","inspectionPriority":"medium"}},{"entityType":"inspector","entityId":"inspector-john-001","linkType":"related","metadata":{"role":"lead_inspector","specialization":["structural","electrical"]}},{"entityType":"account_manager","entityId":"pm-maria-002","linkType":"related","metadata":{"role":"coordinator","responsibility":"scheduling"}}]}}}}}},"responses":{"201":{"description":"Workflow created successfully. Returns the complete workflow object including\nauto-generated workflow number, initial status, and stage information if created from template.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"examples":{"templateBasedWorkflowCreated":{"summary":"Template-based workflow with auto-generated stages","description":"Shows workflow created from template with stages automatically generated","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-042","name":"Customer Onboarding - ACME Corp - Strandgaten 15","description":"Complete customer onboarding process for enterprise client","status":"DRAFT","entityType":"customer_onboarding","entityId":"manhattan-broadway-15-001","templateId":"789e0123-e89b-12d3-a456-426614174222","currentStageId":null,"ownerType":"ROLE","ownerId":"acquisition-manager","dueDate":"2024-12-31T23:59:59.000Z","startedAt":null,"completedAt":null,"totalStages":8,"completedStages":0,"progressPercentage":0,"context":{"accountType":"enterprise","contractValue":45000000,"currency":"NOK","facilitySize":2500,"location":"New York, NY","partnerRef":"DNB-2024-0156"},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-30T10:15:00.000Z","createdBy":"john.smith@company.com","updatedAt":"2024-01-30T10:15:00.000Z","updatedBy":"john.smith@company.com"}}},"standaloneWorkflowCreated":{"summary":"Standalone workflow without stages","description":"Shows workflow created without template - no stages generated","value":{"data":{"id":"987f6543-e21a-43b2-c789-123456789abc","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-043","name":"Emergency Heating System Repair - Frogner Complex","description":"Urgent repair of central heating system affecting multiple units","status":"DRAFT","entityType":"support_ticket","entityId":"frogner-heating-emergency-001","templateId":null,"currentStageId":null,"ownerType":"POSITION","ownerId":"support-supervisor-regional","dueDate":"2024-02-15T17:00:00.000Z","startedAt":null,"completedAt":null,"totalStages":0,"completedStages":0,"progressPercentage":0,"context":{"priority":"emergency","affectedUnits":24,"estimatedBudget":125000,"contractor":"Regional HVAC Services"},"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-30T11:30:00.000Z","createdBy":"maria.hansen@company.com","updatedAt":"2024-01-30T11:30:00.000Z","updatedBy":"maria.hansen@company.com"}}}}}}},"400":{"description":"Bad request due to invalid input data. Common causes include missing required fields,\ninvalid data types, or malformed request structure.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missingRequiredFields":{"summary":"Missing required fields","value":{"error":{"code":"VALIDATION_ERROR","message":"Workflow name is required., Entity type is required., Entity ID is required.","details":{"validationErrors":[{"field":"name","code":"FIELD_REQUIRED","message":"Workflow name is required."},{"field":"entityType","code":"FIELD_REQUIRED","message":"Entity type is required."},{"field":"entityId","code":"FIELD_REQUIRED","message":"Entity ID is required."}]}}}},"invalidFieldFormat":{"summary":"Invalid field format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid due date format, Owner type must be ROLE, POSITION, or USER","details":{"validationErrors":[{"field":"dueDate","code":"INVALID_FORMAT","message":"Invalid due date format"},{"field":"ownerType","code":"INVALID_ENUM_VALUE","message":"Owner type must be ROLE, POSITION, or USER"}]}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden - User lacks permission to create workflows or access specified template.\nThis can occur when trying to use templates from other organizations or when the\nAPI key lacks workflow creation permissions.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User does not have permission to create workflows.","details":{"requiredPermission":"workflows:create"}}}}}},"422":{"description":"Unprocessable Entity - Request is well-formed but contains logical errors.\nCommon scenarios include template not found, inactive template, or invalid entity references.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"templateNotFound":{"summary":"Workflow template not found","value":{"error":{"code":"TEMPLATE_NOT_FOUND","message":"Workflow template not found or not accessible.","details":{"templateId":"invalid-template-id","organizationId":"456e7890-e89b-12d3-a456-426614174111"}}}},"templateInactive":{"summary":"Template is inactive","value":{"error":{"code":"TEMPLATE_INACTIVE","message":"Workflow template is not active and cannot be used to create workflows.","details":{"templateId":"789e0123-e89b-12d3-a456-426614174222","templateStatus":"inactive"}}}},"invalidEntityReference":{"summary":"Invalid entity reference","value":{"error":{"code":"INVALID_ENTITY_REFERENCE","message":"Referenced entity does not exist or is not accessible.","details":{"entityType":"customer_onboarding","entityId":"nonexistent-entity-001"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}":{"get":{"tags":["Workflows"],"summary":"Retrieve detailed workflow information","description":"Retrieves comprehensive information about a specific workflow, including all stages,\ntemplate details, progress metrics, and optional context data. This endpoint provides\ncomplete visibility into workflow execution status and business data.\n\n## Business Logic\n\nThis endpoint implements sophisticated workflow retrieval with several key features:\n\n### Portal Visibility Control\nWhen `portal` and `portalUserId` parameters are provided, the system performs\nvisibility checks to ensure external users (customers, partners) can only access\nworkflows they have permission to view. This is crucial for multi-portal scenarios\nwhere workflows contain sensitive business data.\n\n### Context Data Integration\nThe `includeContext` parameter (default: true) controls whether live context data\nfrom external systems is fetched and included in the response. Context data provides\nreal-time business information that enriches the workflow with current state from\nCRM systems, integrated business systems, or other integrated services.\n\n### Comprehensive Stage Information\nReturns all workflow stages ordered by sequence with detailed status information,\nassignments, and progress metrics. This includes:\n- Current active stage identification\n- Stage-by-stage progress tracking\n- Assignment details for each stage\n- Dependencies and prerequisites\n\n### Template and Metadata\nIncludes full template information that defines the workflow structure,\nplus metadata about execution timeline, ownership, and business entity linkage.\n\n## Norwegian Real Estate Use Cases\n\n- **Customer Onboarding Monitoring**: Track multi-stage customer onboarding\n  processes from initial inquiry through final purchase, including due diligence,\n  legal review, and financial approval stages\n- **Order Fulfillment Status**: Monitor customer order\n  onboarding workflows with document collection, background checks, and\n  lease preparation stages\n- **Maintenance Request Tracking**: View detailed support workflow progress\n  from initial request through completion, including vendor coordination and\n  quality assurance\n- **Quality Audit Workflows**: Track comprehensive quality inspection\n  processes with technical assessments, quality checks, and reporting stages\n- **Contract Renewal Processes**: Monitor contract renewal workflows with customer\n  communication, market analysis, and contract preparation\n- **Business Development Projects**: Track project workflows from planning\n  permission through construction completion and occupancy\n\n## Performance Considerations\n\nContext data fetching may add latency when `includeContext=true`. For\nperformance-critical scenarios, set `includeContext=false` to retrieve\nonly core workflow data.\n","operationId":"getWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to retrieve. Must be a valid UUID\nbelonging to the authenticated organization.\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"example":"123e4567-e89b-12d3-a456-426614174000"},{"name":"portal","in":"query","schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","maxLength":50},"description":"Portal context identifier for visibility filtering. When provided,\nrestricts workflow access based on portal-specific visibility rules.\nUsed for customer portals, partner portals, or vendor access.\n\nCommon portal types:\n- `customer_portal`: Customer-facing portal access\n- `partner_portal`: Business partner access\n- `vendor_portal`: Service vendor access\n- `customer_portal`: Customer self-service portal\n","example":"customer_portal"},{"name":"portalUserId","in":"query","schema":{"type":"string","maxLength":255},"description":"User identifier within the specified portal context. Required when\n`portal` parameter is provided. This ensures workflows are only\naccessible to authorized portal users.\n\nThe format depends on the portal type:\n- Customer portal: customer account ID\n- Partner portal: partner user ID\n- Vendor portal: vendor representative ID\n- Customer portal: customer account ID\n","example":"customer-user-456"},{"name":"includeContext","in":"query","schema":{"type":"boolean","default":true},"description":"Whether to include live context data from external systems in the response.\nWhen true, fetches real-time data from integrated CRM, business systems,\nor other external systems. Set to false for faster response times when\ncontext data is not needed.\n\nContext data includes:\n- External system references\n- Live entity information\n- Customer details\n- Financial data\n- Document status\n","example":true},{"name":"includeHierarchy","in":"query","schema":{"type":"boolean","default":false},"description":"When true, enriches the workflow with complete hierarchy information including:\n- parent: Parent workflow (null if root)\n- children: Array of direct child workflows\n- siblings: Array of sibling workflows\n- depth: Hierarchy depth (0 = root, 1 = child, etc.)\n- isRoot: Whether this is a root workflow (has no parent)\n- breadcrumb: Path from root to this workflow for navigation\n\nThis is useful for displaying hierarchical views and breadcrumb navigation\nin the UI. Note that this adds additional database queries and may impact\nperformance.\n","example":false}],"responses":{"200":{"description":"Workflow details retrieved successfully. Returns comprehensive workflow\ninformation including all stages, progress metrics, template details,\nand optional context data.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["id","organizationId","workflowNumber","name","status","entityType","entityId","totalStages","completedStages","progressPercentage","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this workflow","example":"456e7890-e89b-12d3-a456-426614174111"},"workflowNumber":{"type":"string","description":"Human-readable workflow identifier following the format WF-YYYY-NNN.\nGenerated automatically when workflow is created.\n","pattern":"^WF-\\d{4}-\\d{3}$","example":"WF-2024-001"},"name":{"type":"string","maxLength":255,"description":"Workflow display name","example":"Customer Onboarding - ACME Corp"},"description":{"type":"string","nullable":true,"maxLength":1000,"description":"Detailed workflow description","example":"Complete customer onboarding process including verification, legal review, and account setup procedures"},"status":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"],"description":"Current workflow execution status:\n- DRAFT: Newly created, not yet started\n- ACTIVE: Currently executing with active stages\n- ON_HOLD: Temporarily paused, can be resumed\n- COMPLETED: All stages completed successfully\n- CANCELLED: Terminated before completion\n- ARCHIVED: Completed and archived for historical reference\n","example":"ACTIVE"},"entityType":{"type":"string","maxLength":100,"description":"Type of business entity this workflow operates on.\nCommon entity types:\n- customer_onboarding, order_fulfillment, support_ticket,\n- quality_audit, contract_renewal, business_project\n","example":"customer_onboarding"},"entityId":{"type":"string","maxLength":255,"description":"Identifier of the specific business entity this workflow processes.\nLinks workflow to external system records.\n","example":"cust-acme-001"},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"Template this workflow was created from","example":"789e0123-e89b-12d3-a456-426614174222"},"currentStageId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the currently active stage. Null if workflow hasn't started\nor has no active stages.\n","example":"987e6543-e89b-12d3-a456-426614174333"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of workflow ownership:\n- ROLE: Assigned to a role (e.g., 'acquisition-manager')\n- POSITION: Assigned to a position (e.g., 'regional-manager')\n- USER: Assigned to specific user (e.g., 'maria.hansen@apart.no')\n","example":"ROLE"},"ownerId":{"type":"string","nullable":true,"maxLength":255,"description":"Identifier of the workflow owner. Format depends on ownerType:\n- ROLE: role identifier (acquisition-manager)\n- POSITION: position identifier (regional-manager)\n- USER: user email or ID (maria.hansen@apart.no)\n","example":"acquisition-manager"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Workflow deadline in ISO 8601 format. Used for scheduling\nand progress monitoring.\n","example":"2024-12-31T23:59:59.000Z"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when workflow execution began (status changed to ACTIVE).\nNull for workflows that haven't started.\n","example":"2024-01-15T09:00:00.000Z"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when workflow was completed. Null for incomplete workflows.\n","example":"2024-03-15T16:30:00.000Z"},"totalStages":{"type":"integer","minimum":0,"description":"Total number of stages in the workflow","example":5},"completedStages":{"type":"integer","minimum":0,"description":"Number of stages that have been completed","example":2},"progressPercentage":{"type":"number","format":"float","minimum":0,"maximum":100,"description":"Workflow completion percentage calculated as\n(completedStages / totalStages) * 100\n","example":40},"context":{"type":"object","nullable":true,"description":"Custom workflow context data containing business-specific information.\nStructure varies by workflow type and business requirements.\n","additionalProperties":true,"example":{"contractValue":15000000,"accountType":"enterprise","location":"New York, USA","squareMeters":2500,"establishedYear":1998}},"metadata":{"type":"object","nullable":true,"description":"Additional workflow metadata for system use","additionalProperties":true},"publishEvents":{"type":"boolean","description":"Whether this workflow publishes events to Pub/Sub","example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic ID for workflow events","example":"111e2222-e89b-12d3-a456-426614174444"},"createdAt":{"type":"string","format":"date-time","description":"Workflow creation timestamp","example":"2024-01-10T08:00:00.000Z"},"createdBy":{"type":"string","maxLength":255,"description":"User who created the workflow","example":"lars.andersen@apart.no"},"updatedAt":{"type":"string","format":"date-time","description":"Last modification timestamp","example":"2024-01-20T14:30:00.000Z"},"updatedBy":{"type":"string","maxLength":255,"description":"User who last modified the workflow","example":"maria.hansen@apart.no"},"template":{"type":"object","nullable":true,"description":"Workflow template information","properties":{"id":{"type":"string","format":"uuid","description":"Template identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"code":{"type":"string","description":"Template code identifier","example":"customer-onboarding-standard"},"name":{"type":"string","description":"Template display name","example":"Customer Onboarding Standard Process"},"description":{"type":"string","nullable":true,"description":"Template description","example":"Standard workflow for customer onboarding"},"category":{"type":"string","nullable":true,"description":"Template category for organization","example":"real-estate"}}},"currentStage":{"type":"object","nullable":true,"description":"Details of the currently active stage","properties":{"id":{"type":"string","format":"uuid","description":"Stage identifier","example":"987e6543-e89b-12d3-a456-426614174333"},"stageName":{"type":"string","description":"Stage display name","example":"Technical Assessment"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"],"description":"Current stage status","example":"IN_PROGRESS"},"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of stage assignment","example":"USER"},"assignedToId":{"type":"string","nullable":true,"description":"Identifier of assigned entity","example":"erik.olsen@apart.no"},"assignedToName":{"type":"string","nullable":true,"description":"Display name of assignee","example":"Erik Olsen"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Stage deadline","example":"2024-02-15T17:00:00.000Z"}}},"workflowStages":{"type":"array","description":"All stages in the workflow ordered by sequence","items":{"type":"object","required":["id","stageName","status","sequenceOrder"],"properties":{"id":{"type":"string","format":"uuid","description":"Stage identifier"},"stageName":{"type":"string","description":"Stage display name"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"],"description":"Stage execution status"},"sequenceOrder":{"type":"integer","minimum":1,"description":"Stage position in workflow sequence"},"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of stage assignment"},"assignedToId":{"type":"string","nullable":true,"description":"Identifier of assigned entity"},"assignedToName":{"type":"string","nullable":true,"description":"Display name of assignee"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Stage deadline"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"When stage execution began"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When stage was completed"},"stageDefinition":{"type":"object","nullable":true,"description":"Stage template definition","properties":{"code":{"type":"string","description":"Stage definition code"},"name":{"type":"string","description":"Stage definition name"},"description":{"type":"string","nullable":true,"description":"Stage description"},"category":{"type":"string","nullable":true,"description":"Stage category"},"canBeSkipped":{"type":"boolean","description":"Whether stage can be skipped"},"requiresAssignment":{"type":"boolean","description":"Whether stage requires assignment"}}}}}},"projects":{"type":"array","description":"Projects associated with this workflow","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Project identifier"},"name":{"type":"string","description":"Project name"},"status":{"type":"string","description":"Project status"}}}},"tasks":{"type":"array","description":"Tasks associated with this workflow","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Task identifier"},"title":{"type":"string","description":"Task title"},"status":{"type":"string","description":"Task status"},"priority":{"type":"string","description":"Task priority"}}}},"contexts":{"type":"array","description":"Live context data from external systems (when includeContext=true).\nProvides real-time business information from integrated systems.\n","items":{"type":"object","description":"Context data from external system","additionalProperties":true}}}}}},"examples":{"customerOnboardingActive":{"summary":"Active Customer Onboarding Workflow","description":"Example of an active customer onboarding workflow in progress,\nshowing multiple completed stages and current technical assessment.\n","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-001","name":"Customer Onboarding - ACME Corp","description":"Complete customer onboarding process including verification, legal review, and account setup procedures","status":"ACTIVE","entityType":"customer_onboarding","entityId":"cust-acme-001","templateId":"789e0123-e89b-12d3-a456-426614174222","currentStageId":"987e6543-e89b-12d3-a456-426614174333","ownerType":"ROLE","ownerId":"acquisition-manager","dueDate":"2024-12-31T23:59:59.000Z","startedAt":"2024-01-15T09:00:00.000Z","completedAt":null,"totalStages":5,"completedStages":2,"progressPercentage":40,"context":{"contractValue":15000000,"accountType":"enterprise","location":"New York, USA","squareMeters":2500,"establishedYear":1998,"zoning":"commercial-mixed"},"metadata":{"sourceSystem":"business-crm","importedAt":"2024-01-10T08:00:00.000Z"},"publishEvents":true,"eventTopicId":"111e2222-e89b-12d3-a456-426614174444","createdAt":"2024-01-10T08:00:00.000Z","createdBy":"lars.andersen@apart.no","updatedAt":"2024-01-20T14:30:00.000Z","updatedBy":"maria.hansen@apart.no","template":{"id":"789e0123-e89b-12d3-a456-426614174222","code":"customer-onboarding-standard","name":"Customer Onboarding Standard Process","description":"Standard workflow for customer onboarding","category":"real-estate"},"currentStage":{"id":"987e6543-e89b-12d3-a456-426614174333","stageName":"Technical Assessment","status":"IN_PROGRESS","assignedToType":"USER","assignedToId":"erik.olsen@apart.no","assignedToName":"Erik Olsen","dueDate":"2024-02-15T17:00:00.000Z"},"workflowStages":[{"id":"111e1111-e89b-12d3-a456-426614174111","stageName":"Initial Assessment","status":"COMPLETED","sequenceOrder":1,"assignedToType":"ROLE","assignedToId":"business-analyst","assignedToName":"Business Analyst","startedAt":"2024-01-15T09:00:00.000Z","completedAt":"2024-01-18T16:00:00.000Z","stageDefinition":{"code":"initial-assessment","name":"Initial Customer Assessment","description":"Preliminary customer evaluation and needs analysis","category":"analysis","canBeSkipped":false,"requiresAssignment":true}},{"id":"222e2222-e89b-12d3-a456-426614174222","stageName":"Legal Review","status":"COMPLETED","sequenceOrder":2,"assignedToType":"USER","assignedToId":"anna.berg@apart.no","assignedToName":"Anna Berg","startedAt":"2024-01-19T08:00:00.000Z","completedAt":"2024-01-25T15:30:00.000Z","stageDefinition":{"code":"legal-due-diligence","name":"Legal Review","description":"Legal review of customer documents and agreements","category":"legal","canBeSkipped":false,"requiresAssignment":true}},{"id":"987e6543-e89b-12d3-a456-426614174333","stageName":"Technical Assessment","status":"IN_PROGRESS","sequenceOrder":3,"assignedToType":"USER","assignedToId":"erik.olsen@apart.no","assignedToName":"Erik Olsen","dueDate":"2024-02-15T17:00:00.000Z","startedAt":"2024-01-26T09:00:00.000Z","completedAt":null,"stageDefinition":{"code":"technical-assessment","name":"Technical Assessment","description":"Building inspection and technical evaluation","category":"technical","canBeSkipped":false,"requiresAssignment":true}},{"id":"444e4444-e89b-12d3-a456-426614174444","stageName":"Financial Review","status":"PENDING","sequenceOrder":4,"assignedToType":"ROLE","assignedToId":"financial-analyst","assignedToName":null,"dueDate":null,"startedAt":null,"completedAt":null,"stageDefinition":{"code":"financial-review","name":"Financial Review","description":"Financial analysis and ROI calculation","category":"financial","canBeSkipped":false,"requiresAssignment":true}},{"id":"555e5555-e89b-12d3-a456-426614174555","stageName":"Final Approval","status":"PENDING","sequenceOrder":5,"assignedToType":"ROLE","assignedToId":"acquisition-director","assignedToName":null,"dueDate":null,"startedAt":null,"completedAt":null,"stageDefinition":{"code":"final-approval","name":"Final Approval","description":"Executive approval for customer onboarding","category":"approval","canBeSkipped":false,"requiresAssignment":true}}],"projects":[{"id":"proj-001","name":"Manhattan Business Center","status":"ACTIVE"}],"tasks":[{"id":"task-001","title":"Business Valuation Report","status":"COMPLETED","priority":"HIGH"},{"id":"task-002","title":"Building Inspection","status":"IN_PROGRESS","priority":"HIGH"}],"contexts":[{"contextType":"entity_data","data":{"cadastralNumber":"160/32","titleNumber":"16032001","municipality":"New York","county":"Vestland"}}]}}},"orderFulfillmentCompleted":{"summary":"Completed Order Fulfillment Workflow","description":"Example of a completed order fulfillment workflow showing\nall stages completed and final status.\n","value":{"data":{"id":"abc12345-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-025","name":"New Order Processing - Order #4B","description":"Complete order processing for new customer order","status":"COMPLETED","entityType":"order_fulfillment","entityId":"frogner-apt-4b-001","templateId":"customer-template-001","currentStageId":null,"ownerType":"POSITION","ownerId":"regional-manager","dueDate":"2024-02-01T00:00:00.000Z","startedAt":"2024-01-05T08:00:00.000Z","completedAt":"2024-01-28T16:00:00.000Z","totalStages":4,"completedStages":4,"progressPercentage":100,"context":{"apartmentId":"frogner-apt-4b","customerType":"standard","contractStartDate":"2024-02-01","recurringRevenue":25000,"securityDeposit":75000,"leaseDuration":12},"metadata":{"completionMethod":"automatic","allStagesCompleted":true},"publishEvents":true,"eventTopicId":"222e3333-e89b-12d3-a456-426614174555","createdAt":"2024-01-03T10:00:00.000Z","createdBy":"kari.nordmann@apart.no","updatedAt":"2024-01-28T16:00:00.000Z","updatedBy":"system","template":{"id":"customer-template-001","code":"customer-onboarding-standard","name":"Standard Customer Onboarding","description":"Standard process for onboarding customers","category":"customer-management"},"currentStage":null,"workflowStages":[{"id":"stage-001","stageName":"Document Collection","status":"COMPLETED","sequenceOrder":1,"assignedToType":"USER","assignedToId":"ola.hansen@apart.no","assignedToName":"Ola Hansen","startedAt":"2024-01-05T08:00:00.000Z","completedAt":"2024-01-10T14:00:00.000Z"},{"id":"stage-002","stageName":"Verification Check","status":"COMPLETED","sequenceOrder":2,"assignedToType":"USER","assignedToId":"ola.hansen@apart.no","assignedToName":"Ola Hansen","startedAt":"2024-01-11T09:00:00.000Z","completedAt":"2024-01-15T16:00:00.000Z"},{"id":"stage-003","stageName":"Lease Preparation","status":"COMPLETED","sequenceOrder":3,"assignedToType":"USER","assignedToId":"ann.kristin.lee@apart.no","assignedToName":"Ann-Kristin Lee","startedAt":"2024-01-16T08:00:00.000Z","completedAt":"2024-01-22T15:30:00.000Z"},{"id":"stage-004","stageName":"Move-in Coordination","status":"COMPLETED","sequenceOrder":4,"assignedToType":"USER","assignedToId":"ola.hansen@apart.no","assignedToName":"Ola Hansen","startedAt":"2024-01-23T09:00:00.000Z","completedAt":"2024-01-28T16:00:00.000Z"}],"projects":[],"tasks":[{"id":"customer-task-001","title":"ID Document Verification","status":"COMPLETED","priority":"HIGH"},{"id":"customer-task-002","title":"Income Verification","status":"COMPLETED","priority":"HIGH"},{"id":"customer-task-003","title":"Lease Contract Signing","status":"COMPLETED","priority":"HIGH_PRIORITY"}],"contexts":[{"contextType":"customer_profile","data":{"tenantId":"customer-12345","fullName":"Jon Eriksson","email":"jon.eriksson@email.no","phone":"+47 12345678","nationalId":"01019012345"}}]}}},"supportWorkflowOnHold":{"summary":"Maintenance Workflow On Hold","description":"Example of a support workflow that has been put on hold,\nshowing partial progress and hold status.\n","value":{"data":{"id":"def67890-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-042","name":"HVAC System Repair - Building A","description":"Emergency repair of HVAC system in main office building","status":"ON_HOLD","entityType":"support_ticket","entityId":"hvac-repair-001","templateId":"support-template-001","currentStageId":"maint-stage-002","ownerType":"ROLE","ownerId":"support-supervisor","dueDate":"2024-02-28T18:00:00.000Z","startedAt":"2024-01-20T08:00:00.000Z","completedAt":null,"totalStages":3,"completedStages":1,"progressPercentage":33.33,"context":{"buildingId":"building-a","systemType":"hvac","urgencyLevel":"high","affectedCustomers":45,"estimatedBudget":150000},"metadata":{"holdReason":"Waiting for specialized parts delivery","expectedResumeDate":"2024-02-05"},"publishEvents":true,"eventTopicId":"333e4444-e89b-12d3-a456-426614174666","createdAt":"2024-01-18T12:00:00.000Z","createdBy":"per.jensen@apart.no","updatedAt":"2024-01-25T10:30:00.000Z","updatedBy":"system","template":{"id":"support-template-001","code":"emergency-support","name":"Emergency Support Process","description":"Process for handling urgent support requests","category":"support"},"currentStage":{"id":"maint-stage-002","stageName":"Parts Procurement","status":"BLOCKED","assignedToType":"USER","assignedToId":"supply.manager@apart.no","assignedToName":"Supply Manager","dueDate":"2024-02-05T16:00:00.000Z"},"workflowStages":[{"id":"maint-stage-001","stageName":"Initial Diagnosis","status":"COMPLETED","sequenceOrder":1,"assignedToType":"USER","assignedToId":"tech.expert@apart.no","assignedToName":"Technical Expert","startedAt":"2024-01-20T08:00:00.000Z","completedAt":"2024-01-22T15:00:00.000Z"},{"id":"maint-stage-002","stageName":"Parts Procurement","status":"BLOCKED","sequenceOrder":2,"assignedToType":"USER","assignedToId":"supply.manager@apart.no","assignedToName":"Supply Manager","dueDate":"2024-02-05T16:00:00.000Z","startedAt":"2024-01-23T09:00:00.000Z","completedAt":null},{"id":"maint-stage-003","stageName":"System Repair","status":"PENDING","sequenceOrder":3,"assignedToType":"ROLE","assignedToId":"hvac-technician","assignedToName":null,"dueDate":null,"startedAt":null,"completedAt":null}],"projects":[{"id":"building-maint-proj","name":"Building A Maintenance 2024","status":"ACTIVE"}],"tasks":[{"id":"diag-task-001","title":"System Performance Analysis","status":"COMPLETED","priority":"HIGH_PRIORITY"},{"id":"proc-task-001","title":"Order Replacement Parts","status":"IN_PROGRESS","priority":"HIGH"}],"contexts":[{"contextType":"support_details","data":{"workOrderNumber":"WO-2024-001","contractorId":"hvac-specialist-inc","warrantyStatus":"active","lastServiceDate":"2023-09-15"}}]}}}}}}},"400":{"description":"Bad request due to invalid parameters or malformed request.\nCommon causes include invalid UUID format or missing required parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidWorkflowId":{"summary":"Invalid Workflow ID Format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid workflow ID format. Must be a valid UUID.","details":{"field":"id","value":"invalid-id","expected":"UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"}}}},"missingPortalUserId":{"summary":"Missing Portal User ID","value":{"error":{"code":"VALIDATION_ERROR","message":"Portal user ID is required when portal parameter is provided.","details":{"portal":"customer_portal","missingParameter":"portalUserId"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden access. User lacks permission to access this workflow\nor portal visibility rules prevent access.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"portalAccessDenied":{"summary":"Portal Access Denied","value":{"error":{"code":"PORTAL_ACCESS_DENIED","message":"Workflow is not visible in the specified portal context.","details":{"portal":"customer_portal","portalUserId":"customer-123","workflowId":"123e4567-e89b-12d3-a456-426614174000"}}}},"insufficientPermissions":{"summary":"Insufficient Permissions","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"You do not have permission to access this workflow.","details":{"requiredPermission":"workflow.read","userRole":"viewer"}}}}}}}},"404":{"description":"Workflow not found or does not belong to the authenticated organization.\nThis may also occur if portal visibility rules hide the workflow.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotFound":{"summary":"Workflow Not Found","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111"}}}},"portalVisibilityHidden":{"summary":"Hidden by Portal Visibility","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization.","details":{"note":"Workflow may exist but is not visible in current portal context"}}}}}}}},"500":{"description":"Internal server error occurred while retrieving workflow details.\nThis may include database errors or context service failures.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"databaseError":{"summary":"Database Connection Error","value":{"error":{"code":"DATABASE_ERROR","message":"Failed to retrieve workflow due to database error.","details":{"operation":"workflow.findFirst","retryable":true}}}},"contextServiceError":{"summary":"Context Service Error","value":{"error":{"code":"CONTEXT_SERVICE_ERROR","message":"Failed to retrieve workflow context data from external systems.","details":{"contextTypes":["entity_data","customer_profile"],"note":"Workflow data returned without context information"}}}}}}}}}},"put":{"tags":["Workflows"],"summary":"Update workflow properties and validate status transitions","description":"Updates workflow metadata including name, description, status, ownership, due dates, and business context.\nImplements comprehensive business rule validation for status transitions and workflow lifecycle management.\n\n## Business Logic Overview\n\n**Core Update Operations:**\n- **Metadata Updates**: Modify workflow name, description, and due dates\n- **Ownership Management**: Reassign workflows between users, roles, or positions\n- **Status Lifecycle Management**: Control workflow progression through validated state transitions\n- **Context Data Updates**: Update business-specific information and external system references\n- **Audit Trail Maintenance**: Track all changes with actor information and timestamps\n\n**Status Transition Rules:**\n```\nDRAFT      → ACTIVE, CANCELLED\nACTIVE     → ON_HOLD, COMPLETED, CANCELLED\nON_HOLD    → ACTIVE, CANCELLED\nCOMPLETED  → (no transitions allowed - terminal state)\nCANCELLED  → DRAFT (restart workflow)\nARCHIVED   → (no transitions allowed - terminal state)\n```\n\n**Completion Validation:**\n- All required (non-optional) workflow stages must be COMPLETED or SKIPPED\n- System automatically updates completion timestamp and progress percentage\n- Cannot reverse completion status once workflow is COMPLETED\n\n**Norwegian Real Estate Use Cases:**\n- **Customer Onboarding**: Update timelines, budgets, and regulatory requirements\n- **Order Processing**: Modify ownership assignments and completion deadlines\n- **Maintenance Workflows**: Update status based on contractor availability\n- **Compliance Tracking**: Add regulatory context and update due dates\n- **Investment Analysis**: Update financial parameters and risk assessments\n\n**Business Rule Enforcement:**\n- Validates field length constraints (name: 255 chars, description: 2000 chars)\n- Ensures owner ID is provided when owner type is specified\n- Prevents due dates in the past during creation\n- Maintains data integrity across related workflow stages and tasks\n- Publishes workflow update events for external system integration\n","operationId":"updateWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to update","schema":{"type":"string","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkflowRequest"},"examples":{"basicStatusUpdate":{"summary":"Activate Draft Workflow","description":"Simple status transition from DRAFT to ACTIVE","value":{"status":"ACTIVE","actor":"maria.hansen@apart.no"}},"ownershipTransfer":{"summary":"Change Workflow Owner","description":"Transfer workflow ownership to a different user","value":{"ownerType":"USER","ownerId":"lars.eriksson@apart.no","actor":"maria.hansen@apart.no"}},"comprehensiveUpdate":{"summary":"Update Customer Onboarding Details","description":"Update multiple workflow properties including context data","value":{"name":"Customer Onboarding - ACME Corp - Phase 2","description":"Updated onboarding strategy for key customer in Bergen city center, including environmental assessment and zoning verification.","dueDate":"2024-12-15T23:59:59.000Z","context":{"contractValue":16500000,"urgencyLevel":"high","specialConditions":"Environmental assessment required","currency":"NOK","investorType":"institutional","lastAppraisal":"2024-01-15"},"actor":"maria.hansen@apart.no"}},"workflowOnHold":{"summary":"Put Active Workflow On Hold","description":"Pause an active workflow due to external factors","value":{"status":"ON_HOLD","context":{"holdReason":"Awaiting municipal planning approval","expectedResumeDate":"2024-03-01","contactPerson":"city.planning@bergen.kommune.no"},"actor":"project.manager@apart.no"}},"workflowResume":{"summary":"Resume Workflow from Hold","description":"Reactivate a workflow that was on hold","value":{"status":"ACTIVE","dueDate":"2024-04-30T17:00:00.000Z","context":{"resumeReason":"Planning approval received","updatedTimeline":"Extended by 6 weeks"},"actor":"project.manager@apart.no"}},"contextDataUpdate":{"summary":"Update Business Context Only","description":"Update workflow context without changing status or metadata","value":{"context":{"inspectionDate":"2024-02-15T10:00:00.000Z","inspectorName":"Technical Inspector AS","structuralCondition":"Excellent","estimatedRepairs":125000,"recommendedPurchasePrice":15800000},"actor":"technical.advisor@apart.no"}}}}}},"responses":{"200":{"description":"Workflow updated successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"examples":{"updatedWorkflow":{"summary":"Successfully updated workflow","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-003","name":"Customer Onboarding - ACME Corp - Phase 2","description":"Updated onboarding strategy for key customer","status":"ACTIVE","ownerType":"USER","ownerId":"maria.hansen@apart.no","dueDate":"2024-12-15T23:59:59.000Z","context":{"contractValue":16500000,"urgencyLevel":"high","currency":"NOK"},"updatedAt":"2024-01-26T11:30:00.000Z","updatedBy":"maria.hansen@apart.no"}}}}}}},"400":{"description":"Bad request - validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"fieldValidationError":{"summary":"Field validation failed","value":{"error":{"code":"VALIDATION_ERROR","message":"Workflow name cannot exceed 255 characters.","details":{"validationErrors":[{"field":"name","code":"FIELD_TOO_LONG","message":"Workflow name cannot exceed 255 characters.","maxLength":255,"actualLength":280}]}}}},"missingOwnerIdError":{"summary":"Missing required owner ID","value":{"error":{"code":"VALIDATION_ERROR","message":"Owner ID is required when owner type is specified.","details":{"validationErrors":[{"field":"ownerId","code":"FIELD_REQUIRED","message":"Owner ID is required when owner type is specified."}]}}}},"invalidDateFormatError":{"summary":"Invalid date format","value":{"error":{"code":"VALIDATION_ERROR","message":"Due date must be a valid ISO 8601 date string.","details":{"validationErrors":[{"field":"dueDate","code":"INVALID_DATE_FORMAT","message":"Due date must be a valid ISO 8601 date string."}]}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000"}}}}}},"422":{"description":"Unprocessable Entity - business rule violations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidStatusTransition":{"summary":"Invalid status transition","value":{"error":{"code":"INVALID_STATUS_TRANSITION","message":"Cannot transition from COMPLETED to ACTIVE.","details":{"currentStatus":"COMPLETED","requestedStatus":"ACTIVE","allowedTransitions":[]}}}},"incompleteStagesError":{"summary":"Cannot complete workflow with incomplete stages","value":{"error":{"code":"WORKFLOW_INCOMPLETE_STAGES","message":"Cannot complete workflow with incomplete required stages.","details":{"incompleteStages":["legal-review","financial-approval","contract-signing"],"incompleteCount":3}}}},"workflowNotFoundForUpdate":{"summary":"Workflow not found during validation","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}},"delete":{"tags":["Workflows"],"summary":"Permanently delete workflow with cascade deletion","description":"**Permanently deletes a workflow and all associated data in a cascading operation. \nThis action cannot be undone and should be used with extreme caution.**\n\n## Business Logic & Deletion Process\n\n### Pre-Deletion Validation\nThe system performs comprehensive validation before allowing deletion:\n\n1. **Workflow Existence**: Verifies the workflow exists and belongs to the authenticated organization\n2. **Active Task Validation**: Checks for any incomplete tasks (status != 'COMPLETED')\n3. **Dependency Validation**: Verifies no unsatisfied workflow dependencies exist\n4. **Completion Window Validation**: Prevents deletion of recently completed workflows (< 30 days)\n5. **Organization Security**: Ensures cross-tenant data isolation and access control\n\n### Cascade Deletion Behavior\nUpon successful validation, the system performs complete cascade deletion:\n\n- **Workflow Stages**: All workflow stages and their configurations\n- **Associated Tasks**: All tasks created from this workflow (if completed)  \n- **Stage Dependencies**: All stage-to-stage dependency relationships\n- **Workflow Transitions**: Stage transition history and configurations\n- **Audit Records**: All workflow-related audit trail entries\n- **Event History**: Historical events related to this workflow\n- **Context Associations**: Links to external systems and data\n\n### Post-Deletion Actions\nAfter successful deletion:\n\n1. **Event Publication**: Publishes `WORKFLOW_DELETED` event with deletion context\n2. **Audit Logging**: Records deletion action with actor information\n3. **Dependency Cleanup**: Updates any referencing systems or workflows\n\n## Norwegian Real Estate Use Cases\n\n- **Cancelled Acquisitions**: Remove workflows for cancelled property acquisitions\n- **Duplicate Cleanup**: Clean up accidentally created duplicate workflows  \n- **Test Data Removal**: Remove test workflows from production environments\n- **Compliance Cleanup**: Remove workflows after legal retention periods\n- **Template Updates**: Clear old workflows when updating process templates\n\n## Security & Authorization\n\n- **Organization Scoping**: Only workflows belonging to authenticated organization can be deleted\n- **API Key Validation**: Requires valid API key authentication\n- **Cross-Tenant Protection**: Prevents access to workflows from other organizations\n- **Audit Trail**: All deletion attempts are logged with actor information\n\n## Deletion Constraints & Business Rules\n\n### Active Dependencies Prevention\nWorkflows cannot be deleted if they have:\n- Active (incomplete) tasks in any status except 'COMPLETED'\n- Unsatisfied workflow dependencies that other processes rely on\n- Recently completed status (within 30 days for audit quality)\n\n### Recommended Pre-Deletion Steps\n1. Complete or cancel all active tasks\n2. Resolve any workflow dependencies  \n3. Export audit data if needed for quality\n4. Verify no external systems reference this workflow\n\n**⚠️ WARNING**: This operation is irreversible. All data associated with \nthe workflow will be permanently lost, including historical records and audit trails.\n","operationId":"deleteWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to delete. Must be a valid UUID \nand belong to the authenticated organization.\n","schema":{"type":"string","format":"uuid","example":"123e4567-e89b-12d3-a456-426614174000"}}],"responses":{"204":{"description":"Workflow successfully deleted. All associated data has been permanently \nremoved and a WORKFLOW_DELETED event has been published.\n"},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"404":{"description":"Workflow not found or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotFound":{"summary":"Workflow Not Found","description":"The specified workflow does not exist or does not belong to your organization","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-456e7890-e89b-12d3-a456-426614174111"}}}}}}}},"409":{"description":"Cannot delete workflow due to active dependencies or business constraints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"activeDependencies":{"summary":"Active Dependencies Prevent Deletion","description":"Workflow has active tasks or unsatisfied dependencies","value":{"error":{"code":"WORKFLOW_HAS_DEPENDENCIES","message":"Cannot delete workflow with active tasks or dependencies.","details":{"activeTasks":3,"activeTaskTitles":["Complete quality audit","Review customer application","Finalize lease agreement"],"activeDependencies":2,"workflowId":"123e4567-e89b-12d3-a456-426614174000"}}}},"recentlyCompleted":{"summary":"Recently Completed Workflow","description":"Cannot delete workflows completed within 30 days (audit quality)","value":{"error":{"code":"RECENTLY_COMPLETED_WORKFLOW","message":"Cannot delete workflows that were completed less than 30 days ago.","details":{"completedAt":"2024-01-15T10:30:00.000Z","daysSinceCompletion":10,"minimumRetentionDays":30,"workflowId":"123e4567-e89b-12d3-a456-426614174000"}}}}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}/start":{"post":{"tags":["Workflows"],"summary":"Start workflow execution","description":"**Initiates workflow execution by transitioning from DRAFT to ACTIVE status, establishing\nthe workflow execution environment and activating the first stage. This endpoint serves as\nthe entry point into the workflow orchestration system.**\n\n## Business Logic Process\n\nThe workflow start process implements a sophisticated multi-step orchestration that ensures\nproper initialization and system consistency:\n\n### Pre-Start Validation\nBefore execution begins, the system performs comprehensive readiness checks:\n- **Workflow Existence**: Validates the workflow exists within the organization scope\n- **Status Verification**: Ensures workflow is in DRAFT status (only DRAFT workflows can be started)\n- **Stage Completeness**: Confirms the workflow has at least one stage configured\n- **Template Integrity**: Verifies the underlying template structure is valid\n\n### Atomic State Transition\nThe start operation uses database transactions to ensure data consistency:\n- **Workflow Status**: Transitions from DRAFT → ACTIVE with timestamp recording\n- **Current Stage Assignment**: Sets the first stage (sequence_order: 1) as current_stage_id\n- **Stage Activation**: Updates first stage status from PENDING → READY for immediate execution\n- **Execution Timeline**: Records started_at timestamp for progress tracking\n\n### First Stage Initialization\nThe initial stage receives special handling to establish execution context:\n- **Status Activation**: First stage transitions to READY status, indicating availability for work\n- **Scheduling**: Sets scheduled_at timestamp to mark stage availability\n- **Assignment Preparation**: Prepares stage assignments and dependencies for execution\n- **Progress Calculation**: Initializes workflow progress metrics and completion tracking\n- **Stage Type Processing**:\n  - For TASK stages: Creates tasks from task templates if configured\n  - For WORKFLOW stages: Automatically instantiates child workflows from referenced templates\n    and manages parent-child relationships based on waitForCompletion settings\n\n### Integration with Workflow Orchestration System\nUpon successful start, the workflow integrates with the broader orchestration infrastructure:\n\n#### Event Publication\nPublishes `workflow.started` event to the organization's event stream containing:\n- **Workflow Metadata**: ID, number, name, and business entity linkage\n- **Start Context**: Actor information, start reason, and previous status\n- **Stage Information**: Details about the activated first stage\n- **Timeline Data**: Execution start timestamp and estimated duration\n\n#### Context Integration\nTriggers context system integration for external system synchronization:\n- **CRM Integration**: Notifies connected CRM systems of workflow initiation\n- **Calendar Systems**: Creates calendar entries for time-sensitive stages\n- **Project Management**: Updates linked project management systems\n- **Webhook Delivery**: Dispatches notifications to configured webhook endpoints\n\n#### Orchestration Engine Activation\nActivates workflow monitoring and progression logic:\n- **Progress Tracking**: Begins monitoring stage completion and workflow advancement\n- **Dependency Resolution**: Activates dependency checking for subsequent stages\n- **Assignment Management**: Enables assignment notifications and escalations\n- **SLA Monitoring**: Initiates due date tracking and alert systems\n\n## Norwegian Real Estate Use Cases\n\n- **Customer Onboarding Initiation**: Begin comprehensive property acquisition workflows\n  from initial market research through legal completion, including due diligence coordination,\n  financial approval processes, and regulatory quality checks\n- **Order Processing Launch**: Initiate multi-stage tenant onboarding processes covering\n  application review, background verification, lease preparation, and move-in coordination\n- **Maintenance Request Processing**: Start support workflows from initial reporting\n  through completion verification, including vendor assignment, work scheduling, and quality control\n- **Quality Audit Workflows**: Launch inspection processes covering technical assessments,\n  regulatory quality checks, documentation preparation, and follow-up actions\n- **Lease Renewal Operations**: Begin lease renewal workflows with tenant communication,\n  market analysis, contract negotiation, and documentation preparation\n- **Development Project Management**: Initiate construction and development workflows from\n  planning permission through occupancy certification and handover procedures\n- **Compliance Monitoring**: Start regulatory quality workflows for fire safety,\n  building standards, and environmental requirements with automated scheduling and reporting\n- **Nested Workflow Orchestration**: Start workflows with WORKFLOW-type stages that automatically\n  instantiate child workflows (e.g., property acquisition workflow that triggers inspection sub-workflow,\n  or tenant onboarding that launches background check workflow in parallel)\n\n## Validation Requirements\n\nThe start operation enforces strict validation to prevent invalid workflow execution:\n\n### Workflow State Validation\n- **Status Check**: Only workflows in DRAFT status can be started\n- **Organization Scope**: Workflow must belong to the requesting organization\n- **Template Integrity**: Associated template must be valid and complete\n- **Permission Verification**: User must have workflow start permissions\n\n### Stage Configuration Validation\n- **Stage Presence**: Workflow must have at least one configured stage\n- **Sequence Integrity**: Stage sequence orders must be properly configured\n- **Assignment Validity**: Stage assignments must reference valid users/roles\n- **Dependency Structure**: Stage dependencies must form valid execution paths\n\n### Business Logic Validation\n- **Entity Linkage**: Connected business entities must be accessible\n- **Template Compatibility**: Workflow configuration must match template requirements\n- **Resource Availability**: Required resources and integrations must be available\n- **Context Readiness**: External system connections must be functional\n\n## Stage Initialization Behavior\n\nThe first stage receives comprehensive initialization to establish proper execution context:\n\n### Status Management\n- **Initial Status**: First stage transitions from PENDING to READY\n- **Timestamp Recording**: scheduled_at timestamp marks stage availability\n- **Progress Initialization**: Stage progress metrics are established\n- **Assignment Activation**: Assigned users/roles receive notifications\n\n### Execution Context\n- **Work Environment**: Stage workspace and tools are prepared\n- **Data Access**: Required business data connections are established\n- **Integration Setup**: External system integrations are activated\n- **Notification Systems**: Alert and reminder systems are configured\n\n### Dependency Resolution\n- **Prerequisite Check**: Validates all stage prerequisites are met\n- **Resource Allocation**: Ensures required resources are available\n- **Coordination Setup**: Establishes inter-stage communication channels\n- **Monitoring Activation**: Begins stage progress and performance tracking\n\n## Error Scenarios for Invalid Starts\n\nThe system provides detailed error handling for various failure conditions:\n\n### Workflow State Errors\n- **Already Active**: Workflow is already in ACTIVE, ON_HOLD, COMPLETED, or CANCELLED status\n- **Already Completed**: Workflow has already been completed and cannot be restarted\n- **Invalid Status**: Workflow is in an unexpected status that prevents starting\n- **Archived Workflow**: Archived workflows cannot be started and must be restored first\n\n### Configuration Errors\n- **No Stages**: Workflow has no configured stages and cannot execute\n- **Invalid Template**: Associated template is missing or corrupted\n- **Broken Dependencies**: Stage dependencies contain circular references or invalid targets\n- **Assignment Issues**: Stage assignments reference non-existent users or roles\n\n### System Integration Errors\n- **Database Constraints**: Violates database integrity constraints\n- **External System**: Connected external systems are unavailable\n- **Permission Denied**: User lacks sufficient permissions to start the workflow\n- **Resource Conflicts**: Required resources are already in use by other workflows\n\n### Business Logic Errors\n- **Entity Unavailable**: Linked business entities are in invalid states\n- **Context Conflicts**: External context data conflicts with workflow requirements\n- **Timing Constraints**: Workflow cannot start due to scheduling restrictions\n- **Capacity Limits**: Organization has reached maximum concurrent workflow limits\n\n## Performance Considerations\n\nWorkflow startup involves multiple system operations that may impact performance:\n- **Database Transactions**: Uses atomic transactions for consistency but may create lock contention\n- **Event Publishing**: Event publication to Pub/Sub may add latency during high load\n- **Context Integration**: External system calls for context synchronization may timeout\n- **Notification Delivery**: User notifications and webhook calls execute asynchronously\n\nFor high-volume scenarios, consider batching workflow starts or implementing queued processing.\n","operationId":"startWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to start. Must be a valid UUID for a workflow\nin DRAFT status belonging to the authenticated organization. The workflow must\nhave at least one configured stage to be eligible for starting.\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"description":"Optional request body containing execution context for workflow start.\nThe actor parameter allows specifying who initiated the workflow start for audit purposes.\n","required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","description":"Optional identifier of the user or system initiating the workflow start.\nUsed for audit trails and event attribution. If not provided, uses the\nauthenticated user context.\n","example":"property.manager@realestate.no"}}},"examples":{"systemStart":{"summary":"System-initiated start","value":{"actor":"system.scheduler@realestate.no"}},"userStart":{"summary":"User-initiated start","value":{"actor":"property.manager@realestate.no"}},"minimalStart":{"summary":"Start with default actor","value":{}}}}}},"responses":{"200":{"description":"Workflow started successfully. Returns the updated workflow with ACTIVE status,\nstarted_at timestamp, current_stage_id set to the first stage, and first stage\nstatus updated to READY. All workflow stages are included with current progress\nand assignment information.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"examples":{"propertyAcquisition":{"summary":"Property acquisition workflow started","description":"Example of starting a property acquisition workflow with multiple stages","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-123","name":"Onboard Enterprise Customer","description":"Multi-stage onboarding process for premium customer","status":"ACTIVE","entityType":"customer_onboarding","entityId":"prop-frogner-456","templateId":"789e0123-e89b-12d3-a456-426614174222","currentStageId":"stage-001","ownerType":"USER","ownerId":"acquisition.manager@realestate.no","ownerName":"Customer Onboarding Manager","dueDate":"2024-02-15T17:00:00.000Z","startedAt":"2024-01-15T10:30:00.000Z","completedAt":null,"totalStages":5,"completedStages":0,"progressPercentage":0,"context":{"accountType":"standard","acquisitionValue":8500000,"location":"Frogner, Oslo","budgetApproved":true},"workflowStages":[{"id":"stage-001","stageName":"Market Analysis","status":"READY","sequenceOrder":1,"assignedToType":"ROLE","assignedToId":"market_analyst","assignedToName":"Market Analyst","scheduledAt":"2024-01-15T10:30:00.000Z","dueDate":"2024-01-20T17:00:00.000Z"},{"id":"stage-002","stageName":"Due Diligence","status":"PENDING","sequenceOrder":2,"assignedToType":"USER","assignedToId":"legal.team@realestate.no","assignedToName":"Legal Team"},{"id":"stage-003","stageName":"Financial Approval","status":"PENDING","sequenceOrder":3,"assignedToType":"ROLE","assignedToId":"finance_director","assignedToName":"Finance Director"},{"id":"stage-004","stageName":"Purchase Agreement","status":"PENDING","sequenceOrder":4,"assignedToType":"USER","assignedToId":"contracts.manager@realestate.no","assignedToName":"Contracts Manager"},{"id":"stage-005","stageName":"Closing Process","status":"PENDING","sequenceOrder":5,"assignedToType":"ROLE","assignedToId":"acquisition_closer","assignedToName":"Acquisition Closer"}],"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-10T14:22:00.000Z","createdBy":"acquisition.manager@realestate.no","updatedAt":"2024-01-15T10:30:00.000Z","updatedBy":"acquisition.manager@realestate.no"}}},"tenantOnboarding":{"summary":"Tenant onboarding workflow started","description":"Example of starting a tenant onboarding workflow for residential lease","value":{"data":{"id":"789e0123-e89b-12d3-a456-426614174333","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-456","name":"Process New Order - Order #4B","description":"Complete order processing for new customer","status":"ACTIVE","entityType":"order_fulfillment","entityId":"order-2024-789","templateId":"abc12345-e89b-12d3-a456-426614174555","currentStageId":"stage-101","ownerType":"ROLE","ownerId":"leasing_manager","ownerName":"Leasing Manager","dueDate":"2024-01-25T17:00:00.000Z","startedAt":"2024-01-15T11:45:00.000Z","completedAt":null,"totalStages":4,"completedStages":0,"progressPercentage":0,"context":{"businessAddress":"123 Business St, Suite 4B","contractStartDate":"2024-02-01","recurringRevenue":18500,"customerName":"John Smith"},"workflowStages":[{"id":"stage-101","stageName":"Application Review","status":"READY","sequenceOrder":1,"assignedToType":"USER","assignedToId":"leasing.coordinator@realestate.no","assignedToName":"Leasing Coordinator","scheduledAt":"2024-01-15T11:45:00.000Z","dueDate":"2024-01-17T17:00:00.000Z"},{"id":"stage-102","stageName":"Verification Check","status":"PENDING","sequenceOrder":2,"assignedToType":"ROLE","assignedToId":"quality_officer","assignedToName":"Compliance Officer"},{"id":"stage-103","stageName":"Lease Preparation","status":"PENDING","sequenceOrder":3,"assignedToType":"USER","assignedToId":"legal.assistant@realestate.no","assignedToName":"Legal Assistant"},{"id":"stage-104","stageName":"Move-in Coordination","status":"PENDING","sequenceOrder":4,"assignedToType":"ROLE","assignedToId":"operations_coordinator","assignedToName":"Operations Coordinator"}],"publishEvents":true,"eventTopicId":"def45678-e89b-12d3-a456-426614174444","createdAt":"2024-01-12T09:15:00.000Z","createdBy":"leasing.manager@realestate.no","updatedAt":"2024-01-15T11:45:00.000Z","updatedBy":"leasing.manager@realestate.no"}}}}}}},"400":{"description":"Workflow cannot be started due to validation failures or invalid state.\nThis includes workflows not in DRAFT status, workflows without stages,\nor workflows with configuration issues.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"alreadyActive":{"summary":"Workflow Already Active","description":"Attempting to start a workflow that is already in ACTIVE status","value":{"error":{"code":"WORKFLOW_INVALID_STATUS","message":"Cannot start workflow with status ACTIVE. Only DRAFT workflows can be started.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"ACTIVE","allowedStatuses":["DRAFT"],"operation":"start_workflow"}}}},"noStages":{"summary":"Workflow Without Stages","description":"Attempting to start a workflow that has no configured stages","value":{"error":{"code":"WORKFLOW_NO_STAGES","message":"Cannot start workflow without stages","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","stageCount":0,"operation":"start_workflow","suggestion":"Add stages to the workflow before starting"}}}},"alreadyCompleted":{"summary":"Workflow Already Completed","description":"Attempting to start a workflow that has already been completed","value":{"error":{"code":"WORKFLOW_INVALID_STATUS","message":"Cannot start workflow with status COMPLETED. Only DRAFT workflows can be started.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"COMPLETED","completedAt":"2024-01-10T15:30:00.000Z","operation":"start_workflow"}}}},"invalidTemplate":{"summary":"Invalid Template Configuration","description":"Workflow template has configuration issues preventing start","value":{"error":{"code":"WORKFLOW_TEMPLATE_INVALID","message":"Workflow template configuration is invalid or incomplete","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","templateId":"789e0123-e89b-12d3-a456-426614174222","validationErrors":["missing_stage_assignments","invalid_sequence_order"],"operation":"start_workflow"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"User lacks permission to start workflows or to start this specific workflow.\nThis may occur if the user doesn't have workflow management permissions or\nif organization-level restrictions prevent workflow execution.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficientPermissions":{"summary":"Insufficient Workflow Permissions","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User does not have permission to start workflows","details":{"userId":"user@realestate.no","requiredPermission":"workflow:start","userPermissions":["workflow:read","workflow:update"]}}}},"organizationRestriction":{"summary":"Organization Workflow Restrictions","value":{"error":{"code":"ORGANIZATION_RESTRICTION","message":"Organization has restrictions preventing workflow execution","details":{"organizationId":"456e7890-e89b-12d3-a456-426614174111","restriction":"concurrent_workflow_limit","currentWorkflows":50,"maxAllowed":50}}}}}}}},"404":{"description":"Workflow not found or not accessible within the authenticated organization.\nThe workflow ID may be invalid, the workflow may have been deleted, or it\nmay belong to a different organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotFound":{"summary":"Workflow Not Found","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","operation":"start_workflow"}}}},"workflowDeleted":{"summary":"Workflow Previously Deleted","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found - may have been deleted","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","operation":"start_workflow","suggestion":"Check workflow ID or restore from archive if available"}}}}}}}},"500":{"description":"Internal server error during workflow start operation. This may be due to\ndatabase transaction failures, event publishing errors, or integration system\nfailures. The workflow remains in its original state.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"databaseError":{"summary":"Database Transaction Failure","value":{"error":{"code":"DATABASE_ERROR","message":"Failed to start workflow due to database transaction error","details":{"operation":"workflow_start_transaction","retryable":true,"transactionId":"tx-start-123456"}}}},"eventPublishError":{"summary":"Event Publishing Failure","description":"Workflow started but event publishing failed","value":{"error":{"code":"EVENT_PUBLISH_ERROR","message":"Workflow started successfully but event publishing failed","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","eventType":"workflow.started","pubsubError":"DEADLINE_EXCEEDED","retryable":true}}}},"integrationError":{"summary":"External System Integration Failure","value":{"error":{"code":"INTEGRATION_ERROR","message":"Failed to start workflow due to external system integration failure","details":{"system":"calendar_integration","operation":"create_workflow_calendar_events","errorCode":"CALENDAR_SERVICE_UNAVAILABLE","retryable":true}}}}}}}}}}},"/api/v1/workflows/{id}/pause":{"post":{"tags":["Workflows"],"summary":"Pause active workflow execution","description":"Pauses an active workflow by transitioning its status from ACTIVE to ON_HOLD.\nThis operation provides a controlled way to temporarily halt workflow progression\nwhile preserving all current stage states and progress data.\n\n## Business Logic\n\n**Status Transition:** ACTIVE → ON_HOLD\n- Only workflows in ACTIVE status can be paused\n- All stage progression stops immediately\n- Current stage assignments and data are preserved\n- Workflow can be resumed later using the resume endpoint\n\n**Stage State Preservation:**\n- IN_PROGRESS stages remain in IN_PROGRESS state\n- Task assignments and deadlines are maintained\n- Form data and attachments are preserved\n- Stage dependencies and sequence order remain intact\n\n**Event Publication:**\n- Publishes WORKFLOW_PAUSED event with status transition details\n- Includes pause reason and actor information\n- Triggers downstream integrations and notifications\n\n## Norwegian Real Estate Use Cases\n\n**Customer Onboarding Workflows:**\n- Pause due to financing complications or market volatility\n- Hold for regulatory approval delays (kommunal behandling)\n- Suspend for additional due diligence requirements\n\n**Tenant Management Workflows:**\n- Pause onboarding pending missing documentation (inntektserklæring, referanser)\n- Hold lease renewals for rent regulation reviews\n- Suspend eviction processes during appeal periods\n\n**Property Development Workflows:**\n- Pause construction workflows for permit delays (byggetillatelse)\n- Hold renovation projects for seasonal restrictions\n- Suspend zoning approval processes for municipal reviews\n\n**Maintenance and Inspection Workflows:**\n- Pause scheduled support for weather conditions\n- Hold inspection workflows for scheduling conflicts\n- Suspend emergency repairs pending insurance approval\n\n## Integration with External Systems\n\n**Calendar Integration:**\n- Scheduled appointments remain in calendar with \"PAUSED\" status\n- Meeting invitations include pause notification\n- Recurring calendar events are temporarily disabled\n\n**CRM Integration:**\n- Customer records updated with workflow pause status\n- Communication templates adjusted for pause notifications\n- Sales pipelines reflect paused property processes\n\n**Project Management Integration:**\n- External project boards updated with pause status\n- Resource allocation temporarily released\n- Milestone tracking suspended until resume\n\n## Common Pause Scenarios\n\n1. **External Dependencies:** Waiting for third-party approvals or documentation\n2. **Resource Constraints:** Team unavailability or budget limitations\n3. **Market Conditions:** Unfavorable market timing for property transactions\n4. **Regulatory Delays:** Government or municipal processing delays\n5. **Client Requests:** Property owner or tenant-initiated pauses\n6. **Technical Issues:** System support or integration problems\n7. **Seasonal Factors:** Weather-dependent activities in Norwegian climate\n\n## Best Practices\n\n- Always provide a clear reason for pausing workflows\n- Communicate pause status to all stakeholders\n- Set expected resume timeframes when possible\n- Monitor paused workflows for extended durations\n- Document external blocking conditions for audit trails\n","operationId":"pauseWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier for the workflow to pause","schema":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440000"}}],"requestBody":{"description":"Optional pause request parameters","required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","description":"ID of the user or system initiating the pause","example":"user-123"},"reason":{"type":"string","description":"Reason for pausing the workflow","maxLength":500,"example":"Waiting for bank financing approval"}}},"examples":{"userPause":{"summary":"User-initiated pause","value":{"actor":"user-123","reason":"Pausing property acquisition pending market analysis"}},"systemPause":{"summary":"System-initiated pause","value":{"actor":"system","reason":"External API unavailable - regulatory data service"}}}}}},"responses":{"200":{"description":"Workflow paused successfully","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"example":{"data":{"id":"550e8400-e29b-41d4-a716-446655440000","name":"Customer Onboarding - Storgata 15","workflow_number":"WF-2024-0156","status":"ON_HOLD","entity_type":"property","entity_id":"prop-789","started_at":"2024-01-15T09:00:00.000Z","paused_at":"2024-01-20T14:30:00.000Z","current_stage":{"id":"stage-456","stage_name":"Due Diligence Review","status":"IN_PROGRESS","sequence_order":2},"workflow_stages":[{"id":"stage-123","stage_name":"Initial Assessment","status":"COMPLETED","sequence_order":1},{"id":"stage-456","stage_name":"Due Diligence Review","status":"IN_PROGRESS","sequence_order":2},{"id":"stage-789","stage_name":"Financing Approval","status":"PENDING","sequence_order":3}]}}}}},"400":{"description":"Invalid pause request or workflow cannot be paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotActive":{"summary":"Workflow not in active state","value":{"error":{"code":"WORKFLOW_NOT_ACTIVE","message":"Cannot pause workflow with status COMPLETED. Only ACTIVE workflows can be paused.","details":{"workflowId":"550e8400-e29b-41d4-a716-446655440000","currentStatus":"COMPLETED","allowedStatuses":["ACTIVE"]}}}},"workflowAlreadyPaused":{"summary":"Workflow already paused","value":{"error":{"code":"WORKFLOW_NOT_ACTIVE","message":"Cannot pause workflow with status ON_HOLD. Only ACTIVE workflows can be paused.","details":{"workflowId":"550e8400-e29b-41d4-a716-446655440000","currentStatus":"ON_HOLD","allowedStatuses":["ACTIVE"]}}}},"workflowCancelled":{"summary":"Cancelled workflow cannot be paused","value":{"error":{"code":"WORKFLOW_NOT_ACTIVE","message":"Cannot pause workflow with status CANCELLED. Only ACTIVE workflows can be paused.","details":{"workflowId":"550e8400-e29b-41d4-a716-446655440000","currentStatus":"CANCELLED","allowedStatuses":["ACTIVE"]}}}},"invalidWorkflowId":{"summary":"Invalid workflow ID format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid workflow ID format. Must be a valid UUID.","details":{"field":"id","value":"invalid-workflow-id","expected":"UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"}}}},"reasonTooLong":{"summary":"Pause reason exceeds maximum length","value":{"error":{"code":"VALIDATION_ERROR","message":"Pause reason exceeds maximum length of 500 characters.","details":{"field":"reason","maxLength":500,"actualLength":652}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Insufficient permissions to pause workflow","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User does not have permission to pause workflows in this organization.","details":{"requiredPermission":"workflow:pause","userRole":"viewer"}}}}}},"404":{"$ref":"#/components/responses/NotFoundError"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}/resume":{"post":{"tags":["Workflows"],"summary":"Resume paused workflow execution","description":"Resumes a paused workflow by transitioning its status from ON_HOLD back to ACTIVE, \nrestoring full workflow orchestration and continuing execution from the exact point \nwhere it was paused. This operation maintains all previous progress, stage states, \nand external system integrations.\n\n## Business Logic & Resume Process\n\n### Status Transition\n- Validates workflow exists and belongs to the organization\n- Ensures workflow is currently in ON_HOLD status (only paused workflows can be resumed)\n- Changes status from ON_HOLD → ACTIVE with audit tracking\n- Publishes WORKFLOW_RESUMED event with transition details and actor information\n\n### Progress Preservation\n- **Stage State Restoration:** All workflow stages maintain their exact state from pause time\n- **Assignment Continuity:** Task assignments, owners, and responsibilities remain unchanged  \n- **Timeline Preservation:** Due dates, start dates, and scheduling information are maintained\n- **Data Integrity:** Custom fields, attachments, and metadata remain intact\n- **History Maintenance:** Complete audit trail of pause/resume cycles is preserved\n\n### External System Reintegration\n- **Calendar Integration:** Reactivates Cronofy calendar synchronization for scheduled activities\n- **Notification Systems:** Resumes webhook deliveries and real-time event streaming\n- **Context Integrations:** Reestablishes connections with CRM, project management tools\n- **Pub/Sub Reactivation:** Restarts event publication to Google Cloud Pub/Sub topics\n- **Visibility Restoration:** Reinstates portal visibility and stakeholder access controls\n\n## Norwegian Real Estate Resume Scenarios\n\n### Customer Onboarding Workflows\n- **Market Analysis Complete:** Resume after favorable market assessment results\n- **Financing Approved:** Continue acquisition after mortgage pre-approval secured\n- **Due Diligence Ready:** Restart property inspection and legal review processes\n- **Regulatory Clearance:** Resume after municipal zoning or permit approvals\n\n### Tenant Management Operations  \n- **Documentation Received:** Continue onboarding after tenant provides required documents\n- **Reference Verification:** Resume processing after employment and credit checks complete\n- **Lease Negotiation:** Restart workflow after tenant agreement on terms and conditions\n- **Move-in Coordination:** Resume scheduling after property preparation completion\n\n### Property Maintenance & Services\n- **Contractor Availability:** Resume support workflow after service provider scheduling\n- **Budget Approval:** Continue work after management company or owner funding approval\n- **Weather Conditions:** Restart exterior work after Norwegian winter weather clears\n- **Material Procurement:** Resume after specialized equipment or materials arrive\n\n### Regulatory & Compliance Workflows\n- **Government Processing:** Continue after Kartverket, Brønnøysund, or municipal approvals\n- **Environmental Clearance:** Resume after environmental impact assessments complete\n- **Building Permits:** Continue construction workflows after permit issuance\n- **Fire Safety Compliance:** Resume occupancy workflows after safety inspections pass\n\n## Resume Operation Characteristics\n\n### Immediate Effects\n- Workflow becomes eligible for stage progression and task execution\n- Automated triggers and scheduled activities resume normal operation  \n- Team notifications and assignment alerts are reactivated\n- Integration webhooks begin delivering real-time updates again\n\n### Stakeholder Impact\n- **Property Managers:** Regain full workflow visibility and control capabilities\n- **Field Teams:** Resume receiving task assignments and scheduling updates\n- **External Partners:** Restart receiving automated status updates via webhooks\n- **Compliance Officers:** Resume monitoring workflow progress and milestone completion\n\n## Performance & Reliability\n\n- **Atomic Operation:** Resume completes fully or fails entirely with rollback\n- **Event Consistency:** All downstream systems receive resume notifications\n- **Audit Compliance:** Complete traceability of resume actions and timing\n- **Concurrent Safety:** Multiple simultaneous resume attempts are safely handled\n\n## Integration Points\n\n- **Event System:** Publishes to organization's Pub/Sub topics for real-time updates\n- **Calendar Services:** Reactivates Cronofy integration for German data center quality\n- **Notification Platform:** Resumes webhook deliveries to configured external endpoints\n- **Context Management:** Reestablishes bi-directional integration with connected systems\n","operationId":"resumeWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to resume. Must be a valid UUID \nbelonging to an existing workflow in the organization that is currently \nin ON_HOLD status.\n","schema":{"type":"string","format":"uuid"},"example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"description":"Optional request body containing actor information for audit purposes.\nIf not provided, the authenticated user will be recorded as the actor.\n","required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","description":"Identifier of the user or system initiating the resume operation","example":"user-123"}}},"example":{"actor":"user-456"}}}},"responses":{"200":{"description":"Workflow successfully resumed and returned to ACTIVE status. The response \nincludes the complete workflow object with updated status, timestamps, and \nall related data including template, current stage, and workflow stages.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"example":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Customer Onboarding - Storgata 15","status":"ACTIVE","workflow_number":"WF-2024-001","updated_at":"2024-01-25T14:30:00.000Z","updated_by":"user-456","template":{"name":"Standard Customer Onboarding","category":"PROPERTY_MANAGEMENT"},"current_stage":{"name":"Due Diligence Review","status":"IN_PROGRESS"},"workflow_stages":[]}}}}},"400":{"description":"Invalid resume request. This occurs when the workflow cannot be resumed \ndue to business rule violations or current workflow state constraints.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflow_not_paused":{"summary":"Workflow is not in paused state","value":{"error":{"code":"WORKFLOW_NOT_PAUSED","message":"Cannot resume workflow with status ACTIVE. Only ON_HOLD workflows can be resumed.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"ACTIVE","allowedStatus":"ON_HOLD","operation":"resume"}}}},"workflow_completed":{"summary":"Workflow is already completed","value":{"error":{"code":"WORKFLOW_NOT_PAUSED","message":"Cannot resume workflow with status COMPLETED. Only ON_HOLD workflows can be resumed.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"COMPLETED","completedAt":"2024-01-20T10:15:00.000Z"}}}},"workflow_cancelled":{"summary":"Workflow was cancelled","value":{"error":{"code":"WORKFLOW_NOT_PAUSED","message":"Cannot resume workflow with status CANCELLED. Only ON_HOLD workflows can be resumed.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"CANCELLED","cancelledAt":"2024-01-18T16:45:00.000Z"}}}},"invalid_workflow_id":{"summary":"Invalid workflow ID format","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid workflow ID format. Must be a valid UUID.","details":{"field":"id","providedValue":"invalid-id","expectedFormat":"uuid"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Insufficient permissions to resume workflows in this organization. \nUser lacks the required workflow management permissions.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"User does not have permission to resume workflows in this organization.","details":{"requiredPermission":"workflow:resume","userRole":"viewer","organizationId":"org-123"}}}}}},"404":{"description":"Workflow not found in the organization. Either the workflow ID doesn't exist \nor the workflow belongs to a different organization than the authenticated user.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found in organization","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"org-123","operation":"resume"}}}}}},"409":{"description":"Resume operation conflicts with current workflow state or concurrent operations. \nThis can occur when multiple users attempt to modify the workflow simultaneously.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"concurrent_modification":{"summary":"Concurrent workflow modification","value":{"error":{"code":"CONCURRENT_MODIFICATION","message":"Workflow was modified by another user. Please refresh and try again.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","lastModifiedBy":"other-user-789","lastModifiedAt":"2024-01-25T14:29:30.000Z"}}}},"stage_dependency_conflict":{"summary":"Stage dependencies prevent resume","value":{"error":{"code":"STAGE_DEPENDENCY_CONFLICT","message":"Cannot resume workflow due to unresolved stage dependencies.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","blockingStages":["legal-review","financial-approval"],"requiredActions":["Complete legal document review","Obtain budget approval"]}}}}}}}},"500":{"description":"Internal server error occurred during workflow resume operation. This may be \ndue to database connectivity issues, external service failures, or system errors.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"database_error":{"summary":"Database connection failure","value":{"error":{"code":"DATABASE_ERROR","message":"Database connection failed during workflow resume operation","details":{"operation":"workflow_resume","workflowId":"123e4567-e89b-12d3-a456-426614174000","timestamp":"2024-01-25T14:30:00.000Z"}}}},"event_publish_failure":{"summary":"Event publication failed","value":{"error":{"code":"EVENT_PUBLISH_ERROR","message":"Failed to publish workflow resume event to Pub/Sub","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","eventType":"WORKFLOW_RESUMED","pubsubTopic":"workflow-events","retryable":true}}}},"external_service_error":{"summary":"External service integration failure","value":{"error":{"code":"EXTERNAL_SERVICE_ERROR","message":"Failed to reactivate external system integrations","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","failedServices":["cronofy-calendar","webhook-delivery"],"partialSuccess":true}}}}}}}}}}},"/api/v1/workflows/{id}/complete":{"post":{"tags":["Workflows"],"summary":"Complete workflow execution and finalize all stages","description":"**Completes a workflow by transitioning it to COMPLETED status, performing comprehensive\nvalidation of stage completion requirements, calculating final metrics, and publishing\ncompletion events. This endpoint represents the final step in workflow orchestration,\nensuring all business requirements are satisfied before closure.**\n\n## Business Logic Overview\n\nThe completion process implements sophisticated validation and finalization logic to ensure\nbusiness process integrity and maintain audit quality:\n\n### Pre-Completion Validation\nBefore allowing completion, the system performs comprehensive business rule validation:\n- **Workflow Existence**: Validates workflow exists within organization scope\n- **Status Verification**: Ensures workflow is not already in COMPLETED state\n- **Stage Completion Analysis**: Validates all required (non-optional) stages are COMPLETED or SKIPPED\n- **Business Rule Compliance**: Ensures all mandatory business process steps have been satisfied\n- **Data Integrity**: Verifies all stage data and attachments are properly saved\n\n### Stage Completion Validation Rules \nThe system applies strict validation to ensure workflow integrity:\n\n**Required Stage Validation:**\n- All stages with `is_optional: false` must have status COMPLETED or SKIPPED\n- Stages marked as PENDING, ACTIVE, READY, or BLOCKED prevent completion\n- Failed stages (status: FAILED) are treated as incomplete unless manually overridden\n\n**Optional Stage Handling:**\n- Optional stages (`is_optional: true`) do not prevent completion regardless of status\n- Provides workflow flexibility for non-critical business steps\n- Allows completion when optional stages are skipped due to business conditions\n\n**Stage Status Interpretation:**\n```\nCOMPLETED ✓ - Stage finished successfully, contributes to progress\nSKIPPED   ✓ - Stage bypassed intentionally, counted as complete\nPENDING   ✗ - Stage not started, blocks completion if required\nACTIVE    ✗ - Stage in progress, must finish before completion\nREADY     ✗ - Stage ready but not started, blocks completion\nBLOCKED   ✗ - Stage cannot proceed, must be resolved or skipped\nFAILED    ✗ - Stage failed, requires resolution or manual override\n```\n\n### Final Metrics Calculation\nUpon successful validation, the system calculates comprehensive completion metrics:\n\n**Progress Metrics:**\n- **Completed Stages Count**: Total number of stages with COMPLETED or SKIPPED status\n- **Progress Percentage**: Always set to 100.0% for completed workflows\n- **Completion Duration**: Time elapsed from `started_at` to `completed_at`\n- **Efficiency Metrics**: Actual vs planned duration for performance analysis\n\n**Final State Assignment:**\n- **Status Transition**: Any valid status → COMPLETED (terminal state)\n- **Completion Timestamp**: Records exact completion time (`completed_at`)\n- **Current Stage Reset**: Sets `current_stage_id` to null (no active stage)\n- **Progress Finalization**: Updates `completed_stages` and `progress_percentage`\n\n### Event Publication and Integration\nCompletion triggers comprehensive event publication for downstream systems:\n\n**Core Event Publication:**\n- **WORKFLOW_COMPLETED Event**: Published to `workflow-events` topic\n- **Completion Context**: Includes actor information, duration, and stage statistics\n- **Business Metadata**: Entity type, completion type (manual), and notes\n- **Integration Triggers**: Notifies external systems and webhook endpoints\n\n**Event Data Structure:**\n```json\n{\n  \"eventTypeCode\": \"workflow.completed\",\n  \"eventData\": {\n    \"workflowId\": \"workflow-uuid\",\n    \"completionContext\": {\n      \"completedByActor\": { \"id\": \"user-123\", \"type\": \"user\", \"name\": \"Anna Berg\" },\n      \"completionType\": \"manual\",\n      \"actualDuration\": 1209600,\n      \"stagesCompleted\": 8,\n      \"stagesSkipped\": 1,\n      \"completionNotes\": \"All regulatory requirements satisfied\"\n    }\n  }\n}\n```\n\n### Post-Completion Behavior\nAfter successful completion, the workflow enters its final lifecycle state:\n\n**State Finalization:**\n- Workflow becomes read-only for stage progression (status transitions still allowed to ARCHIVED)\n- All stage assignments remain for historical reference and audit trails\n- Context data and attachments are preserved permanently\n- Integration connections may be cleaned up depending on configuration\n\n**Downstream Integrations:**\n- **Calendar Integration**: Completed workflow events are marked as finished in Cronofy\n- **External Systems**: CRM updates, project management tool notifications\n- **Reporting Systems**: Completion data flows to analytics and reporting platforms\n- **Notification Systems**: Stakeholders receive completion notifications via configured channels\n\n## Norwegian Real Estate Use Cases\n\n### Customer Onboarding Completion\n- **Legal Review Complete**: All legal reviews, document verification, and regulatory quality satisfied\n- **Financial Approval Received**: Investment committee approval and financing arrangements finalized\n- **Technical Assessment Finished**: Building inspections, structural assessments, and condition reports completed\n- **Purchase Agreement Executed**: Final contracts signed and registered with Norwegian property authorities\n- **Ownership Transfer Complete**: Property officially transferred and recorded in Grunnboken (Land Registry)\n\n### Order Processing Finalization\n- **Background Verification Complete**: Credit checks, reference verification, and income validation finished\n- **Lease Agreement Executed**: Contract terms agreed, signed, and legally binding\n- **Delivery Inspection Complete**: Property condition documented and accepted by tenant\n- **Access Provisioning Finished**: Physical and digital access provided to tenant\n- **Tenant Portal Access**: Online systems configured and tenant successfully onboarded\n\n### Maintenance Request Closure\n- **Work Orders Complete**: All support tasks executed and quality-verified\n- **Contractor Sign-off**: Work completion confirmed by certified contractors\n- **Tenant Acceptance**: Repairs accepted and satisfaction confirmed\n- **Documentation Filed**: Warranty information, receipts, and quality documents archived\n- **System Updates**: Property management systems updated with support history\n\n### Quality Inspection Finalization\n- **Technical Assessment Complete**: All building systems, safety features, and quality items checked\n- **Report Generation**: Comprehensive inspection report generated and reviewed\n- **Action Items Resolved**: Any identified issues addressed or scheduled for resolution\n- **Compliance Certification**: Regulatory quality verified and documented\n- **Stakeholder Distribution**: Reports distributed to property managers, owners, and relevant authorities\n\n## Validation Error Scenarios\n\nThe completion endpoint implements comprehensive error handling for various business scenarios:\n\n### Incomplete Required Stages\nWhen required stages are not completed, the system provides detailed feedback:\n- **Error Context**: Lists all incomplete required stages with their current status\n- **Business Impact**: Explains why each stage is critical for process completion\n- **Resolution Guidance**: Suggests actions to complete or skip problematic stages\n- **Stage Dependencies**: Identifies any dependency chains that may be blocking completion\n\n### Already Completed Workflows\n- **Idempotency Check**: Prevents duplicate completion operations\n- **State Preservation**: Maintains original completion timestamp and metrics\n- **Audit Trail**: Logs attempted duplicate completion for quality tracking\n\n### Workflow Access Violations\n- **Organization Boundaries**: Ensures workflows can only be completed by owning organization\n- **Permission Validation**: Verifies user has sufficient privileges for completion operations\n- **Audit Logging**: Records all access attempts for security monitoring\n\n## Performance Considerations\n\nCompletion operations involve multiple system components and may impact performance:\n- **Database Transactions**: Uses atomic operations to ensure data consistency during state transitions\n- **Event Publishing**: Pub/Sub event publication may add latency but ensures reliable downstream notification\n- **External System Calls**: Integration updates to CRM, calendar, and other systems execute asynchronously\n- **Audit Trail Creation**: Comprehensive logging may impact response time for workflows with extensive history\n\nFor high-volume scenarios with many simultaneous completions, consider implementing queued processing\nor stagger completion operations during peak business hours to maintain system responsiveness.\n","operationId":"completeWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to complete. Must be a valid UUID\nbelonging to the authenticated organization. The workflow can be in any\nstatus except COMPLETED (idempotent behavior for already completed workflows).\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"description":"Optional completion context and metadata. While the request body is optional,\nproviding completion notes and actor information enhances audit trails and\nimproves business process tracking.\n","required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"actor":{"type":"string","description":"Optional override for the completing actor. If not provided,\nuses authenticated user information from the request context.\n","example":"anna.berg@apart.no"},"completionNotes":{"type":"string","maxLength":2000,"description":"Optional notes about the completion. Useful for documenting\nspecial circumstances, deviations from standard process,\nor additional context for audit purposes.\n","example":"All regulatory requirements satisfied. Property acquisition completed ahead of schedule."}}},"examples":{"withNotes":{"summary":"Completion with Notes","description":"Standard completion with documentation","value":{"actor":"anna.berg@apart.no","completionNotes":"Property acquisition completed successfully. All due diligence items resolved."}},"minimal":{"summary":"Minimal Completion","description":"Simple completion without additional context","value":{}}}}}},"responses":{"200":{"description":"Workflow completed successfully. The response includes the complete workflow\ndata with updated status, completion timestamp, final progress metrics,\nand all associated stages and context information.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"examples":{"propertyAcquisitionCompleted":{"summary":"Completed Customer Onboarding Workflow","description":"Example of a property acquisition workflow that has been completed\nwith all required stages finished and final metrics calculated.\n","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-001","name":"Enterprise Customer Setup - ACME Corp","description":"Multi-stage onboarding process for enterprise client","status":"COMPLETED","entityType":"customer_onboarding","entityId":"prop-bergen-storgaten-15","templateId":"template-property-acquisition-commercial","currentStageId":null,"ownerType":"ROLE","ownerId":"acquisition-manager","dueDate":"2024-12-31T23:59:59.000Z","startedAt":"2024-01-15T09:00:00.000Z","completedAt":"2024-03-15T16:30:00.000Z","totalStages":5,"completedStages":5,"progressPercentage":100,"context":{"contractValue":15000000,"accountType":"enterprise","location":"New York, USA","currency":"NOK","acquisitionType":"direct_purchase","completionReason":"all_requirements_satisfied"}}}},"orderFulfillmentCompleted":{"summary":"Completed Order Fulfillment Workflow","description":"Example of tenant onboarding workflow completed with all stages\nfinished and tenant successfully activated in the system.\n","value":{"data":{"id":"abc12345-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","workflowNumber":"WF-2024-025","name":"Order Fulfillment - Order #4B","description":"Complete order processing for new customer","status":"COMPLETED","entityType":"order_fulfillment","entityId":"customer-acme-4b","templateId":"template-customer-onboarding-standard","currentStageId":null,"ownerType":"POSITION","ownerId":"regional-manager","dueDate":"2024-02-01T00:00:00.000Z","startedAt":"2024-01-05T08:00:00.000Z","completedAt":"2024-01-28T16:00:00.000Z","totalStages":4,"completedStages":4,"progressPercentage":100,"context":{"apartmentId":"frogner-apt-4b","customerType":"standard","contractStartDate":"2024-02-01","recurringRevenue":25000,"currency":"NOK"}}}}}}}},"400":{"description":"Bad request due to business rule violations, incomplete required stages,\nor invalid workflow state. The response provides detailed information\nabout what prevents completion and how to resolve the issues.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"incompleteRequiredStages":{"summary":"Incomplete Required Stages","description":"Workflow cannot be completed because required stages are not finished.\nThe error details which stages need attention.\n","value":{"error":{"code":"WORKFLOW_INCOMPLETE_STAGES","message":"Cannot complete workflow with 2 incomplete required stages: legal-review, technical-assessment","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","incompleteStages":[{"stageCode":"legal-review","stageName":"Legal Review","currentStatus":"ACTIVE","requiredStatus":"COMPLETED or SKIPPED","assignedTo":"legal-team@apart.no","blockingReason":"Document review in progress"},{"stageCode":"technical-assessment","stageName":"Technical Assessment","currentStatus":"PENDING","requiredStatus":"COMPLETED or SKIPPED","assignedTo":"technical-inspector","blockingReason":"Stage not yet started"}],"totalRequiredStages":4,"completedRequiredStages":2,"optionalStagesCount":1}}}},"alreadyCompleted":{"summary":"Workflow Already Completed","description":"Attempted to complete a workflow that is already in COMPLETED status.\nThis is handled gracefully with the current completion information.\n","value":{"error":{"code":"WORKFLOW_ALREADY_COMPLETED","message":"Workflow is already completed","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","currentStatus":"COMPLETED","completedAt":"2024-01-28T16:00:00.000Z","completedBy":"anna.berg@apart.no","originalCompletionDuration":1987200}}}},"invalidWorkflowId":{"summary":"Invalid Workflow ID Format","description":"The provided workflow ID is not a valid UUID format.\n","value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid workflow ID format. Must be a valid UUID.","details":{"field":"id","value":"invalid-workflow-id","expected":"UUID format (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)"}}}}}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"description":"Forbidden access. User lacks permission to complete workflows\nor the workflow belongs to a different organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"insufficientPermissions":{"summary":"Insufficient Permissions","description":"User does not have the required permissions to complete workflows.\n","value":{"error":{"code":"INSUFFICIENT_PERMISSIONS","message":"You do not have permission to complete workflows.","details":{"requiredPermission":"workflow.complete","userRole":"viewer","operation":"complete_workflow"}}}},"organizationMismatch":{"summary":"Workflow Organization Mismatch","description":"Workflow belongs to a different organization than the authenticated user.\n","value":{"error":{"code":"ORGANIZATION_MISMATCH","message":"Workflow does not belong to your organization.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","userOrganizationId":"456e7890-e89b-12d3-a456-426614174111","operation":"complete_workflow"}}}}}}}},"404":{"description":"Workflow not found in the authenticated organization's scope.\nThis may indicate the workflow doesn't exist, was deleted, or\nbelongs to a different organization.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflowNotFound":{"summary":"Workflow Not Found","description":"No workflow exists with the specified ID in the authenticated organization.\n","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"Workflow not found or does not belong to your organization.","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"456e7890-e89b-12d3-a456-426614174111","operation":"complete_workflow"}}}}}}}},"500":{"description":"Internal server error occurred during workflow completion processing.\nThis may include database errors, event publishing failures, or\nexternal system integration issues.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"databaseError":{"summary":"Database Transaction Error","description":"Database error occurred during workflow completion transaction.\n","value":{"error":{"code":"DATABASE_ERROR","message":"Database error occurred while completing workflow.","details":{"operation":"complete_workflow","workflowId":"123e4567-e89b-12d3-a456-426614174000","errorType":"transaction_failed"}}}},"eventPublishingError":{"summary":"Event Publishing Failure","description":"Workflow completed successfully but event publication to Pub/Sub failed.\nThe workflow state is consistent but downstream notifications may be delayed.\n","value":{"error":{"code":"EVENT_PUBLISHING_ERROR","message":"Workflow completed but event publishing failed.","details":{"operation":"complete_workflow","workflowId":"123e4567-e89b-12d3-a456-426614174000","workflowStatus":"COMPLETED","eventType":"workflow.completed","retryScheduled":true}}}},"externalSystemError":{"summary":"External System Integration Error","description":"Workflow completed successfully but external system notifications failed.\nCore workflow state is consistent.\n","value":{"error":{"code":"EXTERNAL_SYSTEM_ERROR","message":"Workflow completed but external system notification failed.","details":{"operation":"complete_workflow","workflowId":"123e4567-e89b-12d3-a456-426614174000","workflowStatus":"COMPLETED","failedSystem":"calendar_integration","retryScheduled":true}}}}}}}}}}},"/api/v1/workflows/{id}/cancel":{"post":{"tags":["Workflows"],"summary":"Cancel workflow execution with cascade handling","description":"Cancels a workflow and optionally cascades the cancellation to associated stages and tasks.\nThis endpoint provides comprehensive control over the cancellation process with configurable\noptions for handling related entities and notifications.\n\n## Business Context\n\nWorkflow cancellation is a critical operation for managing business processes that are no longer\nneeded or have become obsolete. Common scenarios include:\n- Property acquisition deals falling through\n- Tenant applications being withdrawn\n- Maintenance requests being consolidated\n- Regulatory process changes requiring workflow restart\n\n## Cascade Behavior\n\nThe cancellation process follows these steps:\n\n### 1. Workflow Status Update\n- Changes workflow status to CANCELLED\n- Records cancellation reason and actor\n- Creates comprehensive audit trail\n\n### 2. Stage Cancellation\n- Cancels stages with status: PENDING, READY, or ACTIVE\n- Preserves COMPLETED and SKIPPED stages\n- Updates stage status to CANCELLED\n\n### 3. Task Cancellation (Optional)\n- **Default behavior**: Cancels all incomplete tasks (PENDING, READY, IN_PROGRESS, BLOCKED, WAITING_FOR_EVENT)\n- **Conservative mode**: Only cancels PENDING and READY tasks when `cancelOnlyPendingTasks: true`\n- **Preserve mode**: Skip task cancellation when `cancelTasks: false`\n- Tracks affected assignees for notifications\n\n### 4. Notifications (Optional)\n- Publishes workflow.cancelled event to event stream\n- Includes cascade details (affected stages, tasks, assignees)\n- Enables downstream notification services when `notifyAssignees: true`\n\n## Validation Rules\n\n- Cannot cancel workflows with status CANCELLED (idempotent check)\n- Cannot cancel workflows with status COMPLETED (finalized workflows)\n- Workflow must exist and belong to the authenticated organization\n- Reason field limited to 1000 characters\n\n## Use Cases\n\n**Full Cancellation with Notifications** (Default)\n```json\n{\n  \"reason\": \"Deal fell through - seller withdrew property\",\n  \"options\": {\n    \"cancelTasks\": true,\n    \"notifyAssignees\": true,\n    \"cancelOnlyPendingTasks\": false\n  }\n}\n```\n\n**Conservative Cancellation** (Only pending tasks)\n```json\n{\n  \"reason\": \"Workflow being replaced with updated version\",\n  \"options\": {\n    \"cancelTasks\": true,\n    \"notifyAssignees\": true,\n    \"cancelOnlyPendingTasks\": true\n  }\n}\n```\n\n**Workflow-Only Cancellation** (Preserve task work)\n```json\n{\n  \"reason\": \"Administrative reorganization\",\n  \"options\": {\n    \"cancelTasks\": false,\n    \"notifyAssignees\": false\n  }\n}\n```\n","operationId":"cancelWorkflow","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Unique identifier of the workflow to cancel. Must be a valid UUID\nbelonging to the authenticated organization.\n","schema":{"type":"string","format":"uuid"},"example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"description":"Cancellation configuration including reason and cascade options.\nAll fields are optional with sensible defaults.\n","required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":1000,"description":"Human-readable explanation for the cancellation","example":"Property acquisition deal cancelled by seller"},"options":{"type":"object","description":"Configuration for cascade behavior and notifications","properties":{"cancelTasks":{"type":"boolean","default":true,"description":"Whether to cascade cancellation to tasks","example":true},"notifyAssignees":{"type":"boolean","default":true,"description":"Whether to notify affected task assignees","example":true},"cancelOnlyPendingTasks":{"type":"boolean","default":false,"description":"If true, only cancel PENDING/READY tasks; preserve IN_PROGRESS tasks","example":false}}}}}}}},"responses":{"200":{"description":"Workflow successfully cancelled","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Workflow"}}},"examples":{"fullCancellation":{"summary":"Workflow cancelled with full cascade","value":{"data":{"id":"123e4567-e89b-12d3-a456-426614174000","workflow_number":"WF-2024-001","name":"Customer Onboarding - GlobalTech","status":"CANCELLED","organization_id":"org-123","template_id":"tpl-456","created_at":"2024-01-15T10:00:00Z","updated_at":"2024-01-20T14:30:00Z","updated_by":"user-789"}}}}}}},"400":{"description":"Invalid request - validation errors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalidReason":{"summary":"Cancellation reason exceeds maximum length","value":{"error":"Validation failed","message":"Reason must not exceed 1000 characters"}},"alreadyCancelled":{"summary":"Workflow already cancelled","value":{"error":"Workflow is already cancelled"}},"completedWorkflow":{"summary":"Cannot cancel completed workflow","value":{"error":"Cannot cancel a completed workflow"}}}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/{workflowId}/gantt-data":{"get":{"tags":["Workflows"],"summary":"Get comprehensive Gantt chart data for workflow visualization","description":"Generates comprehensive Gantt chart data for a specific workflow, providing timeline visualization \ncapabilities for project management and workflow orchestration. This endpoint performs complex \ntimeline calculations, dependency analysis, and critical path generation for professional project \nmanagement visualization.\n\n## Business Logic Overview\n\nThe Gantt data generation process follows these key steps:\n\n### 1. Data Collection & Validation\n- **Workflow Verification**: Validates workflow existence and organization ownership\n- **Entity Retrieval**: Collects all tasks and workflow stages associated with the workflow\n- **Dependency Mapping**: Retrieves all dependency relationships between tasks and stages\n- **Timeline Boundaries**: Calculates project start and end dates from all entity timelines\n\n### 2. Timeline Calculation Methodology\n- **Task Timeline Estimation**: For tasks without explicit start dates, calculates start date as 7 days before due date\n- **Stage Timeline Estimation**: For workflow stages, uses 14-day estimation window before due date\n- **Dependency Chain Analysis**: Maps prerequisite and dependent relationships across all entities\n- **Critical Path Identification**: Identifies the longest path through dependent activities (future enhancement)\n\n### 3. Dependency Relationship Processing\n- **Bidirectional Mapping**: Creates both forward (dependencies) and backward (prerequisites) relationship maps\n- **Cross-Entity Dependencies**: Supports dependencies between tasks, workflow stages, and mixed entity types\n- **Slack Calculation**: Computes available buffer time for non-critical activities (future enhancement)\n- **Resource Constraint Analysis**: Identifies potential scheduling conflicts and bottlenecks\n\n### 4. Critical Path Analysis (Planned Enhancement)\nThe system is designed to support full critical path method (CPM) calculations including:\n- **Forward Pass**: Calculates earliest start and finish times for all activities\n- **Backward Pass**: Determines latest start and finish times without delaying project completion\n- **Float Calculation**: Identifies activities with scheduling flexibility\n- **Critical Activity Identification**: Marks activities where delays directly impact project completion\n\n## Norwegian Real Estate Use Cases\n\n### Property Transaction Workflows\n- **Due Diligence Timeline**: Visualize legal review, property inspection, and financial verification stages\n- **Settlement Process**: Track document preparation, signing ceremonies, and registration timelines\n- **Regulatory Compliance**: Monitor quality checkpoints and mandatory waiting periods\n\n### Construction & Development Projects\n- **Permit Workflow Visualization**: Track municipal approvals, environmental assessments, and building permits\n- **Construction Phase Management**: Coordinate subcontractor schedules and material delivery timelines\n- **Inspection & Completion**: Schedule mandatory inspections and final documentation\n\n### Property Management Operations\n- **Maintenance Scheduling**: Coordinate preventive support across multiple properties\n- **Tenant Management**: Visualize lease renewal processes and tenant transition timelines\n- **Compliance Monitoring**: Track annual safety inspections and certification renewals\n\n## Performance Characteristics\n\n### Optimization Features\n- **Efficient Data Retrieval**: Uses optimized Prisma queries with selective field loading\n- **Dependency Batching**: Retrieves all dependencies in a single query to minimize database roundtrips\n- **Timeline Caching**: Calculated timelines are suitable for client-side caching\n- **Incremental Updates**: Data structure supports efficient updates when workflow changes occur\n\n### Scalability Considerations\n- **Workflow Size Limits**: Optimized for workflows with up to 500 tasks and 100 stages\n- **Dependency Complexity**: Efficiently handles up to 1000 dependency relationships per workflow\n- **Response Time**: Typical response time under 500ms for standard-sized workflows\n- **Memory Usage**: Memory-efficient processing suitable for concurrent request handling\n\n## Data Accuracy & Reliability\n\n### Timeline Accuracy\n- **Estimation Algorithms**: Uses industry-standard estimation when exact timelines unavailable\n- **Historical Learning**: System designed to improve estimates based on completed workflow patterns\n- **Manual Override Support**: Calculated dates can be overridden with user-specified timelines\n\n### Dependency Integrity\n- **Circular Dependency Detection**: Prevents and detects circular dependency chains\n- **Cross-Entity Validation**: Ensures dependency relationships are logically consistent\n- **Orphaned Entity Handling**: Gracefully handles entities without clear dependency relationships\n\n## Integration Points\n\n### External Calendar Systems\n- **Cronofy Integration**: Timeline data can be synchronized with external calendar systems\n- **Meeting Scheduling**: Gantt timelines inform availability for property viewings and meetings\n- **Deadline Notifications**: Critical path activities can trigger calendar reminders\n\n### Project Management Tools\n- **Export Compatibility**: Data structure compatible with standard project management formats\n- **Resource Allocation**: Timeline data supports resource planning and allocation\n- **Progress Reporting**: Enables automated progress reporting and dashboard updates\n\n**Note**: Critical path calculation and slack time analysis are currently under development. \nCurrent implementation provides timeline boundaries and dependency mapping with placeholder \nvalues for critical path metrics.\n","operationId":"getWorkflowGanttData","security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"name":"workflowId","in":"path","required":true,"description":"Unique identifier of the workflow for which to generate Gantt chart data.\nThe workflow must belong to the authenticated organization and be in a valid\nstate for timeline generation (not archived or deleted).\n","schema":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$","example":"123e4567-e89b-12d3-a456-426614174000"}}],"responses":{"200":{"description":"Gantt chart data generated successfully. Returns comprehensive timeline visualization\ndata including all tasks, workflow stages, dependencies, and calculated timeline\nboundaries. The response includes both current entity states and calculated timeline\nprojections for project management visualization.\n","content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["tasks","stages","timeline","criticalPath"],"properties":{"tasks":{"type":"array","description":"All tasks associated with the workflow, enhanced with dependency information\nand calculated timeline data. Each task includes both actual dates (if available)\nand calculated timeline positions for Gantt visualization.\n","items":{"type":"object","allOf":[{"$ref":"#/components/schemas/Task"},{"type":"object","required":["dependencies","prerequisites"],"properties":{"dependencies":{"type":"array","description":"Tasks or stages that depend on this task's completion","items":{"$ref":"#/components/schemas/DependencyResponse"}},"prerequisites":{"type":"array","description":"Tasks or stages that must complete before this task can begin","items":{"$ref":"#/components/schemas/DependencyResponse"}},"calculatedStartDate":{"type":"string","format":"date-time","description":"Calculated start date for Gantt visualization. If not explicitly set,\ncalculated as 7 days before the due date to provide reasonable timeline\nestimation for project planning purposes.\n","example":"2024-01-15T09:00:00.000Z"},"calculatedEndDate":{"type":"string","format":"date-time","description":"Calculated end date for timeline visualization, typically using the\ntask's due date if available, or projected completion based on\ndependency analysis and historical patterns.\n","example":"2024-01-22T17:00:00.000Z"},"isCritical":{"type":"boolean","description":"Indicates whether this task is on the critical path. Critical tasks\ndirectly impact the overall workflow completion time. Currently set\nto false as critical path calculation is under development.\n","default":false,"example":false},"slackDays":{"type":"number","description":"Number of days this task can be delayed without affecting the overall\nworkflow completion date. Higher values indicate more scheduling\nflexibility. Currently set to 0 as slack calculation is under development.\n","minimum":0,"default":0,"example":0}}}]}},"stages":{"type":"array","description":"All workflow stages associated with the workflow, ordered by sequence with\ndependency relationships and calculated timeline information for comprehensive\nworkflow visualization and progress tracking.\n","items":{"type":"object","allOf":[{"$ref":"#/components/schemas/WorkflowStage"},{"type":"object","required":["dependencies","prerequisites"],"properties":{"dependencies":{"type":"array","description":"Stages or tasks that depend on this stage's completion","items":{"$ref":"#/components/schemas/DependencyResponse"}},"prerequisites":{"type":"array","description":"Stages or tasks that must complete before this stage can begin","items":{"$ref":"#/components/schemas/DependencyResponse"}},"calculatedStartDate":{"type":"string","format":"date-time","description":"Calculated start date for workflow stage visualization. Uses 14-day\nestimation window before due date to account for the typically longer\nduration and complexity of workflow stages compared to individual tasks.\n","example":"2024-01-01T09:00:00.000Z"},"calculatedEndDate":{"type":"string","format":"date-time","description":"Calculated completion date for the workflow stage, used for timeline\nvisualization and project planning. Typically aligns with the stage's\ndue date or calculated completion based on dependency analysis.\n","example":"2024-01-15T17:00:00.000Z"},"isCritical":{"type":"boolean","description":"Indicates whether this workflow stage is on the critical path and\ndirectly impacts overall workflow completion timing. Critical stages\nrequire priority attention and careful scheduling.\n","default":false,"example":false},"slackDays":{"type":"number","description":"Available buffer time in days for this workflow stage. Stages with\nhigher slack values offer more scheduling flexibility and can accommodate\ndelays without affecting the overall workflow timeline.\n","minimum":0,"default":0,"example":0}}}]}},"timeline":{"type":"object","required":["start","end","criticalPathDuration"],"description":"Calculated timeline boundaries and metrics for the entire workflow, providing\nessential information for Gantt chart visualization, project planning, and\ntimeline management across all workflow entities.\n","properties":{"start":{"type":"string","format":"date-time","description":"Earliest calculated start date across all tasks and workflow stages.\nThis represents the theoretical earliest start time for the entire\nworkflow based on current scheduling and dependency constraints.\n","example":"2024-01-01T09:00:00.000Z"},"end":{"type":"string","format":"date-time","description":"Latest calculated end date across all tasks and workflow stages.\nThis represents the projected completion time for the entire workflow\nassuming all activities complete as scheduled.\n","example":"2024-03-15T17:00:00.000Z"},"criticalPathDuration":{"type":"number","description":"Total duration in days of the critical path through the workflow.\nThis represents the minimum time required to complete the workflow\ngiven current dependencies and constraints. Currently set to 0 as\ncritical path calculation is under development.\n","minimum":0,"default":0,"example":0}}},"criticalPath":{"type":"array","description":"Array of entity IDs representing the critical path through the workflow.\nThe critical path identifies the sequence of activities that directly\ndetermines the overall workflow completion time. Any delay in critical\npath activities will delay the entire workflow. Currently returns empty\narray as critical path calculation is under development.\n","items":{"type":"string","format":"uuid","description":"UUID of a task or workflow stage on the critical path"},"example":[]}}}}},"examples":{"standard_workflow":{"summary":"Standard workflow with mixed tasks and stages","description":"Example response for a typical Norwegian real estate transaction workflow\nshowing property inspection tasks and legal review stages with dependencies.\n","value":{"data":{"tasks":[{"id":"task-001","name":"Quality Inspection","status":"IN_PROGRESS","due_date":"2024-02-15T17:00:00.000Z","dependencies":[],"prerequisites":[],"calculatedStartDate":"2024-02-08T09:00:00.000Z","calculatedEndDate":"2024-02-15T17:00:00.000Z","isCritical":false,"slackDays":0},{"id":"task-002","name":"Legal Document Review","status":"PENDING","due_date":"2024-02-22T17:00:00.000Z","dependencies":[],"prerequisites":[{"dependent_type":"task","dependent_id":"task-002","prerequisite_type":"task","prerequisite_id":"task-001"}],"calculatedStartDate":"2024-02-15T09:00:00.000Z","calculatedEndDate":"2024-02-22T17:00:00.000Z","isCritical":false,"slackDays":0}],"stages":[{"id":"stage-001","stage_code":"DUE_DILIGENCE","stage_name":"Due Diligence","status":"IN_PROGRESS","due_date":"2024-03-01T17:00:00.000Z","dependencies":[],"prerequisites":[],"calculatedStartDate":"2024-02-15T09:00:00.000Z","calculatedEndDate":"2024-03-01T17:00:00.000Z","isCritical":false,"slackDays":0}],"timeline":{"start":"2024-02-08T09:00:00.000Z","end":"2024-03-01T17:00:00.000Z","criticalPathDuration":0},"criticalPath":[]}}},"empty_workflow":{"summary":"Workflow with no tasks or stages","description":"Response for a workflow that has been created but contains no tasks or stages yet","value":{"data":{"tasks":[],"stages":[],"timeline":{"start":"2024-01-31T12:00:00.000Z","end":"2024-01-31T12:00:00.000Z","criticalPathDuration":0},"criticalPath":[]}}}}}}},"400":{"description":"Bad request due to invalid workflow ID format or malformed request parameters.\nCommon causes include non-UUID workflow IDs or missing required parameters.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"invalid_uuid":{"summary":"Invalid workflow ID format","value":{"error":{"code":"INVALID_WORKFLOW_ID","message":"Workflow ID must be a valid UUID format","details":{"providedId":"invalid-id-format","expectedFormat":"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"}}}}}}}},"401":{"description":"Authentication failed due to missing, invalid, or expired API key.\nEnsure your API key is provided in the X-API-Key header or Authorization header.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Access forbidden. The workflow exists but does not belong to your organization,\nor your API key lacks sufficient permissions to access workflow data.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"organization_mismatch":{"summary":"Workflow belongs to different organization","value":{"error":{"code":"WORKFLOW_ACCESS_DENIED","message":"Workflow does not belong to your organization","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","organizationId":"your-org-id"}}}}}}}},"404":{"description":"Workflow not found. The specified workflow ID does not exist in the system\nor has been deleted. Verify the workflow ID and ensure it hasn't been archived.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"workflow_not_found":{"summary":"Workflow does not exist","value":{"error":{"code":"WORKFLOW_NOT_FOUND","message":"The specified workflow could not be found","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","searchedOrganization":"456e7890-e89b-12d3-a456-426614174111"}}}}}}}},"500":{"description":"Internal server error during Gantt data generation. This may occur due to\ndatabase connectivity issues, complex dependency calculations, or system overload.\nThe error details provide information for troubleshooting and support.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"calculation_error":{"summary":"Timeline calculation failure","value":{"error":{"code":"GANTT_CALCULATION_ERROR","message":"Failed to generate workflow Gantt chart data due to timeline calculation error","details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","stage":"dependency_analysis","errorType":"circular_dependency_detected"}}}},"database_error":{"summary":"Database connectivity issue","value":{"error":{"code":"DATABASE_ERROR","message":"Failed to retrieve workflow data for Gantt chart generation","details":{"operation":"workflow_data_retrieval","retryable":true}}}}}}}}}}},"/api/v1/workflows/{workflowId}/data-model-config":{"get":{"tags":["Workflows"],"summary":"Get workflow data model configuration","description":"Retrieves the form-to-data-model bridge configuration for a specific workflow.\nThis configuration determines how form completion data is synchronized with\nstructured workflow data models.\n","parameters":[{"in":"path","name":"workflowId","required":true,"description":"UUID of the workflow","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Data model configuration retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/WorkflowDataModelConfig"}}}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"put":{"tags":["Workflows"],"summary":"Update workflow data model configuration","description":"Updates the form-to-data-model bridge configuration for a workflow.\nThis allows enabling/disabling sync and configuring mapping strategies.\n","parameters":[{"in":"path","name":"workflowId","required":true,"description":"UUID of the workflow","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkflowDataModelConfig"}}}},"responses":{"200":{"description":"Configuration updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"config":{"$ref":"#/components/schemas/WorkflowDataModelConfig"}}}}}},"400":{"description":"Invalid configuration provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/{workflowId}/sync-historical-data":{"post":{"tags":["Workflows"],"summary":"Sync historical form data to data model","description":"Synchronizes previously submitted form data to the workflow data model.\nThis is useful when enabling data model sync on an existing workflow\nthat already has completed tasks with form data.\n","parameters":[{"in":"path","name":"workflowId","required":true,"description":"UUID of the workflow","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Historical data sync completed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoricalSyncResult"}}}},"400":{"description":"Data model sync not enabled for this workflow","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/{workflowId}/data-sync-status":{"get":{"tags":["Workflows"],"summary":"Get data synchronization status","description":"Retrieves the status of form-to-data-model synchronization for a workflow,\nincluding whether a data instance exists and recent sync operations.\n","parameters":[{"in":"path","name":"workflowId","required":true,"description":"UUID of the workflow","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sync status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"hasDataInstance":{"type":"boolean","description":"Whether a data instance exists for this workflow"},"lastSyncAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last data sync"},"instanceId":{"type":"string","nullable":true,"description":"ID of the data instance if it exists"}}}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/linked":{"post":{"summary":"Create linked workflows with event routing","description":"Creates multiple workflow instances that can communicate through events","tags":["Workflows"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLinkedWorkflowsRequest"}}}},"responses":{"201":{"$ref":"#/components/responses/CreateLinkedWorkflowsResponse"},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/batch":{"post":{"summary":"Create linked workflows with event routing (alias for /workflows/linked)","description":"Creates multiple workflow instances that can communicate through events. This is an alias for the /workflows/linked endpoint.","tags":["Workflows"],"security":[{"BearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["workflowTemplateIds","entityType","entityId"],"properties":{"workflowTemplateIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":2,"maxItems":10,"description":"Array of workflow template IDs to create linked workflows from"},"entityType":{"type":"string","description":"Type of entity these workflows will be associated with"},"entityId":{"type":"string","description":"ID of the entity these workflows will be associated with"},"name":{"type":"string","description":"Base name for the linked workflows"},"description":{"type":"string","description":"Description for the linked workflows"},"eventRoutes":{"type":"array","items":{"type":"object","required":["eventKey","sourceWorkflowIndex","targetWorkflowIndex"],"properties":{"eventKey":{"type":"string","pattern":"^[a-z0-9]+(\\\\.[a-z0-9]+)*$","description":"Event key for routing (e.g., inspection.completed)"},"sourceWorkflowIndex":{"type":"integer","minimum":0,"description":"Index of source workflow in workflowTemplateIds array"},"targetWorkflowIndex":{"type":"integer","minimum":0,"description":"Index of target workflow in workflowTemplateIds array"}}},"description":"Event routing configuration between workflows"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of workflow owner"},"ownerId":{"type":"string","description":"ID of the workflow owner"},"dueDate":{"type":"string","format":"date-time","description":"Due date for the workflows"},"metadata":{"type":"object","description":"Additional metadata for the workflows"}}}}}},"responses":{"201":{"description":"Linked workflows created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"workflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"templateId":{"type":"string","format":"uuid"},"status":{"type":"string"}}}},"workflowLinks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workflowAId":{"type":"string","format":"uuid"},"workflowBId":{"type":"string","format":"uuid"}}}},"eventRoutes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventKey":{"type":"string"},"sourceWorkflowId":{"type":"string","format":"uuid"},"targetWorkflowId":{"type":"string","format":"uuid"}}}}}}}}},"400":{"description":"Invalid request data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/{workflowId}/event-routes":{"get":{"summary":"Get event routing configuration for a workflow","description":"Retrieves all event routes where this workflow is source or target","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow"},{"in":"query","name":"active","schema":{"type":"boolean"},"description":"Filter by active routes only"}],"responses":{"200":{"description":"Event routes retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"sourceRoutes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventKey":{"type":"string"},"targetWorkflowId":{"type":"string","format":"uuid"},"routeActive":{"type":"boolean"}}}},"targetRoutes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"eventKey":{"type":"string"},"sourceWorkflowId":{"type":"string","format":"uuid"},"routeActive":{"type":"boolean"}}}}}}}}},"404":{"description":"Workflow not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/workflows/{workflowId}/links":{"get":{"summary":"Get workflow links","description":"Retrieves all bidirectional links for a workflow","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow"}],"responses":{"200":{"description":"Links retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workflowAId":{"type":"string","format":"uuid"},"workflowBId":{"type":"string","format":"uuid"},"linkType":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"404":{"description":"Workflow not found"}}},"post":{"summary":"Create workflow link","description":"Creates a bidirectional link between two workflows","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the source workflow"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["targetWorkflowId"],"properties":{"targetWorkflowId":{"type":"string","format":"uuid","description":"ID of the target workflow to link to"},"linkType":{"type":"string","default":"BIDIRECTIONAL","description":"Type of link"}}}}}},"responses":{"201":{"description":"Link created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workflowAId":{"type":"string","format":"uuid"},"workflowBId":{"type":"string","format":"uuid"},"linkType":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"Invalid request or link already exists"},"404":{"description":"Workflow not found"}}}},"/api/v1/workflow-links/{linkId}":{"delete":{"summary":"Delete workflow link","description":"Deletes a workflow link by ID","tags":["Workflows"],"security":[{"BearerAuth":[]}],"parameters":[{"in":"path","name":"linkId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the link to delete"}],"responses":{"200":{"description":"Link deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"description":"Link not found"}}}},"/health":{"get":{"tags":["Health"],"summary":"Health check endpoint","description":"Returns the current health status of the API service.\nThis endpoint does not require authentication and can be used\nfor monitoring and load balancer health checks.\n","operationId":"getHealth","security":[],"responses":{"200":{"description":"Service is healthy and operational","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"},"example":{"status":"healthy","timestamp":"2024-01-15T10:30:00.000Z","version":"1.0.0"}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}/variables/schema":{"get":{"tags":["Workflows","Variables"],"summary":"Get workflow variables schema","description":"Returns comprehensive schema information for all available workflow variables.\nThis includes entity definitions from data models, computed fields, context schemas,\nform schemas, and system capabilities. Supports both data_model mode (modern workflows\nwith structured data schemas) and legacy mode (backward compatibility with form-based workflows).\n\n**Key Features:**\n- **Schema Discovery**: Understand what variables are available for template population\n- **Dual Mode Support**: Automatic detection of data_model vs legacy workflows\n- **Capability Detection**: Discover what features are supported (computed fields, validation, etc.)\n- **Performance Optimized**: Schema results are cached for fast response times\n\n**Use Cases:**\n- Template editors need to know available variables\n- Document generators need schema information\n- External integrations need to understand data structure\n","operationId":"getWorkflowVariablesSchema","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the workflow","example":"123e4567-e89b-12d3-a456-426614174000"}],"responses":{"200":{"description":"Variables schema retrieved successfully","headers":{"X-API-Version":{"description":"API version used","schema":{"type":"string","example":"1.0"}},"X-Variables-Mode":{"description":"Variables system mode","schema":{"type":"string","enum":["data_model","legacy"]}},"X-Execution-Time":{"description":"Request execution time","schema":{"type":"string","example":"45ms"}},"X-Cache-Status":{"description":"Cache status","schema":{"type":"string","example":"processed"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariablesSchemaResponse"},"examples":{"data_model_workflow":{"summary":"Data model workflow schema","value":{"version":"1.0","mode":"data_model","schema":{"entities":{"Customer":{"name":{"type":"string","required":true},"email":{"type":"email","required":true},"phone":{"type":"phone","required":false}}},"workflow":{"id":{"type":"string","description":"Workflow ID"},"name":{"type":"string","description":"Workflow name"},"status":{"type":"string","description":"Workflow status"}},"computed":{"fullContact":{"type":"string","formula":"{Customer.name} <{Customer.email}>"}},"context":{"workflow":{"type":"object","description":"Workflow-level context"},"stage":{"type":"object","description":"Stage-level context"}}},"capabilities":{"supportsComputed":true,"supportsValidation":true,"supportsExternalSync":true}}},"legacy_workflow":{"summary":"Legacy workflow schema","value":{"version":"1.0","mode":"legacy","schema":{"workflow":{"id":{"type":"string","description":"Workflow ID"},"name":{"type":"string","description":"Workflow name"},"status":{"type":"string","description":"Workflow status"}},"forms":{"task-123":{"taskName":"Customer Information","schema":{"fields":[{"name":"customerName","type":"text","required":true}]}}}},"capabilities":{"supportsComputed":false,"supportsValidation":true,"supportsExternalSync":false}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}/variables":{"get":{"tags":["Workflows","Variables"],"summary":"Get workflow variables data","description":"Returns runtime data values from all configured variable sources for a workflow.\nThis aggregates data from multiple sources including workflow data models, form submissions,\ncontext data, and standard workflow metadata. The response structure varies based on the\nworkflow mode (data_model vs legacy) and the requested options.\n\n**Data Sources:**\n- **Data Model**: Structured entities with current data and computed fields\n- **Workflow Metadata**: Standard workflow properties (name, status, dates, etc.)\n- **Context Data**: Hierarchical context from workflow and stage levels\n- **Form Data**: Aggregated form submissions from completed tasks\n\n**Performance Features:**\n- **Intelligent Caching**: Configurable cache with TTL for fast retrieval\n- **Selective Loading**: Control which data sources to include\n- **Field Filtering**: Request only specific fields to reduce payload size\n","operationId":"getWorkflowVariablesData","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the workflow","example":"123e4567-e89b-12d3-a456-426614174000"},{"in":"query","name":"includeComputed","schema":{"type":"boolean","default":true},"description":"Include computed field values (data_model mode only)","example":true},{"in":"query","name":"includeContext","schema":{"type":"boolean","default":true},"description":"Include hierarchical context data","example":true},{"in":"query","name":"includeForms","schema":{"type":"boolean","default":true},"description":"Include form submission data from completed tasks","example":true},{"in":"query","name":"includeWorkflow","schema":{"type":"boolean","default":true},"description":"Include standard workflow metadata","example":true},{"in":"query","name":"fields","schema":{"type":"string"},"description":"Comma-separated list of specific fields to include","example":"workflow.name,workflow.status,entities.customer.name"},{"in":"query","name":"excludeFields","schema":{"type":"string"},"description":"Comma-separated list of fields to exclude","example":"workflow.createdAt,workflow.updatedAt"},{"in":"query","name":"sources","schema":{"type":"string"},"description":"Comma-separated list of data sources to include","example":"data_model,workflow,context","enum":["data_model","forms","context","workflow"]},{"in":"query","name":"useCache","schema":{"type":"boolean","default":true},"description":"Enable response caching for improved performance","example":true},{"in":"query","name":"refreshCache","schema":{"type":"boolean","default":false},"description":"Force cache refresh to get latest data","example":false},{"in":"query","name":"validateData","schema":{"type":"boolean","default":true},"description":"Enable data validation against schemas","example":true},{"in":"query","name":"includeValidationDetails","schema":{"type":"boolean","default":false},"description":"Include detailed validation error information","example":false}],"responses":{"200":{"description":"Variables data retrieved successfully","headers":{"X-API-Version":{"description":"API version used","schema":{"type":"string"}},"X-Variables-Mode":{"description":"Variables system mode","schema":{"type":"string","enum":["data_model","legacy"]}},"X-Data-Sources":{"description":"Comma-separated list of included data sources","schema":{"type":"string"}},"X-Validation-Status":{"description":"Overall data validation status","schema":{"type":"string","enum":["valid","invalid","unknown"]}},"X-Cache-Status":{"description":"Cache utilization status","schema":{"type":"string"}},"X-Execution-Time":{"description":"Request execution time","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariablesDataResponse"},"examples":{"comprehensive_data":{"summary":"Comprehensive workflow data","value":{"version":"1.0","mode":"data_model","data":{"entities":{"customer":{"name":"John Doe","email":"john.doe@example.com","phone":"+1-555-123-4567","address":{"street":"123 Main St","city":"Anytown","zipCode":"12345"}}},"workflow":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Customer Onboarding","status":"in_progress","workflowNumber":"WF-2024-001","createdAt":"2024-01-15T10:30:00Z"},"computed":{"fullContact":"John Doe <john.doe@example.com>","isHighPriority":true},"context":{"salesRep":"Alice Johnson","region":"North America"},"forms":{"task-456":{"taskName":"Identity Verification","data":{"documentType":"passport","verified":true}}}},"metadata":{"lastUpdated":"2024-01-15T14:22:33Z","dataVersion":"1234567890","validationStatus":"valid","sources":["data_model","workflow","context","forms"]}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflows/{id}/variables/query":{"post":{"tags":["Workflows","Variables"],"summary":"Advanced workflow variables query","description":"Execute advanced queries against workflow variables with comprehensive filtering\nand transformation capabilities. This endpoint provides the most flexible way to\nretrieve exactly the data you need with powerful filtering options.\n\n**Advanced Features:**\n- **Multi-Source Filtering**: Filter data by source type (data_model, forms, context, workflow)\n- **Field Path Filtering**: Target specific nested fields using dot notation\n- **Pattern Matching**: Use regex patterns to filter by value content\n- **Temporal Filtering**: Filter by last modification time\n- **Performance Monitoring**: Detailed execution time reporting\n\n**Use Cases:**\n- **Template Population**: Get exactly the variables needed for document generation\n- **Data Integration**: Extract specific data for external system synchronization\n- **Analytics**: Aggregate workflow data for reporting and insights\n- **Conditional Logic**: Implement business rules based on variable values\n","operationId":"queryWorkflowVariables","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string","format":"uuid"},"description":"Unique identifier of the workflow","example":"123e4567-e89b-12d3-a456-426614174000"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryVariablesRequest"},"examples":{"basic_query":{"summary":"Basic query with options","value":{"options":{"includeComputed":true,"includeContext":false,"sources":["data_model","workflow"],"validateData":true}}},"filtered_query":{"summary":"Query with filters","value":{"options":{"includeWorkflow":true,"includeForms":true},"filters":[{"source":"forms","fieldPath":"priority","valuePattern":"high|urgent"},{"source":"workflow","fieldPath":"status","valuePattern":"active"}]}},"temporal_query":{"summary":"Query with time-based filtering","value":{"options":{"includeForms":true,"includeContext":true},"filters":[{"source":"forms","lastModifiedSince":"2024-01-01T00:00:00Z"}]}},"field_selection":{"summary":"Specific field selection","value":{"options":{"fields":["workflow.name","entities.customer.email","computed.fullContact"],"useCache":false}}}}}}},"responses":{"200":{"description":"Query executed successfully","headers":{"X-Query-Execution-Time":{"description":"Query-specific execution time","schema":{"type":"string"}},"X-Filters-Applied":{"description":"Number of filters applied","schema":{"type":"string"}},"X-Query-Executed-At":{"description":"Query execution timestamp","schema":{"type":"string"}},"X-Variables-Mode":{"description":"Variables system mode","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryVariablesResponse"},"examples":{"successful_query":{"summary":"Successful query result","value":{"version":"1.0","mode":"data_model","data":{"entities":{"customer":{"name":"Jane Smith","email":"jane.smith@example.com"}},"workflow":{"name":"Property Purchase","status":"active"}},"metadata":{"lastUpdated":"2024-01-15T16:45:22Z","dataVersion":"9876543210","validationStatus":"valid","sources":["data_model","workflow"]},"query":{"options":{"includeComputed":true,"sources":["data_model","workflow"]},"filters":[{"source":"workflow","fieldPath":"status","valuePattern":"active"}],"executedAt":"2024-01-15T16:45:22.123Z","executionTimeMs":45}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Query processing error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"COMPUTED_FIELD_EVALUATION_ERROR","message":"Failed to evaluate computed field 'fullContact': Invalid expression syntax","statusCode":422,"details":{"workflowId":"123e4567-e89b-12d3-a456-426614174000","fieldName":"fullContact"}}}}},"500":{"$ref":"#/components/responses/InternalServerError"}}}},"/api/v1/workflow-template-stages/{stageId}/completion-actions":{"post":{"summary":"Create completion action","description":"Creates a new completion action for a workflow template stage. Completion actions are automatically executed when workflows enter or complete COMPLETION stages.\n\n### Business Value\n- **Automate cleanup**: Automatically close open tasks from optional stages\n- **Generate insights**: Create workflow summaries with statistics and timelines\n- **Integrate systems**: Trigger webhooks to notify external systems\n- **Audit trails**: Publish events for compliance and tracking\n\n### Action Types\n- **close_tasks**: Close open tasks based on criteria (e.g., all tasks from optional stages)\n- **archive_attachments**: Archive workflow attachments to long-term storage\n- **generate_summary**: Generate comprehensive workflow summary with metrics\n- **webhook**: Call external HTTP endpoint with workflow data\n- **event**: Publish event to Pub/Sub topic for downstream processing\n\n### Features\n- Conditional execution based on workflow state\n- Configurable execution order for multiple actions\n- Retry logic with exponential backoff\n- Error handling strategies (log, fail, retry)\n- Timeout protection for long-running operations\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow template stage","example":"550e8400-e29b-41d4-a716-446655440003"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","name","trigger","action_type"],"properties":{"code":{"type":"string","maxLength":100,"description":"Unique code identifier for the action","example":"CLOSE_OPTIONAL_TASKS"},"name":{"type":"string","maxLength":255,"description":"Human-readable name for the action","example":"Close Open Tasks from Optional Stages"},"description":{"type":"string","maxLength":1000,"description":"Detailed description of what this action does","example":"Automatically closes all open tasks from optional workflow stages when entering the completion stage"},"trigger":{"type":"string","enum":["on_stage_entry","on_stage_completion"],"description":"When this action should be executed","example":"on_stage_entry"},"action_type":{"type":"string","enum":["close_tasks","archive_attachments","generate_summary","webhook","event"],"description":"Type of action to execute","example":"close_tasks"},"execution_order":{"type":"integer","minimum":0,"description":"Order in which this action should be executed (lower runs first)","example":1},"is_enabled":{"type":"boolean","description":"Whether this action is currently enabled","default":true},"conditions":{"type":"array","items":{"type":"object","required":["field","operator","value"],"properties":{"field":{"type":"string","description":"Context field path to evaluate","example":"statistics.openTasks"},"operator":{"type":"string","enum":["eq","==","ne","!=","gt",">","gte",">=","lt","<","lte","<=","in","contains"],"example":"gt"},"value":{"description":"Value to compare against","example":0}}},"description":"Conditions that must be met for this action to execute"},"close_task_status":{"type":"string","enum":["COMPLETED","CANCELLED"],"description":"Status to set when closing tasks (for close_tasks action)","example":"CANCELLED"},"archive_destination":{"type":"string","maxLength":500,"description":"Destination path for archived attachments (for archive_attachments action)","example":"gs://bucket/archived/workflows/"},"archive_include_types":{"type":"array","items":{"type":"string"},"description":"File types to include in archive (empty = all types)","example":["pdf","docx","xlsx"]},"summary_include_fields":{"type":"object","description":"Fields to include in generated summary (for generate_summary action)","example":{"includeTimeline":true,"includeParticipants":true}},"webhook_endpoint":{"type":"string","format":"uri","maxLength":2000,"description":"URL to call for webhook action","example":"https://api.example.com/webhooks/workflow-completion"},"webhook_method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for webhook request","example":"POST"},"webhook_headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Static headers to include in webhook request","example":{"X-Custom-Header":"value"}},"webhook_header_mapping":{"type":"object","additionalProperties":{"type":"string"},"description":"Dynamic header mapping from context fields","example":{"X-Workflow-Id":"workflow.id"}},"webhook_signing_secret":{"type":"string","maxLength":255,"description":"Secret for signing webhook payloads"},"auth_type":{"type":"string","enum":["pass_through","pass_through_with_fallback","api_key","none"],"description":"Authentication type for webhook requests","example":"api_key"},"auth_api_key":{"type":"string","maxLength":500,"description":"API key for webhook authentication"},"auth_header_name":{"type":"string","maxLength":100,"description":"Header name for API key authentication","default":"X-API-Key"},"payload_mapping":{"type":"object","description":"Custom payload structure mapping from context fields","example":{"workflowId":"workflow.id","status":"workflow.status"}},"event_code":{"type":"string","maxLength":100,"description":"Event type code to publish (for event action)","example":"workflow.completion"},"event_data":{"type":"object","description":"Additional data to include in published event","example":{"category":"workflow","priority":"high"}},"on_error":{"type":"string","enum":["log","fail_stage","retry"],"description":"Behavior when action execution fails","default":"log"},"retry_max_attempts":{"type":"integer","minimum":0,"maximum":10,"description":"Maximum number of retry attempts on failure","default":3},"retry_backoff_ms":{"type":"integer","minimum":100,"maximum":60000,"description":"Backoff time in milliseconds between retries","default":1000},"timeout_ms":{"type":"integer","minimum":1000,"maximum":300000,"description":"Timeout in milliseconds for action execution","default":30000}}},"examples":{"closeTasksAction":{"summary":"Close tasks from optional stages","value":{"code":"CLOSE_OPTIONAL_TASKS","name":"Close Open Tasks from Optional Stages","description":"Automatically closes all open tasks from optional workflow stages","trigger":"on_stage_entry","action_type":"close_tasks","execution_order":1,"close_task_status":"CANCELLED","conditions":[{"field":"statistics.openTasks","operator":"gt","value":0}]}},"generateSummaryAction":{"summary":"Generate workflow summary","value":{"code":"GENERATE_SUMMARY","name":"Generate Workflow Summary","description":"Creates comprehensive workflow summary with statistics","trigger":"on_stage_completion","action_type":"generate_summary","execution_order":2,"summary_include_fields":{"includeTimeline":true,"includeParticipants":true,"includeMetrics":true}}},"webhookAction":{"summary":"Notify external system via webhook","value":{"code":"NOTIFY_CRM","name":"Notify CRM System","description":"Sends completion notification to CRM system","trigger":"on_stage_completion","action_type":"webhook","execution_order":3,"webhook_endpoint":"https://api.example.com/webhooks/workflow-completion","webhook_method":"POST","auth_type":"api_key","auth_api_key":"your-api-key","payload_mapping":{"workflowId":"workflow.id","status":"workflow.status","completedAt":"workflow.completedAt"}}}}}}},"responses":{"201":{"description":"Completion action created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CompletionAction"}}}}}},"400":{"description":"Invalid request data or action configuration","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Invalid action configuration: webhook_endpoint is required for webhook action type"}}}}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"UNAUTHORIZED"},"message":{"type":"string","example":"Authentication required"}}}}}}}},"404":{"description":"Workflow template stage not found","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"NOT_FOUND"},"message":{"type":"string","example":"Workflow template stage not found"}}}}}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"INTERNAL_ERROR"},"message":{"type":"string","example":"Failed to create completion action"}}}}}}}}}},"get":{"summary":"List completion actions for a stage","description":"Retrieves all completion actions configured for a workflow template stage, ordered by execution order.\n\nUse this endpoint to:\n- View all automation actions for a completion stage\n- Check execution order and enabled status\n- Audit action configurations\n- Filter by trigger type (on_stage_entry or on_stage_completion)\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"stageId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow template stage","example":"550e8400-e29b-41d4-a716-446655440003"},{"in":"query","name":"trigger","required":false,"schema":{"type":"string","enum":["on_stage_entry","on_stage_completion"]},"description":"Filter by trigger type","example":"on_stage_entry"}],"responses":{"200":{"description":"List of completion actions retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompletionAction"}}}}}}},"401":{"description":"Authentication required"},"500":{"description":"Internal server error"}}}},"/api/v1/completion-actions/{actionId}":{"get":{"summary":"Get completion action by ID","description":"Retrieves a single completion action by its unique identifier with full configuration details.","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"actionId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the completion action","example":"550e8400-e29b-41d4-a716-446655440010"}],"responses":{"200":{"description":"Completion action retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CompletionAction"}}}}}},"401":{"description":"Authentication required"},"404":{"description":"Completion action not found"},"500":{"description":"Internal server error"}}},"put":{"summary":"Update completion action","description":"Updates an existing completion action configuration. All fields except code and action_type can be modified.\n\nNote: action_type is immutable - create a new action if you need to change the action type.\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"actionId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the completion action","example":"550e8400-e29b-41d4-a716-446655440010"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":255},"description":{"type":"string","maxLength":1000},"trigger":{"type":"string","enum":["on_stage_entry","on_stage_completion"]},"execution_order":{"type":"integer","minimum":0},"is_enabled":{"type":"boolean"},"conditions":{"type":"array","items":{"type":"object"}},"close_task_status":{"type":"string","enum":["COMPLETED","CANCELLED"]},"webhook_endpoint":{"type":"string","format":"uri"},"webhook_method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"]},"on_error":{"type":"string","enum":["log","fail_stage","retry"]},"retry_max_attempts":{"type":"integer","minimum":0,"maximum":10},"retry_backoff_ms":{"type":"integer","minimum":100,"maximum":60000},"timeout_ms":{"type":"integer","minimum":1000,"maximum":300000}}},"example":{"name":"Close Open Tasks from Optional Stages (Updated)","is_enabled":false,"execution_order":2}}}},"responses":{"200":{"description":"Completion action updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CompletionAction"}}}}}},"400":{"description":"Invalid request data"},"401":{"description":"Authentication required"},"404":{"description":"Completion action not found"},"500":{"description":"Internal server error"}}},"delete":{"summary":"Delete completion action (soft delete)","description":"Soft deletes a completion action. The action is marked as deleted but retained in the database for audit purposes.\nDeleted actions will not execute for future workflow completions.\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"actionId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the completion action","example":"550e8400-e29b-41d4-a716-446655440010"}],"responses":{"204":{"description":"Completion action deleted successfully"},"401":{"description":"Authentication required"},"404":{"description":"Completion action not found"},"500":{"description":"Internal server error"}}}},"/api/v1/completion-actions/{actionId}/execution-logs":{"get":{"summary":"List execution logs for a completion action","description":"Retrieves execution history for a specific completion action across all workflows.\n\nUse this to:\n- Debug action failures\n- Monitor action performance\n- Track retry attempts\n- Analyze webhook response times\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"actionId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the completion action","example":"550e8400-e29b-41d4-a716-446655440010"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":100},"description":"Number of logs to return"},{"in":"query","name":"offset","schema":{"type":"integer","default":0},"description":"Number of logs to skip"},{"in":"query","name":"status","schema":{"type":"string","enum":["success","failure","timeout","skipped"]},"description":"Filter by execution status"}],"responses":{"200":{"description":"Execution logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompletionActionExecutionLog"}}}}}}},"401":{"description":"Authentication required"},"500":{"description":"Internal server error"}}}},"/api/v1/workflows/{workflowId}/completion-action-logs":{"get":{"summary":"List execution logs for a workflow","description":"Retrieves all completion action execution logs for a specific workflow.\n\nUse this to:\n- View all automation actions executed for a workflow\n- Audit workflow completion process\n- Troubleshoot workflow completion issues\n- Track which tasks were auto-closed\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow","example":"550e8400-e29b-41d4-a716-446655440011"},{"in":"query","name":"limit","schema":{"type":"integer","default":50,"maximum":100}},{"in":"query","name":"offset","schema":{"type":"integer","default":0}},{"in":"query","name":"status","schema":{"type":"string","enum":["success","failure","timeout","skipped"]}},{"in":"query","name":"trigger","schema":{"type":"string","enum":["on_stage_entry","on_stage_completion"]}}],"responses":{"200":{"description":"Execution logs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompletionActionExecutionLog"}}}}}}},"401":{"description":"Authentication required"},"500":{"description":"Internal server error"}}}},"/api/v1/completion-action-execution-logs/{logId}":{"get":{"summary":"Get specific execution log","description":"Retrieves detailed information about a single completion action execution including full request/response data for webhooks.\n\nThis endpoint provides comprehensive execution details including:\n- Complete webhook request/response data\n- Task closure details with IDs\n- Error messages and retry information\n- Timing and performance metrics\n","tags":["Completion Actions"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"logId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the execution log","example":"550e8400-e29b-41d4-a716-446655440020"}],"responses":{"200":{"description":"Execution log retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CompletionActionExecutionLog"}}}}}},"401":{"description":"Authentication required"},"404":{"description":"Execution log not found"},"500":{"description":"Internal server error"}}}},"/api/v1/workflows/{workflowId}/summary":{"get":{"summary":"Get workflow summary","description":"Retrieves comprehensive workflow summary with statistics, timeline, and participant information.\n\n### Included Data\n- **Workflow metadata**: Name, code, template, entity links\n- **Timeline**: Start/completion times, total duration\n- **Stage statistics**: Total, completed, and skipped stages\n- **Task statistics**: Total, completed, cancelled, and auto-closed tasks\n- **Participants**: Owner, assignee, and participant count\n- **Archived references**: Links to archived attachments\n\n### Use Cases\n- **Reporting**: Generate workflow completion reports\n- **Analytics**: Calculate average completion times\n- **Auditing**: Review workflow execution history\n- **Process improvement**: Identify bottlenecks and optimization opportunities\n","tags":["Workflow Summaries"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"path","name":"workflowId","required":true,"schema":{"type":"string","format":"uuid"},"description":"ID of the workflow","example":"550e8400-e29b-41d4-a716-446655440011"}],"responses":{"200":{"description":"Workflow summary retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WorkflowSummary"}}}}}},"401":{"description":"Authentication required"},"404":{"description":"Workflow summary not found (workflow may not be completed yet)"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-summaries":{"get":{"summary":"List workflow summaries with filters","description":"Retrieves workflow summaries filtered by template or entity. Either template_code or both entity_type and entity_id are required.\n\n### Filter Options\n- **By Template**: Get all summaries for workflows using a specific template\n- **By Entity**: Get all summaries for workflows linked to an entity (e.g., all workflows for a property)\n\n### Common Use Cases\n- **Template analysis**: Analyze performance of all workflows using a template\n- **Entity history**: View all workflows executed for a property or customer\n- **Date range reporting**: Generate reports for specific time periods\n- **Performance tracking**: Monitor workflow efficiency over time\n","tags":["Workflow Summaries"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"template_code","schema":{"type":"string"},"description":"Filter by workflow template code","example":"PROPERTY_ACQUISITION"},{"in":"query","name":"entity_type","schema":{"type":"string"},"description":"Filter by entity type (requires entity_id)","example":"property"},{"in":"query","name":"entity_id","schema":{"type":"string"},"description":"Filter by entity ID (requires entity_type)","example":"prop-123"},{"in":"query","name":"start_date","schema":{"type":"string","format":"date-time"},"description":"Filter by workflow completion date (start of range)","example":"2024-01-01T00:00:00Z"},{"in":"query","name":"end_date","schema":{"type":"string","format":"date-time"},"description":"Filter by workflow completion date (end of range)","example":"2024-12-31T23:59:59Z"},{"in":"query","name":"limit","schema":{"type":"integer","default":100,"maximum":100}},{"in":"query","name":"offset","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Workflow summaries retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowSummary"}}}}}}},"400":{"description":"Invalid request - missing required parameters","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"VALIDATION_ERROR"},"message":{"type":"string","example":"Either template_code or both entity_type and entity_id are required"}}}}}}}},"401":{"description":"Authentication required"},"500":{"description":"Internal server error"}}}},"/api/v1/workflow-summaries/aggregate":{"get":{"summary":"Get aggregate statistics for a template","description":"Calculates aggregate statistics across all workflow summaries for a specific template.\n\n### Calculated Metrics\n- **Total workflows**: Count of completed workflows\n- **Average duration**: Mean workflow execution time in minutes\n- **Average tasks**: Mean completed, cancelled, and auto-closed task counts\n- **Average stages**: Mean completed stage count\n\n### Business Applications\n- **Performance benchmarking**: Compare actual vs. expected completion times\n- **Process optimization**: Identify templates with high cancellation rates\n- **Capacity planning**: Estimate resource requirements for upcoming workflows\n- **Quality metrics**: Track template effectiveness over time\n","tags":["Workflow Summaries"],"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"parameters":[{"in":"query","name":"template_code","required":true,"schema":{"type":"string"},"description":"Workflow template code","example":"PROPERTY_ACQUISITION"},{"in":"query","name":"start_date","schema":{"type":"string","format":"date-time"},"description":"Start of date range for aggregation","example":"2024-01-01T00:00:00Z"},{"in":"query","name":"end_date","schema":{"type":"string","format":"date-time"},"description":"End of date range for aggregation","example":"2024-12-31T23:59:59Z"}],"responses":{"200":{"description":"Aggregate statistics calculated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"totalWorkflows":{"type":"integer","description":"Total number of completed workflows","example":42},"avgDurationMinutes":{"type":"number","format":"float","description":"Average workflow duration in minutes","example":7830.5},"avgCompletedTasks":{"type":"number","format":"float","description":"Average number of completed tasks","example":18.3},"avgCancelledTasks":{"type":"number","format":"float","description":"Average number of cancelled tasks","example":2.1},"avgAutoClosedTasks":{"type":"number","format":"float","description":"Average number of auto-closed tasks","example":3.7},"avgCompletedStages":{"type":"number","format":"float","description":"Average number of completed stages","example":4.2}}}}}}}},"400":{"description":"Missing required template_code parameter"},"401":{"description":"Authentication required"},"500":{"description":"Internal server error"}}}},"/api/v1/positions/assignments":{"get":{"tags":["Positions"],"summary":"Get all assignments for a position","description":"Retrieve all tasks, workflow stages, and workflows assigned to a specific position.\nResults are combined and can be filtered by status and sorted by due date, creation date, or priority.\nBy default, completed and cancelled items are excluded.\n","operationId":"getPositionAssignments","parameters":[{"in":"query","name":"position_id","required":true,"schema":{"type":"string","maxLength":50},"description":"Position ID to filter assignments","example":"pos_abc123"},{"in":"query","name":"status","required":false,"schema":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"description":"Filter by status (single value or array of values)","examples":{"single":{"value":"TODO","summary":"Single status"},"multiple":{"value":["TODO","IN_PROGRESS"],"summary":"Multiple statuses"}}},{"in":"query","name":"sort_by","required":false,"schema":{"type":"string","enum":["due_date","created_at","priority"],"default":"due_date"},"description":"Field to sort results by"},{"in":"query","name":"sort_order","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"},"description":"Sort order (ascending or descending)"},{"in":"query","name":"include_completed","required":false,"schema":{"type":"boolean","default":false},"description":"Include completed and cancelled items in results"},{"in":"query","name":"page","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number for pagination"},{"in":"query","name":"page_size","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Number of items per page (max 100)"}],"responses":{"200":{"description":"Successfully retrieved position assignments","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["TASK"]},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string"},"priority":{"type":"string","nullable":true},"due_date":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"entity_type":{"type":"string","nullable":true},"entity_id":{"type":"string","nullable":true},"assignee_name":{"type":"string","nullable":true},"project_id":{"type":"string","format":"uuid","nullable":true},"workflow_id":{"type":"string","format":"uuid","nullable":true},"workflow_stage_id":{"type":"string","format":"uuid","nullable":true},"completion_mode":{"type":"string"},"requires_approval":{"type":"boolean"}}}},"workflow_stages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["WORKFLOW_STAGE"]},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string"},"due_date":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"entity_type":{"type":"string","nullable":true},"entity_id":{"type":"string","nullable":true},"assignee_name":{"type":"string","nullable":true},"workflow_id":{"type":"string","format":"uuid"},"workflow_name":{"type":"string"},"stage_code":{"type":"string"},"sequence_order":{"type":"integer"},"is_milestone":{"type":"boolean"},"is_blocking":{"type":"boolean"}}}},"workflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["WORKFLOW"]},"title":{"type":"string"},"description":{"type":"string","nullable":true},"status":{"type":"string"},"due_date":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"},"entity_type":{"type":"string"},"entity_id":{"type":"string"},"assignee_name":{"type":"string","nullable":true},"workflow_number":{"type":"string"},"template_id":{"type":"string","format":"uuid","nullable":true},"current_stage_id":{"type":"string","format":"uuid","nullable":true},"total_stages":{"type":"integer"},"completed_stages":{"type":"integer"},"progress_percentage":{"type":"number","format":"float","nullable":true}}}},"summary":{"type":"object","properties":{"total_tasks":{"type":"integer","description":"Total number of tasks assigned to position"},"total_stages":{"type":"integer","description":"Total number of workflow stages assigned to position"},"total_workflows":{"type":"integer","description":"Total number of workflows assigned to position"},"total_items":{"type":"integer","description":"Total number of all assignment items"}}},"pagination":{"type":"object","properties":{"page":{"type":"integer","description":"Current page number"},"page_size":{"type":"integer","description":"Number of items per page"},"total_pages":{"type":"integer","description":"Total number of pages"},"has_more":{"type":"boolean","description":"Whether more pages are available"}}}}}}},"examples":{"success":{"summary":"Successful response with mixed assignments","value":{"data":{"tasks":[{"id":"550e8400-e29b-41d4-a716-446655440001","type":"TASK","title":"Review property inspection report","description":"Complete review of Q1 inspection findings","status":"TODO","priority":"HIGH","due_date":"2025-01-15T10:00:00Z","created_at":"2025-01-10T08:30:00Z","entity_type":"PROPERTY","entity_id":"prop_123","assignee_name":"John Smith","project_id":"550e8400-e29b-41d4-a716-446655440000","workflow_id":null,"workflow_stage_id":null,"completion_mode":"INLINE","requires_approval":false}],"workflow_stages":[{"id":"550e8400-e29b-41d4-a716-446655440002","type":"WORKFLOW_STAGE","title":"Document Review","description":null,"status":"IN_PROGRESS","due_date":"2025-01-20T15:00:00Z","created_at":"2025-01-08T09:00:00Z","entity_type":"CONTRACT","entity_id":"contract_456","assignee_name":"John Smith","workflow_id":"550e8400-e29b-41d4-a716-446655440010","workflow_name":"Contract Approval Process","stage_code":"review","sequence_order":2,"is_milestone":true,"is_blocking":true}],"workflows":[{"id":"550e8400-e29b-41d4-a716-446655440003","type":"WORKFLOW","title":"Q1 Lease Renewal","description":"Process lease renewal for Building A units","status":"ACTIVE","due_date":"2025-02-01T17:00:00Z","created_at":"2025-01-05T10:00:00Z","entity_type":"PROPERTY","entity_id":"prop_789","assignee_name":"John Smith","workflow_number":"WF-2025-001","template_id":"550e8400-e29b-41d4-a716-446655440100","current_stage_id":"550e8400-e29b-41d4-a716-446655440020","total_stages":5,"completed_stages":2,"progress_percentage":40}],"summary":{"total_tasks":1,"total_stages":1,"total_workflows":1,"total_items":3},"pagination":{"page":1,"page_size":50,"total_pages":1,"has_more":false}}}}}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"missing_position_id":{"value":{"error":{"code":"VALIDATION_ERROR","message":"position_id is required"}}},"invalid_status":{"value":{"error":{"code":"VALIDATION_ERROR","message":"Invalid status value"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"500":{"$ref":"#/components/responses/InternalServerError"}},"security":[{"ApiKeyAuth":[]}]}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Organization-scoped API key for authentication"},"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API-Key","description":"Organization-scoped API key using Bearer token format"},"CronofyTokenAuth":{"type":"apiKey","in":"header","name":"X-Cronofy-Token","description":"Cronofy access token for calendar operations. Required for all calendar endpoints."},"PortalTokenAuth":{"type":"apiKey","in":"header","name":"X-Portal-Token","description":"JWT token for external portal users. Used to access tasks and projects through the portal system with visibility-based access control."}},"schemas":{"ErrorResponse":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_ERROR","INVALID_REQUEST","INVALID_PARAMETER","MISSING_PARAMETER","INVALID_FORMAT","UNAUTHORIZED","INVALID_API_KEY","TOKEN_EXPIRED","FORBIDDEN","INSUFFICIENT_PERMISSIONS","RESOURCE_ACCESS_DENIED","NOT_FOUND","RESOURCE_NOT_FOUND","ENDPOINT_NOT_FOUND","CONFLICT","DUPLICATE_RESOURCE","UNIQUE_CONSTRAINT_VIOLATION","RATE_LIMIT_EXCEEDED","INTERNAL_SERVER_ERROR","DATABASE_ERROR","UNEXPECTED_ERROR","EXTERNAL_SERVICE_ERROR","SERVICE_UNAVAILABLE","MAINTENANCE_MODE","PROJECT_NOT_FOUND","PROJECT_CREATION_FAILED","PROJECT_UPDATE_FAILED","PROJECT_DELETION_FAILED","PROJECT_ARCHIVE_FAILED","TASK_NOT_FOUND","TASK_CREATION_FAILED","TASK_UPDATE_FAILED","TASK_DELETION_FAILED","TASK_STATUS_TRANSITION_INVALID","DEPENDENCY_NOT_FOUND","DEPENDENCY_CREATION_FAILED","DEPENDENCY_UPDATE_FAILED","DEPENDENCY_DELETION_FAILED","CIRCULAR_DEPENDENCY_DETECTED","SELF_DEPENDENCY_NOT_ALLOWED","COMMENT_NOT_FOUND","COMMENT_CREATION_FAILED","COMMENT_UPDATE_FAILED","COMMENT_DELETION_FAILED","COMMENT_RETRIEVAL_FAILED","WORKFLOW_NOT_FOUND","WORKFLOW_CREATION_FAILED","WORKFLOW_UPDATE_FAILED","WORKFLOW_DELETION_FAILED","WORKFLOW_STAGE_NOT_FOUND","WORKFLOW_TRANSITION_INVALID","ATTACHMENT_NOT_FOUND","ATTACHMENT_UPLOAD_FAILED","ATTACHMENT_SIZE_EXCEEDED","ATTACHMENT_TYPE_NOT_ALLOWED","CALENDAR_NOT_CONNECTED","CALENDAR_EVENT_CREATION_FAILED","CALENDAR_SYNC_FAILED","CONTEXT_TYPE_NOT_FOUND","CONTEXT_FETCH_FAILED","CONTEXT_ACTION_FAILED","WORKFLOW_DATA_SCHEMA_NOT_FOUND","WORKFLOW_DATA_SCHEMA_CREATION_FAILED","WORKFLOW_DATA_SCHEMA_UPDATE_FAILED","WORKFLOW_DATA_SCHEMA_VALIDATION_FAILED","WORKFLOW_DATA_INSTANCE_NOT_FOUND","WORKFLOW_DATA_INSTANCE_CREATION_FAILED","WORKFLOW_DATA_INSTANCE_UPDATE_FAILED","WORKFLOW_DATA_VALIDATION_FAILED","DATA_MODEL_ERROR","ASSIGNMENT_RESOLVER_NOT_FOUND","ASSIGNMENT_RESOLVER_VALIDATION_ERROR","ASSIGNMENT_RESOLUTION_ERROR","NO_RESOLVER_CONFIGURED","MISSING_CONTEXT","APART_API_ERROR","MULTIPLE_MATCHES","UNSUPPORTED_ASSIGNMENT_TYPE","PORTAL_TOKEN_MISSING","PORTAL_TOKEN_INVALID","PORTAL_TOKEN_EXPIRED","PORTAL_AUTH_ERROR","PORTAL_NOT_FOUND","PORTAL_INACTIVE","PORTAL_ACCESS_DENIED","TASK_NOT_RESPONDING","COMMENT_NOT_OWNED","PORTAL_TASKS_ERROR","PORTAL_PROJECTS_ERROR","PORTAL_PROFILE_ERROR","TASK_COMPLETION_ERROR","COMMENTS_FETCH_ERROR","COMMENT_UPDATE_ERROR","COMMENT_DELETE_ERROR"],"description":"Machine-readable error code for programmatic handling","example":"TASK_NOT_FOUND"},"message":{"type":"string","description":"Human-readable error message","example":"Task not found."},"details":{"type":"object","description":"Additional error context and debugging information","additionalProperties":true,"example":{"taskId":"task-123","organizationId":"org-456"}}}}}},"ApiError":{"$ref":"#/components/schemas/ErrorResponse"},"PaginationMeta":{"type":"object","properties":{"total":{"type":"integer","description":"Total number of items","minimum":0,"example":150},"page":{"type":"integer","description":"Current page number","minimum":1,"example":1},"limit":{"type":"integer","description":"Items per page","minimum":1,"maximum":100,"example":20}}},"Organization":{"type":"object","required":["id","name","calendarFeaturesEnabled","gcpProjectId","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique organization identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"name":{"type":"string","description":"Organization display name","minLength":1,"maxLength":255,"example":"Acme Corporation"},"calendarFeaturesEnabled":{"type":"boolean","description":"Whether calendar integration features are enabled for this organization","example":true},"gcpProjectId":{"type":"string","description":"Google Cloud Platform project ID for organization resources","example":"tasks-462013"},"createdAt":{"type":"string","format":"date-time","description":"Organization creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last organization update timestamp","example":"2024-01-15T14:45:00.000Z"}}},"UpdateOrganizationRequest":{"type":"object","properties":{"name":{"type":"string","description":"New organization display name","minLength":1,"maxLength":255,"example":"Updated Corporation Name"},"calendarFeaturesEnabled":{"type":"boolean","description":"Enable or disable calendar integration features","example":true}},"additionalProperties":false,"minProperties":1,"description":"Request body for updating organization settings. At least one field must be provided."},"Project":{"type":"object","required":["id","name","organizationId","status","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique project identifier","example":"456e7890-e89b-12d3-a456-426614174111"},"name":{"type":"string","description":"Project name","minLength":1,"maxLength":255,"example":"Website Redesign Q1 2024"},"description":{"type":"string","nullable":true,"description":"Project description","maxLength":1000,"example":"Complete overhaul of company website with modern design and improved UX"},"status":{"type":"string","enum":["ACTIVE","ARCHIVED"],"description":"Project status","example":"ACTIVE"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this project","example":"123e4567-e89b-12d3-a456-426614174000"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this project is linked to","maxLength":100,"example":"client"},"entityId":{"type":"string","nullable":true,"description":"ID of external entity this project is linked to","maxLength":255,"example":"client-789"},"createdAt":{"type":"string","format":"date-time","description":"Project creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last project update timestamp","example":"2024-01-20T16:15:00.000Z"},"ownerId":{"type":"string","nullable":true,"maxLength":255,"description":"ID of the project owner (user, role, or position)","example":"user-123"},"ownerType":{"type":"string","nullable":true,"enum":["USER","ROLE","POSITION"],"description":"Type of project ownership assignment","example":"USER"},"startDate":{"type":"string","format":"date-time","nullable":true,"description":"Project start date","example":"2024-01-15T00:00:00.000Z"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Project deadline or target completion date","example":"2024-03-31T23:59:59.999Z"},"workflowId":{"type":"string","format":"uuid","nullable":true,"description":"Associated workflow ID if project is part of a workflow","example":"456e7890-e89b-12d3-a456-426614174111"},"data":{"type":"object","nullable":true,"additionalProperties":true,"description":"Custom metadata for integration-specific data","example":{"budget":50000,"currency":"USD"}},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when project was completed","example":"2024-03-31T18:30:00.000Z"},"createdBy":{"type":"string","description":"User ID or identifier who created the project","example":"user-john-doe"},"updatedBy":{"type":"string","description":"User ID or identifier who last updated the project","example":"user-jane-smith"}}},"ProjectInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Project name - should be descriptive and unique within your organization","minLength":1,"maxLength":255,"example":"Website Redesign Q1 2024"},"description":{"type":"string","nullable":true,"description":"Detailed project description including objectives, scope, and key deliverables","maxLength":1000,"example":"Complete overhaul of company website with modern design and improved UX"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this project is linked to (e.g., client, property, deal, contract). Used for cross-system integration","maxLength":100,"example":"client"},"entityId":{"type":"string","nullable":true,"description":"Unique identifier of the external entity in your system. Must be used together with entityType","maxLength":255,"example":"client-789"},"ownerId":{"type":"string","nullable":true,"description":"ID of the project owner (user, role, or position)","maxLength":255,"example":"user-123"},"ownerType":{"type":"string","nullable":true,"enum":["USER","ROLE","POSITION"],"description":"Type of project ownership assignment","example":"USER"},"status":{"type":"string","nullable":true,"enum":["ACTIVE","ARCHIVED"],"description":"Initial project status. Defaults to ACTIVE if not specified","default":"ACTIVE","example":"ACTIVE"},"startDate":{"type":"string","format":"date-time","nullable":true,"description":"Planned project start date (ISO 8601 format)","example":"2024-01-15T00:00:00.000Z"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Project deadline or target completion date (ISO 8601 format)","example":"2024-03-31T23:59:59.999Z"},"data":{"type":"object","nullable":true,"additionalProperties":true,"description":"Custom metadata for integration-specific data. Store any additional project attributes here","example":{"budget":50000,"currency":"USD","department":"Marketing","tags":["high-priority","client-facing"]}}}},"ProjectUpdate":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","description":"Updated project name - should remain descriptive and clear","minLength":1,"maxLength":255,"example":"Website Redesign Q1 2024 - Updated"},"description":{"type":"string","nullable":true,"description":"Updated project description with any scope changes or new objectives","maxLength":1000,"example":"Updated project scope with additional mobile optimization"},"status":{"type":"string","enum":["ACTIVE","ARCHIVED"],"description":"Project lifecycle status. Archive projects to hide them from active lists while preserving data","example":"ACTIVE"},"ownerId":{"type":"string","nullable":true,"description":"Reassign project ownership by providing new owner ID","maxLength":255,"example":"user-456"},"ownerType":{"type":"string","nullable":true,"enum":["USER","ROLE","POSITION"],"description":"Type of the new project owner","example":"USER"},"startDate":{"type":"string","format":"date-time","nullable":true,"description":"Updated project start date (ISO 8601 format)","example":"2024-01-20T00:00:00.000Z"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Updated project deadline (ISO 8601 format)","example":"2024-04-15T23:59:59.999Z"},"data":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated custom metadata. Merges with existing data by default","example":{"budget":75000,"phase":"implementation","completionPercentage":45}}},"additionalProperties":false},"BulkCreateProjectsRequest":{"type":"object","required":["projects"],"properties":{"projects":{"type":"array","description":"Array of projects to create in a single atomic operation","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/ProjectInput"},"example":[{"name":"Q1 Marketing Campaign","description":"Complete Q1 marketing initiative including social media, content, and paid advertising","entityType":"campaign","entityId":"q1-2024-marketing"},{"name":"Q1 Product Development","description":"New feature development for Q1 release cycle","ownerId":"user-123","ownerType":"USER","startDate":"2024-01-01T00:00:00.000Z","dueDate":"2024-03-31T23:59:59.999Z"}]}},"additionalProperties":false},"PubSubTopicInput":{"type":"object","required":["topicName","topicFullName","gcpProjectId","eventTypes"],"properties":{"topicName":{"type":"string","description":"Short identifier for the topic. Must be unique within organization and contain only lowercase letters, numbers, and hyphens.","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$","example":"entity-updates"},"topicFullName":{"type":"string","description":"Complete Google Cloud Pub/Sub topic identifier in format: projects/{project-id}/topics/{topic-name}. Must follow GCP naming conventions.","pattern":"^projects\\/[a-z0-9-]+\\/topics\\/[a-z0-9-]+$","example":"projects/tasks-462013/topics/org-123-entity-updates"},"gcpProjectId":{"type":"string","description":"Google Cloud Project ID hosting the Pub/Sub infrastructure. Must have Pub/Sub API enabled with appropriate permissions.","pattern":"^[a-z0-9-]+$","example":"tasks-462013"},"description":{"type":"string","nullable":true,"description":"Human-readable description of the topic's purpose and use case for team documentation.","maxLength":500,"example":"Handles entity listing updates, event schedules, and submission notifications from external portals"},"category":{"type":"string","nullable":true,"description":"Business category classification for topic organization. Used for filtering and management grouping.","enum":["webhook","workflow","attachment","crm","calendar","consolidated","system"],"example":"webhook"},"messageRetentionDurationHours":{"type":"integer","format":"int32","description":"Duration in hours to retain messages for redelivery and recovery. Default is 168 hours (7 days), maximum is 8760 hours (1 year).","minimum":1,"maximum":8760,"default":168,"example":168},"eventTypes":{"type":"array","description":"Array of event type identifiers that will be published to this topic. Event types must be uppercase with underscores (e.g., 'ENTITY_UPDATED').","minItems":1,"maxItems":50,"items":{"type":"string","pattern":"^[A-Z_]+$"},"example":["ENTITY_UPDATED","EVENT_SCHEDULED","SUBMISSION_RECEIVED","AGREEMENT_SIGNED"]},"entityFilters":{"type":"object","nullable":true,"additionalProperties":true,"description":"JSON object defining filters for message routing based on entity properties. Supports arrays for multiple values and nested object filtering. Used by subscribers to receive only relevant messages.","example":{"property_type":["apartment","house","commercial"],"municipality":["Oslo","Bergen","Trondheim"],"price_range":{"min":1000000,"max":5000000}}}}},"PubSubTopicUpdate":{"type":"object","properties":{"description":{"type":"string","nullable":true,"description":"Updated human-readable description of the topic's purpose","maxLength":500,"example":"Updated description for enhanced functionality"},"category":{"type":"string","nullable":true,"description":"Updated business category classification","enum":["webhook","workflow","attachment","crm","calendar","consolidated","system"],"example":"workflow"},"messageRetentionDurationHours":{"type":"integer","format":"int32","description":"Updated message retention duration in hours. Changing this value updates the GCP topic configuration.","minimum":1,"maximum":8760,"example":336},"eventTypes":{"type":"array","description":"Updated array of event type identifiers","items":{"type":"string","pattern":"^[A-Z_]+$"},"example":["ENTITY_UPDATED","EVENT_SCHEDULED"]},"entityFilters":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated JSON filters for message routing","example":{"property_type":["apartment","house"]}},"isActive":{"type":"boolean","description":"Set topic activation status. Inactive topics are paused for maintenance or configuration updates.","example":true}}},"PublishMessageInput":{"type":"object","required":["data"],"properties":{"data":{"type":"object","additionalProperties":true,"description":"Message payload containing the event data to be published. Will be JSON serialized and base64 encoded for transmission.","example":{"eventType":"ENTITY_UPDATED","entityId":"550e8400-e29b-41d4-a716-446655440000","timestamp":"2024-01-15T10:30:00Z","changes":{"status":"active"}}},"attributes":{"type":"object","additionalProperties":{"type":"string"},"description":"Key-value pairs of message attributes for filtering and routing. All values must be strings.","example":{"source":"api","priority":"high","version":"1.0"}},"orderingKey":{"type":"string","nullable":true,"description":"Ordering key for message ordering guarantees. Messages with the same ordering key are delivered in the order they are published.","example":"entity-550e8400"}}},"PubSubSubscriptionInput":{"type":"object","required":["topicId","subscriptionName","subscriptionFullName","serviceName"],"properties":{"topicId":{"type":"string","format":"uuid","description":"UUID of the Pub/Sub topic to subscribe to. Topic must exist and belong to the organization.","example":"550e8400-e29b-41d4-a716-446655440000"},"subscriptionName":{"type":"string","description":"Short identifier for the subscription. Must be unique within organization.","minLength":1,"maxLength":100,"example":"crm-sync-handler"},"subscriptionFullName":{"type":"string","description":"Complete Google Cloud Pub/Sub subscription identifier in format: projects/{project-id}/subscriptions/{subscription-name}","pattern":"^projects\\/[a-z0-9-]+\\/subscriptions\\/[a-z0-9-]+$","example":"projects/tasks-462013/subscriptions/org-123-crm-sync"},"serviceName":{"type":"string","description":"Name of the service that will consume messages from this subscription","maxLength":100,"example":"CRM Integration Service"},"serviceDescription":{"type":"string","nullable":true,"description":"Human-readable description of the consuming service's purpose","maxLength":500,"example":"Synchronizes contact and lead data with external CRM system"},"subscriptionType":{"type":"string","description":"Type of subscription delivery mechanism. PUSH sends messages to endpoint, PULL requires manual retrieval, export types send to data warehouses.","enum":["PUSH","PULL","BIGQUERY_EXPORT","CLOUD_STORAGE_EXPORT"],"default":"PUSH","example":"PUSH"},"pushEndpointUrl":{"type":"string","format":"uri","nullable":true,"description":"HTTPS endpoint URL to receive push notifications. Required for PUSH subscription type. Must be publicly accessible or within allowed network.","example":"https://crm-integration.example.com/webhook/pubsub"},"pushAuthentication":{"type":"object","nullable":true,"additionalProperties":true,"description":"Authentication configuration for push endpoint. Supports various auth methods like Bearer tokens, OAuth, or API keys.","example":{"type":"bearer","token":"encrypted_token_value"}},"ackDeadlineSeconds":{"type":"integer","format":"int32","description":"Maximum time in seconds that a message can remain unacknowledged before being re-delivered. Default is 600 seconds (10 minutes).","minimum":10,"maximum":600,"default":600,"example":300},"messageRetentionDurationHours":{"type":"integer","format":"int32","description":"Duration in hours to retain unacknowledged messages. Default is 168 hours (7 days).","minimum":1,"maximum":8760,"default":168,"example":168},"exportDestination":{"type":"string","nullable":true,"description":"Destination for export subscriptions. Required for BIGQUERY_EXPORT and CLOUD_STORAGE_EXPORT types. Format depends on export type.","example":"projects/tasks-462013/datasets/events/tables/pubsub_messages"},"exportSchema":{"type":"object","nullable":true,"additionalProperties":true,"description":"Schema configuration for export subscriptions. Defines how messages are mapped to export destination columns/fields.","example":{"useTopicSchema":true,"writeMetadata":false}},"messageFilters":{"type":"object","nullable":true,"additionalProperties":true,"description":"Filters to apply on received messages. Only messages matching the filters will be delivered to this subscription.","example":{"eventType":["ENTITY_UPDATED","ENTITY_CREATED"],"priority":["high","critical"]}},"deadLetterTopic":{"type":"string","nullable":true,"description":"Topic to send messages that cannot be delivered after max delivery attempts. Enables dead letter queue pattern.","example":"projects/tasks-462013/topics/org-123-dead-letter"},"maxDeliveryAttempts":{"type":"integer","format":"int32","description":"Maximum number of delivery attempts before sending message to dead letter topic. Default is 5 attempts.","minimum":1,"maximum":100,"default":5,"example":5},"retryPolicy":{"type":"object","nullable":true,"additionalProperties":true,"description":"Retry policy configuration for failed message deliveries. Controls exponential backoff and retry timing.","example":{"minimumBackoff":"10s","maximumBackoff":"600s"}},"enableMessageOrdering":{"type":"boolean","description":"Enable message ordering guarantees for messages with the same ordering key. Default is false.","default":false,"example":false},"sourceServiceFilter":{"type":"array","nullable":true,"description":"Filter events by source service for inter-service coordination. Accepts single string or array of service names.","items":{"type":"string"},"example":["workflow-service","task-service"]}}},"PubSubSubscriptionUpdate":{"type":"object","properties":{"serviceDescription":{"type":"string","nullable":true,"description":"Updated human-readable description of the consuming service","maxLength":500,"example":"Enhanced CRM integration with bidirectional sync"},"status":{"type":"string","description":"Updated subscription status. ACTIVE enables delivery, PAUSED temporarily stops, DISABLED permanently stops, FAILED indicates delivery problems.","enum":["ACTIVE","PAUSED","DISABLED","FAILED"],"example":"ACTIVE"},"pushEndpointUrl":{"type":"string","format":"uri","nullable":true,"description":"Updated HTTPS endpoint URL for push notifications. Only applies to PUSH subscriptions.","example":"https://new-endpoint.example.com/webhook/pubsub"},"pushAuthentication":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated authentication configuration for push endpoint","example":{"type":"oauth","audience":"https://example.com"}},"ackDeadlineSeconds":{"type":"integer","format":"int32","description":"Updated acknowledgment deadline in seconds","minimum":10,"maximum":600,"example":450},"messageRetentionDurationHours":{"type":"integer","format":"int32","description":"Updated message retention duration in hours","minimum":1,"maximum":8760,"example":336},"exportDestination":{"type":"string","nullable":true,"description":"Updated export destination for export subscriptions","example":"projects/tasks-462013/datasets/events_v2/tables/messages"},"exportSchema":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated schema configuration for exports"},"messageFilters":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated message filtering configuration"},"deadLetterTopic":{"type":"string","nullable":true,"description":"Updated dead letter topic identifier","example":"projects/tasks-462013/topics/org-123-dlq-v2"},"maxDeliveryAttempts":{"type":"integer","format":"int32","description":"Updated maximum delivery attempts","minimum":1,"maximum":100,"example":10},"retryPolicy":{"type":"object","nullable":true,"additionalProperties":true,"description":"Updated retry policy configuration"},"enableMessageOrdering":{"type":"boolean","description":"Updated message ordering setting","example":true}}},"Task":{"type":"object","required":["id","title","organizationId","projectId","status","priority","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique task identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"title":{"type":"string","description":"Task title","minLength":1,"maxLength":500,"example":"Schedule quarterly review"},"description":{"type":"string","nullable":true,"description":"Detailed task description","maxLength":2000,"example":"Complete standard quarterly review process with stakeholder input"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"],"description":"Current task status","example":"IN_PROGRESS"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority level","example":"HIGH"},"completionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Indicates how the task should be presented for completion in the UI","default":"INLINE","example":"DETAIL_VIEW"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this task","example":"123e4567-e89b-12d3-a456-426614174000"},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Project this task belongs to (nullable for workflow-only tasks)","example":"456e7890-e89b-12d3-a456-426614174111"},"sectionId":{"type":"string","format":"uuid","nullable":true,"description":"Section within the project (optional)","example":"321e6547-e89b-12d3-a456-426614174333"},"assignmentType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of assignment (if assigned)","example":"ROLE"},"assigneeRole":{"type":"string","nullable":true,"description":"Role name when assignmentType is ROLE","maxLength":255,"example":"ui-designer"},"assigneePosition":{"type":"string","nullable":true,"description":"Position name when assignmentType is POSITION","maxLength":255,"example":"senior-developer"},"assigneeUserId":{"type":"string","nullable":true,"description":"User ID when assignmentType is USER","maxLength":255,"example":"user-123"},"estimatedMinutes":{"type":"integer","nullable":true,"description":"Estimated time to complete in minutes","minimum":0,"example":480},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Task due date and time","example":"2024-01-25T17:00:00.000Z"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this task is linked to","maxLength":100,"example":"resource"},"entityId":{"type":"string","nullable":true,"description":"ID of external entity this task is linked to","maxLength":255,"example":"resource-456"},"scheduledAt":{"type":"string","format":"date-time","nullable":true,"description":"Scheduled start time for the task","example":"2024-01-20T09:00:00.000Z"},"parentTaskId":{"type":"string","format":"uuid","nullable":true,"description":"ID of parent task for task hierarchies","example":"987e6543-e89b-12d3-a456-426614174333"},"actualDurationMinutes":{"type":"integer","nullable":true,"description":"Actual time spent on the task in minutes","minimum":0,"example":120},"completionNotes":{"type":"string","nullable":true,"description":"Notes provided when task was completed","maxLength":2000,"example":"Inspection completed successfully"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when task was completed","example":"2024-01-25T15:30:00.000Z"},"metadata":{"type":"object","nullable":true,"description":"Custom metadata for the task","additionalProperties":true,"example":{"customField":"value"}},"requiresApproval":{"type":"boolean","nullable":true,"description":"Whether this task requires approval after completion","example":true},"approvalAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of assignment for task approval","example":"USER"},"approvalAssigneeId":{"type":"string","nullable":true,"description":"Assignee ID for task approval","maxLength":255,"example":"user-456"},"approvedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when task was approved","example":"2024-01-25T16:00:00.000Z"},"approvedBy":{"type":"string","nullable":true,"description":"User ID who approved the task","maxLength":255,"example":"user-789"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when task was started","example":"2024-01-25T09:00:00.000Z"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"ID of form template associated with this task","example":"123e4567-e89b-12d3-a456-426614174000"},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"ID of task template this task was created from","example":"456e7890-e89b-12d3-a456-426614174111"},"workflowStageId":{"type":"string","format":"uuid","nullable":true,"description":"ID of workflow stage this task belongs to","example":"789e0123-e89b-12d3-a456-426614174222"},"project":{"allOf":[{"$ref":"#/components/schemas/Project"},{"description":"Project details (included in task responses)"}]},"section":{"type":"object","nullable":true,"description":"Section details (if task is in a section)","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"}}},"checklistItems":{"type":"array","nullable":true,"description":"Checklist items for the task","items":{"type":"object","properties":{"title":{"type":"string","example":"Review design mockups"},"required":{"type":"boolean","example":true},"description":{"type":"string","nullable":true,"example":"Ensure all designs follow brand guidelines"},"completed":{"type":"boolean","nullable":true,"description":"Whether this checklist item has been completed","example":false},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When this checklist item was completed","example":"2024-01-20T10:30:00.000Z"},"completedBy":{"type":"string","nullable":true,"description":"User ID of who completed this checklist item","maxLength":255,"example":"user-123"},"comment":{"type":"string","nullable":true,"description":"Comment added when completing the checklist item","maxLength":2000,"example":"All designs verified against brand guidelines v2.1"}}}},"createdAt":{"type":"string","format":"date-time","description":"Task creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last task update timestamp","example":"2024-01-18T09:45:00.000Z"}}},"TaskInput":{"type":"object","required":["title","projectId"],"properties":{"title":{"type":"string","description":"Task title","minLength":1,"maxLength":500,"example":"Schedule quarterly review"},"description":{"type":"string","nullable":true,"description":"Detailed task description","maxLength":2000,"example":"Design 3 different homepage layouts focusing on improved conversion rates and modern aesthetic"},"projectId":{"type":"string","format":"uuid","description":"Project this task belongs to","example":"456e7890-e89b-12d3-a456-426614174111"},"sectionId":{"type":"string","format":"uuid","nullable":true,"description":"Section within the project (optional)","example":"321e6547-e89b-12d3-a456-426614174333"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority level","default":"MEDIUM","example":"HIGH"},"completionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Indicates how the task should be presented for completion in the UI","default":"INLINE","example":"DETAIL_VIEW"},"assignmentType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of assignment","example":"ROLE"},"assigneeRole":{"type":"string","nullable":true,"description":"Role name when assignmentType is ROLE","maxLength":255,"example":"ui-designer"},"assigneePosition":{"type":"string","nullable":true,"description":"Position name when assignmentType is POSITION","maxLength":255,"example":"senior-developer"},"assigneeUserId":{"type":"string","nullable":true,"description":"User ID when assignmentType is USER","maxLength":255,"example":"user-123"},"estimatedMinutes":{"type":"integer","nullable":true,"description":"Estimated time to complete in minutes","minimum":0,"example":480},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Task due date and time","example":"2024-01-25T17:00:00.000Z"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this task is linked to","maxLength":100,"example":"resource"},"entityId":{"type":"string","nullable":true,"description":"ID of external entity this task is linked to","maxLength":255,"example":"resource-456"},"tempId":{"type":"string","nullable":true,"description":"Temporary client-side identifier for bulk operations with dependencies","maxLength":255,"example":"temp-task-123"},"parentTaskId":{"type":"string","format":"uuid","nullable":true,"description":"ID of parent task for creating subtasks/task hierarchies","example":"987e6543-e89b-12d3-a456-426614174333"},"scheduledAt":{"type":"string","format":"date-time","nullable":true,"description":"Scheduled start time for the task (ISO 8601 format)","example":"2024-01-20T09:00:00.000Z"},"actualDurationMinutes":{"type":"integer","nullable":true,"description":"Actual time spent on the task in minutes (typically set on completion)","minimum":0,"example":450},"metadata":{"type":"object","nullable":true,"description":"Custom metadata for task-specific data, form definitions, or integration data","additionalProperties":true,"example":{"customField":"value","tags":["urgent","client-facing"]}},"checklistItems":{"type":"array","nullable":true,"description":"Checklist items for the task","maxItems":50,"items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string","description":"Checklist item title","maxLength":500,"example":"Review design mockups"},"required":{"type":"boolean","description":"Whether this checklist item is required","example":true},"description":{"type":"string","nullable":true,"description":"Optional description for the checklist item","maxLength":1000,"example":"Ensure all designs follow brand guidelines"},"completed":{"type":"boolean","nullable":true,"description":"Whether this checklist item has been completed","example":false},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When this checklist item was completed","example":"2024-01-20T10:30:00.000Z"},"completedBy":{"type":"string","nullable":true,"description":"User ID of who completed this checklist item","maxLength":255,"example":"user-123"},"comment":{"type":"string","nullable":true,"description":"Comment added when completing the checklist item","maxLength":2000,"example":"All designs verified against brand guidelines v2.1"}}}}}},"TaskUpdate":{"type":"object","properties":{"title":{"type":"string","description":"Task title","minLength":1,"maxLength":500,"example":"Updated homepage design mockups"},"description":{"type":"string","nullable":true,"description":"Detailed task description","maxLength":2000,"example":"Updated scope: Design 5 different homepage layouts with A/B testing considerations"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"],"description":"Current task status","example":"COMPLETED"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority level","example":"URGENT"},"completionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Indicates how the task should be presented for completion in the UI","example":"DETAIL_VIEW"},"assignmentType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of assignment","example":"USER"},"assigneeRole":{"type":"string","nullable":true,"description":"Role name when assignmentType is ROLE","maxLength":255,"example":"senior-designer"},"assigneePosition":{"type":"string","nullable":true,"description":"Position name when assignmentType is POSITION","maxLength":255,"example":"lead-developer"},"assigneeUserId":{"type":"string","nullable":true,"description":"User ID when assignmentType is USER","maxLength":255,"example":"user-456"},"estimatedMinutes":{"type":"integer","nullable":true,"description":"Estimated time to complete in minutes","minimum":0,"example":600},"actualDurationMinutes":{"type":"integer","nullable":true,"description":"Actual time spent on the task in minutes","minimum":0,"example":550},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Task due date and time","example":"2024-01-30T17:00:00.000Z"},"scheduledAt":{"type":"string","format":"date-time","nullable":true,"description":"Scheduled start time for the task (ISO 8601 format)","example":"2024-01-25T09:00:00.000Z"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this task is linked to","maxLength":100,"example":"feature"},"entityId":{"type":"string","nullable":true,"description":"ID of external entity this task is linked to","maxLength":255,"example":"feature-789"},"metadata":{"type":"object","nullable":true,"description":"Custom metadata for the task","additionalProperties":true,"example":{"phase":"implementation","tags":["urgent","review-needed"]}},"parentTaskId":{"type":"string","format":"uuid","nullable":true,"description":"ID of parent task (set to null to remove parent)","example":"987e6543-e89b-12d3-a456-426614174333"},"checklistItems":{"type":"array","nullable":true,"description":"Updated checklist items for the task","maxItems":50,"items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string","description":"Checklist item title","maxLength":500,"example":"Review design mockups"},"required":{"type":"boolean","description":"Whether this checklist item is required","example":true},"description":{"type":"string","nullable":true,"description":"Optional description for the checklist item","maxLength":1000,"example":"Ensure all designs follow brand guidelines"},"completed":{"type":"boolean","nullable":true,"description":"Whether this checklist item has been completed","example":true},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When this checklist item was completed","example":"2024-01-20T10:30:00.000Z"},"completedBy":{"type":"string","nullable":true,"description":"User ID of who completed this checklist item","maxLength":255,"example":"user-123"},"comment":{"type":"string","nullable":true,"description":"Comment added when completing the checklist item","maxLength":2000,"example":"Verified all mockups match brand guidelines v2.1"}}}}}},"BulkCreateTasksRequest":{"type":"object","required":["tasks"],"properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskInput"},"description":"Array of tasks to create","minItems":1,"maxItems":100},"dependencies":{"type":"array","items":{"$ref":"#/components/schemas/BulkCreateDependencyRequest"},"description":"Array of dependencies between tasks in this bulk operation","nullable":true}}},"BulkCreateDependencyRequest":{"type":"object","required":["dependentType","prerequisiteType"],"properties":{"dependentTempId":{"type":"string","nullable":true,"description":"Temporary ID of dependent task (reference to task in same bulk request)","maxLength":255,"example":"temp-frontend-task"},"dependentId":{"type":"string","format":"uuid","nullable":true,"description":"ID of existing dependent task","example":"123e4567-e89b-12d3-a456-426614174000"},"dependentType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of dependent entity","example":"task"},"prerequisiteTempId":{"type":"string","nullable":true,"description":"Temporary ID of prerequisite task (reference to task in same bulk request)","maxLength":255,"example":"temp-design-task"},"prerequisiteId":{"type":"string","format":"uuid","nullable":true,"description":"ID of existing prerequisite task","example":"456e7890-e89b-12d3-a456-426614174111"},"prerequisiteType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of prerequisite entity","example":"task"},"constraintType":{"type":"string","enum":["HARD","SOFT"],"nullable":true,"description":"Type of dependency constraint (HARD blocks progress, SOFT is advisory)","default":"HARD","example":"HARD"},"relationType":{"type":"string","enum":["FINISH_TO_START","START_TO_START","FINISH_TO_FINISH","START_TO_FINISH"],"nullable":true,"description":"Type of dependency relationship","default":"FINISH_TO_START","example":"FINISH_TO_START"},"lagDays":{"type":"integer","nullable":true,"description":"Number of days to delay after prerequisite completion","minimum":0,"maximum":365,"example":2},"workflowId":{"type":"string","format":"uuid","nullable":true,"description":"Workflow ID if dependencies are within a specific workflow","example":"789e0123-e89b-12d3-a456-426614174222"}}},"HealthResponse":{"type":"object","required":["status","timestamp","version"],"properties":{"status":{"type":"string","description":"Service health status","example":"healthy"},"timestamp":{"type":"string","format":"date-time","description":"Health check timestamp","example":"2024-01-15T10:30:00.000Z"},"version":{"type":"string","description":"Service version","example":"1.0.0"}}},"DependencyConstraint":{"type":"string","enum":["HARD","SOFT"],"description":"Type of dependency constraint","example":"HARD"},"DependencyRelation":{"type":"string","enum":["FINISH_TO_START","START_TO_START","FINISH_TO_FINISH","START_TO_FINISH"],"description":"Type of dependency relation between entities","example":"FINISH_TO_START"},"Dependency":{"type":"object","required":["id","organizationId","dependentType","dependentId","prerequisiteType","prerequisiteId","constraintType","relationType","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique dependency identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this dependency","example":"123e4567-e89b-12d3-a456-426614174000"},"workflowId":{"type":"string","format":"uuid","nullable":true,"description":"Workflow this dependency belongs to","example":"456e7890-e89b-12d3-a456-426614174111"},"dependentType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the dependent entity","example":"task"},"dependentId":{"type":"string","format":"uuid","description":"ID of the dependent entity","example":"987e6543-e89b-12d3-a456-426614174333"},"prerequisiteType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the prerequisite entity","example":"task"},"prerequisiteId":{"type":"string","format":"uuid","description":"ID of the prerequisite entity","example":"321e6547-e89b-12d3-a456-426614174444"},"constraintType":{"$ref":"#/components/schemas/DependencyConstraint"},"relationType":{"$ref":"#/components/schemas/DependencyRelation"},"lagDays":{"type":"integer","minimum":0,"description":"Number of lag days between entities","example":0},"prerequisiteStatus":{"type":"string","description":"Status of the prerequisite entity","example":"COMPLETED"},"isSatisfied":{"type":"boolean","description":"Whether this dependency is currently satisfied","example":true},"criticalPath":{"type":"boolean","description":"Whether this dependency is on the critical path","example":false},"slackDays":{"type":"integer","description":"Available slack time for this dependency","example":0},"createdAt":{"type":"string","format":"date-time","description":"Dependency creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last dependency update timestamp","example":"2024-01-20T16:15:00.000Z"}}},"DependencyResponse":{"allOf":[{"$ref":"#/components/schemas/Dependency"},{"type":"object","properties":{"_links":{"type":"object","description":"HATEOAS links for the dependency","properties":{"self":{"type":"string","format":"uri","description":"Link to this dependency","example":"/api/v1/dependencies/789e0123-e89b-12d3-a456-426614174222"},"dependent":{"type":"string","format":"uri","description":"Link to the dependent entity","example":"/api/v1/tasks/987e6543-e89b-12d3-a456-426614174333"},"prerequisite":{"type":"string","format":"uri","description":"Link to the prerequisite entity","example":"/api/v1/tasks/321e6547-e89b-12d3-a456-426614174444"}}}}}]},"CreateDependencyRequest":{"type":"object","required":["dependentType","dependentId","prerequisiteType","prerequisiteId"],"properties":{"dependentType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the dependent entity","example":"task"},"dependentId":{"type":"string","format":"uuid","description":"ID of the dependent entity","example":"987e6543-e89b-12d3-a456-426614174333"},"prerequisiteType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the prerequisite entity","example":"task"},"prerequisiteId":{"type":"string","format":"uuid","description":"ID of the prerequisite entity","example":"321e6547-e89b-12d3-a456-426614174444"},"constraintType":{"$ref":"#/components/schemas/DependencyConstraint"},"relationType":{"$ref":"#/components/schemas/DependencyRelation"},"lagDays":{"type":"integer","minimum":0,"description":"Number of lag days between entities","example":0},"workflowId":{"type":"string","format":"uuid","nullable":true,"description":"Workflow this dependency belongs to","example":"456e7890-e89b-12d3-a456-426614174111"}}},"UpdateDependencyRequest":{"type":"object","properties":{"constraintType":{"$ref":"#/components/schemas/DependencyConstraint"},"relationType":{"$ref":"#/components/schemas/DependencyRelation"},"lagDays":{"type":"integer","minimum":0,"description":"Number of lag days between entities","example":0},"prerequisiteStatus":{"type":"string","description":"Status of the prerequisite entity","example":"COMPLETED"}}},"GanttChartData":{"type":"object","required":["tasks","stages","timeline","criticalPath"],"properties":{"tasks":{"type":"array","items":{"type":"object","description":"Task with dependency and scheduling information"},"description":"Tasks with dependency information"},"stages":{"type":"array","items":{"type":"object","description":"Workflow stage with dependency and scheduling information"},"description":"Workflow stages with dependency information"},"timeline":{"type":"object","required":["start","end","criticalPathDuration"],"properties":{"start":{"type":"string","format":"date-time","description":"Timeline start date","example":"2024-01-15T00:00:00.000Z"},"end":{"type":"string","format":"date-time","description":"Timeline end date","example":"2024-03-30T23:59:59.000Z"},"criticalPathDuration":{"type":"integer","description":"Duration of critical path in days","example":75}}},"criticalPath":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of entity IDs on the critical path","example":["task-1","task-2","stage-1"]}}},"CriticalPathAnalysis":{"type":"object","required":["criticalPath","totalDuration","bottlenecks","riskFactors"],"properties":{"criticalPath":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of entity IDs on the critical path","example":["task-1","task-2","stage-1"]},"totalDuration":{"type":"integer","description":"Total project duration in days","example":75},"bottlenecks":{"type":"array","items":{"type":"object","required":["entityId","entityType","title","impact"],"properties":{"entityId":{"type":"string","format":"uuid","description":"ID of the bottleneck entity"},"entityType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the bottleneck entity"},"title":{"type":"string","description":"Title of the bottleneck entity"},"impact":{"type":"integer","description":"Impact in days if this entity is delayed"}}},"description":"Identified bottlenecks in the project"},"riskFactors":{"type":"array","items":{"type":"object","required":["type","entityId","description","severity"],"properties":{"type":{"type":"string","enum":["OVERDUE_DEPENDENCY","CIRCULAR_DEPENDENCY","MISSING_ASSIGNMENT"],"description":"Type of risk factor"},"entityId":{"type":"string","format":"uuid","description":"ID of the affected entity"},"description":{"type":"string","description":"Description of the risk factor"},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Severity level of the risk factor"}}},"description":"Identified risk factors in the project"}}},"ScheduleRecalculationResult":{"type":"object","required":["updated","affectedEntities","criticalPathChanged"],"properties":{"updated":{"type":"boolean","description":"Whether the schedule was updated","example":true},"affectedEntities":{"type":"array","items":{"type":"object","required":["entityId","entityType"],"properties":{"entityId":{"type":"string","format":"uuid","description":"ID of the affected entity"},"entityType":{"type":"string","enum":["task","workflow_stage"],"description":"Type of the affected entity"},"oldStartDate":{"type":"string","format":"date-time","nullable":true,"description":"Previous start date"},"newStartDate":{"type":"string","format":"date-time","nullable":true,"description":"New start date"},"oldEndDate":{"type":"string","format":"date-time","nullable":true,"description":"Previous end date"},"newEndDate":{"type":"string","format":"date-time","nullable":true,"description":"New end date"}}},"description":"Entities that were affected by the recalculation"},"criticalPathChanged":{"type":"boolean","description":"Whether the critical path changed","example":false},"newCriticalPath":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true,"description":"New critical path if it changed"}}},"DependencyValidationResult":{"type":"object","required":["isValid","errors","warnings"],"properties":{"isValid":{"type":"boolean","description":"Whether the dependency is valid","example":true},"errors":{"type":"array","items":{"type":"object","required":["type","message","affectedEntities"],"properties":{"type":{"type":"string","enum":["CIRCULAR_DEPENDENCY","INVALID_RELATIONSHIP","MISSING_ENTITY","CONSTRAINT_VIOLATION"],"description":"Type of validation error"},"message":{"type":"string","description":"Error message"},"affectedEntities":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Entities affected by this error"},"cycle":{"type":"array","items":{"type":"string","format":"uuid"},"nullable":true,"description":"Cycle path for circular dependency errors"}}},"description":"Validation errors found"},"warnings":{"type":"array","items":{"type":"object","required":["type","message","entityId"],"properties":{"type":{"type":"string","enum":["SOFT_DEPENDENCY_VIOLATION","POTENTIAL_DELAY"],"description":"Type of warning"},"message":{"type":"string","description":"Warning message"},"entityId":{"type":"string","format":"uuid","description":"Entity affected by this warning"}}},"description":"Validation warnings found"}}},"Attachment":{"type":"object","required":["id","organizationId","targetType","targetId","filename","originalFilename","fileSize","mimeType","storageUrl","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique attachment identifier with att- prefix","example":"att-123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this attachment","example":"123e4567-e89b-12d3-a456-426614174000"},"targetType":{"type":"string","enum":["project","task","workflow"],"description":"Type of entity this attachment is linked to","example":"project"},"targetId":{"type":"string","format":"uuid","description":"ID of the entity this attachment is linked to","example":"456e7890-e89b-12d3-a456-426614174111"},"filename":{"type":"string","description":"Sanitized filename stored in the system","maxLength":255,"example":"project-requirements.pdf"},"originalFilename":{"type":"string","description":"Original filename as uploaded by user","maxLength":255,"example":"Project Requirements Document v2.1.pdf"},"fileSize":{"type":"integer","description":"File size in bytes","minimum":1,"maximum":104857600,"example":2048576},"mimeType":{"type":"string","description":"MIME type of the file","maxLength":100,"example":"application/pdf"},"storageUrl":{"type":"string","description":"Google Cloud Storage URL for the file","example":"gs://tasks-attachments/org123/attachments/att-123-file.pdf"},"downloadUrl":{"type":"string","format":"uri","nullable":true,"description":"Temporary signed download URL (only included in download responses)","example":"https://storage.googleapis.com/tasks-attachments/org123/attachments/att-123-file.pdf?X-Goog-Algorithm=..."},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"Download URL expiration time (only included in download responses)","example":"2024-01-16T10:30:00.000Z"},"externalDocumentId":{"type":"string","nullable":true,"description":"Optional external system document identifier for integration","maxLength":255,"example":"sharepoint-doc-789"},"createdAt":{"type":"string","format":"date-time","description":"Attachment upload timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last attachment update timestamp","example":"2024-01-15T10:30:00.000Z"}}},"AttachmentUploadRequest":{"type":"object","description":"Request schema for uploading attachments via multipart/form-data","required":["file","targetType","targetId"],"properties":{"file":{"type":"string","format":"binary","description":"File to upload. Maximum size 100MB. All common file types supported including images, documents, videos, and archives.","example":"(binary file data)"},"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Type of entity the attachment belongs to. Determines organizational hierarchy and access control.","example":"task"},"targetId":{"type":"string","format":"uuid","description":"UUID of the target entity. Entity must exist and belong to the authenticated organization.","example":"123e4567-e89b-12d3-a456-426614174000"},"externalDocumentId":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"Optional external system document identifier for integration tracking and bidirectional linking with CRM, DMS, or other systems.","example":"EXT-DOC-12345"}}},"AttachmentListResponse":{"type":"object","description":"Paginated list of attachments with metadata","required":["attachments","pagination"],"properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/AttachmentResponse"},"description":"Array of attachment objects for the current page"},"pagination":{"type":"object","required":["total","page","limit","totalPages"],"properties":{"total":{"type":"integer","minimum":0,"description":"Total number of attachments matching the query","example":42},"page":{"type":"integer","minimum":1,"description":"Current page number (1-indexed)","example":1},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Number of items per page. Maximum 100 per page","example":20},"totalPages":{"type":"integer","minimum":0,"description":"Total number of pages available","example":3}}}}},"AttachmentQuery":{"type":"object","description":"Query parameters for filtering and paginating attachments","properties":{"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Filter by target entity type","example":"project"},"targetId":{"type":"string","format":"uuid","description":"Filter by target entity ID","example":"123e4567-e89b-12d3-a456-426614174000"},"mimeType":{"type":"string","description":"Filter by MIME type using partial match. Supports wildcards like 'image/' to match all images.","example":"application/pdf"},"includeDownloadUrls":{"type":"string","enum":["true","false"],"default":"false","description":"Include 15-minute signed download URLs in response. Set to 'true' to enable.","example":"true"},"page":{"type":"integer","minimum":1,"default":1,"description":"Page number for pagination (1-indexed)","example":1},"limit":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Number of items per page. Maximum 100","example":20}}},"AttachmentDownloadResponse":{"type":"object","required":["downloadUrl","expiresAt","filename","fileSize","mimeType"],"properties":{"downloadUrl":{"type":"string","format":"uri","description":"Temporary signed download URL","example":"https://storage.googleapis.com/tasks-attachments/org123/attachments/att-123-file.pdf?X-Goog-Algorithm=..."},"expiresAt":{"type":"string","format":"date-time","description":"Download URL expiration time","example":"2024-01-16T10:30:00.000Z"},"filename":{"type":"string","description":"Filename for download","example":"project-requirements.pdf"},"fileSize":{"type":"integer","description":"File size in bytes","example":2048576},"mimeType":{"type":"string","description":"MIME type of the file","example":"application/pdf"}}},"AttachmentSummary":{"type":"object","required":["totalCount","totalSizeBytes","fileTypes","recentActivity"],"properties":{"totalCount":{"type":"integer","description":"Total number of attachments","minimum":0,"example":156},"totalSizeBytes":{"type":"integer","description":"Total storage used in bytes","minimum":0,"example":523456789},"totalSizeMB":{"type":"number","format":"float","description":"Total storage used in megabytes","minimum":0,"example":499.2},"fileTypes":{"type":"array","items":{"type":"object","required":["mimeType","count","totalSize"],"properties":{"mimeType":{"type":"string","description":"MIME type","example":"application/pdf"},"extension":{"type":"string","description":"File extension","example":"pdf"},"count":{"type":"integer","description":"Number of files of this type","minimum":0,"example":23},"totalSize":{"type":"integer","description":"Total size of files of this type in bytes","minimum":0,"example":45678901}}},"description":"Breakdown of files by type"},"recentActivity":{"type":"object","required":["uploadsLastWeek","downloadsLastWeek","deletionsLastWeek"],"properties":{"uploadsLastWeek":{"type":"integer","description":"Number of uploads in the last 7 days","minimum":0,"example":12},"downloadsLastWeek":{"type":"integer","description":"Number of downloads in the last 7 days","minimum":0,"example":45},"deletionsLastWeek":{"type":"integer","description":"Number of deletions in the last 7 days","minimum":0,"example":3}},"description":"Recent activity statistics"}}},"FormTemplate":{"type":"object","description":"Complete form template object with all fields","properties":{"id":{"type":"string","format":"uuid","description":"Unique form template identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organization_id":{"type":"string","format":"uuid","description":"Organization that owns this form template"},"code":{"type":"string","description":"Unique template identifier code using alphanumeric characters, underscores, and hyphens","maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","example":"property_inspection_v1"},"name":{"type":"string","description":"Human-readable template name","maxLength":255,"example":"Property Inspection Checklist"},"description":{"type":"string","nullable":true,"description":"Detailed template description"},"category":{"type":"string","nullable":true,"description":"Template category (e.g., real_estate, maintenance, legal)","maxLength":100,"example":"real_estate"},"version_major":{"type":"integer","description":"Major version number (breaking changes)","minimum":1,"default":1},"version_minor":{"type":"integer","description":"Minor version number (compatible changes)","minimum":0,"default":0},"is_active":{"type":"boolean","description":"Whether template is active and available for use","default":true},"form_schema":{"type":"object","description":"JSON schema defining form structure, fields, and validation","additionalProperties":true},"ui_schema":{"type":"object","nullable":true,"description":"UI schema for customizing form rendering","additionalProperties":true},"metadata":{"type":"object","nullable":true,"description":"Additional custom metadata","additionalProperties":true},"created_at":{"type":"string","format":"date-time","description":"Template creation timestamp"},"updated_at":{"type":"string","format":"date-time","description":"Last update timestamp"},"created_by":{"type":"string","description":"User or system that created the template"},"updated_by":{"type":"string","description":"User or system that last updated the template"}}},"FormTemplateInput":{"type":"object","required":["code","name","schema"],"properties":{"code":{"type":"string","description":"Unique template code for identification","maxLength":100,"pattern":"^[a-zA-Z0-9_-]+$","example":"property-inspection-form"},"name":{"type":"string","description":"Human-readable template name","maxLength":200,"example":"Property Inspection Form"},"description":{"type":"string","nullable":true,"description":"Detailed template description","maxLength":1000,"example":"Comprehensive property inspection form with Norwegian real estate standards"},"category":{"type":"string","nullable":true,"description":"Template category for organization","maxLength":50,"example":"real_estate"},"schema":{"type":"object","description":"JSON Schema definition for the form","additionalProperties":true,"example":{"type":"object","properties":{"propertyAddress":{"type":"string","title":"Property Address"}},"required":["propertyAddress"]}},"uiSchema":{"type":"object","nullable":true,"description":"UI Schema for form rendering customization","additionalProperties":true},"version":{"type":"string","description":"Template version","maxLength":20,"default":"1.0.0","example":"1.0.0"},"isActive":{"type":"boolean","description":"Whether the template is active","default":true,"example":true},"metadata":{"type":"object","nullable":true,"description":"Additional template metadata","additionalProperties":true}}},"FormResponse":{"type":"object","description":"A form submission response","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the form response"},"organization_id":{"type":"string","format":"uuid","description":"Organization ID"},"task_id":{"type":"string","format":"uuid","description":"Task ID this response belongs to"},"form_template_id":{"type":"string","format":"uuid","description":"Form template ID used for this submission"},"submitted_at":{"type":"string","format":"date-time","description":"When the form was submitted"},"submitted_by":{"type":"string","description":"User ID or identifier of who submitted the form"},"template_version":{"type":"string","description":"Version of the form template at time of submission","example":"1.2"},"response_data":{"type":"object","description":"The actual form response data","additionalProperties":true},"created_at":{"type":"string","format":"date-time","description":"When the record was created"}},"required":["id","organization_id","task_id","form_template_id","submitted_at","submitted_by","template_version","response_data","created_at"]},"FormAction":{"type":"object","description":"Configurable action that executes on form submission or task completion","properties":{"id":{"type":"string","format":"uuid","description":"Unique form action identifier"},"organization_id":{"type":"string","format":"uuid","description":"Organization identifier"},"form_template_id":{"type":"string","format":"uuid","description":"Form template this action belongs to"},"code":{"type":"string","description":"Unique action code within template","maxLength":50,"pattern":"^[a-z][a-z0-9_]*$"},"name":{"type":"string","description":"Human-readable action name","maxLength":255},"description":{"type":"string","nullable":true,"description":"Detailed action description"},"version":{"type":"integer","description":"Action version number","default":1},"trigger":{"type":"string","description":"When the action executes","enum":["on_submit","on_task_complete","on_approved"]},"execution_order":{"type":"integer","description":"Execution order (lower executes first)","minimum":0,"default":0},"is_enabled":{"type":"boolean","description":"Whether action is currently enabled","default":true},"action_type":{"type":"string","description":"Type of action","enum":["webhook","workflow_data_sync","event","context_action"]},"webhook_endpoint":{"type":"string","nullable":true,"description":"HTTP endpoint for webhook actions","maxLength":500},"webhook_method":{"type":"string","nullable":true,"description":"HTTP method for webhook","enum":["GET","POST","PUT","PATCH","DELETE"]},"webhook_headers":{"type":"object","nullable":true,"description":"Static HTTP headers"},"webhook_header_mapping":{"type":"object","nullable":true,"description":"Dynamic header mappings"},"webhook_success_codes":{"type":"array","nullable":true,"description":"HTTP status codes considered successful","items":{"type":"integer"}},"webhook_response_schema":{"type":"object","nullable":true,"description":"Response validation schema"},"webhook_response_extract":{"type":"object","nullable":true,"description":"Extract fields from response"},"auth_type":{"type":"string","nullable":true,"description":"Authentication strategy","enum":["pass_through","pass_through_with_fallback","api_key","none"]},"auth_header_name":{"type":"string","nullable":true,"description":"Header name for API key auth","maxLength":100},"has_api_key":{"type":"boolean","description":"Indicates presence of API key (actual key not exposed)"},"has_signing_secret":{"type":"boolean","description":"Indicates presence of signing secret (actual secret not exposed)"},"payload_mapping":{"type":"object","nullable":true,"description":"Payload transformation mapping"},"sync_schema_code":{"type":"string","nullable":true,"description":"Workflow data schema code for sync","maxLength":50},"sync_merge_strategy":{"type":"string","nullable":true,"description":"Data merge strategy","enum":["replace","merge","append"]},"event_code":{"type":"string","nullable":true,"description":"Event code to publish","maxLength":100},"context_type_code":{"type":"string","nullable":true,"description":"Context type for context actions","maxLength":50},"context_action_code":{"type":"string","nullable":true,"description":"Context action to execute","maxLength":50},"conditions":{"type":"object","nullable":true,"description":"Conditional execution logic"},"rate_limit_requests":{"type":"integer","nullable":true,"description":"Max requests in rate limit window","minimum":1},"rate_limit_window_ms":{"type":"integer","nullable":true,"description":"Rate limit window in milliseconds","minimum":1000},"on_error":{"type":"string","nullable":true,"description":"Error handling strategy","enum":["log","fail_task","retry"]},"retry_max_attempts":{"type":"integer","nullable":true,"description":"Maximum retry attempts","minimum":0,"maximum":10},"retry_backoff_ms":{"type":"integer","nullable":true,"description":"Initial retry backoff delay","minimum":100},"timeout_ms":{"type":"integer","nullable":true,"description":"Action execution timeout","minimum":1000,"maximum":300000},"created_at":{"type":"string","format":"date-time","description":"Creation timestamp"},"updated_at":{"type":"string","format":"date-time","description":"Last update timestamp"},"deleted_at":{"type":"string","format":"date-time","nullable":true,"description":"Soft deletion timestamp"}}},"FormActionExecutionLog":{"type":"object","description":"Execution log for form action with request/response details","properties":{"id":{"type":"string","format":"uuid","description":"Unique execution log identifier"},"organization_id":{"type":"string","format":"uuid","description":"Organization identifier"},"form_action_id":{"type":"string","format":"uuid","description":"Form action that was executed"},"task_id":{"type":"string","format":"uuid","description":"Task context for execution"},"workflow_id":{"type":"string","format":"uuid","nullable":true,"description":"Workflow context if applicable"},"form_template_id":{"type":"string","format":"uuid","description":"Form template identifier"},"trigger":{"type":"string","description":"Trigger that caused execution","enum":["on_submit","on_task_complete","on_approved"]},"execution_id":{"type":"string","description":"Unique execution identifier","maxLength":50},"batch_id":{"type":"string","nullable":true,"description":"Batch identifier for grouped executions","maxLength":50},"action_type":{"type":"string","description":"Type of action executed","enum":["webhook","workflow_data_sync","event","context_action"]},"status":{"type":"string","description":"Execution status","enum":["pending","in_progress","success","failure","timeout","skipped","cancelled"]},"request_url":{"type":"string","nullable":true,"description":"HTTP request URL for webhook actions","maxLength":1000},"request_method":{"type":"string","nullable":true,"description":"HTTP request method","maxLength":10},"request_headers":{"type":"object","nullable":true,"description":"HTTP request headers (sensitive data redacted)"},"request_body":{"type":"object","nullable":true,"description":"HTTP request body (sensitive data redacted)"},"form_data":{"type":"object","nullable":true,"description":"Snapshot of form data at execution time"},"context_data":{"type":"object","nullable":true,"description":"Snapshot of context data"},"resolved_payload":{"type":"object","nullable":true,"description":"Final payload after transformations"},"response_status":{"type":"integer","nullable":true,"description":"HTTP response status code"},"response_headers":{"type":"object","nullable":true,"description":"HTTP response headers"},"response_body":{"type":"object","nullable":true,"description":"HTTP response body"},"error_message":{"type":"string","nullable":true,"description":"Error message if execution failed"},"error_stack":{"type":"string","nullable":true,"description":"Error stack trace for debugging"},"is_recoverable":{"type":"boolean","description":"Whether execution can be retried"},"retry_count":{"type":"integer","description":"Number of retry attempts","minimum":0,"default":0},"max_retries":{"type":"integer","description":"Maximum allowed retries","minimum":0},"next_retry_at":{"type":"string","format":"date-time","nullable":true,"description":"Scheduled time for next retry"},"queued_at":{"type":"string","format":"date-time","description":"When execution was queued"},"started_at":{"type":"string","format":"date-time","nullable":true,"description":"When execution started"},"completed_at":{"type":"string","format":"date-time","nullable":true,"description":"When execution completed"},"duration_ms":{"type":"integer","nullable":true,"description":"Execution duration in milliseconds"}}},"CreateFormActionRequest":{"type":"object","description":"Request schema for creating a new form action"},"UpdateFormActionRequest":{"type":"object","description":"Request schema for updating a form action (all fields optional)"},"Translation":{"type":"object","required":["id","organizationId","namespace","key","language","value","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique translation identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this translation","example":"123e4567-e89b-12d3-a456-426614174000"},"namespace":{"type":"string","description":"Translation namespace for organization","maxLength":100,"example":"real_estate_forms"},"key":{"type":"string","description":"Translation key identifier","maxLength":200,"example":"property.address.label"},"language":{"type":"string","description":"Language code (ISO 639-1)","maxLength":10,"example":"no"},"value":{"type":"string","description":"Translated text value","maxLength":2000,"example":"Eiendomsadresse"},"context":{"type":"string","nullable":true,"description":"Additional context for translators","maxLength":500,"example":"Field label for property address input in inspection form"},"metadata":{"type":"object","nullable":true,"description":"Additional translation metadata","additionalProperties":true,"example":{"category":"form_labels","region":"norway"}},"createdAt":{"type":"string","format":"date-time","description":"Translation creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last translation update timestamp","example":"2024-01-20T16:15:00.000Z"}}},"TranslationInput":{"type":"object","required":["namespace","key","language","value"],"properties":{"namespace":{"type":"string","description":"Translation namespace for organization","maxLength":100,"example":"real_estate_forms"},"key":{"type":"string","description":"Translation key identifier","maxLength":200,"example":"property.address.label"},"language":{"type":"string","description":"Language code (ISO 639-1)","maxLength":10,"example":"no"},"value":{"type":"string","description":"Translated text value","maxLength":2000,"example":"Eiendomsadresse"},"context":{"type":"string","nullable":true,"description":"Additional context for translators","maxLength":500,"example":"Field label for property address input"},"metadata":{"type":"object","nullable":true,"description":"Additional translation metadata","additionalProperties":true}}},"BulkTranslationInput":{"type":"object","required":["translations"],"properties":{"translations":{"type":"array","items":{"$ref":"#/components/schemas/TranslationInput"},"description":"Array of translations to create or update","minItems":1,"maxItems":1000},"overwrite":{"type":"boolean","description":"Whether to overwrite existing translations","default":false,"example":false}}},"ContextType":{"type":"object","required":["id","organizationId","code","name","apiUrl","httpMethod","authenticationType","requestFormat","isActive","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique context type identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this context type","example":"123e4567-e89b-12d3-a456-426614174000"},"code":{"type":"string","description":"Unique context type code for identification","maxLength":100,"pattern":"^[a-zA-Z0-9_-]+$","example":"property_management_api"},"name":{"type":"string","description":"Human-readable context type name","maxLength":200,"example":"Property Management System API"},"description":{"type":"string","nullable":true,"description":"Detailed description of the context type","maxLength":1000,"example":"Integration with external property management system for real-time property data"},"apiUrl":{"type":"string","description":"API endpoint URL template with placeholder support","maxLength":500,"example":"https://api.propertymanager.com/v1/properties/{propertyId}"},"httpMethod":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for API requests","example":"GET"},"authenticationType":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC"],"description":"Authentication method for API requests","example":"API_KEY"},"authenticationConfig":{"type":"object","nullable":true,"description":"Authentication configuration (credentials stored securely)","additionalProperties":true,"example":{"apiKeyHeader":"X-API-Key","apiKeyValue":"[REDACTED]"}},"requestFormat":{"type":"string","enum":["URL_PARAMS","JSON_BODY","FORM_DATA"],"description":"Request format for sending data","example":"URL_PARAMS"},"requestHeaders":{"type":"object","nullable":true,"description":"Additional headers to include in requests","additionalProperties":true,"example":{"Content-Type":"application/json","Accept":"application/json"}},"responseMapping":{"type":"object","nullable":true,"description":"Mapping configuration for response data","additionalProperties":true,"example":{"address":"data.property.address","value":"data.property.marketValue"}},"timeoutMs":{"type":"integer","nullable":true,"description":"Request timeout in milliseconds","minimum":1000,"maximum":60000,"default":30000,"example":30000},"retryConfig":{"type":"object","nullable":true,"description":"Retry configuration for failed requests","properties":{"maxRetries":{"type":"integer","minimum":0,"maximum":5,"example":3},"retryDelayMs":{"type":"integer","minimum":100,"maximum":10000,"example":1000}}},"isActive":{"type":"boolean","description":"Whether the context type is active","example":true},"metadata":{"type":"object","nullable":true,"description":"Additional context type metadata","additionalProperties":true,"example":{"provider":"PropertyManager Pro","version":"2.1","region":"norway"}},"createdAt":{"type":"string","format":"date-time","description":"Context type creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last context type update timestamp","example":"2024-01-20T16:15:00.000Z"}}},"ContextTypeInput":{"type":"object","required":["code","name","apiUrl","httpMethod","authenticationType","requestFormat"],"properties":{"code":{"type":"string","description":"Unique context type code for identification","maxLength":100,"pattern":"^[a-zA-Z0-9_-]+$","example":"property_management_api"},"name":{"type":"string","description":"Human-readable context type name","maxLength":200,"example":"Property Management System API"},"description":{"type":"string","nullable":true,"description":"Detailed description of the context type","maxLength":1000,"example":"Integration with external property management system"},"apiUrl":{"type":"string","description":"API endpoint URL template with placeholder support","maxLength":500,"example":"https://api.propertymanager.com/v1/properties/{propertyId}"},"httpMethod":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for API requests","example":"GET"},"authenticationType":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC"],"description":"Authentication method for API requests","example":"API_KEY"},"authenticationConfig":{"type":"object","nullable":true,"description":"Authentication configuration","additionalProperties":true},"requestFormat":{"type":"string","enum":["URL_PARAMS","JSON_BODY","FORM_DATA"],"description":"Request format for sending data","example":"URL_PARAMS"},"requestHeaders":{"type":"object","nullable":true,"description":"Additional headers to include in requests","additionalProperties":true},"responseMapping":{"type":"object","nullable":true,"description":"Mapping configuration for response data","additionalProperties":true},"timeoutMs":{"type":"integer","nullable":true,"description":"Request timeout in milliseconds","minimum":1000,"maximum":60000,"default":30000,"example":30000},"retryConfig":{"type":"object","nullable":true,"description":"Retry configuration for failed requests","properties":{"maxRetries":{"type":"integer","minimum":0,"maximum":5},"retryDelayMs":{"type":"integer","minimum":100,"maximum":10000}}},"isActive":{"type":"boolean","description":"Whether the context type is active","default":true,"example":true},"metadata":{"type":"object","nullable":true,"description":"Additional context type metadata","additionalProperties":true}}},"TestContextTypeRequest":{"type":"object","required":["externalEntityId"],"properties":{"externalEntityId":{"type":"string","description":"External entity ID to use for testing","example":"property-123"},"dynamicParameters":{"type":"object","description":"Dynamic parameters to substitute in the endpoint pattern","additionalProperties":true,"example":{"entityId":"property-123","businessRole":"Ansvarlig Megler"}},"customEndpoint":{"type":"string","description":"Optional custom endpoint to override the configured pattern","example":"/api/v1/custom-endpoint"},"customRequestParams":{"type":"object","description":"Optional custom request parameters","additionalProperties":true},"customHeaders":{"type":"object","description":"Optional custom headers for the request","additionalProperties":{"type":"string"}}}},"TestContextTypeResponse":{"type":"object","required":["success","responseTime"],"properties":{"success":{"type":"boolean","description":"Whether the test was successful","example":true},"responseTime":{"type":"integer","description":"Response time in milliseconds","example":245},"statusCode":{"type":"integer","nullable":true,"description":"HTTP status code from API","example":200},"responseData":{"type":"object","nullable":true,"description":"Sample response data from API","additionalProperties":true},"error":{"type":"string","nullable":true,"description":"Error message if test failed","example":"Connection timeout after 30 seconds"},"requestUrl":{"type":"string","nullable":true,"description":"Final URL that was requested","example":"https://api.propertymanager.com/v1/properties/prop-123"}}},"EntityContext":{"type":"object","required":["id","organizationId","entityType","entityId","contextTypeId","isActive","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique entity context identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this entity context","example":"123e4567-e89b-12d3-a456-426614174000"},"entityType":{"type":"string","enum":["project","workflow","task","section"],"description":"Type of entity this context is attached to","example":"project"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity this context is attached to","example":"456e7890-e89b-12d3-a456-426614174111"},"contextTypeId":{"type":"string","format":"uuid","description":"Context type configuration to use","example":"321e6547-e89b-12d3-a456-426614174333"},"contextData":{"type":"object","nullable":true,"description":"Parameters to pass to the context API","additionalProperties":true,"example":{"propertyId":"prop-123","includeFinancials":true}},"lastFetchedAt":{"type":"string","format":"date-time","nullable":true,"description":"When context data was last successfully fetched","example":"2024-01-20T16:15:00.000Z"},"lastError":{"type":"string","nullable":true,"description":"Last error message if fetch failed","example":"API rate limit exceeded"},"fetchCount":{"type":"integer","description":"Number of times context has been fetched","minimum":0,"example":45},"errorCount":{"type":"integer","description":"Number of fetch errors encountered","minimum":0,"example":2},"isActive":{"type":"boolean","description":"Whether context fetching is active","example":true},"contextType":{"allOf":[{"$ref":"#/components/schemas/ContextType"},{"description":"Context type configuration (included in responses)"}]},"cachedData":{"type":"object","nullable":true,"description":"Last successfully fetched data (included when fetching context)","additionalProperties":true},"createdAt":{"type":"string","format":"date-time","description":"Entity context creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last entity context update timestamp","example":"2024-01-20T16:15:00.000Z"}}},"EntityContextInput":{"type":"object","required":["contextTypeId"],"properties":{"contextTypeId":{"type":"string","format":"uuid","description":"Context type configuration to use","example":"321e6547-e89b-12d3-a456-426614174333"},"contextData":{"type":"object","nullable":true,"description":"Parameters to pass to the context API","additionalProperties":true,"example":{"propertyId":"prop-123","includeFinancials":true}},"isActive":{"type":"boolean","description":"Whether context fetching is active","default":true,"example":true}}},"EntityContextRefreshResponse":{"type":"object","required":["success","fetchedAt"],"properties":{"success":{"type":"boolean","description":"Whether the refresh was successful","example":true},"fetchedAt":{"type":"string","format":"date-time","description":"When the data was fetched","example":"2024-01-20T16:15:00.000Z"},"data":{"type":"object","nullable":true,"description":"Fresh data from external API","additionalProperties":true},"error":{"type":"string","nullable":true,"description":"Error message if refresh failed","example":"External API returned 404 Not Found"},"responseTime":{"type":"integer","nullable":true,"description":"API response time in milliseconds","example":487}}},"ContextOperation":{"type":"object","required":["id","contextTypeId","operationType","operationCode","name","endpoint","method","successCodes","cacheEnabled","isActive","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the context operation","example":"op-7f8d9e12-4567-890a-bcde-f1234567890a"},"contextTypeId":{"type":"string","format":"uuid","description":"Reference to the context type this operation belongs to","example":"ct-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"contextType":{"$ref":"#/components/schemas/ContextType"},"operationType":{"type":"string","enum":["RETRIEVE","CREATE","UPDATE","DELETE"],"description":"Type of operation this performs","example":"RETRIEVE"},"operationCode":{"type":"string","description":"Unique code for this operation within the context type","example":"get_property_details"},"name":{"type":"string","description":"Human-readable name for this operation","example":"Get Property Details"},"description":{"type":"string","nullable":true,"description":"Detailed description of what this operation does","example":"Retrieves comprehensive property information including photos, specifications, and pricing"},"endpoint":{"type":"string","description":"API endpoint path for this operation","example":"/properties/{propertyId}"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for this operation","example":"GET"},"headers":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Default headers to include with requests","example":{"Content-Type":"application/json","Accept":"application/json"}},"authType":{"type":"string","enum":["Bearer","API_KEY","Basic","OAuth2","Internal"],"nullable":true,"description":"Authentication method for this operation","example":"Bearer"},"authConfig":{"type":"object","nullable":true,"additionalProperties":true,"description":"Authentication configuration specific to the auth type"},"requestTemplate":{"type":"object","nullable":true,"additionalProperties":true,"description":"Template for request body/parameters"},"queryParams":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Default query parameters for this operation"},"responseMapping":{"type":"object","nullable":true,"properties":{"primaryKeyPath":{"type":"string","description":"JSONPath to primary key in response","example":"$.id"},"dataPath":{"type":"string","description":"JSONPath to main data in response","example":"$.data"},"errorPath":{"type":"string","description":"JSONPath to error information","example":"$.error.message"},"successIndicatorPath":{"type":"string","description":"JSONPath to success indicator","example":"$.success"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/ResponseFieldMapping"},"description":"Field mapping configurations"}},"description":"Configuration for mapping response data to context"},"successCodes":{"type":"array","items":{"type":"integer","minimum":100,"maximum":599},"description":"HTTP status codes considered successful","example":[200,201]},"cacheEnabled":{"type":"boolean","description":"Whether to cache responses from this operation","example":true},"cacheTtlSeconds":{"type":"integer","nullable":true,"minimum":1,"maximum":86400,"description":"Cache time-to-live in seconds (max 24 hours)","example":3600},"isActive":{"type":"boolean","description":"Whether this operation is currently active","example":true},"requestFields":{"type":"array","items":{"$ref":"#/components/schemas/RequestFieldMapping"},"description":"Configuration for request field mappings"},"responseFields":{"type":"array","items":{"$ref":"#/components/schemas/ResponseFieldMapping"},"description":"Configuration for response field mappings"},"createdAt":{"type":"string","format":"date-time","description":"When this operation was created","example":"2024-01-20T16:15:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When this operation was last updated","example":"2024-01-20T16:15:00.000Z"}}},"RequestFieldMapping":{"type":"object","required":["fieldName","fieldPath","sourceType","isRequired"],"properties":{"fieldName":{"type":"string","description":"Name of the field in the request","example":"propertyId"},"fieldPath":{"type":"string","description":"Path where this field should be placed in request","example":"pathParams.propertyId"},"sourceType":{"type":"string","enum":["workflow_context","stage_context","task_context","static","dynamic","operation","manual","system"],"description":"Source type for this field value","example":"workflow_context"},"sourcePath":{"type":"string","nullable":true,"description":"Path to extract value from source","example":"propertyId"},"defaultValue":{"type":"string","nullable":true,"description":"Default value if source value is not available","example":"unknown"},"isRequired":{"type":"boolean","description":"Whether this field is required for the operation","example":true},"transformType":{"type":"string","nullable":true,"description":"Type of transformation to apply to the value","example":"string"},"transformConfig":{"type":"object","nullable":true,"additionalProperties":true,"description":"Configuration for value transformation"}}},"ResponseFieldMapping":{"type":"object","required":["responsePath","fieldName","dataType","storeInLevel"],"properties":{"responsePath":{"type":"string","description":"JSONPath to field in response","example":"$.property.address"},"fieldName":{"type":"string","description":"Name to store this field as in context","example":"address"},"dataType":{"type":"string","description":"Expected data type of this field","example":"string"},"isPrimaryKey":{"type":"boolean","description":"Whether this field is a primary key","example":false},"storeInLevel":{"type":"string","enum":["workflow","stage","task"],"description":"Which context level to store this field in","example":"workflow"},"transformType":{"type":"string","nullable":true,"description":"Type of transformation to apply","example":"string"},"transformConfig":{"type":"object","nullable":true,"additionalProperties":true,"description":"Configuration for response transformation"}}},"CreateContextOperationRequest":{"type":"object","required":["contextTypeId","operationType","operationCode","name","endpoint","method"],"properties":{"contextTypeId":{"type":"string","format":"uuid","description":"ID of the context type this operation belongs to","example":"550e8400-e29b-41d4-a716-446655440000"},"operationType":{"type":"string","enum":["RETRIEVE","CREATE","UPDATE","DELETE"],"description":"Type of operation - RETRIEVE for read operations, CREATE/UPDATE/DELETE for write operations","example":"RETRIEVE"},"operationCode":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-zA-Z0-9_]+$","description":"Unique code for this operation within the context type. Must be alphanumeric with underscores only.","example":"get_property_details"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for the operation","example":"Get Property Details"},"description":{"type":"string","nullable":true,"maxLength":1000,"description":"Optional detailed description of what this operation does","example":"Retrieves comprehensive property information from the property management system"},"endpoint":{"type":"string","minLength":1,"description":"API endpoint path template with parameter placeholders (e.g., /properties/{propertyId})","example":"/api/v1/properties/{propertyId}"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for this operation","default":"GET","example":"GET"},"headers":{"type":"object","nullable":true,"description":"Static headers to include in requests. Dynamic headers should use header templates.","example":{"Content-Type":"application/json","Accept":"application/json"}},"authType":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC","OAUTH2"],"nullable":true,"description":"Authentication type for this operation. Defaults to context type's authentication.","example":"BEARER"},"authConfig":{"type":"object","nullable":true,"description":"Authentication configuration specific to this operation if different from context type default","example":{"headerName":"Authorization","tokenPrefix":"Bearer"}},"requestTemplate":{"type":"object","nullable":true,"description":"JSON template for request body with parameter placeholders","example":{"filters":{"status":"active","ownerType":"{ownerType}"}}},"queryParams":{"type":"object","nullable":true,"description":"Static or template query parameters to include in the URL","example":{"include":"details,images","format":"json"}},"responseMapping":{"type":"object","nullable":true,"description":"Configuration for mapping external API response to internal context data structure","example":{"dataPath":"result.property","fields":{"id":"externalId","name":"propertyName","address":"location.fullAddress"}}},"successCodes":{"type":"array","items":{"type":"integer","minimum":100,"maximum":599},"nullable":true,"default":[200],"description":"HTTP status codes considered successful for this operation","example":[200,201,204]},"cacheEnabled":{"type":"boolean","default":false,"description":"Whether to cache responses from this operation","example":true},"cacheTtlSeconds":{"type":"integer","minimum":1,"maximum":86400,"nullable":true,"description":"Cache time-to-live in seconds (1 to 86400 = 1 day). Only used if cacheEnabled is true.","example":3600},"isActive":{"type":"boolean","default":true,"description":"Whether this operation is currently active and can be executed","example":true}}},"UpdateContextOperationRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable name","example":"Get Property Details"},"description":{"type":"string","description":"Detailed description of the operation"},"endpoint":{"type":"string","description":"API endpoint path"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Default headers"},"authType":{"type":"string","enum":["Bearer","API_KEY","Basic","OAuth2","Internal"],"description":"Authentication method"},"authConfig":{"type":"object","additionalProperties":true,"description":"Authentication configuration"},"requestTemplate":{"type":"object","additionalProperties":true,"description":"Request template"},"queryParams":{"type":"object","additionalProperties":{"type":"string"},"description":"Default query parameters"},"responseMapping":{"type":"object","description":"Response mapping configuration"},"successCodes":{"type":"array","items":{"type":"integer","minimum":100,"maximum":599},"description":"HTTP success codes"},"cacheEnabled":{"type":"boolean","description":"Enable caching"},"cacheTtlSeconds":{"type":"integer","minimum":1,"maximum":86400,"description":"Cache TTL in seconds"},"isActive":{"type":"boolean","description":"Whether operation is active"},"requestFields":{"type":"array","items":{"$ref":"#/components/schemas/RequestFieldMapping"},"description":"Request field mappings"},"responseFields":{"type":"array","items":{"$ref":"#/components/schemas/ResponseFieldMapping"},"description":"Response field mappings"}}},"ExecuteOperationRequest":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","enum":["workflow","stage","task"],"description":"Type of entity to execute operation for","example":"workflow"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"wf-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"triggerEvent":{"type":"string","description":"Event that triggered this operation","example":"workflow.started"},"parameters":{"type":"object","additionalProperties":true,"description":"Additional parameters for the operation"},"options":{"type":"object","properties":{"async":{"type":"boolean","description":"Execute operation asynchronously","default":false},"retryOnFailure":{"type":"boolean","description":"Retry operation if it fails","default":true},"maxRetries":{"type":"integer","minimum":0,"maximum":10,"description":"Maximum number of retries","default":3},"timeoutMs":{"type":"integer","minimum":1000,"maximum":300000,"description":"Timeout in milliseconds","default":30000}},"description":"Execution options"}}},"ExecuteOperationResponse":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"Whether the operation succeeded","example":true},"data":{"type":"object","nullable":true,"additionalProperties":true,"description":"Data returned from the operation"},"error":{"type":"object","nullable":true,"properties":{"code":{"type":"string","description":"Error code","example":"EXTERNAL_API_ERROR"},"message":{"type":"string","description":"Error message","example":"External API returned 404 Not Found"},"details":{"type":"object","additionalProperties":true,"description":"Additional error details"},"retryable":{"type":"boolean","description":"Whether this error can be retried","example":true},"statusCode":{"type":"integer","description":"HTTP status code from external API","example":404}},"description":"Error information if operation failed"},"executionLog":{"$ref":"#/components/schemas/ContextExecutionLog"},"contextUpdates":{"type":"array","items":{"$ref":"#/components/schemas/ContextData"},"description":"Context data that was updated as a result"}}},"ContextData":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this context data record"},"contextKey":{"type":"string","description":"Key identifying this context data"},"dataValue":{"type":"object","description":"The actual context data stored"},"dataType":{"type":"string","description":"Type of the data value"},"sourceType":{"type":"string","enum":["OPERATION","WEBHOOK","MANUAL","FORM","DATA_MODEL","SYSTEM"],"description":"Where this context data originated from"},"sourceId":{"type":"string","nullable":true,"description":"ID of the source for audit tracking"},"retrievedAt":{"type":"string","format":"date-time","description":"When this data was retrieved or stored"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When this data expires and should be refreshed"},"isStale":{"type":"boolean","description":"Whether this data is marked as stale and should be refreshed"}}},"StoreContextDataRequest":{"type":"object","required":["level","entityId","contextKey","data","sourceType"],"properties":{"level":{"type":"string","enum":["workflow","stage","task"],"description":"Context data level in the workflow hierarchy. Data flows down from workflow to stage to task.","example":"workflow"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity (workflow, stage, or task) to store context data for","example":"550e8400-e29b-41d4-a716-446655440000"},"contextKey":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-zA-Z0-9_\\.]+$","description":"Unique key identifying this context data. Should be descriptive and follow dot notation for namespacing (e.g., property.address, customer.contact_info).","example":"property.ownership_details"},"data":{"type":"object","description":"The context data to store. Can be any valid JSON object structure.","example":{"owner":"John Doe","purchaseDate":"2023-01-15","propertyValue":450000,"mortgageProvider":"ABC Bank"}},"sourceType":{"type":"string","enum":["OPERATION","WEBHOOK","MANUAL","FORM","DATA_MODEL","SYSTEM"],"description":"Source type indicating where this context data originated from","example":"OPERATION"},"sourceId":{"type":"string","nullable":true,"description":"Optional ID of the source (operation ID, webhook ID, user ID, etc.) for audit tracking","example":"operation_abc123"},"ttlSeconds":{"type":"integer","minimum":1,"maximum":2592000,"nullable":true,"description":"Time-to-live in seconds after which this data expires (1 second to 30 days). If not specified, data does not expire.","example":86400}}},"UpdateContextDataRequest":{"type":"object","required":["data"],"properties":{"data":{"description":"Updated data (can be any type)","example":{"address":"456 Oak Avenue","city":"Bergen","price":3200000}},"ttlSeconds":{"type":"integer","minimum":1,"maximum":86400,"description":"Updated time-to-live in seconds","example":7200}}},"HierarchicalContextData":{"type":"object","required":["workflow"],"properties":{"workflow":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ContextData"},"description":"Workflow-level context data"},"stage":{"type":"object","nullable":true,"additionalProperties":{"$ref":"#/components/schemas/ContextData"},"description":"Stage-level context data"},"task":{"type":"object","nullable":true,"additionalProperties":{"$ref":"#/components/schemas/ContextData"},"description":"Task-level context data"},"inherited":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ContextData"},"description":"Merged context data with inheritance applied"}}},"TemplateContextConfig":{"type":"object","required":["id","workflowTemplateId","contextTypeId","isRequired","autoRetrieveOnStart","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this configuration","example":"tc-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"workflowTemplateId":{"type":"string","format":"uuid","description":"ID of the workflow template","example":"wt-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"contextTypeId":{"type":"string","format":"uuid","description":"ID of the context type","example":"ct-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"contextType":{"$ref":"#/components/schemas/ContextType"},"isRequired":{"type":"boolean","description":"Whether this context is required for workflows","example":true},"autoRetrieveOnStart":{"type":"boolean","description":"Whether to automatically retrieve data when workflow starts","example":true},"configuration":{"type":"object","nullable":true,"additionalProperties":true,"description":"Additional configuration for this context"},"triggerConfigs":{"type":"array","items":{"$ref":"#/components/schemas/ContextTriggerConfig"},"description":"Trigger configurations for this context"},"createdAt":{"type":"string","format":"date-time","description":"When this configuration was created","example":"2024-01-20T16:15:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When this configuration was last updated","example":"2024-01-20T16:15:00.000Z"}}},"ContextTriggerConfig":{"type":"object","required":["id","triggerEvent","operationId","executionOrder","isAsync","continueOnFailure","retryCount","retryDelayMs"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this trigger configuration","example":"tg-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"triggerEvent":{"type":"string","description":"Event that triggers this operation","example":"workflow.started"},"operationId":{"type":"string","format":"uuid","description":"ID of the operation to execute","example":"op-7f8d9e12-4567-890a-bcde-f1234567890a"},"contextOperation":{"$ref":"#/components/schemas/ContextOperation"},"executionOrder":{"type":"integer","minimum":1,"description":"Order in which to execute this trigger","example":1},"isAsync":{"type":"boolean","description":"Whether to execute this trigger asynchronously","example":false},"continueOnFailure":{"type":"boolean","description":"Whether to continue if this trigger fails","example":false},"retryCount":{"type":"integer","minimum":0,"maximum":10,"description":"Number of retries on failure","example":3},"retryDelayMs":{"type":"integer","minimum":100,"maximum":60000,"description":"Delay between retries in milliseconds","example":1000},"conditionType":{"type":"string","nullable":true,"description":"Type of condition evaluation","example":"jsonlogic"},"conditionConfig":{"type":"object","nullable":true,"additionalProperties":true,"description":"Configuration for condition evaluation"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/TriggerCondition"},"description":"Conditions that must be met to execute this trigger"}}},"TriggerCondition":{"type":"object","required":["fieldPath","operator","expectedValue","isActive"],"properties":{"fieldPath":{"type":"string","description":"Path to field to evaluate","example":"workflow.context.propertyType"},"operator":{"type":"string","enum":["equals","not_equals","contains","greater_than","less_than","in","not_in"],"description":"Comparison operator","example":"equals"},"expectedValue":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"array","items":{"type":"string"}}],"description":"Expected value for comparison","example":"apartment"},"isActive":{"type":"boolean","description":"Whether this condition is active","example":true}}},"CreateTemplateContextConfigRequest":{"type":"object","required":["contextTypeId"],"properties":{"contextTypeId":{"type":"string","format":"uuid","description":"ID of the context type to configure for this workflow template","example":"550e8400-e29b-41d4-a716-446655440000"},"isRequired":{"type":"boolean","default":false,"description":"Whether this context is required for the workflow to start. If true, workflow cannot start without this context being configured.","example":true},"autoRetrieveOnStart":{"type":"boolean","default":false,"description":"Whether to automatically retrieve context data when the workflow starts. Useful for pre-loading required data.","example":true},"configuration":{"type":"object","nullable":true,"description":"Additional configuration specific to this context type and template combination","example":{"defaultFilters":{"status":"active"},"refreshInterval":3600,"autoSync":true}},"triggerConfigs":{"type":"array","items":{"type":"object","required":["triggerEvent","operationId","executionOrder"],"properties":{"triggerEvent":{"type":"string","description":"Event that triggers the operation","example":"workflow.started"},"operationId":{"type":"string","format":"uuid","description":"ID of operation to execute","example":"op-7f8d9e12-4567-890a-bcde-f1234567890a"},"executionOrder":{"type":"integer","minimum":1,"description":"Execution order","example":1},"isAsync":{"type":"boolean","description":"Execute asynchronously","default":false},"continueOnFailure":{"type":"boolean","description":"Continue on failure","default":false},"retryCount":{"type":"integer","minimum":0,"maximum":10,"description":"Retry count","default":0},"retryDelayMs":{"type":"integer","minimum":100,"maximum":60000,"description":"Retry delay in milliseconds","default":1000},"conditionType":{"type":"string","description":"Condition type"},"conditionConfig":{"type":"object","additionalProperties":true,"description":"Condition configuration"},"conditions":{"type":"array","items":{"$ref":"#/components/schemas/TriggerCondition"},"description":"Trigger conditions"}}},"description":"Trigger configurations"}}},"UpdateTemplateContextConfigRequest":{"type":"object","properties":{"isRequired":{"type":"boolean","description":"Whether this context is required"},"autoRetrieveOnStart":{"type":"boolean","description":"Whether to auto-retrieve on workflow start"},"configuration":{"type":"object","additionalProperties":true,"description":"Additional configuration"}}},"ContextExecutionLog":{"type":"object","required":["id","organizationId","operationId","entityType","entityId","requestUrl","requestMethod","status","retryCount","maxRetries","startedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for this execution log","example":"ex-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"organizationId":{"type":"string","format":"uuid","description":"ID of the organization","example":"org-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"operationId":{"type":"string","format":"uuid","description":"ID of the executed operation","example":"op-7f8d9e12-4567-890a-bcde-f1234567890a"},"operation":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid"},"operationCode":{"type":"string"},"name":{"type":"string"},"operationType":{"type":"string"},"endpoint":{"type":"string"},"contextType":{"$ref":"#/components/schemas/ContextType"}},"description":"Operation details"},"entityType":{"type":"string","enum":["workflow","stage","task"],"description":"Type of entity this was executed for","example":"workflow"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"wf-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"triggerEvent":{"type":"string","nullable":true,"description":"Event that triggered this execution","example":"workflow.started"},"requestUrl":{"type":"string","description":"Full URL that was requested","example":"https://api.properties.com/v1/properties/prop-123"},"requestMethod":{"type":"string","description":"HTTP method used","example":"GET"},"requestHeaders":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Headers sent with request"},"requestBody":{"nullable":true,"description":"Body sent with request"},"responseStatus":{"type":"integer","nullable":true,"description":"HTTP response status code","example":200},"responseHeaders":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Headers received in response"},"responseBody":{"nullable":true,"description":"Body received in response"},"responseTimeMs":{"type":"integer","nullable":true,"description":"Response time in milliseconds","example":450},"status":{"type":"string","enum":["pending","success","failure","timeout","skipped"],"description":"Execution status","example":"success"},"errorMessage":{"type":"string","nullable":true,"description":"Error message if execution failed","example":"Connection timeout after 30 seconds"},"errorCode":{"type":"string","nullable":true,"description":"Error code if execution failed","example":"TIMEOUT"},"retryCount":{"type":"integer","description":"Number of retries attempted","example":1},"maxRetries":{"type":"integer","description":"Maximum retries allowed","example":3},"startedAt":{"type":"string","format":"date-time","description":"When execution started","example":"2024-01-20T16:15:00.000Z"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When execution completed","example":"2024-01-20T16:15:00.450Z"}}},"FormSubmissionRequest":{"type":"object","required":["level","entityId","formData"],"properties":{"level":{"type":"string","enum":["workflow","stage","task"],"description":"Context data level where the form data should be stored","example":"task"},"entityId":{"type":"string","format":"uuid","description":"ID of the entity to store the form data for","example":"550e8400-e29b-41d4-a716-446655440000"},"formData":{"type":"object","description":"The form field data to store. Keys are field names, values are field values.","example":{"customerName":"Jane Smith","phoneNumber":"+1-555-0123","preferredContactMethod":"email","notes":"Customer prefers morning appointments"}},"contextKey":{"type":"string","nullable":true,"description":"Optional custom context key. If not provided, defaults to 'form_submission'.","example":"customer_intake_form"},"metadata":{"type":"object","nullable":true,"description":"Optional metadata about the form submission","example":{"formVersion":"1.2.0","submittedVia":"web","ipAddress":"192.168.1.1"}}}},"FormSubmissionResponse":{"type":"object","required":["id","success","submittedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"ID of the submission","example":"fs-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"success":{"type":"boolean","description":"Whether submission was successful","example":true},"contextData":{"$ref":"#/components/schemas/ContextData"},"submittedAt":{"type":"string","format":"date-time","description":"When form was submitted","example":"2024-01-20T16:15:00.000Z"}}},"AggregateFormDataRequest":{"type":"object","required":["criteria"],"properties":{"criteria":{"type":"object","description":"Criteria for selecting form data to aggregate","properties":{"workflowId":{"type":"string","format":"uuid","nullable":true},"contextKeys":{"type":"array","items":{"type":"string"},"nullable":true},"dateRange":{"type":"object","nullable":true,"properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"}}}},"example":{"workflowId":"550e8400-e29b-41d4-a716-446655440000","contextKeys":["customer_feedback","satisfaction_survey"],"dateRange":{"from":"2024-01-01T00:00:00Z","to":"2024-12-31T23:59:59Z"}}},"aggregationType":{"type":"string","enum":["summary","average","count","list"],"default":"summary","description":"Type of aggregation to perform on the form data","example":"summary"},"groupBy":{"type":"string","nullable":true,"description":"Field to group aggregated results by","example":"submissionDate"}}},"AggregatedFormDataResponse":{"type":"object","required":["summary","generatedAt"],"properties":{"summary":{"type":"object","properties":{"totalSubmissions":{"type":"integer","description":"Total number of form submissions","example":150},"uniqueEntities":{"type":"integer","description":"Number of unique entities","example":45},"dateRange":{"type":"object","properties":{"earliest":{"type":"string","format":"date-time","description":"Earliest submission date"},"latest":{"type":"string","format":"date-time","description":"Latest submission date"}},"description":"Date range of included data"}},"description":"Summary statistics"},"data":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"Aggregated form data"},"groups":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","additionalProperties":true}},"description":"Grouped results if groupBy was specified"},"generatedAt":{"type":"string","format":"date-time","description":"When this aggregation was generated","example":"2024-01-20T16:15:00.000Z"}}},"PaginatedOperationsResponse":{"type":"object","required":["items","total","page","pageSize","hasMore"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ContextOperation"},"description":"Context operations for this page"},"total":{"type":"integer","description":"Total number of operations","example":25},"page":{"type":"integer","description":"Current page number","example":1},"pageSize":{"type":"integer","description":"Number of items per page","example":20},"hasMore":{"type":"boolean","description":"Whether there are more pages","example":true}}},"PaginatedExecutionLogsResponse":{"type":"object","required":["items","total","page","pageSize","hasMore"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ContextExecutionLog"},"description":"Execution logs for this page"},"total":{"type":"integer","description":"Total number of logs","example":150},"page":{"type":"integer","description":"Current page number","example":1},"pageSize":{"type":"integer","description":"Number of items per page","example":20},"hasMore":{"type":"boolean","description":"Whether there are more pages","example":true}}},"ContextOperationResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"$ref":"#/components/schemas/ContextOperation"},"metadata":{"type":"object","properties":{"cached":{"type":"boolean","description":"Whether this data came from cache","example":false},"executionTimeMs":{"type":"integer","description":"How long the request took","example":145},"version":{"type":"string","description":"API version used","example":"2.0"}},"description":"Additional response metadata"}}},"ContextDataResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"oneOf":[{"$ref":"#/components/schemas/ContextData"},{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ContextData"}}],"description":"Context data (single item or object with multiple items)"}}},"TemplateContextConfigResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"oneOf":[{"$ref":"#/components/schemas/TemplateContextConfig"},{"type":"array","items":{"$ref":"#/components/schemas/TemplateContextConfig"}}],"description":"Template context configuration (single item or array)"}}},"ExecutionLogResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"$ref":"#/components/schemas/ContextExecutionLog"}}},"FormDataResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"type":"object","properties":{"contextData":{"$ref":"#/components/schemas/ContextData"},"formData":{"type":"object","additionalProperties":true,"description":"The actual form data"},"metadata":{"type":"object","additionalProperties":true,"description":"Form submission metadata"}},"description":"Form data and context information"}}},"HierarchicalContextDataResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","description":"Whether the request was successful","example":true},"data":{"$ref":"#/components/schemas/HierarchicalContextData"}}},"TaskTemplate":{"type":"object","required":["id","organizationId","code","name","assigneeType","assigneeId","priority","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique task template identifier","example":"789e0123-e89b-12d3-a456-426614174222"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this task template","example":"123e4567-e89b-12d3-a456-426614174000"},"code":{"type":"string","description":"Unique template code for identification","maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","example":"property-inspection-checklist"},"name":{"type":"string","description":"Human-readable template name","maxLength":200,"example":"Property Inspection Checklist"},"description":{"type":"string","nullable":true,"description":"Detailed template description","maxLength":2000,"example":"Standard inspection tasks for property evaluation including electrical, plumbing, and structural checks"},"category":{"type":"string","nullable":true,"description":"Template category for organization","maxLength":50,"example":"inspection"},"stageDefinitionId":{"type":"string","format":"uuid","nullable":true,"description":"Stage definition this template is associated with","example":"456e7890-e89b-12d3-a456-426614174111"},"estimatedDurationMinutes":{"type":"integer","nullable":true,"description":"Estimated time to complete tasks created from this template (in minutes)","minimum":0,"maximum":10080,"example":120},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Default priority for tasks created from this template","example":"HIGH"},"defaultCompletionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Default completion mode for tasks created from this template","default":"INLINE","example":"DETAIL_VIEW"},"assigneeType":{"type":"string","enum":["ROLE","POSITION"],"description":"Type of assignee for task templates (only ROLE and POSITION allowed)","example":"ROLE"},"assigneeId":{"type":"string","description":"ID/name of the role or position to assign tasks to","maxLength":100,"example":"property-inspector"},"requiresApproval":{"type":"boolean","description":"Whether tasks created from this template require approval","default":false,"example":true},"approvalAssigneeType":{"type":"string","enum":["ROLE","POSITION"],"nullable":true,"description":"Type of approval assignee (only ROLE and POSITION allowed)","example":"ROLE"},"approvalAssigneeId":{"type":"string","nullable":true,"description":"ID/name of the role or position for approval","maxLength":100,"example":"senior-inspector"},"checklistItems":{"type":"array","nullable":true,"description":"Checklist items for tasks created from this template","maxItems":50,"items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string","description":"Checklist item title","maxLength":500,"example":"Check electrical systems"},"required":{"type":"boolean","description":"Whether this checklist item is required","example":true},"description":{"type":"string","nullable":true,"description":"Optional description for the checklist item","maxLength":1000,"example":"Verify all electrical outlets, switches, and circuit breakers are functioning properly"},"completed":{"type":"boolean","nullable":true,"description":"Whether this checklist item has been completed","example":false},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When this checklist item was completed","example":"2024-01-20T10:30:00.000Z"},"completedBy":{"type":"string","nullable":true,"description":"User ID of who completed this checklist item","maxLength":255,"example":"user-123"},"comment":{"type":"string","nullable":true,"description":"Comment added when completing the checklist item","maxLength":2000,"example":"All electrical systems verified and functioning properly"}}},"example":[{"title":"Check electrical systems","required":true,"description":"Verify all electrical outlets and switches work properly"},{"title":"Inspect plumbing","required":true,"description":"Check for leaks, water pressure, and drainage issues"}]},"dependencies":{"type":"object","nullable":true,"description":"Template dependencies configuration (JSON)","additionalProperties":true,"example":{"prerequisiteTemplates":["foundation-check"],"estimatedDelay":2}},"metadata":{"type":"object","nullable":true,"description":"Additional template metadata (JSON)","additionalProperties":true,"example":{"industry":"real-estate","version":"2.1","lastReviewed":"2024-01-15"}},"contextRequirements":{"type":"object","nullable":true,"description":"Context requirements for tasks created from this template","additionalProperties":{"type":"object","required":["contextTypeCode","required","idSource"],"properties":{"contextTypeCode":{"type":"string","description":"Code of the context type","pattern":"^[a-z][a-z0-9_]*$","example":"salesforce"},"required":{"type":"boolean","description":"Whether this context is required for task creation","example":true},"idSource":{"type":"string","enum":["workflow","manual","compute","entity"],"description":"How the external ID should be resolved","example":"workflow"},"idPattern":{"type":"string","nullable":true,"description":"Pattern for extracting the ID (e.g., {workflow.context.salesforce_id})","example":"{workflow.context.salesforce_id}"},"defaultValue":{"type":"string","nullable":true,"description":"Default value if pattern resolution fails (only for non-required contexts)","example":"default-123"}}},"example":{"salesforce":{"contextTypeCode":"salesforce","required":true,"idSource":"workflow","idPattern":"{workflow.context.salesforce_id}"},"calendar":{"contextTypeCode":"calendar","required":false,"idSource":"manual"}}},"stageDefinition":{"type":"object","nullable":true,"description":"Associated stage definition details (when included)","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time","description":"Template creation timestamp","example":"2024-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last template update timestamp","example":"2024-01-20T16:15:00.000Z"}}},"TaskTemplateInput":{"type":"object","required":["code","name","assigneeType","assigneeId"],"properties":{"code":{"type":"string","description":"Unique template code for identification (alphanumeric, underscore, hyphen only)","minLength":1,"maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","example":"property-inspection-checklist"},"name":{"type":"string","description":"Human-readable template name","minLength":1,"maxLength":200,"example":"Property Inspection Checklist"},"description":{"type":"string","nullable":true,"description":"Detailed template description","maxLength":2000,"example":"Standard inspection tasks for property evaluation"},"category":{"type":"string","nullable":true,"description":"Template category for organization and filtering","maxLength":50,"example":"inspection"},"stageDefinitionId":{"type":"string","format":"uuid","nullable":true,"description":"Stage definition this template is associated with - must belong to organization","example":"456e7890-e89b-12d3-a456-426614174111"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Form template to associate with tasks created from this template - must belong to organization","example":"123e4567-e89b-12d3-a456-426614174000"},"estimatedDurationMinutes":{"type":"integer","nullable":true,"description":"Estimated time to complete tasks in minutes (max 1 week = 10080 minutes)","minimum":0,"maximum":10080,"example":120},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Default priority for tasks created from this template","default":"MEDIUM","example":"HIGH"},"defaultCompletionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Default completion mode for tasks - how task completion is handled in UI","default":"INLINE","example":"DETAIL_VIEW"},"assigneeType":{"type":"string","enum":["ROLE","POSITION"],"description":"Type of assignee - only ROLE and POSITION allowed for templates (USER not allowed for reusability)","example":"ROLE"},"assigneeId":{"type":"string","description":"ID/name of the role or position to assign tasks to","minLength":1,"maxLength":100,"example":"property-inspector"},"requiresApproval":{"type":"boolean","description":"Whether tasks created from this template require approval after completion","default":false,"example":false},"approvalAssigneeType":{"type":"string","enum":["ROLE","POSITION"],"nullable":true,"description":"Type of approval assignee (only ROLE and POSITION allowed)","example":"ROLE"},"approvalAssigneeId":{"type":"string","nullable":true,"description":"ID/name of the role or position for approval","maxLength":100,"example":"senior-inspector"},"checklistItems":{"type":"array","nullable":true,"description":"Checklist items for tasks created from this template","maxItems":50,"items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string","description":"Checklist item title","maxLength":500,"example":"Check electrical systems"},"required":{"type":"boolean","description":"Whether this checklist item must be completed","example":true},"description":{"type":"string","nullable":true,"description":"Detailed description of checklist item","maxLength":1000,"example":"Verify all electrical outlets work properly"},"completed":{"type":"boolean","nullable":true,"description":"Whether this checklist item has been completed","example":false},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When this checklist item was completed","example":"2024-01-20T10:30:00.000Z"},"completedBy":{"type":"string","nullable":true,"description":"User ID of who completed this checklist item","maxLength":255,"example":"user-123"},"comment":{"type":"string","nullable":true,"description":"Comment added when completing the checklist item","maxLength":2000,"example":"All electrical systems verified and functioning properly"}}}},"dependencies":{"type":"object","nullable":true,"description":"Template dependencies configuration (JSON) - defines task dependencies to be created during instantiation","additionalProperties":true},"metadata":{"type":"object","nullable":true,"description":"Additional template metadata (JSON) - custom data fields for template-specific information","additionalProperties":true},"contextRequirements":{"type":"object","nullable":true,"description":"Context requirements for tasks created from this template - defines which external context data is needed","additionalProperties":{"type":"object","required":["contextTypeCode","required","idSource"],"properties":{"contextTypeCode":{"type":"string","description":"Code of the context type (lowercase, alphanumeric, underscore)","pattern":"^[a-z][a-z0-9_]*$"},"required":{"type":"boolean","description":"Whether this context is required for task creation"},"idSource":{"type":"string","enum":["workflow","manual","compute","entity"],"description":"How the external ID should be resolved: workflow (from workflow data), manual (provided by user), compute (calculated), entity (from linked entity)"},"idPattern":{"type":"string","nullable":true,"description":"Pattern for extracting the ID (e.g., template string with variables)"},"defaultValue":{"type":"string","nullable":true,"description":"Default value if pattern resolution fails"}}}},"assignmentInheritanceOverride":{"type":"object","nullable":true,"description":"Override default assignment inheritance behavior - allows tasks to inherit assignment from workflow owner or other source","properties":{"enabled":{"type":"boolean","description":"Whether to enable assignment inheritance override"},"strategy":{"type":"string","enum":["WORKFLOW_OWNER","WORKFLOW_ASSIGNEE","STAGE_ASSIGNEE"],"description":"Strategy for assignment inheritance"}}}}},"TaskTemplateUpdate":{"type":"object","properties":{"name":{"type":"string","description":"Updated human-readable template name","minLength":1,"maxLength":200,"example":"Updated Property Inspection Checklist"},"description":{"type":"string","nullable":true,"description":"Updated template description","maxLength":2000,"example":"Updated standard inspection tasks with new requirements"},"category":{"type":"string","nullable":true,"description":"Updated template category","maxLength":50,"example":"inspection"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Updated form template ID - set to null to remove association","example":"123e4567-e89b-12d3-a456-426614174000"},"estimatedDurationMinutes":{"type":"integer","nullable":true,"description":"Updated estimated duration in minutes","minimum":0,"maximum":10080,"example":150},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Updated default priority","example":"URGENT"},"defaultCompletionMode":{"type":"string","enum":["INLINE","DETAIL_VIEW","EXTERNAL_ACTION"],"description":"Updated default completion mode","example":"DETAIL_VIEW"},"assigneeType":{"type":"string","enum":["ROLE","POSITION"],"description":"Updated assignee type - only ROLE and POSITION allowed","example":"POSITION"},"assigneeId":{"type":"string","description":"Updated assignee ID","maxLength":100,"example":"senior-property-inspector"},"requiresApproval":{"type":"boolean","description":"Updated approval requirement","example":true},"approvalAssigneeType":{"type":"string","enum":["ROLE","POSITION"],"nullable":true,"description":"Updated approval assignee type","example":"ROLE"},"approvalAssigneeId":{"type":"string","nullable":true,"description":"Updated approval assignee ID","maxLength":100,"example":"quality-control-manager"},"checklistItems":{"type":"array","nullable":true,"description":"Updated checklist items (replaces existing)","maxItems":50,"items":{"type":"object","required":["title","required"],"properties":{"title":{"type":"string","maxLength":500},"required":{"type":"boolean"},"description":{"type":"string","nullable":true,"maxLength":1000},"completed":{"type":"boolean","nullable":true},"completedAt":{"type":"string","format":"date-time","nullable":true},"completedBy":{"type":"string","nullable":true,"maxLength":255},"comment":{"type":"string","nullable":true,"maxLength":2000}}}},"dependencies":{"type":"object","nullable":true,"description":"Updated dependencies configuration","additionalProperties":true},"metadata":{"type":"object","nullable":true,"description":"Updated metadata (replaces existing)","additionalProperties":true},"assigneeResolutionConfig":{"type":"object","nullable":true,"description":"Configuration for dynamic assignee resolution from external systems - validates via validateAssigneeResolutionConfig","properties":{"enabled":{"type":"boolean","description":"Whether assignee resolution is enabled","example":true},"contextTypeId":{"type":"string","description":"Context type to use for resolving assignees","example":"crm-contact"},"dynamicParameters":{"type":"object","nullable":true,"description":"Dynamic parameters to pass to the context type API","additionalProperties":true,"example":{"entityId":"{{entityId}}","businessRole":"account-manager"}},"resolutionStrategy":{"type":"string","enum":["FIELD_MAPPING","LOOKUP_TABLE","EXPRESSION","API_CALL"],"description":"Strategy to use when resolving assignees","example":"FIELD_MAPPING"},"strategyConfig":{"type":"object","description":"Configuration specific to resolution strategy","additionalProperties":true,"example":{"strategy":"FIELD_MAPPING","fieldPath":"$.data.owner.email","assigneeType":"USER","transform":"EMAIL_TO_USER_ID"}},"fallbackAssignee":{"type":"object","nullable":true,"description":"Fallback assignee if resolution fails","properties":{"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"example":"ROLE"},"assigneeId":{"type":"string","example":"default-manager"}}},"retryOnFailure":{"type":"boolean","nullable":true,"description":"Whether to retry resolution if it fails","example":true},"maxRetries":{"type":"integer","nullable":true,"description":"Maximum number of retry attempts","minimum":0,"maximum":10,"example":3}}},"contextRequirements":{"type":"object","nullable":true,"description":"Updated context requirements","additionalProperties":true},"assignmentInheritanceOverride":{"type":"object","nullable":true,"description":"Updated assignment inheritance override configuration"}}},"TaskTemplateInstantiationRequest":{"type":"object","properties":{"title":{"type":"string","nullable":true,"description":"Override template name for this task instance - defaults to template name","maxLength":200,"example":"Property Inspection - 123 Main St"},"description":{"type":"string","nullable":true,"description":"Override template description for this task instance","maxLength":2000,"example":"Inspection for property at 123 Main St as part of acquisition process"},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Project to create the task in - must belong to organization","example":"456e7890-e89b-12d3-a456-426614174111"},"sectionId":{"type":"string","format":"uuid","nullable":true,"description":"Section within the project (optional) - must belong to organization/project","example":"321e6547-e89b-12d3-a456-426614174333"},"workflowId":{"type":"string","format":"uuid","nullable":true,"description":"Workflow to create the task in - must belong to organization","example":"789e0123-e89b-12d3-a456-426614174222"},"workflowStageId":{"type":"string","format":"uuid","nullable":true,"description":"Workflow stage to create the task in - must belong to organization/workflow","example":"987e6543-e89b-12d3-a456-426614174333"},"assigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Override assignee type - can upgrade to USER for specific assignment (templates can only have ROLE or POSITION)","example":"USER"},"assigneeId":{"type":"string","nullable":true,"description":"Override assignee ID - user ID if assigneeType is USER","maxLength":100,"example":"user-123"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"nullable":true,"description":"Override priority for this task instance","example":"URGENT"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Due date for this task instance (ISO 8601 format)","example":"2024-01-25T17:00:00.000Z"},"entityType":{"type":"string","nullable":true,"description":"Type of external entity this task is linked to","maxLength":50,"example":"property"},"entityId":{"type":"string","nullable":true,"description":"ID of external entity this task is linked to","maxLength":100,"example":"property-456"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata to merge with template metadata (merged, not replaced)","additionalProperties":true,"example":{"requested_date":"2025-08-15T00:00:00.000Z","client_reference":"ABC123"}},"entityLinks":{"type":"array","nullable":true,"description":"Optional entity links to create alongside the task. Maximum 20 links.","maxItems":20,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","minLength":1,"maxLength":100,"description":"Type of the entity to link to","example":"property"},"entityId":{"type":"string","minLength":1,"maxLength":50,"description":"ID of the entity to link to","example":"prop-123"},"linkType":{"type":"string","enum":["related","reference","associated"],"default":"related","description":"Type of relationship"},"metadata":{"type":"object","nullable":true,"description":"Optional metadata for the link","additionalProperties":true}}}}}},"SimpleAssigneeResolution":{"type":"object","required":["enabled","contextType","assigneeField","assigneeType"],"properties":{"enabled":{"type":"boolean","description":"Whether to enable assignee resolution","example":true},"contextType":{"type":"string","description":"Context type code to use for resolution","example":"crm-contact"},"assigneeField":{"type":"string","description":"Simple field path to extract assignee from (e.g., \"Owner.Email\")","example":"Owner.Email"},"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of assignee being resolved","example":"USER"},"transform":{"type":"string","enum":["UPPERCASE","LOWERCASE","TRIM","EXTRACT_USERNAME"],"nullable":true,"description":"Optional transformation to apply (default: none)","example":"EXTRACT_USERNAME"},"fallback":{"type":"object","nullable":true,"description":"Optional fallback assignee if resolution fails","properties":{"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of fallback assignee","example":"ROLE"},"assigneeId":{"type":"string","description":"ID of fallback assignee","example":"property-manager"}}},"retryOnFailure":{"type":"boolean","nullable":true,"description":"Whether to retry if resolution fails (default: false)","example":false}}},"TaskTemplateTestResolutionRequest":{"type":"object","required":["sampleContextData"],"properties":{"sampleContextData":{"type":"object","description":"Sample context data to use for testing resolution - structure matches expected context type data","additionalProperties":true,"example":{"Owner":{"Email":"john.doe@example.com","Name":"John Doe","Role":"PROPERTY_MANAGER"}}},"resolutionConfig":{"$ref":"#/components/schemas/SimpleAssigneeResolution","nullable":true,"description":"Optional resolution config override - uses template's config if not provided"}}},"TaskTemplatePreviewInstantiationRequest":{"type":"object","required":["contextData","resolveAssignee"],"properties":{"contextData":{"type":"object","description":"Context data for assignee resolution","additionalProperties":true,"example":{"Owner":{"Email":"jane.doe@company.com","Name":"Jane Doe"}}},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Optional project ID for the preview - validated if provided","example":"456e7890-e89b-12d3-a456-426614174111"},"resolveAssignee":{"type":"boolean","description":"Whether to resolve assignee during preview - if true, performs resolution using template config","example":true}}},"TaskTemplateInstantiateResolvedRequest":{"type":"object","required":["projectId"],"properties":{"projectId":{"type":"string","format":"uuid","description":"Project to create the task in - must belong to organization","example":"456e7890-e89b-12d3-a456-426614174111"},"contextData":{"type":"object","nullable":true,"description":"Context data for assignee resolution - overrides fetched context if provided","additionalProperties":true,"example":{"Owner":{"Email":"specific.owner@example.com"}}},"contextEntityId":{"type":"string","nullable":true,"description":"External entity ID for context resolution - used to fetch context data","example":"property-12345"},"waitForResolution":{"type":"boolean","nullable":true,"description":"Whether to wait for resolution to complete before returning - if false, may return before task fully resolved","default":true,"example":true},"taskOverrides":{"type":"object","nullable":true,"description":"Optional overrides for task properties","properties":{"title":{"type":"string","nullable":true,"description":"Override task title","maxLength":200,"example":"Custom Property Inspection Task"},"description":{"type":"string","nullable":true,"description":"Override task description","maxLength":2000,"example":"Custom description for this specific task"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"nullable":true,"description":"Override priority","example":"HIGH"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Override due date","example":"2024-01-30T17:00:00.000Z"},"sectionId":{"type":"string","format":"uuid","nullable":true,"description":"Override section - must belong to project","example":"321e6547-e89b-12d3-a456-426614174333"},"entityType":{"type":"string","nullable":true,"description":"Override entity type","example":"property"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata to merge","additionalProperties":true,"example":{"custom_field":"custom_value"}}}},"entityLinks":{"type":"array","nullable":true,"description":"Optional entity links to create alongside the task. Maximum 20 links.","maxItems":20,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","minLength":1,"maxLength":100,"description":"Type of the entity to link to","example":"property"},"entityId":{"type":"string","minLength":1,"maxLength":50,"description":"ID of the entity to link to","example":"prop-123"},"linkType":{"type":"string","enum":["related","reference","associated"],"default":"related","description":"Type of relationship"},"metadata":{"type":"object","nullable":true,"description":"Optional metadata for the link","additionalProperties":true}}}},"actor":{"type":"string","nullable":true,"description":"Actor performing the action (for audit trail)","example":"user@example.com"},"updatedBy":{"type":"string","nullable":true,"description":"User ID who initiated the action","example":"user@example.com"}}},"CreateTaskTemplateContextTrigger":{"type":"object","required":["taskTemplateContextId","triggerEvent","operationId"],"properties":{"taskTemplateContextId":{"type":"string","description":"ID of the task template context - must exist and be accessible","minLength":1,"maxLength":100},"triggerEvent":{"type":"string","enum":["task.created","task.updated","task.completed"],"description":"Event that triggers this context action - uses EventTypeCode constants"},"operationId":{"type":"string","description":"ID of the context operation to execute - must exist and be accessible","minLength":1,"maxLength":100},"executionOrder":{"type":"integer","default":0,"minimum":0,"maximum":999,"description":"Order of execution when multiple triggers exist for the same event (lower numbers execute first)"},"isAsync":{"type":"boolean","default":false,"description":"Whether to execute this trigger asynchronously - if true, doesn't block task operations"},"continueOnFailure":{"type":"boolean","default":true,"description":"Whether to continue processing other triggers if this one fails"},"retryCount":{"type":"integer","default":3,"minimum":0,"maximum":10,"description":"Number of retry attempts on failure"},"retryDelayMs":{"type":"integer","default":1000,"minimum":100,"maximum":60000,"description":"Delay in milliseconds between retry attempts (100ms to 60s)"},"conditionType":{"type":"string","nullable":true,"maxLength":50,"description":"Type of condition to evaluate before executing (e.g., 'jsonlogic', 'expression')"},"conditionConfig":{"type":"object","nullable":true,"description":"Configuration for the condition evaluation - structure depends on conditionType","additionalProperties":true}}},"UpdateTaskTemplateContextTrigger":{"type":"object","properties":{"triggerEvent":{"type":"string","enum":["task.created","task.updated","task.completed"],"description":"Updated trigger event"},"operationId":{"type":"string","minLength":1,"maxLength":100,"description":"Updated operation ID"},"executionOrder":{"type":"integer","minimum":0,"maximum":999,"description":"Updated execution order"},"isAsync":{"type":"boolean","description":"Updated async execution flag"},"continueOnFailure":{"type":"boolean","description":"Updated continue on failure flag"},"retryCount":{"type":"integer","minimum":0,"maximum":10,"description":"Updated retry count"},"retryDelayMs":{"type":"integer","minimum":100,"maximum":60000,"description":"Updated retry delay"},"conditionType":{"type":"string","nullable":true,"maxLength":50,"description":"Updated condition type"},"conditionConfig":{"type":"object","nullable":true,"description":"Updated condition configuration","additionalProperties":true}}},"TaskPreview":{"type":"object","required":["title","priority","assigneeType","assigneeId","templateId","organizationId"],"properties":{"templateId":{"type":"string","format":"uuid","description":"ID of the template this preview is based on","example":"123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization ID","example":"123e4567-e89b-12d3-a456-426614174000"},"title":{"type":"string","description":"Task title","example":"Property Inspection Checklist"},"description":{"type":"string","nullable":true,"description":"Task description","example":"Complete property inspection with standardized checklist"},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Project ID if task will be created in a project","example":"456e7890-e89b-12d3-a456-426614174111"},"sectionId":{"type":"string","format":"uuid","nullable":true,"description":"Section ID if task will be created in a section","example":"321e6547-e89b-12d3-a456-426614174333"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority","example":"HIGH"},"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of assignee","example":"USER"},"assigneeId":{"type":"string","description":"Assignee identifier","example":"john.doe@example.com"},"assigneeName":{"type":"string","nullable":true,"description":"Human-readable assignee name","example":"John Doe"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Task due date","example":"2024-01-25T17:00:00.000Z"},"estimatedDurationMinutes":{"type":"integer","nullable":true,"description":"Estimated duration in minutes","example":120},"requiresApproval":{"type":"boolean","nullable":true,"description":"Whether task requires approval","example":false},"approvalAssigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"nullable":true,"description":"Type of approval assignee","example":"ROLE"},"approvalAssigneeId":{"type":"string","nullable":true,"description":"Approval assignee identifier","example":"manager"},"entityType":{"type":"string","nullable":true,"description":"Type of linked entity","example":"property"},"entityId":{"type":"string","nullable":true,"description":"ID of linked entity","example":"property-456"},"checklistItems":{"type":"array","nullable":true,"description":"Task checklist items","items":{"type":"object","properties":{"title":{"type":"string","example":"Check electrical systems"},"required":{"type":"boolean","example":true},"description":{"type":"string","nullable":true},"completed":{"type":"boolean","nullable":true,"example":false},"completedAt":{"type":"string","format":"date-time","nullable":true},"completedBy":{"type":"string","nullable":true,"maxLength":255},"comment":{"type":"string","nullable":true,"maxLength":2000}}}},"metadata":{"type":"object","nullable":true,"description":"Task metadata","additionalProperties":true,"example":{"inspection_type":"annual","building_floor":3}},"assigneeResolvedFromContext":{"type":"boolean","nullable":true,"description":"Whether the assignee was resolved from context data","example":true}}},"TaskTemplateResolutionResult":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"Whether the operation was successful","example":true},"assignee":{"type":"object","nullable":true,"description":"Resolved assignee information (if successful)","properties":{"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of assignee","example":"USER"},"assigneeId":{"type":"string","description":"Assignee identifier","example":"john.doe@example.com"},"assigneeName":{"type":"string","nullable":true,"description":"Human-readable assignee name","example":"John Doe"}}},"task":{"oneOf":[{"$ref":"#/components/schemas/Task"},{"$ref":"#/components/schemas/TaskPreview"}],"nullable":true,"description":"Task that was created or preview data (if applicable)"},"error":{"type":"string","nullable":true,"description":"Error message if operation failed","example":"Unable to resolve assignee from context data"},"debug":{"type":"object","nullable":true,"description":"Debug information for troubleshooting","properties":{"contextData":{"type":"object","nullable":true,"description":"Context data that was fetched","additionalProperties":true},"extractedValue":{"nullable":true,"description":"Raw value extracted from context","example":"john.doe@example.com"},"transformedValue":{"nullable":true,"description":"Value after transformation","example":"john.doe"},"usedFallback":{"type":"boolean","nullable":true,"description":"Whether fallback was used","example":false},"strategy":{"type":"string","nullable":true,"description":"Resolution strategy that was applied","example":"CONTEXT_FIELD_EXTRACTION"},"attemptedAt":{"type":"string","format":"date-time","description":"Timestamp of resolution attempt","example":"2024-01-15T10:30:00.000Z"},"attemptCount":{"type":"integer","nullable":true,"description":"Number of attempts made","example":1},"taskCreated":{"type":"boolean","nullable":true,"description":"Whether a task was created during this operation","example":true},"assigneeResolvedFromContext":{"type":"boolean","nullable":true,"description":"Whether assignee was resolved from context","example":true}}}}},"UpdateWorkflowRequest":{"type":"object","properties":{"name":{"type":"string","description":"Name of the workflow","maxLength":255,"example":"Bergen Waterfront Property Acquisition - Phase 2"},"description":{"type":"string","nullable":true,"description":"Detailed description of the workflow","maxLength":2000,"example":"Updated acquisition strategy for prime waterfront property in Bergen city center, including environmental assessment and zoning verification."},"status":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"],"description":"Workflow status - must follow valid transition rules","example":"ACTIVE"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of workflow owner","example":"USER"},"ownerId":{"type":"string","description":"ID of the workflow owner (required when ownerType is specified)","example":"maria.hansen@apart.no"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Due date for workflow completion (ISO 8601 format)","example":"2024-12-15T23:59:59.000Z"},"context":{"type":"object","nullable":true,"description":"Additional business context data as key-value pairs","additionalProperties":true,"example":{"propertyValue":16500000,"urgencyLevel":"high","specialConditions":"Environmental assessment required","currency":"NOK","investorType":"institutional"}},"actor":{"type":"string","description":"Actor performing the update (for audit trail)","example":"maria.hansen@apart.no"},"updatedBy":{"type":"string","description":"User ID who updated the workflow","example":"maria.hansen@apart.no"}}},"UpdateWorkflowStageRequest":{"type":"object","description":"All fields optional. Validates status transitions.","properties":{"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"],"description":"Stage status. Cannot change from COMPLETED to other states."},"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of assignee"},"assignedToId":{"type":"string","maxLength":50,"nullable":true,"description":"ID of assignee"},"assignedToName":{"type":"string","maxLength":255,"nullable":true,"description":"Name of assignee for display"},"scheduledAt":{"type":"string","format":"date-time","nullable":true,"description":"When stage is scheduled to start"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Stage due date"},"skipReason":{"type":"string","maxLength":1000,"nullable":true,"description":"Reason for skipping (if status is SKIPPED)"},"completionNotes":{"type":"string","maxLength":2000,"nullable":true,"description":"Notes about stage completion"}}},"StartWorkflowStageRequest":{"type":"object","description":"Optional assignment when starting stage","properties":{"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of assignee"},"assignedToId":{"type":"string","maxLength":50,"description":"ID of assignee"},"assignedToName":{"type":"string","maxLength":255,"description":"Name of assignee for display"}}},"CompleteWorkflowStageRequest":{"type":"object","properties":{"completionNotes":{"type":"string","maxLength":2000,"nullable":true,"description":"Notes about stage completion"}}},"SkipWorkflowStageRequest":{"type":"object","required":["skipReason"],"properties":{"skipReason":{"type":"string","minLength":1,"maxLength":1000,"description":"Required business justification for skipping the stage","example":"Property environmental assessment not required for this type of commercial building."}}},"AttachmentResponse":{"type":"object","description":"Attachment metadata with optional signed download URL","required":["id","targetType","targetId","filename","originalFilename","fileSize","storageUrl","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique attachment identifier generated by the system","example":"123e4567-e89b-12d3-a456-426614174000"},"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Type of entity this attachment belongs to","example":"task"},"targetId":{"type":"string","format":"uuid","description":"UUID of the entity this attachment belongs to","example":"456e7890-e89b-12d3-a456-426614174111"},"filename":{"type":"string","description":"Storage filename with path including timestamp prefix and sanitization. Format: {targetType}/{targetId}/{timestamp}-{sanitized-filename}","example":"task/456e7890-e89b-12d3-a456-426614174111/1703001234567-project_plan.pdf"},"originalFilename":{"type":"string","minLength":1,"maxLength":255,"description":"Original filename as uploaded by user, preserved for display purposes","example":"project plan.pdf"},"fileSize":{"type":"integer","format":"int64","minimum":0,"maximum":104857600,"description":"File size in bytes. Maximum 100MB (104857600 bytes)","example":2097152},"mimeType":{"type":"string","nullable":true,"description":"MIME type detected from file content. Used for preview generation and content-type headers.","example":"application/pdf"},"storageUrl":{"type":"string","format":"uri","description":"Public GCS URL (requires authentication). Not directly accessible without signed URL.","example":"https://storage.googleapis.com/tasks-462013-attachments/org123/task/456/file.pdf"},"downloadUrl":{"type":"string","format":"uri","nullable":true,"description":"Time-limited signed URL for direct download. Valid for 15 minutes by default. Only included when explicitly requested via includeDownloadUrls parameter.","example":"https://storage.googleapis.com/tasks-462013-attachments/org123/task/456/file.pdf?X-Goog-Signature=..."},"uploadedByType":{"type":"string","nullable":true,"enum":["USER","API_KEY","SYSTEM"],"description":"Type of actor that uploaded the attachment","example":"USER"},"uploadedById":{"type":"string","nullable":true,"description":"ID of the user, API key, or system that uploaded the attachment","example":"user-123"},"uploadedByName":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"Display name of the uploader for audit trail and UI display","example":"John Doe"},"externalDocumentId":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"External system document identifier for integration tracking","example":"EXT-DOC-12345"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when attachment was uploaded","example":"2025-01-15T10:30:00.000Z"}}},"RequestUploadUrlRequest":{"type":"object","description":"Request body for generating a presigned upload URL","required":["targetType","targetId","filename","contentType","fileSize"],"properties":{"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Type of entity the attachment will belong to","example":"task"},"targetId":{"type":"string","format":"uuid","description":"UUID of the target entity","example":"456e7890-e89b-12d3-a456-426614174111"},"filename":{"type":"string","minLength":1,"maxLength":255,"description":"Original filename of the file to upload","example":"document.pdf"},"contentType":{"type":"string","minLength":1,"maxLength":255,"description":"MIME type of the file","example":"application/pdf"},"fileSize":{"type":"integer","minimum":1,"maximum":104857600,"description":"Size of the file in bytes (max 100MB)","example":5242880},"public":{"type":"boolean","description":"Whether to upload as a public attachment","default":false,"example":false},"externalDocumentId":{"type":"string","maxLength":255,"description":"External document identifier for integration tracking","example":"EXT-DOC-12345"}}},"RequestUploadUrlResponse":{"type":"object","description":"Response containing presigned upload URL and metadata","required":["uploadUrl","storageFilename","expiresAt","headers","maxFileSize"],"properties":{"uploadUrl":{"type":"string","format":"uri","description":"Presigned URL for direct upload to GCS. Use PUT method with the file body.","example":"https://storage.googleapis.com/bucket/path?X-Goog-Signature=..."},"storageFilename":{"type":"string","description":"Generated storage path for the file. Pass this to confirm-upload endpoint.","example":"task/456e7890-e89b-12d3-a456-426614174111/1703001234567-document.pdf"},"expiresAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the presigned URL expires (15 minutes from generation)","example":"2025-01-15T10:45:00.000Z"},"headers":{"type":"object","description":"Headers that must be included with the upload request","additionalProperties":{"type":"string"},"example":{"Content-Type":"application/pdf"}},"maxFileSize":{"type":"integer","description":"Maximum file size in bytes that was validated","example":5242880}}},"ConfirmUploadRequest":{"type":"object","description":"Request body for confirming upload and creating attachment record","required":["storageFilename","originalFilename","targetType","targetId","contentType","fileSize"],"properties":{"storageFilename":{"type":"string","minLength":1,"maxLength":512,"description":"Storage filename returned from upload-url endpoint","example":"task/456e7890-e89b-12d3-a456-426614174111/1703001234567-document.pdf"},"originalFilename":{"type":"string","minLength":1,"maxLength":255,"description":"Original filename of the uploaded file","example":"document.pdf"},"targetType":{"type":"string","enum":["project","task","workflow","comment"],"description":"Type of entity the attachment belongs to","example":"task"},"targetId":{"type":"string","format":"uuid","description":"UUID of the target entity","example":"456e7890-e89b-12d3-a456-426614174111"},"contentType":{"type":"string","minLength":1,"maxLength":255,"description":"MIME type of the file","example":"application/pdf"},"fileSize":{"type":"integer","minimum":1,"maximum":104857600,"description":"Size of the uploaded file in bytes","example":5242880},"public":{"type":"boolean","description":"Whether the attachment is publicly accessible","default":false,"example":false},"externalDocumentId":{"type":"string","maxLength":255,"description":"External document identifier for integration tracking","example":"EXT-DOC-12345"}}},"EntityAttachmentResponse":{"allOf":[{"$ref":"#/components/schemas/AttachmentResponse"},{"type":"object","required":["entityContext"],"properties":{"entityContext":{"type":"object","required":["entityName","entityType"],"properties":{"entityName":{"type":"string","description":"Name of the entity this attachment belongs to","example":"Project Alpha"},"entityType":{"type":"string","enum":["project","task"],"description":"Type of entity this attachment belongs to","example":"project"},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Project ID if entity is a task","example":"123e4567-e89b-12d3-a456-426614174000"},"projectName":{"type":"string","nullable":true,"description":"Project name if entity is a task","example":"Project Alpha"}}}}}]},"EntityAttachmentListResponse":{"type":"object","required":["attachments","entityContext","pagination"],"properties":{"attachments":{"type":"array","items":{"$ref":"#/components/schemas/EntityAttachmentResponse"},"description":"List of attachments for the entity"},"entityContext":{"type":"object","required":["entityId","entityName","entityType"],"properties":{"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"123e4567-e89b-12d3-a456-426614174000"},"entityName":{"type":"string","description":"Name of the entity","example":"Project Alpha"},"entityType":{"type":"string","enum":["project","task"],"description":"Type of entity","example":"project"},"projectId":{"type":"string","format":"uuid","nullable":true,"description":"Project ID if entity is a task","example":"123e4567-e89b-12d3-a456-426614174000"},"projectName":{"type":"string","nullable":true,"description":"Project name if entity is a task","example":"Project Alpha"}}},"pagination":{"$ref":"#/components/schemas/PaginationResponse"}}},"EntityAttachmentStatsResponse":{"type":"object","required":["entityId","entityName","entityType","statistics"],"properties":{"entityId":{"type":"string","format":"uuid","description":"ID of the entity","example":"123e4567-e89b-12d3-a456-426614174000"},"entityName":{"type":"string","description":"Name of the entity","example":"Project Alpha"},"entityType":{"type":"string","enum":["project","task"],"description":"Type of entity","example":"project"},"statistics":{"type":"object","required":["totalAttachments","totalFileSize","fileTypeBreakdown","recentAttachments"],"properties":{"totalAttachments":{"type":"integer","minimum":0,"description":"Total number of attachments","example":25},"totalFileSize":{"type":"integer","minimum":0,"description":"Total file size in bytes","example":10485760},"fileTypeBreakdown":{"type":"array","description":"Breakdown of attachments by file type","items":{"type":"object","required":["mimeType","count","totalSize"],"properties":{"mimeType":{"type":"string","description":"MIME type of the files","example":"application/pdf"},"count":{"type":"integer","minimum":0,"description":"Number of files of this type","example":5},"totalSize":{"type":"integer","minimum":0,"description":"Total size of files of this type in bytes","example":2097152}}}},"recentAttachments":{"type":"array","description":"Most recently added attachments","items":{"$ref":"#/components/schemas/EntityAttachmentResponse"}}}},"projectContext":{"type":"object","nullable":true,"description":"Project context if entity is a task","properties":{"projectId":{"type":"string","format":"uuid","description":"Project ID","example":"123e4567-e89b-12d3-a456-426614174000"},"projectName":{"type":"string","description":"Project name","example":"Project Alpha"}},"required":["projectId","projectName"]}}},"EntityVisibilityResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","description":"Entity visibility data"}},"description":"Response for visibility grant operation"},"PortalTaskListResponse":{"type":"object","required":["data","total","page","pageSize","totalPages"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Task"},"description":"Array of tasks visible to portal user"},"total":{"type":"integer","description":"Total count of visible tasks (all pages)","example":47},"page":{"type":"integer","minimum":1,"description":"Current page number","example":1},"pageSize":{"type":"integer","minimum":1,"maximum":100,"description":"Number of items per page","example":20},"totalPages":{"type":"integer","description":"Total number of pages","example":3},"message":{"type":"string","description":"Optional message (shown when no tasks visible)","example":"No tasks visible to this portal user"}},"description":"Response for portal task list with pagination and visibility filtering"},"PortalProfileResponse":{"type":"object","required":["data"],"properties":{"data":{"type":"object","required":["user","portal","token","access"],"properties":{"user":{"type":"object","required":["id","portalCode","permissions"],"properties":{"id":{"type":"string","description":"Portal user ID","example":"user-123"},"portalCode":{"type":"string","description":"Portal code user is accessing","example":"customer_portal"},"permissions":{"type":"array","items":{"type":"string"},"description":"User permissions in portal","example":["view_tasks","comment_tasks"]}}},"portal":{"type":"object","required":["name","isActive"],"properties":{"name":{"type":"string","description":"Portal display name","example":"Customer Portal"},"description":{"type":"string","nullable":true,"description":"Portal description","example":"External customer access"},"isActive":{"type":"boolean","description":"Whether portal is active","example":true}}},"token":{"type":"object","properties":{"issuedAt":{"type":"string","format":"date-time","description":"When token was issued","example":"2024-12-15T10:00:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"When token expires","example":"2024-12-15T18:00:00Z"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last token usage","example":"2024-12-15T14:30:00Z"}}},"access":{"type":"object","required":["visibleTasks","visibleProjects"],"properties":{"visibleTasks":{"type":"integer","description":"Count of tasks visible to user","example":12},"visibleProjects":{"type":"integer","description":"Count of projects visible to user","example":3}}}}}},"description":"Comprehensive portal user profile with access summary"},"PortalTaskCommentRequest":{"type":"object","required":["content"],"properties":{"content":{"type":"string","minLength":1,"description":"Comment text (required, non-empty)","example":"I have completed the initial review and have some questions."}},"description":"Request to add comment to task via portal"},"PortalWorkflowViewResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Workflow ID"},"name":{"type":"string","description":"Workflow name (possibly translated)"},"description":{"type":"string","nullable":true,"description":"Workflow description (possibly translated)"},"status":{"type":"string","enum":["ACTIVE","COMPLETED","PAUSED","CANCELLED"],"description":"Workflow status"},"overallProgress":{"type":"number","minimum":0,"maximum":100,"description":"Overall workflow completion percentage","example":45.5},"phases":{"type":"array","description":"Workflow phases (if includePhases=true)","items":{"type":"object","properties":{"phaseCode":{"type":"string","description":"Phase identifier"},"phaseName":{"type":"string","description":"Phase name (translated)"},"phaseDescription":{"type":"string","description":"Phase description (translated)"},"status":{"type":"string","description":"Phase status"},"progress":{"type":"number","description":"Phase completion percentage"}}}}}}},"description":"Workflow view for portal with translations and visibility filtering"},"PortalEntityLabelsResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","additionalProperties":{"type":"string"},"description":"Map of entity label keys to translated values","example":{"task_singular":"Aufgabe","task_plural":"Aufgaben","project_singular":"Projekt","project_plural":"Projekte","workflow_singular":"Workflow","workflow_plural":"Workflows"}}},"description":"Translated entity labels for portal display"},"PortalConfigResponse":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","required":["defaultLocale","showSummaryOnly"],"properties":{"defaultLocale":{"type":"string","description":"Default locale for portal","example":"de"},"showSummaryOnly":{"type":"boolean","description":"Whether to show only summary information","example":false}}}},"description":"Public portal configuration (no sensitive data)"},"HealthCheckResponse":{"type":"object","required":["status","timestamp"],"properties":{"status":{"type":"string","enum":["ok"],"description":"Health status","example":"ok"},"timestamp":{"type":"string","format":"date-time","description":"Current server timestamp","example":"2024-12-15T14:30:00.000Z"}},"description":"Health check response for load balancer monitoring"},"LiveContextData":{"type":"object","required":["contextId","contextType","externalEntityId","fetchAttemptCount"],"properties":{"contextId":{"type":"string","format":"uuid","description":"Context configuration ID","example":"123e4567-e89b-12d3-a456-426614174000"},"contextType":{"type":"object","required":["code","name"],"properties":{"code":{"type":"string","description":"Context type code","example":"property_api"},"name":{"type":"string","description":"Context type display name","example":"Property Management API"}}},"externalEntityId":{"type":"string","description":"External entity identifier","example":"PROP-12345"},"liveData":{"type":"object","nullable":true,"description":"Fetched live data from external source","additionalProperties":true,"example":{"address":"123 Main St","price":250000,"status":"active"}},"error":{"type":"string","nullable":true,"description":"Error message if fetch failed","example":"API rate limit exceeded"},"lastFetchedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of last successful fetch","example":"2025-01-15T10:30:00Z"},"fetchAttemptCount":{"type":"integer","minimum":0,"description":"Number of fetch attempts made","example":3}}},"ServiceResponse":{"type":"object","allOf":[{"$ref":"#/components/schemas/RegisteredService"},{"type":"object","required":["eventSubscriptions","infrastructure","apiEndpoints"],"properties":{"eventSubscriptions":{"type":"array","items":{"$ref":"#/components/schemas/ServiceEventSubscription"},"description":"Event subscriptions for this service"},"infrastructure":{"type":"object","required":["topics","subscriptions"],"properties":{"topics":{"type":"array","items":{"type":"object","required":["id","name","fullName"],"properties":{"id":{"type":"string","format":"uuid","description":"Topic ID","example":"123e4567-e89b-12d3-a456-426614174000"},"name":{"type":"string","description":"Topic name","example":"task-events"},"fullName":{"type":"string","description":"Full GCP topic name","example":"projects/tasks-prod/topics/org-123-task-events"}}}},"subscriptions":{"type":"array","items":{"type":"object","required":["id","name","fullName","pushEndpoint"],"properties":{"id":{"type":"string","format":"uuid","description":"Subscription ID","example":"123e4567-e89b-12d3-a456-426614174001"},"name":{"type":"string","description":"Subscription name","example":"task-service-subscription"},"fullName":{"type":"string","description":"Full GCP subscription name","example":"projects/tasks-prod/subscriptions/org-123-task-service"},"pushEndpoint":{"type":"string","format":"uri","description":"Push endpoint URL","example":"https://api.taskservice.com/webhooks/events"}}}}}},"apiEndpoints":{"type":"object","required":["status","webhook","events","deregister"],"properties":{"status":{"type":"string","format":"uri","description":"Service status endpoint","example":"/api/v1/services/task-service/status"},"webhook":{"type":"string","format":"uri","description":"Webhook configuration endpoint","example":"/api/v1/services/task-service/webhook"},"events":{"type":"string","format":"uri","description":"Event subscription endpoint","example":"/api/v1/services/task-service/events"},"deregister":{"type":"string","format":"uri","description":"Service deregistration endpoint","example":"/api/v1/services/task-service"}}}}}]},"ServiceStatusResponse":{"type":"object","required":["serviceId","serviceName","status","healthCheck","deliveryStats","infrastructure","eventSubscriptions"],"properties":{"serviceId":{"type":"string","format":"uuid","description":"Service unique identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"serviceName":{"type":"string","description":"Service name","example":"task-management-service"},"status":{"type":"string","enum":["PENDING","ACTIVE","FAILED","DEREGISTERED"],"description":"Current service status","example":"ACTIVE"},"healthCheck":{"type":"object","required":["isHealthy"],"properties":{"lastCheck":{"type":"string","format":"date-time","nullable":true,"description":"Last health check timestamp","example":"2025-01-15T10:30:00Z"},"isHealthy":{"type":"boolean","description":"Service health status","example":true},"responseTime":{"type":"number","nullable":true,"description":"Health check response time in milliseconds","example":125.5}}},"deliveryStats":{"type":"object","required":["totalDelivered","totalFailed","consecutiveFailures"],"properties":{"totalDelivered":{"type":"integer","minimum":0,"description":"Total successful event deliveries","example":1234},"totalFailed":{"type":"integer","minimum":0,"description":"Total failed event deliveries","example":12},"lastSuccessfulDelivery":{"type":"string","format":"date-time","nullable":true,"description":"Last successful delivery timestamp","example":"2025-01-15T10:25:00Z"},"consecutiveFailures":{"type":"integer","minimum":0,"description":"Consecutive delivery failures","example":0}}},"infrastructure":{"$ref":"#/components/schemas/ServiceResponse/allOf/1/properties/infrastructure"},"eventSubscriptions":{"type":"array","items":{"type":"string","description":"Event type code","example":"task.created"}}}},"ServiceRegistrationResponse":{"type":"object","required":["serviceId","organizationId","serviceName","status","webhookEndpoint","infrastructure","eventSubscriptions","apiEndpoints","createdAt"],"properties":{"serviceId":{"type":"string","format":"uuid","description":"Service unique identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization ID","example":"123e4567-e89b-12d3-a456-426614174001"},"serviceName":{"type":"string","description":"Service name","example":"task-management-service"},"status":{"type":"string","enum":["PENDING","ACTIVE","FAILED","DEREGISTERED"],"description":"Current service status","example":"PENDING"},"webhookEndpoint":{"type":"string","format":"uri","description":"Service webhook endpoint URL","example":"https://api.taskservice.com/webhooks/events"},"infrastructure":{"$ref":"#/components/schemas/ServiceResponse/allOf/1/properties/infrastructure"},"eventSubscriptions":{"type":"array","items":{"type":"string","description":"Event type code","example":"task.created"}},"apiEndpoints":{"$ref":"#/components/schemas/ServiceResponse/allOf/1/properties/apiEndpoints"},"createdAt":{"type":"string","format":"date-time","description":"Service registration timestamp","example":"2025-01-15T10:30:00Z"},"provisioningErrors":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Errors encountered during infrastructure provisioning","example":["Failed to create topic: permission denied"]}}},"DownloadUrlResponse":{"type":"object","description":"Response containing signed download URL with expiration","required":["downloadUrl","expiresAt"],"properties":{"downloadUrl":{"type":"string","format":"uri","description":"Signed URL for direct file access from Google Cloud Storage","example":"https://storage.googleapis.com/tasks-462013-attachments/org123/task/456/file.pdf?X-Goog-Signature=..."},"expiresAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when the signed URL expires and becomes invalid","example":"2025-01-15T11:30:00.000Z"}}},"ServiceRegistrationInput":{"type":"object","required":["serviceName","webhookEndpoint","eventSubscriptions"],"properties":{"serviceName":{"type":"string","description":"Unique service name within organization. Used for subscription naming and service identification. Should be lowercase with hyphens.","minLength":1,"maxLength":100,"pattern":"^[a-z0-9-]+$","example":"letting-service"},"serviceDescription":{"type":"string","nullable":true,"description":"Human-readable description of the service's purpose and functionality","maxLength":500,"example":"Property letting and rental management service for tenant onboarding and lease management"},"webhookEndpoint":{"type":"string","format":"uri","description":"HTTPS endpoint to receive events. Must be publicly accessible or within allowed network. All subscriptions will use this endpoint.","pattern":"^https://","example":"https://letting-service.example.com/webhook/events"},"eventSubscriptions":{"type":"array","description":"Event patterns to subscribe to. Supports wildcards (e.g., 'task.*' for all task events) and specific events (e.g., 'workflow.completed'). Infrastructure will be auto-provisioned for matching topics.","minItems":1,"maxItems":50,"items":{"type":"string","pattern":"^[a-z._*]+$"},"example":["task.*","workflow.completed","project.created"]},"authenticationMethod":{"type":"string","description":"Webhook authentication method for securing event delivery. NONE for no auth (not recommended), BEARER for OAuth/JWT tokens, APIKEY for API key header.","enum":["NONE","BEARER","APIKEY"],"default":"NONE","example":"BEARER"},"retryPolicy":{"type":"object","nullable":true,"description":"Retry policy for failed webhook deliveries. Controls how many times and with what backoff to retry.","properties":{"maxRetries":{"type":"integer","minimum":1,"maximum":10,"default":5,"description":"Maximum number of retry attempts for failed deliveries"},"backoffMultiplier":{"type":"number","minimum":1,"maximum":3,"default":2,"description":"Exponential backoff multiplier for retry delays"}},"example":{"maxRetries":5,"backoffMultiplier":2}},"metadata":{"type":"object","nullable":true,"additionalProperties":true,"description":"Service-specific configuration and metadata for custom settings and extensions","example":{"version":"1.0.0","environment":"production","team":"letting-operations"}}}},"UpdateServiceWebhookInput":{"type":"object","required":["webhookEndpoint"],"properties":{"webhookEndpoint":{"type":"string","format":"uri","description":"New HTTPS endpoint to receive events. This will update all related Pub/Sub subscriptions.","pattern":"^https://","example":"https://new-endpoint.example.com/webhook/events"},"authenticationMethod":{"type":"string","description":"Updated webhook authentication method","enum":["NONE","BEARER","APIKEY"],"example":"APIKEY"},"retryPolicy":{"type":"object","nullable":true,"description":"Updated retry policy for webhook deliveries","properties":{"maxRetries":{"type":"integer","minimum":1,"maximum":10},"backoffMultiplier":{"type":"number","minimum":1,"maximum":3}},"example":{"maxRetries":3,"backoffMultiplier":1.5}}}},"UpdateServiceEventsInput":{"type":"object","required":["eventSubscriptions"],"properties":{"eventSubscriptions":{"type":"array","description":"New event patterns to subscribe to. This will create new subscriptions and disable unused ones. May trigger infrastructure provisioning for new event categories.","minItems":1,"maxItems":50,"items":{"type":"string","pattern":"^[a-z._*]+$"},"example":["task.*","workflow.*","project.created","comment.created"]}}},"UpdateAttachmentRequest":{"type":"object","description":"Request schema for updating attachment metadata. File content is immutable.","properties":{"externalDocumentId":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"Update or clear external document identifier. Set to null to remove existing value.","example":"EXT-DOC-54321"}}},"EntityAttachmentSummaryResponse":{"type":"object","description":"Aggregate attachment statistics across multiple entities","required":["entities","aggregateStats"],"properties":{"entities":{"type":"array","description":"Per-entity attachment statistics","items":{"type":"object","required":["entityId","entityName","entityType","attachmentCount","totalFileSize"],"properties":{"entityId":{"type":"string","format":"uuid","description":"Entity ID","example":"123e4567-e89b-12d3-a456-426614174000"},"entityName":{"type":"string","description":"Entity name for display","example":"Project Alpha"},"entityType":{"type":"string","enum":["project","task"],"description":"Entity type","example":"project"},"attachmentCount":{"type":"integer","minimum":0,"description":"Total number of attachments for this entity","example":15},"totalFileSize":{"type":"integer","format":"int64","minimum":0,"description":"Total file size in bytes for all attachments","example":52428800},"lastAttachmentDate":{"type":"string","format":"date-time","nullable":true,"description":"ISO 8601 timestamp of most recent attachment upload","example":"2025-01-15T10:30:00.000Z"},"projectContext":{"type":"object","nullable":true,"description":"Project context if entity is a task","properties":{"projectId":{"type":"string","format":"uuid","example":"456e7890-e89b-12d3-a456-426614174111"},"projectName":{"type":"string","example":"Project Beta"}}}}}},"aggregateStats":{"type":"object","required":["totalEntities","totalAttachments","totalFileSize","averageAttachmentsPerEntity"],"description":"Organization-wide aggregate statistics","properties":{"totalEntities":{"type":"integer","minimum":0,"description":"Total number of entities with attachments","example":25},"totalAttachments":{"type":"integer","minimum":0,"description":"Total number of attachments across all entities","example":342},"totalFileSize":{"type":"integer","format":"int64","minimum":0,"description":"Total file size in bytes across all attachments","example":1073741824},"averageAttachmentsPerEntity":{"type":"number","format":"double","minimum":0,"description":"Average number of attachments per entity (rounded to 2 decimal places)","example":13.68}}}}},"DownloadAudit":{"type":"object","description":"Audit log entry for attachment access tracking","required":["attachmentId","downloadedAt","downloadMethod","success"],"properties":{"attachmentId":{"type":"string","format":"uuid","description":"ID of the accessed attachment","example":"123e4567-e89b-12d3-a456-426614174000"},"userId":{"type":"string","nullable":true,"description":"ID of the user who accessed the attachment","example":"user-123"},"downloadedAt":{"type":"string","format":"date-time","description":"Timestamp of the access attempt","example":"2025-01-15T10:30:00.000Z"},"downloadMethod":{"type":"string","enum":["DOWNLOAD","STREAM","PREVIEW","URL_GENERATION"],"description":"Type of access method used","example":"DOWNLOAD"},"success":{"type":"boolean","description":"Whether the access attempt was successful or blocked","example":true},"ipAddress":{"type":"string","nullable":true,"description":"IP address of the access request for security tracking","example":"192.168.1.100"},"userAgent":{"type":"string","nullable":true,"description":"User agent string of the access request","example":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"},"failureReason":{"type":"string","nullable":true,"description":"Reason for access failure if success is false","example":"QUOTA_EXCEEDED"}}},"Comment":{"type":"object","description":"Comment object with threading support","required":["id","organizationId","targetType","targetId","content","authorType","authorId","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique comment identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization ID for multi-tenant isolation","example":"456e7890-e89b-12d3-a456-426614174111"},"targetType":{"type":"string","description":"Type of entity being commented on (e.g., task, project, workflow, workflow_stage)","example":"task"},"targetId":{"type":"string","format":"uuid","description":"ID of the entity being commented on","example":"789e0123-e89b-12d3-a456-426614174222"},"content":{"type":"string","minLength":1,"maxLength":10000,"description":"Comment content. Can include user mentions in format user:UUID","example":"This task looks great! user:550e8400-e29b-41d4-a716-446655440000 please review."},"contentType":{"type":"string","enum":["text","markdown"],"default":"text","description":"Format of the comment content for rendering","example":"text"},"authorType":{"type":"string","enum":["USER","API_KEY","SYSTEM","PORTAL_USER"],"description":"Type of comment author","example":"USER"},"authorId":{"type":"string","nullable":true,"description":"ID of the comment author","example":"user-123"},"authorName":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"Display name of the comment author","example":"John Doe"},"parentCommentId":{"type":"string","format":"uuid","nullable":true,"description":"ID of parent comment for threaded replies","example":"321e7654-e89b-12d3-a456-426614174333"},"externalMessageId":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"External system message ID for integration tracking","example":"ext-msg-12345"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when comment was created","example":"2025-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when comment was last updated","example":"2025-01-15T11:00:00.000Z"},"childComments":{"type":"array","items":{"$ref":"#/components/schemas/Comment"},"description":"Nested child comments (replies) when includeReplies is true"}}},"CreateCommentRequest":{"type":"object","description":"Request schema for creating a new comment","required":["targetType","targetId","content"],"properties":{"targetType":{"type":"string","minLength":1,"description":"Type of entity being commented on (e.g., task, project, workflow, workflow_stage)","example":"task"},"targetId":{"type":"string","format":"uuid","description":"ID of the entity being commented on. Entity must exist and belong to organization.","example":"789e0123-e89b-12d3-a456-426614174222"},"content":{"type":"string","minLength":1,"maxLength":10000,"description":"Comment content. Supports user mentions using format user:UUID","example":"This task is ready for testing. All requirements met."},"contentType":{"type":"string","enum":["text","markdown"],"default":"text","description":"Format of the comment content","example":"text"},"authorType":{"type":"string","nullable":true,"enum":["USER","API_KEY","SYSTEM"],"description":"Type of comment author. Auto-derived from authenticated user if not provided.","example":"USER"},"authorId":{"type":"string","nullable":true,"description":"ID of the comment author. Auto-derived from authenticated user if not provided.","example":"user-123"},"authorName":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"Display name of the comment author. Auto-derived from authenticated user if not provided.","example":"John Doe"},"parentCommentId":{"type":"string","format":"uuid","nullable":true,"description":"ID of parent comment to create a threaded reply","example":"321e7654-e89b-12d3-a456-426614174333"},"externalMessageId":{"type":"string","nullable":true,"minLength":1,"maxLength":255,"description":"External system message ID for integration tracking","example":"ext-msg-12345"}}},"UpdateCommentRequest":{"type":"object","description":"Request schema for updating comment content","properties":{"content":{"type":"string","minLength":1,"maxLength":10000,"description":"Updated comment content","example":"Updated: This task is now ready for final review."},"contentType":{"type":"string","enum":["text","markdown"],"description":"Updated content format","example":"text"}}},"CommentListQuery":{"type":"object","description":"Query parameters for filtering and paginating comments","properties":{"targetType":{"type":"string","description":"Filter by target entity type","example":"task"},"targetId":{"type":"string","format":"uuid","description":"Filter by target entity ID","example":"789e0123-e89b-12d3-a456-426614174222"},"authorType":{"type":"string","enum":["USER","API_KEY","SYSTEM","PORTAL_USER"],"description":"Filter by author type","example":"USER"},"authorId":{"type":"string","description":"Filter by author ID","example":"user-123"},"parentCommentId":{"type":"string","format":"uuid","nullable":true,"description":"Filter by parent comment for threading","example":"321e7654-e89b-12d3-a456-426614174333"},"includeReplies":{"type":"string","enum":["true","false"],"default":"false","description":"Include nested child comments in response","example":"true"},"sortBy":{"type":"string","enum":["created_at","updated_at"],"default":"created_at","description":"Field to sort by","example":"created_at"},"sortOrder":{"type":"string","enum":["asc","desc"],"default":"desc","description":"Sort direction","example":"desc"},"page":{"type":"integer","minimum":1,"default":1,"description":"Page number for pagination","example":1},"limit":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Number of items per page","example":20}}},"ConversationSummary":{"type":"object","description":"Summary of a conversation on an entity","required":["entity_type","entity_id","user_involvement","comment_count","unread_mention_count"],"properties":{"entity_type":{"type":"string","enum":["task","project","workflow","workflow_stage"],"description":"Type of entity with conversation","example":"task"},"entity_id":{"type":"string","format":"uuid","description":"Entity ID","example":"789e0123-e89b-12d3-a456-426614174222"},"entity_title":{"type":"string","nullable":true,"description":"Entity title or name for display","example":"Fix login authentication bug"},"entity_metadata":{"type":"object","nullable":true,"description":"Additional entity metadata like status, project_id, etc."},"user_involvement":{"type":"object","required":["is_author","is_mentioned","mention_count"],"properties":{"is_author":{"type":"boolean","description":"User has authored comments on this entity","example":true},"is_mentioned":{"type":"boolean","description":"User was mentioned in comments on this entity","example":true},"mention_count":{"type":"integer","minimum":0,"description":"Total times user was mentioned","example":2},"unread_mentions":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of unread mention IDs"}}},"comment_count":{"type":"integer","minimum":0,"description":"Total comments on this entity","example":5},"unread_mention_count":{"type":"integer","minimum":0,"description":"Unread mentions for current user","example":1},"latest_activity_at":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of most recent comment","example":"2025-12-02T10:30:00Z"},"latest_comment":{"type":"object","nullable":true,"description":"Preview of most recent comment","properties":{"id":{"type":"string","format":"uuid"},"content":{"type":"string","description":"Comment preview (truncated to 100 chars)"},"author_id":{"type":"string","nullable":true},"author_name":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"}}}}},"EventPublication":{"type":"object","required":["id","status","topicId"],"properties":{"id":{"type":"string","format":"uuid","description":"Publication record identifier","example":"pub-123e4567-e89b-12d3-a456-426614174000"},"status":{"type":"string","description":"Publication status for this specific topic","example":"PUBLISHED","enum":["PENDING","PUBLISHED","FAILED"]},"topicId":{"type":"string","format":"uuid","description":"Target topic identifier","example":"topic-123e4567-e89b-12d3-a456-426614174000"},"publishedAt":{"type":"string","format":"date-time","nullable":true,"description":"Publication timestamp for this topic","example":"2024-02-15T10:35:00.000Z"},"topic":{"type":"object","nullable":true,"properties":{"topicName":{"type":"string","description":"Topic name","example":"org-12345678-project-events"}}}}},"EventsListResponse":{"type":"object","required":["events","total","limit","offset"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"},"description":"Array of events matching the filter criteria"},"total":{"type":"integer","minimum":0,"description":"Total number of events matching the filter (for pagination)","example":245},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Number of events returned in this response","example":20},"offset":{"type":"integer","minimum":0,"description":"Number of events skipped (for pagination)","example":0}}},"ExecuteActionRequest":{"type":"object","required":["action","entityId","entityType","entityData"],"properties":{"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Type of action to execute on the external system","example":"CREATE"},"entityId":{"type":"string","format":"uuid","description":"Unique identifier for the entity to perform action on","example":"550e8400-e29b-41d4-a716-446655440000"},"entityType":{"type":"string","description":"Type of entity (e.g., customer, property, lead)","example":"customer"},"entityData":{"type":"object","additionalProperties":true,"description":"Data payload for the action","example":{"name":"John Doe","email":"john.doe@example.com","phone":"+1234567890"}},"dryRun":{"type":"boolean","default":false,"description":"Whether to perform a dry run (validation only)","example":false},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"default":"MEDIUM","description":"Priority level for action execution","example":"HIGH"}}},"ExecuteActionResponse":{"type":"object","required":["actionLogId","status"],"properties":{"actionLogId":{"type":"string","format":"uuid","description":"Unique identifier for tracking the action execution","example":"550e8400-e29b-41d4-a716-446655440001"},"status":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","RETRYING"],"description":"Current status of the action execution","example":"PENDING"},"externalId":{"type":"string","description":"ID assigned by the external system","example":"EXT-12345"},"estimatedCompletionTime":{"type":"string","format":"date-time","description":"Estimated completion time for the action","example":"2025-01-15T10:30:00Z"},"retryAfter":{"type":"string","format":"date-time","description":"Time when the action will be retried if it failed","example":"2025-01-15T10:35:00Z"}}},"TestActionRequest":{"type":"object","required":["action","entityData","dryRun"],"properties":{"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Type of action to test","example":"CREATE"},"entityData":{"type":"object","additionalProperties":true,"description":"Test data payload for validation","example":{"name":"Test Customer","email":"test@example.com"}},"authToken":{"type":"string","description":"Optional authentication token for testing","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"dryRun":{"type":"boolean","enum":[true],"description":"Must be true for test operations","example":true}}},"TestActionResponse":{"type":"object","required":["success","validationResults"],"properties":{"success":{"type":"boolean","description":"Whether the test was successful","example":true},"validationResults":{"type":"object","required":["requestValid","authenticationValid","endpointReachable"],"properties":{"requestValid":{"type":"boolean","description":"Whether the request structure is valid","example":true},"authenticationValid":{"type":"boolean","description":"Whether authentication credentials are valid","example":true},"endpointReachable":{"type":"boolean","description":"Whether the external endpoint is reachable","example":true}}},"mockResponse":{"type":"object","additionalProperties":true,"description":"Simulated response from external system","example":{"id":"MOCK-123","status":"created"}},"errors":{"type":"array","items":{"type":"string"},"description":"List of validation errors","example":["Invalid email format"]},"warnings":{"type":"array","items":{"type":"string"},"description":"List of validation warnings","example":["Phone number format may not be supported by external system"]}}},"RetryActionRequest":{"type":"object","properties":{"force":{"type":"boolean","default":false,"description":"Force retry even if max retries exceeded","example":false},"resetRetryCount":{"type":"boolean","default":false,"description":"Reset retry counter to 0","example":false}}},"RetryActionResponse":{"type":"object","required":["actionLogId","newStatus","retryCount"],"properties":{"actionLogId":{"type":"string","format":"uuid","description":"Action log identifier","example":"550e8400-e29b-41d4-a716-446655440001"},"newStatus":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","RETRYING"],"description":"Updated status after retry attempt","example":"RETRYING"},"retryCount":{"type":"integer","minimum":0,"description":"Current retry attempt count","example":2},"estimatedCompletionTime":{"type":"string","format":"date-time","description":"Estimated completion time for the retry","example":"2025-01-15T10:35:00Z"}}},"ActionDetailsResponse":{"type":"object","required":["id","contextTypeId","contextTypeName","entityType","entityId","actionType","status","retryCount","maxRetries","createdAt","createdBy","priority"],"properties":{"id":{"type":"string","format":"uuid","description":"Action log unique identifier","example":"550e8400-e29b-41d4-a716-446655440001"},"contextTypeId":{"type":"string","format":"uuid","description":"Context type this action belongs to","example":"550e8400-e29b-41d4-a716-446655440002"},"contextTypeName":{"type":"string","description":"Human-readable name of the context type","example":"CRM Integration"},"entityType":{"type":"string","description":"Type of entity the action was performed on","example":"customer"},"entityId":{"type":"string","description":"Unique identifier of the target entity","example":"CUST-12345"},"actionType":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Type of action performed","example":"CREATE"},"status":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED","RETRYING"],"description":"Current execution status","example":"COMPLETED"},"errorMessage":{"type":"string","description":"Error message if action failed","example":"Network timeout while connecting to external API"},"errorDetails":{"type":"object","additionalProperties":true,"description":"Detailed error information","example":{"httpStatus":504,"timeout":30000,"retryable":true}},"retryCount":{"type":"integer","minimum":0,"description":"Number of retry attempts made","example":2},"maxRetries":{"type":"integer","minimum":0,"description":"Maximum number of retries allowed","example":3},"executedAt":{"type":"string","format":"date-time","description":"When the action was last executed","example":"2025-01-15T10:30:00Z"},"completedAt":{"type":"string","format":"date-time","description":"When the action was completed","example":"2025-01-15T10:32:00Z"},"createdAt":{"type":"string","format":"date-time","description":"When the action was created","example":"2025-01-15T10:25:00Z"},"createdBy":{"type":"string","format":"uuid","description":"User who initiated the action","example":"550e8400-e29b-41d4-a716-446655440003"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Action execution priority","example":"HIGH"},"externalId":{"type":"string","description":"ID assigned by external system","example":"EXT-12345"},"requestData":{"type":"object","additionalProperties":true,"description":"Original request data sent to external system","example":{"name":"John Doe","email":"john.doe@example.com"}},"responseData":{"type":"object","additionalProperties":true,"description":"Response data received from external system","example":{"id":"EXT-12345","status":"created","timestamp":"2025-01-15T10:32:00Z"}},"executionTimeMs":{"type":"integer","minimum":0,"description":"Execution time in milliseconds","example":1250}}},"ActionMetricsResponse":{"type":"object","required":["contextTypeId","organizationId","timeRange","metrics"],"properties":{"contextTypeId":{"type":"string","format":"uuid","description":"Context type identifier","example":"550e8400-e29b-41d4-a716-446655440002"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440004"},"timeRange":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time","description":"Start of metrics time range","example":"2025-01-01T00:00:00Z"},"end":{"type":"string","format":"date-time","description":"End of metrics time range","example":"2025-01-15T23:59:59Z"}}},"metrics":{"type":"object","required":["totalActions","successfulActions","failedActions","retryingActions","averageResponseTime","errorBreakdown","actionTypeBreakdown"],"properties":{"totalActions":{"type":"integer","minimum":0,"description":"Total number of actions executed","example":150},"successfulActions":{"type":"integer","minimum":0,"description":"Number of successful actions","example":142},"failedActions":{"type":"integer","minimum":0,"description":"Number of failed actions","example":5},"retryingActions":{"type":"integer","minimum":0,"description":"Number of actions currently retrying","example":3},"averageResponseTime":{"type":"number","minimum":0,"description":"Average response time in milliseconds","example":1250.5},"errorBreakdown":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Count of errors by type","example":{"NETWORK_ERROR":3,"AUTHENTICATION_FAILED":1,"RATE_LIMITED":1}},"actionTypeBreakdown":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Count of actions by type","example":{"CREATE":75,"UPDATE":50,"DELETE":25}}}}}},"CreateWorkflowConditionRequest":{"type":"object","required":["name","condition"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for the condition","example":"Premium Customer Check"},"description":{"type":"string","maxLength":1000,"description":"Detailed description of what the condition checks","example":"Verifies if customer has premium status and high value"},"condition":{"type":"object","additionalProperties":true,"description":"JSONLogic condition definition","example":{"and":[{"==":[{"var":"customer.type"},"premium"]},{">":[{"var":"customer.value"},10000]}]}},"isActive":{"type":"boolean","default":true,"description":"Whether the condition is active","example":true},"priority":{"type":"integer","minimum":0,"maximum":100,"default":50,"description":"Priority for condition evaluation (0-100)","example":75},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for organizing conditions","example":["customer","premium","validation"]}}},"UpdateWorkflowConditionRequest":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for the condition","example":"Premium Customer Check v2"},"description":{"type":"string","maxLength":1000,"description":"Updated description of the condition","example":"Enhanced premium customer validation with regional criteria"},"condition":{"type":"object","additionalProperties":true,"description":"Updated JSONLogic condition definition","example":{"and":[{"==":[{"var":"customer.type"},"premium"]},{">":[{"var":"customer.value"},15000]},{"in":[{"var":"customer.region"},["EU","US"]]}]}},"isActive":{"type":"boolean","description":"Whether the condition is active","example":false},"priority":{"type":"integer","minimum":0,"maximum":100,"description":"Priority for condition evaluation (0-100)","example":80},"tags":{"type":"array","items":{"type":"string"},"description":"Updated tags for organizing conditions","example":["customer","premium","validation","regional"]}}},"WorkflowCondition":{"type":"object","required":["id","organizationId","name","condition","isActive","priority","tags","createdAt","updatedAt","createdBy","usageCount"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique condition identifier","example":"550e8400-e29b-41d4-a716-446655440005"},"organizationId":{"type":"string","format":"uuid","description":"Organization this condition belongs to","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Human-readable condition name","example":"Premium Customer Check"},"description":{"type":"string","description":"Detailed condition description","example":"Verifies if customer has premium status and high value"},"condition":{"type":"object","additionalProperties":true,"description":"JSONLogic condition definition","example":{"and":[{"==":[{"var":"customer.type"},"premium"]},{">":[{"var":"customer.value"},10000]}]}},"isActive":{"type":"boolean","description":"Whether the condition is currently active","example":true},"priority":{"type":"integer","minimum":0,"maximum":100,"description":"Evaluation priority (0-100)","example":75},"tags":{"type":"array","items":{"type":"string"},"description":"Organization tags","example":["customer","premium","validation"]},"createdAt":{"type":"string","format":"date-time","description":"When the condition was created","example":"2025-01-10T09:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the condition was last updated","example":"2025-01-14T14:30:00Z"},"createdBy":{"type":"string","format":"uuid","description":"User who created the condition","example":"550e8400-e29b-41d4-a716-446655440003"},"lastUsedAt":{"type":"string","format":"date-time","description":"When the condition was last evaluated","example":"2025-01-15T10:00:00Z"},"usageCount":{"type":"integer","minimum":0,"description":"Number of times condition has been evaluated","example":47}}},"EvaluateConditionRequest":{"type":"object","required":["condition","context"],"properties":{"condition":{"type":"object","additionalProperties":true,"description":"JSONLogic condition to evaluate","example":{"==":[{"var":"workflow.status"},"ACTIVE"]}},"context":{"type":"object","description":"Context data for condition evaluation","properties":{"workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440006"},"status":{"type":"string","example":"ACTIVE"},"entityType":{"type":"string","example":"customer"},"entityId":{"type":"string","example":"CUST-123"},"totalStages":{"type":"integer","example":5},"completedStages":{"type":"integer","example":2},"progressPercentage":{"type":"number","example":40}}},"stage":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"550e8400-e29b-41d4-a716-446655440007"},"code":{"type":"string","example":"approval"},"name":{"type":"string","example":"Document Approval"},"status":{"type":"string","example":"PENDING"},"isOptional":{"type":"boolean","example":false}}},"custom":{"type":"object","additionalProperties":true,"description":"Custom variables","example":{"priority":"high","customer_type":"premium"}}}},"options":{"type":"object","properties":{"skipCache":{"type":"boolean","default":false,"description":"Skip evaluation cache","example":false},"timeoutMs":{"type":"integer","minimum":10,"maximum":1000,"default":100,"description":"Evaluation timeout in milliseconds","example":100}}}}},"EvaluateConditionResponse":{"type":"object","required":["success","evaluation","validation","suggestions"],"properties":{"success":{"type":"boolean","description":"Whether the evaluation was successful","example":true},"evaluation":{"type":"object","required":["success","result","evaluationTimeMs"],"properties":{"success":{"type":"boolean","description":"Whether condition evaluation succeeded","example":true},"result":{"type":"boolean","description":"Result of condition evaluation","example":true},"evaluationTimeMs":{"type":"number","minimum":0,"description":"Time taken to evaluate condition","example":12.5},"error":{"type":"string","description":"Error message if evaluation failed","example":"Invalid operator in condition"}}},"validation":{"type":"object","required":["valid","errors","warnings","operators","complexity","maxDepth"],"properties":{"valid":{"type":"boolean","description":"Whether the condition syntax is valid","example":true},"errors":{"type":"array","items":{"type":"string"},"description":"Validation errors","example":[]},"warnings":{"type":"array","items":{"type":"string"},"description":"Validation warnings","example":["Complex nested condition may impact performance"]},"operators":{"type":"array","items":{"type":"string"},"description":"JSONLogic operators used","example":["==","and",">"]},"complexity":{"type":"integer","minimum":0,"description":"Condition complexity score","example":15},"maxDepth":{"type":"integer","minimum":0,"description":"Maximum nesting depth","example":3}}},"suggestions":{"type":"array","items":{"type":"string"},"description":"Optimization suggestions","example":["Consider simplifying nested conditions for better performance","Use index variables for frequent property access"]}}},"BulkEvaluateRequest":{"type":"object","required":["conditions","context"],"properties":{"conditions":{"type":"array","items":{"type":"object","required":["id","condition"],"properties":{"id":{"type":"string","description":"Unique identifier for this condition in the batch","example":"condition-1"},"condition":{"type":"object","additionalProperties":true,"description":"JSONLogic condition to evaluate","example":{"==":[{"var":"customer.type"},"premium"]}}}},"description":"Array of conditions to evaluate"},"context":{"type":"object","description":"Shared context data for all conditions","example":{"customer":{"type":"premium","value":15000},"workflow":{"status":"ACTIVE"}}},"options":{"type":"object","properties":{"stopOnFirstFailure":{"type":"boolean","default":false,"description":"Stop evaluation on first error","example":false},"maxConcurrency":{"type":"integer","minimum":1,"maximum":10,"default":5,"description":"Maximum concurrent evaluations","example":3},"timeoutMs":{"type":"integer","minimum":10,"maximum":5000,"default":1000,"description":"Total timeout for all evaluations","example":2000}}}}},"BulkEvaluateResponse":{"type":"object","required":["success","results","summary"],"properties":{"success":{"type":"boolean","description":"Whether bulk evaluation completed successfully","example":true},"results":{"type":"array","items":{"type":"object","required":["id","evaluation"],"properties":{"id":{"type":"string","description":"Condition identifier from request","example":"condition-1"},"evaluation":{"type":"object","required":["success","result","evaluationTimeMs"],"properties":{"success":{"type":"boolean","description":"Whether this condition evaluation succeeded","example":true},"result":{"type":"boolean","description":"Result of condition evaluation","example":true},"evaluationTimeMs":{"type":"number","minimum":0,"description":"Time taken for this evaluation","example":8.2},"error":{"type":"string","description":"Error message if evaluation failed","example":"Variable not found in context"}}}}},"description":"Results for each condition"},"summary":{"type":"object","required":["total","successful","failed","truthy","falsy","totalEvaluationTimeMs"],"properties":{"total":{"type":"integer","minimum":0,"description":"Total number of conditions evaluated","example":5},"successful":{"type":"integer","minimum":0,"description":"Number of successful evaluations","example":4},"failed":{"type":"integer","minimum":0,"description":"Number of failed evaluations","example":1},"truthy":{"type":"integer","minimum":0,"description":"Number of conditions that evaluated to true","example":3},"falsy":{"type":"integer","minimum":0,"description":"Number of conditions that evaluated to false","example":1},"totalEvaluationTimeMs":{"type":"number","minimum":0,"description":"Total time for all evaluations","example":45.7}}}}},"ComplexityMetrics":{"type":"object","required":["overall","breakdown","riskFactors","suggestions","performanceWarnings"],"properties":{"overall":{"type":"object","required":["complexity","maxDepth","operatorCount","variableCount","literalCount"],"properties":{"complexity":{"type":"integer","minimum":0,"description":"Overall complexity score","example":25},"maxDepth":{"type":"integer","minimum":0,"description":"Maximum nesting depth","example":4},"operatorCount":{"type":"integer","minimum":0,"description":"Total number of operators","example":8},"variableCount":{"type":"integer","minimum":0,"description":"Number of unique variables referenced","example":6},"literalCount":{"type":"integer","minimum":0,"description":"Number of literal values","example":10}}},"breakdown":{"type":"object","required":["logicalOperators","comparisonOperators","arithmeticOperators","arrayOperators","stringOperators","conditionalOperators"],"properties":{"logicalOperators":{"type":"integer","minimum":0,"description":"Count of logical operators (and, or, not)","example":3},"comparisonOperators":{"type":"integer","minimum":0,"description":"Count of comparison operators (==, >, <, etc.)","example":4},"arithmeticOperators":{"type":"integer","minimum":0,"description":"Count of arithmetic operators (+, -, *, /)","example":1},"arrayOperators":{"type":"integer","minimum":0,"description":"Count of array operators (in, map, filter)","example":2},"stringOperators":{"type":"integer","minimum":0,"description":"Count of string operators (substr, cat)","example":0},"conditionalOperators":{"type":"integer","minimum":0,"description":"Count of conditional operators (if)","example":1}}},"riskFactors":{"type":"object","required":["deepNesting","manyVariables","complexArithmetic","recursiveStructure"],"properties":{"deepNesting":{"type":"boolean","description":"Condition has deep nesting (>5 levels)","example":false},"manyVariables":{"type":"boolean","description":"Uses many variables (>10)","example":false},"complexArithmetic":{"type":"boolean","description":"Contains complex arithmetic operations","example":false},"recursiveStructure":{"type":"boolean","description":"Has potentially recursive patterns","example":false}}},"suggestions":{"type":"array","items":{"type":"string"},"description":"Optimization suggestions","example":["Consider breaking complex condition into smaller parts","Use variables for repeated calculations"]},"performanceWarnings":{"type":"array","items":{"type":"string"},"description":"Performance-related warnings","example":["Deep nesting may slow evaluation","Many variables increase memory usage"]}}},"AddMemberRequest":{"type":"object","required":["userId","role"],"properties":{"userId":{"type":"string","format":"uuid","description":"User to add as member","example":"550e8400-e29b-41d4-a716-446655440008"},"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER"],"description":"Role to assign to the user","example":"MEMBER"},"permissions":{"type":"array","items":{"type":"string"},"description":"Specific permissions to grant","example":["TASK_CREATE","TASK_UPDATE","COMMENT_CREATE"]},"inviteMessage":{"type":"string","maxLength":500,"description":"Optional invitation message","example":"Welcome to the project team! Looking forward to working with you."},"sendNotification":{"type":"boolean","default":true,"description":"Whether to send invitation notification","example":true}}},"UpdateMemberRequest":{"type":"object","minProperties":1,"properties":{"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER"],"description":"Updated role for the member","example":"ADMIN"},"permissions":{"type":"array","items":{"type":"string"},"description":"Updated permissions list","example":["TASK_CREATE","TASK_UPDATE","TASK_DELETE","PROJECT_UPDATE"]},"isActive":{"type":"boolean","description":"Whether the member is active","example":false},"notificationPreferences":{"type":"object","properties":{"emailUpdates":{"type":"boolean","description":"Receive email updates","example":true},"taskAssignments":{"type":"boolean","description":"Notifications for task assignments","example":true},"deadlineReminders":{"type":"boolean","description":"Deadline reminder notifications","example":true},"workflowUpdates":{"type":"boolean","description":"Workflow status update notifications","example":false}}}}},"CollaborationMember":{"type":"object","required":["id","userId","user","organizationId","entityType","entityId","role","permissions","isActive","joinedAt","invitedBy","notificationPreferences"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique member identifier","example":"550e8400-e29b-41d4-a716-446655440009"},"userId":{"type":"string","format":"uuid","description":"User identifier","example":"550e8400-e29b-41d4-a716-446655440008"},"user":{"type":"object","required":["id","name","email"],"properties":{"id":{"type":"string","format":"uuid","description":"User identifier","example":"550e8400-e29b-41d4-a716-446655440008"},"name":{"type":"string","description":"User full name","example":"John Doe"},"email":{"type":"string","format":"email","description":"User email address","example":"john.doe@example.com"},"avatar":{"type":"string","format":"uri","description":"User avatar image URL","example":"https://example.com/avatars/john-doe.jpg"}}},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440004"},"entityType":{"type":"string","enum":["PROJECT","TASK","WORKFLOW","SECTION"],"description":"Type of entity the member has access to","example":"PROJECT"},"entityId":{"type":"string","format":"uuid","description":"Identifier of the entity","example":"550e8400-e29b-41d4-a716-446655440010"},"role":{"type":"string","enum":["OWNER","ADMIN","MEMBER","VIEWER"],"description":"Member role","example":"MEMBER"},"permissions":{"type":"array","items":{"type":"string"},"description":"Specific permissions granted","example":["TASK_CREATE","TASK_UPDATE","COMMENT_CREATE"]},"isActive":{"type":"boolean","description":"Whether the member is currently active","example":true},"joinedAt":{"type":"string","format":"date-time","description":"When the member joined","example":"2025-01-10T08:00:00Z"},"lastActiveAt":{"type":"string","format":"date-time","description":"When the member was last active","example":"2025-01-15T16:30:00Z"},"invitedBy":{"type":"string","format":"uuid","description":"User who invited this member","example":"550e8400-e29b-41d4-a716-446655440003"},"notificationPreferences":{"type":"object","required":["emailUpdates","taskAssignments","deadlineReminders","workflowUpdates"],"properties":{"emailUpdates":{"type":"boolean","description":"Receive email updates","example":true},"taskAssignments":{"type":"boolean","description":"Notifications for task assignments","example":true},"deadlineReminders":{"type":"boolean","description":"Deadline reminder notifications","example":true},"workflowUpdates":{"type":"boolean","description":"Workflow status update notifications","example":false}}}}},"CollaborationActivity":{"type":"object","required":["id","organizationId","entityType","entityId","userId","user","activityType","description","timestamp","isVisible"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique activity identifier","example":"550e8400-e29b-41d4-a716-446655440011"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440004"},"entityType":{"type":"string","enum":["PROJECT","TASK","WORKFLOW","SECTION"],"description":"Type of entity the activity relates to","example":"TASK"},"entityId":{"type":"string","format":"uuid","description":"Identifier of the related entity","example":"550e8400-e29b-41d4-a716-446655440012"},"userId":{"type":"string","format":"uuid","description":"User who performed the activity","example":"550e8400-e29b-41d4-a716-446655440008"},"user":{"type":"object","required":["id","name","email"],"properties":{"id":{"type":"string","format":"uuid","description":"User identifier","example":"550e8400-e29b-41d4-a716-446655440008"},"name":{"type":"string","description":"User full name","example":"John Doe"},"email":{"type":"string","format":"email","description":"User email address","example":"john.doe@example.com"},"avatar":{"type":"string","format":"uri","description":"User avatar image URL","example":"https://example.com/avatars/john-doe.jpg"}}},"activityType":{"type":"string","enum":["JOINED","LEFT","ROLE_CHANGED","PERMISSIONS_UPDATED","INVITED","TASK_ASSIGNED","TASK_COMPLETED","COMMENT_ADDED","FILE_UPLOADED","STATUS_CHANGED"],"description":"Type of activity performed","example":"TASK_COMPLETED"},"description":{"type":"string","description":"Human-readable activity description","example":"John Doe completed task \"Review documentation\""},"metadata":{"type":"object","properties":{"oldValue":{"type":"object","additionalProperties":true,"description":"Previous value before change","example":{"status":"IN_PROGRESS"}},"newValue":{"type":"object","additionalProperties":true,"description":"New value after change","example":{"status":"COMPLETED"}},"targetUserId":{"type":"string","format":"uuid","description":"Target user for user-related activities","example":"550e8400-e29b-41d4-a716-446655440013"},"targetEntityId":{"type":"string","format":"uuid","description":"Target entity for entity-related activities","example":"550e8400-e29b-41d4-a716-446655440014"},"changeReason":{"type":"string","description":"Reason for the change","example":"All requirements have been met"}}},"timestamp":{"type":"string","format":"date-time","description":"When the activity occurred","example":"2025-01-15T14:30:00Z"},"isVisible":{"type":"boolean","description":"Whether the activity is visible to members","example":true}}},"FileUploadRequest":{"type":"object","required":["file","filename","mimeType","entityType","entityId"],"properties":{"file":{"type":"string","format":"binary","description":"File data to upload"},"filename":{"type":"string","minLength":1,"maxLength":255,"description":"Original filename with extension","example":"document.pdf"},"mimeType":{"type":"string","description":"MIME type of the file","example":"application/pdf"},"entityType":{"type":"string","enum":["PROJECT","TASK","WORKFLOW","SECTION"],"description":"Type of entity to attach file to","example":"TASK"},"entityId":{"type":"string","format":"uuid","description":"ID of entity to attach file to","example":"550e8400-e29b-41d4-a716-446655440015"},"description":{"type":"string","maxLength":1000,"description":"Optional file description","example":"Project requirements document"},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for organizing files","example":["requirements","documentation","official"]},"isPublic":{"type":"boolean","default":false,"description":"Whether file is publicly accessible","example":false},"processingOptions":{"type":"object","properties":{"generateThumbnail":{"type":"boolean","default":true,"description":"Generate thumbnail for images","example":true},"extractText":{"type":"boolean","default":true,"description":"Extract text from PDFs/documents","example":true},"thumbnailSize":{"type":"string","enum":["small","medium","large"],"default":"medium","description":"Size of generated thumbnail","example":"medium"},"compressionQuality":{"type":"integer","minimum":1,"maximum":100,"default":85,"description":"Image compression quality (1-100)","example":85}}}}},"FileMetadata":{"type":"object","required":["id","filename","mimeType","sizeBytes","entityType","entityId","organizationId","downloadUrl","checksumSha256","uploadedBy","createdAt","processingStatus","virusScanStatus"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique file identifier","example":"550e8400-e29b-41d4-a716-446655440016"},"filename":{"type":"string","description":"Original filename","example":"project-requirements.pdf"},"mimeType":{"type":"string","description":"MIME type of the file","example":"application/pdf"},"sizeBytes":{"type":"integer","minimum":0,"description":"File size in bytes","example":2048576},"entityType":{"type":"string","enum":["PROJECT","TASK","WORKFLOW","SECTION"],"description":"Type of entity file is attached to","example":"TASK"},"entityId":{"type":"string","format":"uuid","description":"ID of entity file is attached to","example":"550e8400-e29b-41d4-a716-446655440015"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns the file","example":"550e8400-e29b-41d4-a716-446655440004"},"description":{"type":"string","description":"File description","example":"Updated project requirements document"},"tags":{"type":"array","items":{"type":"string"},"description":"File organization tags","example":["requirements","documentation","official"]},"isPublic":{"type":"boolean","description":"Whether file is publicly accessible","example":false},"downloadUrl":{"type":"string","format":"uri","description":"Signed URL for downloading the file","example":"https://storage.googleapis.com/bucket/files/550e8400.pdf?expires=1642680000"},"thumbnailUrl":{"type":"string","format":"uri","description":"URL for file thumbnail (if available)","example":"https://storage.googleapis.com/bucket/thumbnails/550e8400.jpg"},"previewUrl":{"type":"string","format":"uri","description":"URL for file preview (if available)","example":"https://storage.googleapis.com/bucket/previews/550e8400.jpg"},"checksumSha256":{"type":"string","description":"SHA256 checksum of the file","example":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"},"storageLocation":{"type":"string","description":"Internal storage location","example":"gs://tasks-attachments/550e8400-e29b-41d4-a716-446655440016.pdf"},"accessCount":{"type":"integer","minimum":0,"description":"Number of times file has been accessed","example":12},"lastAccessedAt":{"type":"string","format":"date-time","description":"When file was last accessed","example":"2025-01-15T11:00:00Z"},"uploadedBy":{"type":"string","format":"uuid","description":"User who uploaded the file","example":"550e8400-e29b-41d4-a716-446655440008"},"createdAt":{"type":"string","format":"date-time","description":"When file was uploaded","example":"2025-01-15T09:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When file metadata was last updated","example":"2025-01-15T09:05:00Z"},"processingStatus":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED"],"description":"File processing status","example":"COMPLETED"},"processingMetadata":{"type":"object","properties":{"thumbnailGenerated":{"type":"boolean","description":"Whether thumbnail was generated","example":true},"textExtracted":{"type":"boolean","description":"Whether text was extracted","example":true},"previewGenerated":{"type":"boolean","description":"Whether preview was generated","example":false},"processingTimeMs":{"type":"integer","minimum":0,"description":"Processing time in milliseconds","example":2500},"processorUsed":{"type":"string","description":"Name of processor used","example":"pdf-processor"},"extractedText":{"type":"string","description":"Extracted text content (if applicable)","example":"Project Requirements Document..."},"pageCount":{"type":"integer","minimum":0,"description":"Number of pages (for documents)","example":15},"dimensions":{"type":"object","properties":{"width":{"type":"integer","minimum":0,"description":"Width in pixels (for images)","example":1920},"height":{"type":"integer","minimum":0,"description":"Height in pixels (for images)","example":1080}}}}},"virusScanStatus":{"type":"string","enum":["PENDING","CLEAN","INFECTED","FAILED"],"description":"Virus scan status","example":"CLEAN"},"expiresAt":{"type":"string","format":"date-time","description":"When file access expires (if applicable)","example":"2025-06-15T09:00:00Z"}}},"FileSharingRequest":{"type":"object","required":["fileId"],"properties":{"fileId":{"type":"string","format":"uuid","description":"ID of file to share","example":"550e8400-e29b-41d4-a716-446655440016"},"shareWith":{"type":"array","items":{"type":"object","required":["userId","permissions"],"properties":{"userId":{"type":"string","format":"uuid","description":"User to share with","example":"550e8400-e29b-41d4-a716-446655440017"},"permissions":{"type":"string","enum":["VIEW","DOWNLOAD","EDIT"],"description":"Permission level for the user","example":"DOWNLOAD"}}},"description":"List of users to share with"},"makePublic":{"type":"boolean","default":false,"description":"Make file publicly accessible","example":false},"expirationDate":{"type":"string","format":"date-time","description":"When sharing access expires","example":"2025-02-15T09:00:00Z"},"requireAuthentication":{"type":"boolean","default":true,"description":"Require authentication to access","example":true},"allowDownload":{"type":"boolean","default":true,"description":"Allow downloading the file","example":true},"watermarkText":{"type":"string","maxLength":100,"description":"Watermark text to add to file","example":"CONFIDENTIAL - Property of Acme Corp"},"accessPassword":{"type":"string","minLength":8,"description":"Password required to access file","example":"securePassword123"},"maxDownloads":{"type":"integer","minimum":1,"description":"Maximum number of downloads allowed","example":10},"notifyOnAccess":{"type":"boolean","default":false,"description":"Send notification when file is accessed","example":true}}},"NotificationPreferences":{"type":"object","required":["id","userId","organizationId","emailNotifications","inAppNotifications","smsNotifications","pushNotifications","quietHours","frequency","language","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique preferences identifier","example":"550e8400-e29b-41d4-a716-446655440018"},"userId":{"type":"string","format":"uuid","description":"User these preferences belong to","example":"550e8400-e29b-41d4-a716-446655440008"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440004"},"emailNotifications":{"type":"object","required":["taskAssignments","deadlineReminders","workflowUpdates","projectInvitations","commentMentions","statusChanges"],"properties":{"taskAssignments":{"type":"boolean","description":"Email for task assignments","example":true},"deadlineReminders":{"type":"boolean","description":"Email for deadline reminders","example":true},"workflowUpdates":{"type":"boolean","description":"Email for workflow updates","example":false},"projectInvitations":{"type":"boolean","description":"Email for project invitations","example":true},"commentMentions":{"type":"boolean","description":"Email when mentioned in comments","example":true},"statusChanges":{"type":"boolean","description":"Email for status changes","example":false}}},"inAppNotifications":{"type":"object","required":["taskAssignments","deadlineReminders","workflowUpdates","projectInvitations","commentMentions","statusChanges"],"properties":{"taskAssignments":{"type":"boolean","description":"In-app notifications for task assignments","example":true},"deadlineReminders":{"type":"boolean","description":"In-app notifications for deadline reminders","example":true},"workflowUpdates":{"type":"boolean","description":"In-app notifications for workflow updates","example":true},"projectInvitations":{"type":"boolean","description":"In-app notifications for project invitations","example":true},"commentMentions":{"type":"boolean","description":"In-app notifications when mentioned","example":true},"statusChanges":{"type":"boolean","description":"In-app notifications for status changes","example":true}}},"smsNotifications":{"type":"object","required":["urgentTasks","deadlineAlerts","workflowFailures"],"properties":{"urgentTasks":{"type":"boolean","description":"SMS for urgent tasks","example":true},"deadlineAlerts":{"type":"boolean","description":"SMS for approaching deadlines","example":true},"workflowFailures":{"type":"boolean","description":"SMS for workflow failures","example":true}}},"pushNotifications":{"type":"object","required":["enabled","taskAssignments","deadlineReminders","commentMentions"],"properties":{"enabled":{"type":"boolean","description":"Whether push notifications are enabled","example":true},"taskAssignments":{"type":"boolean","description":"Push notifications for task assignments","example":true},"deadlineReminders":{"type":"boolean","description":"Push notifications for deadline reminders","example":true},"commentMentions":{"type":"boolean","description":"Push notifications when mentioned","example":true}}},"quietHours":{"type":"object","required":["enabled","startTime","endTime","timezone","weekdaysOnly"],"properties":{"enabled":{"type":"boolean","description":"Whether quiet hours are enabled","example":true},"startTime":{"type":"string","pattern":"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Start time for quiet hours (HH:MM)","example":"22:00"},"endTime":{"type":"string","pattern":"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$","description":"End time for quiet hours (HH:MM)","example":"08:00"},"timezone":{"type":"string","description":"Timezone for quiet hours","example":"Europe/Oslo"},"weekdaysOnly":{"type":"boolean","description":"Apply quiet hours only on weekdays","example":false}}},"frequency":{"type":"object","required":["immediate","hourly","daily","weekly"],"properties":{"immediate":{"type":"boolean","description":"Send notifications immediately","example":true},"hourly":{"type":"boolean","description":"Send hourly digest","example":false},"daily":{"type":"boolean","description":"Send daily digest","example":false},"weekly":{"type":"boolean","description":"Send weekly digest","example":false},"digestTime":{"type":"string","pattern":"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Time to send daily/weekly digest (HH:MM)","example":"09:00"}}},"language":{"type":"string","description":"Preferred language for notifications","example":"en"},"createdAt":{"type":"string","format":"date-time","description":"When preferences were created","example":"2025-01-10T08:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When preferences were last updated","example":"2025-01-15T10:00:00Z"}}},"NotificationChannel":{"type":"object","required":["id","organizationId","name","type","isActive","configuration","eventFilters","rateLimiting","createdAt","updatedAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique channel identifier","example":"550e8400-e29b-41d4-a716-446655440019"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this channel","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Human-readable channel name","example":"Project Team Slack"},"type":{"type":"string","enum":["EMAIL","SLACK","TEAMS","WEBHOOK","SMS","PUSH"],"description":"Type of notification channel","example":"SLACK"},"isActive":{"type":"boolean","description":"Whether the channel is currently active","example":true},"configuration":{"type":"object","description":"Channel-specific configuration","properties":{"smtpHost":{"type":"string","description":"SMTP host for email","example":"smtp.gmail.com"},"slackWebhookUrl":{"type":"string","format":"uri","description":"Slack webhook URL","example":"https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX"},"slackChannel":{"type":"string","description":"Slack channel name","example":"#project-notifications"},"webhookUrl":{"type":"string","format":"uri","description":"Generic webhook URL","example":"https://api.example.com/webhooks/notifications"},"smsProvider":{"type":"string","enum":["TWILIO","SENDGRID"],"description":"SMS service provider","example":"TWILIO"}},"additionalProperties":true},"eventFilters":{"type":"object","required":["eventTypes","entityTypes","priorities","userRoles"],"properties":{"eventTypes":{"type":"array","items":{"type":"string"},"description":"Event types to send notifications for","example":["TASK_ASSIGNED","DEADLINE_REMINDER","WORKFLOW_COMPLETED"]},"entityTypes":{"type":"array","items":{"type":"string"},"description":"Entity types to filter by","example":["TASK","PROJECT"]},"priorities":{"type":"array","items":{"type":"string"},"description":"Priority levels to filter by","example":["HIGH","URGENT"]},"userRoles":{"type":"array","items":{"type":"string"},"description":"User roles to filter by","example":["ADMIN","MANAGER"]}}},"rateLimiting":{"type":"object","required":["maxPerMinute","maxPerHour","maxPerDay"],"properties":{"maxPerMinute":{"type":"integer","minimum":1,"description":"Maximum notifications per minute","example":10},"maxPerHour":{"type":"integer","minimum":1,"description":"Maximum notifications per hour","example":100},"maxPerDay":{"type":"integer","minimum":1,"description":"Maximum notifications per day","example":1000}}},"lastUsedAt":{"type":"string","format":"date-time","description":"When channel was last used","example":"2025-01-15T14:00:00Z"},"createdAt":{"type":"string","format":"date-time","description":"When channel was created","example":"2025-01-10T08:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When channel was last updated","example":"2025-01-14T16:00:00Z"},"createdBy":{"type":"string","format":"uuid","description":"User who created the channel","example":"550e8400-e29b-41d4-a716-446655440003"}}},"NotificationTemplate":{"type":"object","required":["id","organizationId","name","eventType","channelType","isActive","template","formatting","localization","scheduling","analytics","createdAt","updatedAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique template identifier","example":"550e8400-e29b-41d4-a716-446655440020"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this template","example":"550e8400-e29b-41d4-a716-446655440004"},"name":{"type":"string","description":"Human-readable template name","example":"Task Assignment Email Template"},"description":{"type":"string","description":"Template description","example":"Email template for notifying users about new task assignments"},"eventType":{"type":"string","enum":["TASK_ASSIGNED","TASK_COMPLETED","TASK_OVERDUE","WORKFLOW_STARTED","WORKFLOW_COMPLETED","PROJECT_CREATED","COMMENT_MENTION","DEADLINE_REMINDER","STATUS_CHANGED"],"description":"Event type this template handles","example":"TASK_ASSIGNED"},"channelType":{"type":"string","enum":["EMAIL","SLACK","TEAMS","WEBHOOK","SMS","PUSH","IN_APP"],"description":"Channel type this template is for","example":"EMAIL"},"isActive":{"type":"boolean","description":"Whether template is currently active","example":true},"template":{"type":"object","required":["bodyText","variables"],"properties":{"subject":{"type":"string","description":"Subject line (for email/push)","example":"New Task Assigned: {{task.title}}"},"bodyText":{"type":"string","description":"Plain text content","example":"You have been assigned a new task: {{task.title}}. Due date: {{task.dueDate}}"},"bodyHtml":{"type":"string","description":"HTML content (for email)","example":"<h2>New Task Assignment</h2><p>You have been assigned: <strong>{{task.title}}</strong></p>"},"variables":{"type":"array","items":{"type":"string"},"description":"Available template variables","example":["task.title","task.dueDate","assignee.name","project.name"]}}},"formatting":{"type":"object","properties":{"useMarkdown":{"type":"boolean","description":"Use Markdown formatting","example":true},"includeAttachments":{"type":"boolean","description":"Include file attachments","example":false},"includeActionButtons":{"type":"boolean","description":"Include action buttons","example":true},"actionButtons":{"type":"array","items":{"type":"object","required":["text","url","style"],"properties":{"text":{"type":"string","description":"Button text","example":"View Task"},"url":{"type":"string","format":"uri","description":"Button URL","example":"https://app.example.com/tasks/{{task.id}}"},"style":{"type":"string","enum":["PRIMARY","SECONDARY","DANGER"],"description":"Button style","example":"PRIMARY"}}},"description":"Action buttons to include"}}},"localization":{"type":"object","additionalProperties":{"type":"object","properties":{"subject":{"type":"string","description":"Localized subject"},"bodyText":{"type":"string","description":"Localized body text"},"bodyHtml":{"type":"string","description":"Localized body HTML"}}},"description":"Localized versions of the template","example":{"no":{"subject":"Ny oppgave tildelt: {{task.title}}","bodyText":"Du har fått tildelt en ny oppgave: {{task.title}}"}}},"scheduling":{"type":"object","required":["immediate"],"properties":{"immediate":{"type":"boolean","description":"Send notification immediately","example":true},"delayMinutes":{"type":"integer","minimum":0,"description":"Delay before sending (minutes)","example":15},"retryPolicy":{"type":"object","required":["maxRetries","backoffMultiplier","initialDelayMinutes"],"properties":{"maxRetries":{"type":"integer","minimum":0,"description":"Maximum retry attempts","example":3},"backoffMultiplier":{"type":"number","minimum":1,"description":"Backoff multiplier for retries","example":2},"initialDelayMinutes":{"type":"integer","minimum":1,"description":"Initial delay before first retry","example":5}}}}},"analytics":{"type":"object","required":["sentCount","deliveredCount","failedCount","clickCount"],"properties":{"sentCount":{"type":"integer","minimum":0,"description":"Total notifications sent","example":1250},"deliveredCount":{"type":"integer","minimum":0,"description":"Successfully delivered notifications","example":1200},"failedCount":{"type":"integer","minimum":0,"description":"Failed notification deliveries","example":50},"clickCount":{"type":"integer","minimum":0,"description":"Number of clicks on notification links","example":450},"lastSentAt":{"type":"string","format":"date-time","description":"When last notification was sent","example":"2025-01-15T16:00:00Z"}}},"createdAt":{"type":"string","format":"date-time","description":"When template was created","example":"2025-01-05T10:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When template was last updated","example":"2025-01-14T15:00:00Z"},"createdBy":{"type":"string","format":"uuid","description":"User who created the template","example":"550e8400-e29b-41d4-a716-446655440003"}}},"CreateTemplateRequest":{"type":"object","required":["name","category","templateData"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable template name","example":"Real Estate Task Template"},"description":{"type":"string","maxLength":1000,"description":"Template description","example":"Template for creating standard real estate transaction tasks"},"category":{"type":"string","enum":["TASK","WORKFLOW","PROJECT","FORM"],"description":"Type of template","example":"TASK"},"tags":{"type":"array","items":{"type":"string"},"description":"Tags for organizing templates","example":["real-estate","transaction","standard"]},"templateData":{"type":"object","additionalProperties":true,"description":"Template-specific data structure","example":{"title":"Property Inspection - {{property.address}}","description":"Conduct thorough inspection of {{property.type}}","estimatedDuration":120,"checklist":["Exterior inspection","Interior inspection","Documentation"]}},"isPublic":{"type":"boolean","default":false,"description":"Whether template is publicly available","example":false},"defaultAssigneeRole":{"type":"string","description":"Default role for task assignment","example":"inspector"},"estimatedDurationMinutes":{"type":"integer","minimum":1,"description":"Estimated completion time in minutes","example":120},"prerequisites":{"type":"array","items":{"type":"string"},"description":"Prerequisites before using template","example":["Property access arranged","Inspection tools available"]},"successCriteria":{"type":"array","items":{"type":"string"},"description":"Criteria for successful completion","example":["All areas inspected","Report completed","Photos uploaded"]},"variables":{"type":"array","items":{"type":"object","required":["name","type","required"],"properties":{"name":{"type":"string","description":"Variable name","example":"property.address"},"type":{"type":"string","enum":["TEXT","NUMBER","DATE","BOOLEAN","SELECT","MULTI_SELECT"],"description":"Variable data type","example":"TEXT"},"required":{"type":"boolean","description":"Whether variable is required","example":true},"defaultValue":{"description":"Default value for the variable","example":"Standard property"},"options":{"type":"array","items":{"type":"string"},"description":"Options for SELECT/MULTI_SELECT types","example":["house","apartment","commercial"]},"description":{"type":"string","description":"Variable description","example":"Property address for inspection"},"validation":{"type":"object","properties":{"min":{"type":"number","description":"Minimum value (for numbers)","example":1},"max":{"type":"number","description":"Maximum value (for numbers)","example":1000},"pattern":{"type":"string","description":"Regex pattern for validation","example":"^[A-Za-z0-9\\s,.-]+$"},"customValidation":{"type":"string","description":"Custom validation logic","example":"address.length > 10"}}}}},"description":"Template variables and their configuration"}}},"UpdateTemplateRequest":{"type":"object","minProperties":1,"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Updated template name","example":"Enhanced Real Estate Task Template"},"description":{"type":"string","maxLength":1000,"description":"Updated template description","example":"Enhanced template with additional validation steps"},"category":{"type":"string","enum":["TASK","WORKFLOW","PROJECT","FORM"],"description":"Updated template category","example":"WORKFLOW"},"tags":{"type":"array","items":{"type":"string"},"description":"Updated tags","example":["real-estate","transaction","enhanced","validation"]},"templateData":{"type":"object","additionalProperties":true,"description":"Updated template data structure","example":{"title":"Enhanced Property Inspection - {{property.address}}","stages":["Pre-inspection","Inspection","Post-inspection"]}},"isPublic":{"type":"boolean","description":"Whether template should be public","example":true},"isActive":{"type":"boolean","description":"Whether template is active","example":true},"defaultAssigneeRole":{"type":"string","description":"Updated default assignee role","example":"senior-inspector"},"estimatedDurationMinutes":{"type":"integer","minimum":1,"description":"Updated estimated duration","example":180},"prerequisites":{"type":"array","items":{"type":"string"},"description":"Updated prerequisites","example":["Property access confirmed","Inspection tools ready","Weather conditions suitable"]},"successCriteria":{"type":"array","items":{"type":"string"},"description":"Updated success criteria","example":["Comprehensive inspection completed","Quality report generated","Client notification sent"]},"variables":{"type":"array","items":{"type":"object","required":["name","type","required"],"properties":{"name":{"type":"string","description":"Variable name","example":"property.type"},"type":{"type":"string","enum":["TEXT","NUMBER","DATE","BOOLEAN","SELECT","MULTI_SELECT"],"description":"Variable data type","example":"SELECT"},"required":{"type":"boolean","description":"Whether variable is required","example":true},"defaultValue":{"description":"Default value for the variable","example":"house"},"options":{"type":"array","items":{"type":"string"},"description":"Options for SELECT types","example":["house","apartment","commercial","land"]},"description":{"type":"string","description":"Variable description","example":"Type of property being inspected"},"validation":{"type":"object","properties":{"min":{"type":"number","description":"Minimum value"},"max":{"type":"number","description":"Maximum value"},"pattern":{"type":"string","description":"Validation pattern"},"customValidation":{"type":"string","description":"Custom validation logic"}}}}},"description":"Updated template variables"}}},"TemplateInstance":{"type":"object","required":["id","templateId","template","organizationId","instanceName","entityType","entityId","status","variableValues","resolvedTemplate","metadata","createdAt","updatedAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique instance identifier","example":"550e8400-e29b-41d4-a716-446655440021"},"templateId":{"type":"string","format":"uuid","description":"Template this instance was created from","example":"550e8400-e29b-41d4-a716-446655440022"},"template":{"type":"object","required":["id","name","category","version"],"properties":{"id":{"type":"string","format":"uuid","description":"Template identifier","example":"550e8400-e29b-41d4-a716-446655440022"},"name":{"type":"string","description":"Template name at time of instantiation","example":"Real Estate Task Template"},"category":{"type":"string","enum":["TASK","WORKFLOW","PROJECT","FORM"],"description":"Template category","example":"TASK"},"version":{"type":"integer","minimum":1,"description":"Template version used","example":2}}},"organizationId":{"type":"string","format":"uuid","description":"Organization that created this instance","example":"550e8400-e29b-41d4-a716-446655440004"},"instanceName":{"type":"string","description":"Human-readable name for this instance","example":"Property Inspection for 123 Main St"},"description":{"type":"string","description":"Instance description","example":"Inspection task created from template for residential property"},"entityType":{"type":"string","enum":["TASK","WORKFLOW","PROJECT"],"description":"Type of entity created from template","example":"TASK"},"entityId":{"type":"string","format":"uuid","description":"ID of the created entity","example":"550e8400-e29b-41d4-a716-446655440023"},"status":{"type":"string","enum":["PENDING","CREATING","CREATED","FAILED"],"description":"Instance creation status","example":"CREATED"},"variableValues":{"type":"object","additionalProperties":true,"description":"Values provided for template variables","example":{"property.address":"123 Main Street, Oslo","property.type":"house","inspector.name":"John Doe"}},"resolvedTemplate":{"type":"object","additionalProperties":true,"description":"Template with variables resolved","example":{"title":"Property Inspection - 123 Main Street, Oslo","description":"Conduct thorough inspection of house","assignedTo":"John Doe"}},"creationResult":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether creation was successful","example":true},"createdEntities":{"type":"array","items":{"type":"object","required":["type","id","name"],"properties":{"type":{"type":"string","description":"Type of created entity","example":"TASK"},"id":{"type":"string","format":"uuid","description":"ID of created entity","example":"550e8400-e29b-41d4-a716-446655440023"},"name":{"type":"string","description":"Name of created entity","example":"Property Inspection - 123 Main Street"}}},"description":"Entities created from template"},"errors":{"type":"array","items":{"type":"string"},"description":"Creation errors if any","example":[]},"warnings":{"type":"array","items":{"type":"string"},"description":"Creation warnings","example":["Default assignee not found, assigned to template creator"]}}},"metadata":{"type":"object","required":["triggerType"],"properties":{"triggerType":{"type":"string","enum":["MANUAL","WORKFLOW","AUTOMATION","API"],"description":"How template instantiation was triggered","example":"MANUAL"},"triggerSource":{"type":"string","description":"Source that triggered instantiation","example":"web-ui"},"parentEntityType":{"type":"string","description":"Parent entity type if triggered from another entity","example":"PROJECT"},"parentEntityId":{"type":"string","format":"uuid","description":"Parent entity ID","example":"550e8400-e29b-41d4-a716-446655440024"},"estimatedCompletionTime":{"type":"string","format":"date-time","description":"When creation was estimated to complete","example":"2025-01-15T10:05:00Z"},"actualCompletionTime":{"type":"string","format":"date-time","description":"When creation actually completed","example":"2025-01-15T10:03:30Z"},"processingTimeMs":{"type":"integer","minimum":0,"description":"Time taken to process template","example":1500}}},"createdAt":{"type":"string","format":"date-time","description":"When instance was created","example":"2025-01-15T10:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When instance was last updated","example":"2025-01-15T10:03:30Z"},"createdBy":{"type":"string","format":"uuid","description":"User who created the instance","example":"550e8400-e29b-41d4-a716-446655440008"},"completedAt":{"type":"string","format":"date-time","description":"When instance creation completed","example":"2025-01-15T10:03:30Z"}}},"BulkOperationRequest":{"type":"object","required":["operation","entityType","entityIds"],"properties":{"operation":{"type":"string","enum":["UPDATE","DELETE","ARCHIVE","RESTORE","ASSIGN","STATUS_CHANGE","TAG_ADD","TAG_REMOVE","MOVE","DUPLICATE"],"description":"Type of bulk operation to perform","example":"STATUS_CHANGE"},"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW","SECTION"],"description":"Type of entities to operate on","example":"TASK"},"entityIds":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":1000,"description":"IDs of entities to operate on","example":["550e8400-e29b-41d4-a716-446655440025","550e8400-e29b-41d4-a716-446655440026","550e8400-e29b-41d4-a716-446655440027"]},"operationData":{"type":"object","additionalProperties":true,"description":"Operation-specific data","example":{"status":"COMPLETED","completedAt":"2025-01-15T16:00:00Z","completionNote":"Bulk completion of similar tasks"}},"options":{"type":"object","properties":{"validateBeforeExecution":{"type":"boolean","default":true,"description":"Validate all operations before executing any","example":true},"stopOnFirstError":{"type":"boolean","default":false,"description":"Stop processing on first error","example":false},"maxConcurrency":{"type":"integer","minimum":1,"maximum":20,"default":5,"description":"Maximum concurrent operations","example":10},"dryRun":{"type":"boolean","default":false,"description":"Perform validation only, do not execute","example":false},"sendNotifications":{"type":"boolean","default":true,"description":"Send notifications for changes","example":false},"skipValidation":{"type":"boolean","default":false,"description":"Skip individual validation steps","example":false},"batchSize":{"type":"integer","minimum":1,"maximum":100,"default":20,"description":"Number of operations per batch","example":25}}},"filters":{"type":"object","properties":{"status":{"type":"array","items":{"type":"string"},"description":"Filter by status values","example":["IN_PROGRESS","PENDING"]},"assigneeIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Filter by assignee IDs","example":["550e8400-e29b-41d4-a716-446655440008"]},"tags":{"type":"array","items":{"type":"string"},"description":"Filter by tags","example":["urgent","review-needed"]},"createdAfter":{"type":"string","format":"date-time","description":"Filter by creation date (after)","example":"2025-01-01T00:00:00Z"},"createdBefore":{"type":"string","format":"date-time","description":"Filter by creation date (before)","example":"2025-01-15T23:59:59Z"},"dueDateAfter":{"type":"string","format":"date-time","description":"Filter by due date (after)","example":"2025-01-20T00:00:00Z"},"dueDateBefore":{"type":"string","format":"date-time","description":"Filter by due date (before)","example":"2025-01-30T23:59:59Z"},"priority":{"type":"array","items":{"type":"string"},"description":"Filter by priority levels","example":["HIGH","URGENT"]}}}}},"BulkOperationResponse":{"type":"object","required":["operationId","status","operation","entityType","summary","results","errors","metadata"],"properties":{"operationId":{"type":"string","format":"uuid","description":"Unique identifier for this bulk operation","example":"550e8400-e29b-41d4-a716-446655440028"},"status":{"type":"string","enum":["PENDING","RUNNING","COMPLETED","FAILED","CANCELLED"],"description":"Current status of bulk operation","example":"COMPLETED"},"operation":{"type":"string","enum":["UPDATE","DELETE","ARCHIVE","RESTORE","ASSIGN","STATUS_CHANGE","TAG_ADD","TAG_REMOVE","MOVE","DUPLICATE"],"description":"Type of operation performed","example":"STATUS_CHANGE"},"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW","SECTION"],"description":"Type of entities operated on","example":"TASK"},"summary":{"type":"object","required":["totalRequested","totalProcessed","successful","failed","skipped","inProgress"],"properties":{"totalRequested":{"type":"integer","minimum":0,"description":"Total number of operations requested","example":150},"totalProcessed":{"type":"integer","minimum":0,"description":"Total number of operations processed","example":150},"successful":{"type":"integer","minimum":0,"description":"Number of successful operations","example":142},"failed":{"type":"integer","minimum":0,"description":"Number of failed operations","example":5},"skipped":{"type":"integer","minimum":0,"description":"Number of skipped operations","example":3},"inProgress":{"type":"integer","minimum":0,"description":"Number of operations still in progress","example":0}}},"results":{"type":"array","items":{"type":"object","required":["entityId","status"],"properties":{"entityId":{"type":"string","format":"uuid","description":"ID of the entity that was operated on","example":"550e8400-e29b-41d4-a716-446655440025"},"status":{"type":"string","enum":["SUCCESS","FAILED","SKIPPED","PENDING"],"description":"Result status for this entity","example":"SUCCESS"},"error":{"type":"string","description":"Error message if operation failed","example":"Entity not found or access denied"},"warnings":{"type":"array","items":{"type":"string"},"description":"Warning messages for this operation","example":["Related entity not updated due to permissions"]},"updatedFields":{"type":"array","items":{"type":"string"},"description":"Fields that were updated","example":["status","completedAt","updatedAt"]},"oldValues":{"type":"object","additionalProperties":true,"description":"Previous values before operation","example":{"status":"IN_PROGRESS","completedAt":null}},"newValues":{"type":"object","additionalProperties":true,"description":"New values after operation","example":{"status":"COMPLETED","completedAt":"2025-01-15T16:00:00Z"}},"processingTimeMs":{"type":"integer","minimum":0,"description":"Time taken to process this entity","example":125}}},"description":"Detailed results for each entity"},"errors":{"type":"array","items":{"type":"object","required":["errorType","message"],"properties":{"entityId":{"type":"string","format":"uuid","description":"Entity ID if error is entity-specific","example":"550e8400-e29b-41d4-a716-446655440026"},"errorType":{"type":"string","enum":["VALIDATION_ERROR","PERMISSION_ERROR","NOT_FOUND","DEPENDENCY_ERROR","SYSTEM_ERROR"],"description":"Type of error that occurred","example":"PERMISSION_ERROR"},"message":{"type":"string","description":"Human-readable error message","example":"Insufficient permissions to modify this entity"},"details":{"type":"object","additionalProperties":true,"description":"Additional error details","example":{"requiredPermission":"TASK_UPDATE","currentRole":"VIEWER"}}}},"description":"Errors encountered during bulk operation"},"metadata":{"type":"object","required":["startedAt","dryRun","batchesProcessed","totalBatches"],"properties":{"startedAt":{"type":"string","format":"date-time","description":"When the bulk operation started","example":"2025-01-15T15:30:00Z"},"completedAt":{"type":"string","format":"date-time","description":"When the bulk operation completed","example":"2025-01-15T15:45:30Z"},"estimatedCompletionTime":{"type":"string","format":"date-time","description":"Estimated completion time","example":"2025-01-15T15:50:00Z"},"totalProcessingTimeMs":{"type":"integer","minimum":0,"description":"Total processing time in milliseconds","example":925000},"dryRun":{"type":"boolean","description":"Whether this was a dry run","example":false},"batchesProcessed":{"type":"integer","minimum":0,"description":"Number of batches processed","example":6},"totalBatches":{"type":"integer","minimum":0,"description":"Total number of batches","example":6}}},"progressUrl":{"type":"string","format":"uri","description":"URL to poll for operation progress","example":"https://api.example.com/v1/bulk-operations/550e8400-e29b-41d4-a716-446655440028/progress"},"cancelUrl":{"type":"string","format":"uri","description":"URL to cancel the operation","example":"https://api.example.com/v1/bulk-operations/550e8400-e29b-41d4-a716-446655440028/cancel"}}},"AuditLogEntry":{"type":"object","required":["id","organizationId","entityType","entityId","action","userId","user","timestamp","details","metadata","severity","category","retentionPolicy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique audit log entry identifier","example":"550e8400-e29b-41d4-a716-446655440029"},"organizationId":{"type":"string","format":"uuid","description":"Organization this audit entry belongs to","example":"550e8400-e29b-41d4-a716-446655440004"},"entityType":{"type":"string","enum":["TASK","PROJECT","WORKFLOW","SECTION","USER","ORGANIZATION","CONTEXT_TYPE","TEMPLATE"],"description":"Type of entity that was acted upon","example":"TASK"},"entityId":{"type":"string","description":"ID of the entity that was acted upon","example":"550e8400-e29b-41d4-a716-446655440025"},"action":{"type":"string","enum":["CREATE","UPDATE","DELETE","ARCHIVE","RESTORE","ASSIGN","UNASSIGN","STATUS_CHANGE","PERMISSION_CHANGE","LOGIN","LOGOUT","EXPORT","IMPORT"],"description":"Action that was performed","example":"STATUS_CHANGE"},"userId":{"type":"string","format":"uuid","description":"User who performed the action","example":"550e8400-e29b-41d4-a716-446655440008"},"user":{"type":"object","required":["id","name","email"],"properties":{"id":{"type":"string","format":"uuid","description":"User identifier","example":"550e8400-e29b-41d4-a716-446655440008"},"name":{"type":"string","description":"User full name","example":"John Doe"},"email":{"type":"string","format":"email","description":"User email address","example":"john.doe@example.com"}}},"timestamp":{"type":"string","format":"date-time","description":"When the action was performed","example":"2025-01-15T16:00:00Z"},"ipAddress":{"type":"string","description":"IP address of the user","example":"192.168.1.100"},"userAgent":{"type":"string","description":"User agent string","example":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"},"details":{"type":"object","properties":{"oldValues":{"type":"object","additionalProperties":true,"description":"Previous values before the action","example":{"status":"IN_PROGRESS","assigneeId":"550e8400-e29b-41d4-a716-446655440030"}},"newValues":{"type":"object","additionalProperties":true,"description":"New values after the action","example":{"status":"COMPLETED","completedAt":"2025-01-15T16:00:00Z"}},"affectedFields":{"type":"array","items":{"type":"string"},"description":"Fields that were changed","example":["status","completedAt","updatedAt"]},"reason":{"type":"string","description":"Reason provided for the action","example":"Task completed as per requirements"},"bulkOperationId":{"type":"string","format":"uuid","description":"ID of bulk operation if part of one","example":"550e8400-e29b-41d4-a716-446655440028"},"apiKey":{"type":"string","description":"Masked API key if action performed via API","example":"ak_****1234"},"sessionId":{"type":"string","description":"Session identifier","example":"sess_550e8400e29b41d4a716446655440031"}}},"metadata":{"type":"object","required":["source","success"],"properties":{"source":{"type":"string","enum":["WEB_UI","API","WEBHOOK","AUTOMATION","BULK_OPERATION","SYSTEM"],"description":"Source of the action","example":"WEB_UI"},"requestId":{"type":"string","description":"Request identifier for tracking","example":"req_550e8400-e29b-41d4-a716-446655440032"},"correlationId":{"type":"string","description":"Correlation ID for related actions","example":"corr_550e8400-e29b-41d4-a716-446655440033"},"duration":{"type":"integer","minimum":0,"description":"Duration of the action in milliseconds","example":250},"success":{"type":"boolean","description":"Whether the action was successful","example":true},"errorMessage":{"type":"string","description":"Error message if action failed","example":"Validation failed: invalid status transition"}}},"severity":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"],"description":"Severity level of the action","example":"MEDIUM"},"category":{"type":"string","enum":["DATA_CHANGE","PERMISSION_CHANGE","AUTHENTICATION","SYSTEM_EVENT","SECURITY_EVENT","BUSINESS_EVENT"],"description":"Category of the audit event","example":"DATA_CHANGE"},"retentionPolicy":{"type":"object","required":["retainUntil","archiveAfter"],"properties":{"retainUntil":{"type":"string","format":"date-time","description":"When this entry should be deleted","example":"2032-01-15T16:00:00Z"},"archiveAfter":{"type":"string","format":"date-time","description":"When this entry should be archived","example":"2027-01-15T16:00:00Z"},"complianceCategory":{"type":"string","description":"Compliance category affecting retention","example":"GDPR"}}}}},"ActionHistoryResponse":{"type":"object","required":["actions","pagination"],"description":"Paginated list of context action execution history","properties":{"actions":{"type":"array","description":"List of executed context actions","items":{"type":"object","required":["id","contextTypeId","contextTypeName","entityType","entityId","actionType","status","retryCount","createdAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique action log identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"contextTypeId":{"type":"string","format":"uuid","description":"Context type that executed this action","example":"550e8400-e29b-41d4-a716-446655440001"},"contextTypeName":{"type":"string","description":"Human-readable name of the context type","example":"Salesforce CRM Integration"},"entityType":{"type":"string","description":"Type of entity that was acted upon","example":"project"},"entityId":{"type":"string","description":"Unique identifier of the entity","example":"550e8400-e29b-41d4-a716-446655440002"},"actionType":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Type of action performed","example":"CREATE"},"status":{"type":"string","enum":["SUCCESS","FAILED","PENDING","RETRYING"],"description":"Current status of the action","example":"SUCCESS"},"errorMessage":{"type":"string","nullable":true,"description":"Error message if action failed","example":"Authentication failed: Invalid access token"},"retryCount":{"type":"integer","minimum":0,"description":"Number of retry attempts made","example":0},"executedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the action was successfully executed","example":"2025-01-15T10:30:00Z"},"createdAt":{"type":"string","format":"date-time","description":"When the action was created","example":"2025-01-15T10:25:00Z"},"createdBy":{"type":"string","description":"User or system that created this action","example":"user_550e8400-e29b-41d4-a716-446655440003"}}}},"pagination":{"type":"object","required":["total","page","limit","totalPages"],"description":"Pagination information","properties":{"total":{"type":"integer","minimum":0,"description":"Total number of actions","example":125},"page":{"type":"integer","minimum":1,"description":"Current page number","example":1},"limit":{"type":"integer","minimum":1,"maximum":100,"description":"Items per page","example":20},"totalPages":{"type":"integer","minimum":1,"description":"Total number of pages","example":7}}}}},"CreateWorkflowTemplateRequest":{"type":"object","required":["code","name","validFrom"],"properties":{"code":{"type":"string","minLength":3,"maxLength":100,"pattern":"^[a-z0-9-]+$","description":"Unique template identifier within organization. Lowercase alphanumeric with hyphens only.","example":"commercial-property-acquisition-v2"},"name":{"type":"string","minLength":3,"maxLength":255,"description":"Human-readable template name for display purposes","example":"Commercial Property Acquisition Process v2.1"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed template description explaining business purpose and key stages","example":"Comprehensive acquisition process for commercial properties including legal due diligence, technical inspection, and regulatory compliance."},"category":{"type":"string","enum":["real-estate","tenant-management","maintenance","legal","financial","operations","compliance"],"nullable":true,"description":"Template category for organizational and filtering purposes","example":"real-estate"},"versionMajor":{"type":"integer","minimum":1,"maximum":999,"default":1,"description":"Major version number for significant structural changes","example":2},"versionMinor":{"type":"integer","minimum":0,"maximum":999,"default":0,"description":"Minor version number for incremental improvements","example":1},"validFrom":{"type":"string","format":"date","description":"Template activation date (YYYY-MM-DD). Template becomes available from this date.","example":"2024-01-01"},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Template expiration date (YYYY-MM-DD). Null means no expiration.","example":"2024-12-31"},"publishEvents":{"type":"boolean","default":true,"description":"Enable automatic event publishing to Google Pub/Sub for workflows from this template","example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Optional specific Pub/Sub topic ID. If not provided, uses organization default topic.","example":"550e8400-e29b-41d4-a716-446655440020"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Optional form template ID for collecting initialization data when instantiating workflows","example":"650e8400-f29c-51e5-b817-556655441234"},"rules":{"type":"object","additionalProperties":true,"description":"Configuration rules governing workflow behavior","properties":{"autoAdvance":{"type":"boolean","default":false,"description":"Automatically advance to next stage when current stage is completed"},"requireAllStages":{"type":"boolean","default":true,"description":"Require completion of all stages for workflow completion"},"allowParallelStages":{"type":"boolean","default":false,"description":"Allow multiple stages to be active simultaneously"},"maxDurationDays":{"type":"integer","minimum":1,"maximum":3650,"description":"Maximum allowed workflow duration in days"},"approvalRequired":{"type":"boolean","default":false,"description":"Require explicit approval for workflow progression"},"digitalFirst":{"type":"boolean","default":false,"description":"Prioritize digital processes over manual ones"},"escalationEnabled":{"type":"boolean","default":true,"description":"Enable automatic escalation for overdue stages"},"notificationEnabled":{"type":"boolean","default":true,"description":"Enable automatic notifications for stage transitions"}},"example":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":false,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true}},"taskCreationStrategy":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"default":"UPFRONT","description":"Defines when tasks are created: UPFRONT (all at once), ON_STAGE_START (when stage starts), or HYBRID (mixed)","example":"UPFRONT"},"assignmentInheritanceStrategy":{"type":"object","description":"Strategy for dynamically assigning tasks during workflow instantiation","required":["mode"],"properties":{"mode":{"type":"string","enum":["WORKFLOW_OWNER","WORKFLOW_ASSIGNEE","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","HYBRID"],"description":"Assignment inheritance mode","example":"WORKFLOW_OWNER"},"rules":{"type":"object","description":"Rules for HYBRID mode - define per-task or per-role strategies","properties":{"byTaskCode":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","WORKFLOW_ASSIGNEE","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"]},"description":"Override mode by specific task codes","example":{"approval-task":"WORKFLOW_OWNER","review-task":"STAGE_DEFAULT"}},"byRole":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","WORKFLOW_ASSIGNEE","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"]},"description":"Override mode by assignee roles/types","example":{"manager":"WORKFLOW_OWNER","reviewer":"STAGE_DEFAULT"}},"fallback":{"type":"string","enum":["WORKFLOW_OWNER","WORKFLOW_ASSIGNEE","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"],"description":"Fallback mode when no specific rule matches","example":"TEMPLATE_DEFINED"}}},"contextMapping":{"type":"object","description":"Context mapping configuration for CONTEXT_BASED mode","required":["source","field","type"],"properties":{"source":{"type":"string","enum":["initializationData","entityContext"],"description":"Source of context data","example":"initializationData"},"field":{"type":"string","description":"Field name in the context data","example":"assignedUserId"},"type":{"type":"string","enum":["USER","POSITION"],"description":"Type of assignment target","example":"USER"}}}},"example":{"mode":"WORKFLOW_OWNER"}},"supportedEntityTypes":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":50,"description":"Entity types this template supports","example":["commercial_property","office_building"]},"metadata":{"type":"object","additionalProperties":true,"description":"Rich metadata for template classification and intelligent routing","properties":{"complexity":{"type":"string","enum":["low","medium","high","critical"],"description":"Business process complexity level"},"averageDuration":{"type":"string","description":"Typical workflow completion time (human-readable)","example":"75 days"},"targetEntityTypes":{"type":"array","items":{"type":"string"},"description":"List of entity types this template is designed for"},"requiredRoles":{"type":"array","items":{"type":"string"},"description":"List of organizational roles required for workflow execution"},"complianceLevel":{"type":"string","enum":["basic","standard","enhanced","regulatory"],"description":"Compliance and audit requirements level"},"automationLevel":{"type":"string","enum":["manual","semi-automated","automated","fully-automated"],"description":"Level of process automation"},"industry":{"type":"string","description":"Industry or business domain for template specialization"},"tags":{"type":"array","items":{"type":"string"},"description":"Custom tags for template organization and discovery"}},"example":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property"],"requiredRoles":["acquisition_manager","legal_counsel"],"complianceLevel":"enhanced"}}}},"UpdateWorkflowTemplateRequest":{"type":"object","description":"All fields optional for update. Code cannot be changed after creation.","properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"Human-readable template name"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed template description"},"category":{"type":"string","enum":["real-estate","tenant-management","maintenance","legal","financial","operations","compliance"],"description":"Template category"},"isActive":{"type":"boolean","description":"Whether template is active for new workflows"},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Template expiration date (YYYY-MM-DD)"},"publishEvents":{"type":"boolean","description":"Enable event publishing"},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic ID for events"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Form template ID for initialization data collection"},"rules":{"type":"object","additionalProperties":true,"description":"Workflow behavior rules"},"taskCreationStrategy":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"description":"Task creation timing strategy"},"assignmentInheritanceStrategy":{"$ref":"#/components/schemas/AssignmentInheritanceStrategy"},"supportedEntityTypes":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"Supported entity types"},"metadata":{"type":"object","additionalProperties":true,"description":"Template metadata"}}},"WorkflowTemplate":{"type":"object","required":["id","organizationId","code","name","versionMajor","versionMinor","isActive","validFrom","publishEvents","createdAt","createdBy","updatedAt","updatedBy"],"description":"Complete workflow template with all configuration details","properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow template identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this template","example":"550e8400-e29b-41d4-a716-446655440001"},"code":{"type":"string","maxLength":50,"description":"Unique code for the workflow template within the organization","example":"COMM_PROP_ACQ"},"name":{"type":"string","maxLength":255,"description":"Human-readable name of the workflow template","example":"Commercial Property Acquisition"},"description":{"type":"string","nullable":true,"description":"Detailed description of the workflow template","example":"Standard workflow for acquiring commercial real estate properties"},"category":{"type":"string","maxLength":100,"nullable":true,"description":"Category for organizing templates","example":"Real Estate"},"versionMajor":{"type":"integer","minimum":1,"description":"Major version number","example":2},"versionMinor":{"type":"integer","minimum":0,"description":"Minor version number","example":1},"isActive":{"type":"boolean","description":"Whether the template is active and can be instantiated","example":true},"validFrom":{"type":"string","format":"date","description":"Date from which this template version is valid","example":"2025-01-01"},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Date until which this template version is valid","example":"2025-12-31"},"rules":{"type":"object","nullable":true,"description":"Business rules and constraints for workflow execution","additionalProperties":true,"example":{"maxDurationDays":90,"requiresApproval":true,"escalationRules":{"level1":2,"level2":5}}},"publishEvents":{"type":"boolean","description":"Whether to publish events for workflow lifecycle changes","example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic for publishing workflow events","example":"550e8400-e29b-41d4-a716-446655440002"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Form template for workflow initialization data collection","example":"650e8400-f29c-51e5-b817-556655441234"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata for the workflow template","additionalProperties":true,"example":{"department":"Real Estate","priority":"high","compliance":{"SOX":true,"GDPR":false}}},"taskCreationStrategy":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"description":"Strategy for when tasks are created during workflow instantiation","example":"UPFRONT"},"assignmentInheritanceStrategy":{"allOf":[{"$ref":"#/components/schemas/AssignmentInheritanceStrategy"}],"nullable":true,"description":"Strategy for dynamically assigning tasks during workflow instantiation"},"supportedEntityTypes":{"type":"array","items":{"type":"string"},"description":"Entity types this workflow template supports","example":["property","deal"]},"createdAt":{"type":"string","format":"date-time","description":"When the template was created","example":"2025-01-15T10:30:00Z"},"createdBy":{"type":"string","description":"User who created the template","example":"user_admin@apart.tech"},"updatedAt":{"type":"string","format":"date-time","description":"When the template was last updated","example":"2025-01-15T14:22:15Z"},"updatedBy":{"type":"string","description":"User who last updated the template","example":"user_manager@apart.tech"}}},"WorkflowPhase":{"type":"object","required":["id","organizationId","workflowTemplateId","phaseCode","name","sequenceOrder","completionRule","createdAt","updatedAt"],"description":"Workflow phase definition for portal views","properties":{"id":{"type":"string","format":"uuid","description":"Unique phase identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this phase"},"workflowTemplateId":{"type":"string","format":"uuid","description":"Workflow template this phase belongs to"},"phaseCode":{"type":"string","maxLength":50,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Unique kebab-case code for the phase","example":"initial-review"},"name":{"type":"string","maxLength":255,"description":"Human-readable name of the phase","example":"Initial Review"},"description":{"type":"string","nullable":true,"description":"Detailed description of the phase","example":"Initial review and assessment of submitted documents"},"sequenceOrder":{"type":"integer","minimum":1,"description":"Order of this phase in the workflow","example":1},"completionRule":{"type":"string","enum":["ALL_STAGES","ANY_STAGE","BLOCKING_ONLY","CUSTOM"],"description":"Rule for determining when the phase is complete","example":"ALL_STAGES"},"completionConfig":{"type":"object","nullable":true,"description":"Configuration for custom completion rules","properties":{"requiredStageIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Specific stages required for completion"},"minStagesComplete":{"type":"integer","minimum":1,"description":"Minimum number of stages that must be completed"}}},"color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Hex color for UI display","example":"#4CAF50"},"icon":{"type":"string","nullable":true,"maxLength":50,"description":"Icon identifier for UI display","example":"checklist"},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the phase was created"},"createdBy":{"type":"string","description":"User who created the phase"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the phase was last updated"},"updatedBy":{"type":"string","description":"User who last updated the phase"},"stage_mappings":{"type":"array","description":"Stages mapped to this phase","items":{"$ref":"#/components/schemas/WorkflowPhaseStageMapping"}},"portal_configs":{"type":"array","description":"Portal-specific configurations","items":{"$ref":"#/components/schemas/WorkflowPhasePortalConfig"}}}},"WorkflowPhaseStageMapping":{"type":"object","required":["id","organizationId","phaseId","workflowTemplateStageId","isRequiredForCompletion","weight"],"description":"Mapping between a phase and a workflow template stage","properties":{"id":{"type":"string","format":"uuid","description":"Unique mapping identifier"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this mapping"},"phaseId":{"type":"string","format":"uuid","description":"Phase this mapping belongs to"},"workflowTemplateStageId":{"type":"string","format":"uuid","description":"Stage being mapped"},"isRequiredForCompletion":{"type":"boolean","description":"Whether this stage must be completed for the phase to be considered complete","example":true},"weight":{"type":"integer","minimum":1,"maximum":100,"description":"Weight for progress calculation","example":1},"workflow_template_stage":{"type":"object","description":"Stage details","properties":{"id":{"type":"string","format":"uuid"},"stage_code":{"type":"string"},"stage_name":{"type":"string"},"sequence_order":{"type":"integer"}}}}},"WorkflowPhasePortalConfig":{"type":"object","required":["id","organizationId","phaseId","portalCode","isVisible","createdAt","updatedAt"],"description":"Portal-specific configuration for a phase","properties":{"id":{"type":"string","format":"uuid","description":"Unique config identifier"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this config"},"phaseId":{"type":"string","format":"uuid","description":"Phase this config belongs to"},"portalCode":{"type":"string","description":"Portal code this config applies to","example":"client-portal"},"isVisible":{"type":"boolean","description":"Whether this phase is visible in the portal","example":true},"displayNameKey":{"type":"string","nullable":true,"maxLength":255,"description":"Translation key for portal-specific display name","example":"phase.initial-review.client.name"},"displayDescriptionKey":{"type":"string","nullable":true,"maxLength":255,"description":"Translation key for portal-specific description","example":"phase.initial-review.client.description"},"color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Portal-specific color override","example":"#2196F3"},"icon":{"type":"string","nullable":true,"maxLength":50,"description":"Portal-specific icon override","example":"document-review"},"metadata":{"type":"object","nullable":true,"description":"Additional portal-specific metadata","additionalProperties":true},"createdAt":{"type":"string","format":"date-time","description":"Timestamp when the config was created"},"updatedAt":{"type":"string","format":"date-time","description":"Timestamp when the config was last updated"}}},"CreatePhaseRequest":{"type":"object","required":["phaseCode","name","sequenceOrder"],"properties":{"phaseCode":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-z0-9]+(-[a-z0-9]+)*$","description":"Unique kebab-case code for the phase","example":"initial-review"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name of the phase","example":"Initial Review"},"description":{"type":"string","maxLength":2000,"description":"Detailed description of the phase"},"sequenceOrder":{"type":"integer","minimum":1,"description":"Order of this phase in the workflow","example":1},"completionRule":{"type":"string","enum":["ALL_STAGES","ANY_STAGE","BLOCKING_ONLY","CUSTOM"],"description":"Rule for determining when the phase is complete","default":"ALL_STAGES"},"completionConfig":{"type":"object","description":"Configuration for custom completion rules","properties":{"requiredStageIds":{"type":"array","items":{"type":"string","format":"uuid"}},"minStagesComplete":{"type":"integer","minimum":1}}},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"Hex color for UI display"},"icon":{"type":"string","maxLength":50,"description":"Icon identifier"},"stageMappings":{"type":"array","description":"Initial stage mappings to create","items":{"type":"object","required":["stageId"],"properties":{"stageId":{"type":"string","format":"uuid"},"isRequiredForCompletion":{"type":"boolean","default":true},"weight":{"type":"integer","minimum":1,"maximum":100,"default":1}}}}}},"UpdatePhaseRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name of the phase"},"description":{"type":"string","nullable":true,"maxLength":2000,"description":"Detailed description of the phase"},"completionRule":{"type":"string","enum":["ALL_STAGES","ANY_STAGE","BLOCKING_ONLY","CUSTOM"],"description":"Rule for determining when the phase is complete"},"completionConfig":{"type":"object","nullable":true,"description":"Configuration for custom completion rules","properties":{"requiredStageIds":{"type":"array","items":{"type":"string","format":"uuid"}},"minStagesComplete":{"type":"integer","minimum":1}}},"color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Hex color for UI display"},"icon":{"type":"string","nullable":true,"maxLength":50,"description":"Icon identifier"}}},"ReorderPhasesRequest":{"type":"object","required":["phases"],"properties":{"phases":{"type":"array","minItems":1,"description":"New phase ordering","items":{"type":"object","required":["phaseCode","sequenceOrder"],"properties":{"phaseCode":{"type":"string"},"sequenceOrder":{"type":"integer","minimum":1}}}}}},"AddStagesToPhaseRequest":{"type":"object","required":["stageMappings"],"properties":{"stageMappings":{"type":"array","minItems":1,"description":"Stage mappings to add","items":{"type":"object","required":["stageId"],"properties":{"stageId":{"type":"string","format":"uuid"},"isRequiredForCompletion":{"type":"boolean","default":true},"weight":{"type":"integer","minimum":1,"maximum":100,"default":1}}}}}},"UpdateStageMappingRequest":{"type":"object","properties":{"isRequiredForCompletion":{"type":"boolean"},"weight":{"type":"integer","minimum":1,"maximum":100}}},"SetPortalConfigRequest":{"type":"object","required":["isVisible"],"properties":{"isVisible":{"type":"boolean","description":"Whether this phase is visible in the portal"},"displayNameKey":{"type":"string","maxLength":255,"description":"Translation key for portal-specific display name"},"displayDescriptionKey":{"type":"string","maxLength":255,"description":"Translation key for portal-specific description"},"color":{"type":"string","pattern":"^#[0-9A-Fa-f]{6}$","description":"Portal-specific color override"},"icon":{"type":"string","maxLength":50,"description":"Portal-specific icon override"},"metadata":{"type":"object","description":"Additional portal-specific metadata","additionalProperties":true}}},"SetInstanceOverrideRequest":{"type":"object","properties":{"displayNameOverride":{"type":"string","description":"Custom display name for this instance (bypasses translation)","example":"Reviewing Smith Property Documents"},"displayDescriptionOverride":{"type":"string","description":"Custom description for this instance","example":"We are reviewing the documents for 123 Main St"},"isVisibleOverride":{"type":"boolean","description":"Override visibility (null = use template config)","example":true}}},"WorkflowInstancePhaseOverride":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workflowId":{"type":"string","format":"uuid"},"phaseId":{"type":"string","format":"uuid"},"portalCode":{"type":"string"},"displayNameOverride":{"type":"string","nullable":true},"displayDescriptionOverride":{"type":"string","nullable":true},"isVisibleOverride":{"type":"boolean","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"phase":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"phaseCode":{"type":"string"},"name":{"type":"string"}}}}},"PortalViewConfig":{"type":"object","properties":{"entityLabelKeys":{"type":"object","description":"Translation keys for entity type labels","additionalProperties":{"type":"string"},"example":{"TASK":"task.label","PROJECT":"project.label"}},"hiddenFields":{"type":"array","description":"Fields to hide from all entities on this portal","items":{"type":"string"},"example":["internalNotes","costEstimate","markup"]},"fieldVisibilityRules":{"type":"object","description":"Per-entity-type field visibility rules","additionalProperties":{"$ref":"#/components/schemas/FieldVisibilityRule"},"example":{"TASK":{"hidden":["internalNotes","priority"],"readonly":["dueDate","status"]}}},"showSummaryOnly":{"type":"boolean","description":"Whether to show only summary view (no detailed data)","default":false},"summaryConfig":{"$ref":"#/components/schemas/SummaryViewConfig"},"defaultLocale":{"type":"string","description":"Default locale for this portal","example":"en-US","pattern":"^[a-z]{2}-[A-Z]{2}$"}}},"PortalViewConfigWithPortalCode":{"allOf":[{"$ref":"#/components/schemas/PortalViewConfig"},{"type":"object","properties":{"portalCode":{"type":"string","description":"Portal code this configuration applies to","example":"customer_portal"}}}]},"FieldVisibilityRule":{"type":"object","required":["hidden"],"properties":{"hidden":{"type":"array","description":"Fields to completely hide","items":{"type":"string"}},"readonly":{"type":"array","description":"Fields to show as read-only","items":{"type":"string"}},"masked":{"type":"array","description":"Fields to show masked (e.g., \"****\")","items":{"type":"string"}}}},"SummaryViewConfig":{"type":"object","properties":{"showProgress":{"type":"boolean","description":"Show progress percentage","default":true},"showDueDate":{"type":"boolean","description":"Show due date","default":true},"showAssignee":{"type":"boolean","description":"Show assignee name","default":false},"showStatus":{"type":"boolean","description":"Show status","default":true},"customFields":{"type":"array","description":"Custom fields to include in summary","items":{"type":"string"}}}},"CreatePortalViewConfigRequest":{"type":"object","properties":{"entityLabelKeys":{"type":"object","additionalProperties":{"type":"string"}},"hiddenFields":{"type":"array","items":{"type":"string"}},"fieldVisibilityRules":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FieldVisibilityRule"}},"showSummaryOnly":{"type":"boolean","default":false},"summaryConfig":{"$ref":"#/components/schemas/SummaryViewConfig"},"defaultLocale":{"type":"string","pattern":"^[a-z]{2}-[A-Z]{2}$","default":"en-US"}}},"UpdatePortalViewConfigRequest":{"type":"object","properties":{"entityLabelKeys":{"type":"object","nullable":true,"additionalProperties":{"type":"string"}},"hiddenFields":{"type":"array","items":{"type":"string"}},"fieldVisibilityRules":{"type":"object","nullable":true,"additionalProperties":{"$ref":"#/components/schemas/FieldVisibilityRule"}},"showSummaryOnly":{"type":"boolean"},"summaryConfig":{"$ref":"#/components/schemas/SummaryViewConfig","nullable":true},"defaultLocale":{"type":"string","pattern":"^[a-z]{2}-[A-Z]{2}$"}}},"WorkflowPortalView":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Workflow ID"},"displayName":{"type":"string","description":"Translated workflow name","example":"Your Property Purchase"},"displayDescription":{"type":"string","description":"Translated workflow description"},"status":{"type":"string","description":"Workflow status","example":"IN_PROGRESS"},"overallProgress":{"$ref":"#/components/schemas/OverallProgress"},"phases":{"type":"array","items":{"$ref":"#/components/schemas/PhasePortalView"}}}},"PhasePortalView":{"type":"object","properties":{"phaseCode":{"type":"string","description":"Phase identifier","example":"due-diligence"},"displayName":{"type":"string","description":"Translated phase name","example":"Review in Progress"},"displayDescription":{"type":"string","description":"Translated phase description","example":"Our team is reviewing all documentation"},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","BLOCKED","SKIPPED"],"description":"Computed phase status"},"progress":{"$ref":"#/components/schemas/PhaseProgress"},"color":{"type":"string","description":"Display color (hex)","example":"#3B82F6"},"icon":{"type":"string","description":"Icon identifier","example":"search"},"sequenceOrder":{"type":"integer","description":"Position in workflow","example":1}}},"PhaseProgress":{"type":"object","properties":{"completed":{"type":"integer","description":"Number of completed stages","example":2},"total":{"type":"integer","description":"Total stages in phase","example":3},"percentage":{"type":"integer","description":"Completion percentage (0-100)","example":67},"blockedCount":{"type":"integer","description":"Number of blocked stages","example":0}}},"OverallProgress":{"type":"object","properties":{"currentPhase":{"type":"string","description":"Code of the current phase","example":"due-diligence"},"phasesCompleted":{"type":"integer","description":"Number of completed phases","example":1},"totalPhases":{"type":"integer","description":"Total number of phases","example":3},"percentage":{"type":"integer","description":"Overall completion percentage","example":45}}},"TaskTemplateContextTrigger":{"type":"object","required":["id","taskTemplateContextId","triggerEvent","operationId","executionOrder","isAsync","continueOnFailure","retryCount","retryDelayMs","createdAt","updatedAt"],"properties":{"id":{"type":"string","description":"Unique identifier for the trigger","example":"ttct-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"taskTemplateContextId":{"type":"string","description":"ID of the task template context","example":"ttc-1a2b3c4d-5e6f-7890-abcd-ef1234567890"},"triggerEvent":{"type":"string","enum":["task.created","task.updated","task.completed"],"description":"Event that triggers this context action","example":"task.created"},"operationId":{"type":"string","description":"ID of the context operation to execute","example":"op-7f8d9e12-4567-890a-bcde-f1234567890a"},"executionOrder":{"type":"integer","minimum":0,"description":"Order of execution when multiple triggers exist for the same event","example":1,"default":0},"isAsync":{"type":"boolean","description":"Whether to execute this trigger asynchronously","example":false,"default":false},"continueOnFailure":{"type":"boolean","description":"Whether to continue processing other triggers if this one fails","example":true,"default":true},"retryCount":{"type":"integer","minimum":0,"maximum":10,"description":"Number of retry attempts on failure","example":3,"default":3},"retryDelayMs":{"type":"integer","minimum":100,"maximum":60000,"description":"Delay in milliseconds between retry attempts","example":1000,"default":1000},"conditionType":{"type":"string","nullable":true,"maxLength":50,"description":"Type of condition to evaluate before executing","example":"field_match"},"conditionConfig":{"type":"object","nullable":true,"additionalProperties":true,"description":"Configuration for the condition evaluation","example":{"field":"status","operator":"equals","value":"completed"}},"createdAt":{"type":"string","format":"date-time","description":"When this trigger was created","example":"2024-01-20T16:15:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When this trigger was last updated","example":"2024-01-20T16:15:00.000Z"}}},"TaskTemplateContextTriggerResponse":{"type":"object","required":["data"],"properties":{"data":{"allOf":[{"$ref":"#/components/schemas/TaskTemplateContextTrigger"},{"type":"object","properties":{"taskTemplateContext":{"type":"object","properties":{"id":{"type":"string","description":"Task template context ID"},"taskTemplate":{"type":"object","properties":{"id":{"type":"string","description":"Task template ID"},"code":{"type":"string","description":"Task template code"},"name":{"type":"string","description":"Task template name"}}},"contextType":{"type":"object","properties":{"id":{"type":"string","description":"Context type ID"},"code":{"type":"string","description":"Context type code"},"name":{"type":"string","description":"Context type name"}}}}},"operation":{"type":"object","properties":{"id":{"type":"string","description":"Operation ID"},"operationCode":{"type":"string","description":"Operation code"},"operationType":{"type":"string","description":"Operation type"},"name":{"type":"string","description":"Operation name"},"description":{"type":"string","nullable":true,"description":"Operation description"}}}}}]}}},"CronofyWebhook":{"type":"object","properties":{"type":{"type":"string","enum":["event.created","event.updated","event.deleted","invitation.created","invitation.updated"],"description":"Type of webhook event"},"event":{"$ref":"#/components/schemas/CalendarEvent"},"invitation":{"type":"object","properties":{"event_id":{"type":"string","description":"Calendar event ID"},"attendee_email":{"type":"string","format":"email","description":"Attendee email address"},"status":{"type":"string","enum":["accepted","declined","tentative"],"description":"Invitation response status"}}},"changes_since":{"type":"string","format":"date-time","description":"Timestamp of changes"}}},"CalendarEvent":{"type":"object","properties":{"event_id":{"type":"string","description":"Unique calendar event identifier"},"summary":{"type":"string","description":"Event title"},"description":{"type":"string","description":"Event description"},"start":{"type":"string","format":"date-time","description":"Event start time (ISO 8601)"},"end":{"type":"string","format":"date-time","description":"Event end time (ISO 8601)"},"location":{"type":"string","description":"Event location"},"url":{"type":"string","description":"Calendar event URL"}}},"CalendarAttendee":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Attendee email address"},"displayName":{"type":"string","description":"Attendee display name"},"responseRequired":{"type":"boolean","description":"Whether response is required from attendee"}}},"AvailabilitySlot":{"type":"object","properties":{"start":{"type":"string","format":"date-time","description":"Available slot start time"},"end":{"type":"string","format":"date-time","description":"Available slot end time"},"participants":{"type":"array","items":{"type":"string"},"description":"Available participants for this slot"}}},"Event":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"eventTypeCode":{"type":"string"},"eventSource":{"type":"string","enum":["USER","SYSTEM","WEBHOOK","SCHEDULE"]},"correlationId":{"type":"string","format":"uuid"},"aggregateType":{"type":"string"},"aggregateId":{"type":"string","format":"uuid"},"entityType":{"type":"string"},"entityId":{"type":"string"},"eventData":{"type":"object"},"previousData":{"type":"object"},"actorId":{"type":"string"},"actorType":{"type":"string"},"actorName":{"type":"string"},"version":{"type":"string"},"publishingStatus":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"OrganizationPortal":{"type":"object","required":["id","organization_id","portal_code","portal_name","is_active","is_default","created_at","updated_at","created_by"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique portal identifier"},"organization_id":{"type":"string","format":"uuid","description":"Organization this portal belongs to"},"portal_code":{"type":"string","example":"vendor_portal","description":"Unique portal code within organization"},"portal_name":{"type":"string","example":"Vendor Portal","description":"Human-readable portal name"},"description":{"type":"string","nullable":true,"example":"Portal for external vendor access","description":"Optional portal description"},"is_active":{"type":"boolean","description":"Whether the portal is currently active"},"is_default":{"type":"boolean","description":"Whether this is the default portal"},"metadata":{"type":"object","nullable":true,"description":"Optional metadata object"},"created_at":{"type":"string","format":"date-time","description":"When the portal was created"},"updated_at":{"type":"string","format":"date-time","description":"When the portal was last updated"},"created_by":{"type":"string","description":"User who created the portal"}},"example":{"id":"550e8400-e29b-41d4-a716-446655440000","organization_id":"550e8400-e29b-41d4-a716-446655440001","portal_code":"customer_portal","portal_name":"Customer Portal","description":"Portal for customer access","is_active":true,"is_default":false,"metadata":{"color":"blue","icon":"vendors"},"created_at":"2024-01-15T10:30:00Z","updated_at":"2024-01-15T10:30:00Z","created_by":"user123"}},"PubSubSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"topicId":{"type":"string","format":"uuid"},"subscriptionName":{"type":"string"},"subscriptionFullName":{"type":"string"},"serviceName":{"type":"string"},"serviceDescription":{"type":"string"},"subscriptionType":{"type":"string","enum":["PUSH","PULL","BIGQUERY_EXPORT","CLOUD_STORAGE_EXPORT"]},"status":{"type":"string","enum":["ACTIVE","PAUSED","DISABLED","FAILED"]},"pushEndpointUrl":{"type":"string"},"ackDeadlineSeconds":{"type":"integer"},"messageRetentionDurationHours":{"type":"integer"},"totalMessagesDelivered":{"type":"integer"},"totalMessagesFailed":{"type":"integer"},"lastSuccessfulDelivery":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}},"PubSubTopic":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"topicName":{"type":"string"},"topicFullName":{"type":"string"},"gcpProjectId":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"messageRetentionDurationHours":{"type":"integer"},"eventTypes":{"type":"array","items":{"type":"string"}},"entityFilters":{"type":"object"},"isActive":{"type":"boolean"},"lastPublishedAt":{"type":"string","format":"date-time"},"totalMessagesPublished":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"SmartInviteCallback":{"type":"object","properties":{"smart_invite_id":{"type":"string","description":"Unique Smart Invite identifier (format org_{orgId}_event_{eventId}_{hash})"},"recipient":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Attendee email address"},"status":{"type":"string","enum":["accepted","tentative","declined"],"description":"RSVP response status"},"comment":{"type":"string","description":"Optional comment from attendee"},"proposal":{"type":"object","description":"Counter-proposal for alternative time","properties":{"start":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"tzid":{"type":"string"}}},"end":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"tzid":{"type":"string"}}}}}}}}},"CounterProposalAction":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["accept","decline"],"description":"Action to take on counter-proposal"}}},"WebhookRegistration":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Webhook unique identifier"},"organizationId":{"type":"string","format":"uuid","description":"Organization ID that owns this webhook"},"endpoint":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"events":{"type":"array","items":{"type":"string"},"description":"List of event types to subscribe to"},"active":{"type":"boolean","description":"Whether webhook is active"},"secret":{"type":"string","description":"Webhook secret for signature verification"},"config":{"type":"object","properties":{"retryPolicy":{"type":"object","properties":{"maxRetries":{"type":"integer","minimum":0,"maximum":10},"backoffMultiplier":{"type":"number","minimum":1}}},"timeout":{"type":"integer","minimum":1000,"maximum":30000},"verifySSL":{"type":"boolean"}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CreateWebhookRequest":{"type":"object","required":["endpoint","events"],"properties":{"endpoint":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"events":{"type":"array","items":{"type":"string"},"description":"Event types to subscribe to"},"config":{"type":"object","properties":{"retryPolicy":{"type":"object","properties":{"maxRetries":{"type":"integer","default":3},"backoffMultiplier":{"type":"number","default":2}}},"timeout":{"type":"integer","default":5000},"verifySSL":{"type":"boolean","default":true}}}}},"WebhookDeliveryLog":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"webhookId":{"type":"string","format":"uuid"},"eventType":{"type":"string"},"status":{"type":"string","enum":["success","failed","pending"]},"responseCode":{"type":"integer"},"responseTime":{"type":"integer"},"payload":{"type":"object"},"error":{"type":"string"},"attemptCount":{"type":"integer"},"timestamp":{"type":"string","format":"date-time"}}}},"responses":{"BadRequestError":{"description":"Bad Request - Invalid input or validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"validationError":{"summary":"Validation Error","value":{"error":{"code":"VALIDATION_ERROR","message":"File type not allowed","details":{"filename":"malicious.exe","mimeType":"application/x-msdownload","allowedTypes":["image/*","application/pdf","text/*"]}}}},"fileTooLarge":{"summary":"File Too Large","value":{"error":{"code":"FILE_TOO_LARGE","message":"File exceeds maximum size limit of 100MB","details":{"filename":"large-video.mp4","fileSize":157286400,"maxSize":104857600}}}}}}}},"UnauthorizedError":{"description":"Unauthorized - Invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"UNAUTHORIZED","message":"Invalid API key"}}}}},"NotFoundError":{"description":"Not Found - Resource does not exist or access denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"attachmentNotFound":{"summary":"Attachment Not Found","value":{"error":{"code":"ATTACHMENT_NOT_FOUND","message":"Attachment not found","details":{"attachmentId":"att-123e4567-e89b-12d3-a456-426614174000"}}}},"entityNotFound":{"summary":"Target Entity Not Found","value":{"error":{"code":"ENTITY_NOT_FOUND","message":"Project not found","details":{"targetType":"project","targetId":"456e7890-e89b-12d3-a456-426614174111"}}}}}}}},"FileTooLargeError":{"description":"Payload Too Large - File exceeds size limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"FILE_TOO_LARGE","message":"File exceeds maximum size limit of 100MB","details":{"maxSize":104857600}}}}}},"RateLimitError":{"description":"Too Many Requests - Rate limit exceeded","headers":{"X-RateLimit-Limit":{"description":"Request limit per time window","schema":{"type":"integer"},"example":100},"X-RateLimit-Remaining":{"description":"Remaining requests in current window","schema":{"type":"integer"},"example":0},"X-RateLimit-Reset":{"description":"Time when rate limit resets (Unix timestamp)","schema":{"type":"integer"},"example":1642680000}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"RATE_LIMIT_EXCEEDED","message":"Too many requests. Please try again later.","details":{"retryAfter":60}}}}}},"InternalServerError":{"description":"Internal Server Error - Unexpected server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":{"code":"INTERNAL_SERVER_ERROR","message":"An internal server error occurred"}}}}},"BadRequest":{"$ref":"#/components/responses/BadRequestError"},"Unauthorized":{"$ref":"#/components/responses/UnauthorizedError"},"NotFound":{"$ref":"#/components/responses/NotFoundError"}},"parameters":{"PageParam":{"name":"page","in":"query","description":"Page number for pagination","required":false,"schema":{"type":"integer","minimum":1,"default":1},"example":1},"LimitParam":{"name":"limit","in":"query","description":"Number of items per page","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"example":20},"ProjectIdParam":{"name":"projectId","in":"query","description":"Filter tasks by project ID","required":false,"schema":{"type":"string","format":"uuid"},"example":"456e7890-e89b-12d3-a456-426614174111"},"AttachmentTargetTypeParam":{"name":"targetType","in":"query","description":"Filter attachments by target entity type","required":false,"schema":{"type":"string","enum":["project","task"]},"example":"project"},"AttachmentTargetIdParam":{"name":"targetId","in":"query","description":"Filter attachments by target entity ID","required":false,"schema":{"type":"string","format":"uuid"},"example":"456e7890-e89b-12d3-a456-426614174111"},"FileTypeParam":{"name":"fileType","in":"query","description":"Filter attachments by file type/extension","required":false,"schema":{"type":"string"},"example":"pdf"},"AttachmentIdParam":{"name":"id","in":"path","description":"Attachment UUID","required":true,"schema":{"type":"string","format":"uuid"},"example":"att-123e4567-e89b-12d3-a456-426614174000"},"UuidPathParam":{"name":"id","in":"path","description":"Resource UUID","required":true,"schema":{"type":"string","format":"uuid"},"example":"123e4567-e89b-12d3-a456-426614174000"},"CalendarEvent":{"type":"object","required":["eventId","calendarId","title","start","end"],"properties":{"eventId":{"type":"string","description":"Unique calendar event identifier","example":"evt_2024011510001234"},"calendarId":{"type":"string","description":"Calendar identifier","example":"primary"},"title":{"type":"string","description":"Event title","maxLength":255,"example":"Property Viewing - 123 Main St"},"description":{"type":"string","nullable":true,"description":"Event description","maxLength":2000,"example":"Property viewing with client and owner at 123 Main St, Example City"},"start":{"type":"string","format":"date-time","description":"Event start time","example":"2024-01-15T10:00:00Z"},"end":{"type":"string","format":"date-time","description":"Event end time","example":"2024-01-15T11:00:00Z"},"location":{"type":"string","nullable":true,"description":"Event location","maxLength":500,"example":"123 Main St, Example City"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Event attendees"},"reminders":{"type":"array","items":{"$ref":"#/components/schemas/CalendarReminder"},"description":"Event reminders"},"url":{"type":"string","format":"uri","nullable":true,"description":"Calendar event URL","example":"https://calendar.cronofy.com/events/evt_2024011510001234"},"status":{"type":"string","enum":["confirmed","tentative","cancelled"],"description":"Event status","example":"confirmed"},"createdAt":{"type":"string","format":"date-time","description":"Event creation timestamp","example":"2024-01-15T09:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last event update timestamp","example":"2024-01-15T09:35:00.000Z"}}},"CalendarAttendee":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","maxLength":255,"description":"Attendee email address. Validated for proper email format.","example":"john.doe@example.com"},"displayName":{"type":"string","maxLength":100,"description":"Attendee display name shown in calendar invitations","example":"John Doe"},"responseRequired":{"type":"boolean","default":true,"description":"Whether RSVP response is required from this attendee","example":true}}},"CalendarReminder":{"type":"object","required":["minutes"],"properties":{"minutes":{"type":"integer","minimum":0,"maximum":43200,"description":"Minutes before event to send reminder","example":15},"method":{"type":"string","enum":["email","popup","sms"],"description":"Reminder delivery method","default":"email","example":"email"}}},"CalendarEventFromTaskInput":{"type":"object","required":["taskId"],"properties":{"taskId":{"type":"string","format":"uuid","description":"UUID of existing task to create calendar event for. The task must belong to the authenticated organization.","example":"123e4567-e89b-12d3-a456-426614174000"},"calendarId":{"type":"string","default":"primary","description":"Target calendar ID. Use 'primary' for the user's primary calendar or a specific calendar ID from the connected calendar provider.","example":"primary"},"attendees":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"List of event attendees. Maximum 100 attendees (configurable via MAX_CALENDAR_ATTENDEES env var). Email validation and internal/external categorization applied automatically."},"location":{"type":"string","maxLength":500,"description":"Physical or virtual location for the event. Supports addresses, room names, or video conference URLs.","example":"Conference Room A, 123 Main St, Berlin"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Event duration in minutes. Must be between 15 minutes and 8 hours.","example":60},"reminders":{"type":"array","maxItems":5,"items":{"type":"object","required":["minutes"],"properties":{"minutes":{"type":"integer","minimum":0,"maximum":40320,"description":"Minutes before event to send reminder (max 4 weeks = 40320 minutes)","example":30},"method":{"type":"string","enum":["popup","email","sms"],"description":"Reminder delivery method (Cronofy support varies by method)","example":"email"}}},"description":"Event reminder configurations. Maximum 5 reminders per event."},"responseTracking":{"type":"boolean","default":false,"description":"Enable RSVP tracking via Cronofy Smart Invites. When true, sends trackable calendar invitations to each attendee with automated response callbacks. Requires at least one attendee. Smart Invite callbacks are received at /api/webhooks/cronofy/smart-invite."}}},"CalendarEventWithNewTaskInput":{"type":"object","required":["task"],"properties":{"task":{"type":"object","required":["title"],"properties":{"title":{"type":"string","minLength":1,"maxLength":500,"description":"Task and calendar event title","example":"Property Viewing - 123 Main Street"},"description":{"type":"string","maxLength":5000,"description":"Task and calendar event description","example":"Show property to potential buyers"},"projectId":{"type":"string","format":"uuid","description":"Project ID to associate the task with (optional)","example":"proj-123e4567-e89b-12d3-a456-426614174000"},"sectionId":{"type":"string","format":"uuid","description":"Section ID within the project","example":"sect-123e4567-e89b-12d3-a456-426614174000"},"dueDate":{"type":"string","format":"date-time","description":"Task due date (ISO 8601 format)","example":"2024-02-15T17:00:00.000Z"},"scheduledAt":{"type":"string","format":"date-time","description":"Task scheduled time - used as calendar event start time (ISO 8601 format). If not provided, uses dueDate.","example":"2024-02-15T14:00:00.000Z"},"assigneeUserId":{"type":"string","format":"uuid","description":"User ID to assign the task to","example":"user-123e4567-e89b-12d3-a456-426614174000"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority level","example":"HIGH"}}},"calendarId":{"type":"string","default":"primary","description":"Target calendar ID","example":"primary"},"attendees":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Event attendees (max 100, configurable)"},"location":{"type":"string","maxLength":500,"description":"Event location","example":"123 Main Street, Berlin"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Event duration in minutes","example":60},"reminders":{"type":"array","maxItems":5,"items":{"type":"object","required":["minutes"],"properties":{"minutes":{"type":"integer","minimum":0,"maximum":40320,"description":"Minutes before event to remind"},"method":{"type":"string","enum":["popup","email","sms"]}}}},"responseTracking":{"type":"boolean","default":false,"description":"Enable RSVP tracking via Smart Invites. Requires at least one attendee."}}},"CalendarEventUpdateInput":{"type":"object","properties":{"summary":{"type":"string","minLength":1,"maxLength":500,"description":"Updated event title"},"description":{"type":"string","maxLength":5000,"description":"Updated event description"},"start":{"type":"string","format":"date-time","description":"Updated event start time (ISO 8601)"},"end":{"type":"string","format":"date-time","description":"Updated event end time (ISO 8601)"},"location":{"type":"string","maxLength":500,"description":"Updated event location"},"attendees":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Updated attendee list"},"reminders":{"type":"array","maxItems":5,"items":{"type":"object","properties":{"minutes":{"type":"integer","minimum":0,"maximum":40320}}}}}},"RescheduleEventInput":{"type":"object","required":["taskId"],"properties":{"taskId":{"type":"string","format":"uuid","description":"Task ID for validation - must match the event's associated task","example":"123e4567-e89b-12d3-a456-426614174000"},"scheduledAt":{"type":"string","format":"date-time","description":"New scheduled date/time for the event (ISO 8601)"},"dueDate":{"type":"string","format":"date-time","description":"New due date for the task (ISO 8601)"},"duration":{"type":"integer","minimum":15,"maximum":10080,"description":"Updated duration in minutes (15 min to 1 week)"},"location":{"type":"string","maxLength":500,"description":"Updated event location"},"attendees":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Updated attendee list"},"reminders":{"type":"array","maxItems":5,"items":{"type":"object","properties":{"minutes":{"type":"integer"}}}},"rescheduleReason":{"type":"string","maxLength":500,"description":"Reason for rescheduling (stored in audit trail)","example":"Client requested different time"},"notifyAttendees":{"type":"boolean","default":true,"description":"Whether to send update notifications to attendees"},"calendarId":{"type":"string","description":"Move event to different calendar if needed"}}},"AvailabilityCheckInput":{"type":"object","required":["participants","duration","timeframe"],"properties":{"participants":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"string","format":"email"},"description":"Email addresses of participants to check availability for","example":["john@example.com","jane@example.com"]},"duration":{"type":"integer","minimum":15,"maximum":480,"description":"Required meeting duration in minutes","example":60},"timeframe":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time","description":"Start of availability search window (ISO 8601)","example":"2024-02-15T09:00:00.000Z"},"end":{"type":"string","format":"date-time","description":"End of availability search window (ISO 8601)","example":"2024-02-15T17:00:00.000Z"}},"description":"Time window to search for availability"},"preferences":{"type":"object","properties":{"timeOfDay":{"type":"string","enum":["morning","afternoon","evening"],"description":"Preferred time of day for the meeting"},"daysOfWeek":{"type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"]},"description":"Preferred days of the week"}},"description":"Optional scheduling preferences to filter availability results"}}},"MeetingInvitationInput":{"type":"object","required":["taskId","organizer","attendees"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of the task for the meeting","example":"123e4567-e89b-12d3-a456-426614174000"},"organizer":{"type":"string","format":"email","description":"Meeting organizer email address","example":"organizer@example.com"},"attendees":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Meeting attendees (at least one required)"},"location":{"type":"string","maxLength":500,"description":"Meeting location or video conference URL","example":"https://meet.example.com/abc-123"},"duration":{"type":"integer","minimum":15,"maximum":480,"default":60,"description":"Meeting duration in minutes","example":60},"scheduledAt":{"type":"string","format":"date-time","description":"Scheduled meeting time (ISO 8601). Defaults to task.scheduledAt if not provided.","example":"2024-02-15T14:00:00.000Z"}}},"CalendarEventType":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Event type UUID"},"organizationId":{"type":"string","format":"uuid","description":"Organization UUID"},"code":{"type":"string","description":"Unique code identifier","example":"open_house"},"name":{"type":"string","description":"Display name","example":"Open House"},"description":{"type":"string","nullable":true,"description":"Event type description"},"category":{"type":"string","nullable":true,"description":"Category for grouping","example":"property"},"color":{"type":"string","nullable":true,"description":"Color code for UI","example":"#6366f1"},"icon":{"type":"string","nullable":true,"description":"Icon identifier"},"defaultDuration":{"type":"integer","nullable":true,"description":"Default duration in minutes","example":60},"defaultBufferBefore":{"type":"integer","nullable":true,"description":"Default prep time in minutes","example":15},"defaultBufferAfter":{"type":"integer","nullable":true,"description":"Default wrap-up time in minutes","example":15},"defaultReminders":{"type":"array","items":{"$ref":"#/components/schemas/CalendarReminder"},"nullable":true},"capacityEnabled":{"type":"boolean","description":"Whether capacity management is enabled","example":true},"defaultCapacity":{"type":"integer","nullable":true,"description":"Default maximum attendees","example":50},"waitlistEnabled":{"type":"boolean","description":"Whether waitlist is enabled when at capacity","example":true},"metadataSchema":{"type":"object","nullable":true,"description":"JSON Schema for custom metadata validation"},"outcomeOptions":{"type":"array","items":{"$ref":"#/components/schemas/OutcomeOption"},"nullable":true},"outcomeRequired":{"type":"boolean","description":"Whether outcome recording is required","example":false},"defaultInviteMethod":{"type":"string","enum":["events_api","smart_invite","auto"],"nullable":true,"description":"Default method for sending calendar invites","example":"smart_invite"},"isActive":{"type":"boolean","description":"Whether event type is active","example":true},"sortOrder":{"type":"integer","description":"Display order","example":0},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"OutcomeOption":{"type":"object","required":["code","label"],"properties":{"code":{"type":"string","description":"Unique outcome code","example":"successful"},"label":{"type":"string","description":"Display label","example":"Successful"},"description":{"type":"string","nullable":true,"description":"Help text"},"color":{"type":"string","nullable":true,"example":"#22c55e"},"icon":{"type":"string","nullable":true},"createsFollowUp":{"type":"boolean","description":"Whether this outcome suggests a follow-up","example":false},"completesTask":{"type":"boolean","description":"Whether this outcome completes the linked task","example":true},"taskStatus":{"type":"string","nullable":true,"description":"Task status to set when this outcome is recorded","example":"completed"}}},"CreateEventTypeRequest":{"type":"object","required":["code","name"],"properties":{"code":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-z][a-z0-9_]*$","description":"Unique code for this event type. Must be lowercase alphanumeric with underscores, starting with a letter. Used for programmatic references.","example":"open_house"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for the event type","example":"Open House"},"description":{"type":"string","maxLength":2000,"description":"Detailed description of the event type and its purpose"},"category":{"type":"string","maxLength":100,"description":"Category for grouping event types (e.g., 'property', 'internal', 'client')","example":"property"},"color":{"type":"string","maxLength":50,"description":"Color code for calendar display (hex or named color)","example":"#FF5733"},"icon":{"type":"string","maxLength":100,"description":"Icon identifier for UI display","example":"home"},"defaultDuration":{"type":"integer","minimum":5,"maximum":1440,"description":"Default event duration in minutes (5 min to 24 hours)","example":60},"defaultBufferBefore":{"type":"integer","minimum":0,"maximum":120,"description":"Default buffer time before event in minutes (max 2 hours)","example":15},"defaultBufferAfter":{"type":"integer","minimum":0,"maximum":120,"description":"Default buffer time after event in minutes (max 2 hours)","example":15},"defaultReminders":{"type":"array","maxItems":5,"items":{"type":"object","required":["minutes"],"properties":{"minutes":{"type":"integer","minimum":0,"maximum":40320,"description":"Minutes before event (max 4 weeks)"},"method":{"type":"string","enum":["popup","email","sms"]}}},"description":"Default reminder configurations for this event type"},"capacityEnabled":{"type":"boolean","default":false,"description":"Whether capacity limits are enabled for this event type"},"defaultCapacity":{"type":"integer","minimum":1,"maximum":10000,"description":"Default maximum capacity when capacity is enabled","example":50},"waitlistEnabled":{"type":"boolean","default":false,"description":"Whether waitlist functionality is enabled when capacity is reached"},"metadataSchema":{"type":"object","description":"JSON Schema for validating custom event metadata. Allows structured data validation for event-specific fields.","example":{"type":"object","properties":{"propertyId":{"type":"string"},"expectedAttendees":{"type":"integer"}}}},"outcomeOptions":{"type":"array","maxItems":20,"items":{"type":"object","required":["code","label"],"properties":{"code":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-z][a-z0-9_]*$","description":"Unique outcome code"},"label":{"type":"string","minLength":1,"maxLength":100,"description":"Display label for the outcome"},"description":{"type":"string","maxLength":500},"color":{"type":"string","maxLength":50},"icon":{"type":"string","maxLength":100},"createsFollowUp":{"type":"boolean","description":"Whether this outcome triggers follow-up task creation"},"completesTask":{"type":"boolean","description":"Whether this outcome marks the associated task as complete"},"taskStatus":{"type":"string","maxLength":50,"description":"Task status to set when this outcome is selected"}}},"description":"Predefined outcome options for event completion tracking"},"outcomeRequired":{"type":"boolean","default":false,"description":"Whether recording an outcome is required after event conclusion"},"defaultInviteMethod":{"type":"string","enum":["events_api","smart_invite","auto"],"default":"auto","description":"Default method for sending invitations. 'events_api' uses standard calendar invites, 'smart_invite' uses Cronofy Smart Invites with RSVP tracking, 'auto' selects based on attendee type."},"sortOrder":{"type":"integer","minimum":0,"description":"Sort order for displaying event types in lists"}}},"UpdateEventTypeRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255},"description":{"type":"string","maxLength":2000},"category":{"type":"string","maxLength":100},"color":{"type":"string","maxLength":50},"icon":{"type":"string","maxLength":100},"defaultDuration":{"type":"integer","minimum":5,"maximum":1440},"defaultBufferBefore":{"type":"integer","minimum":0,"maximum":120},"defaultBufferAfter":{"type":"integer","minimum":0,"maximum":120},"defaultReminders":{"type":"array","maxItems":5,"items":{"type":"object","properties":{"minutes":{"type":"integer","minimum":0,"maximum":40320},"method":{"type":"string","enum":["popup","email","sms"]}}}},"capacityEnabled":{"type":"boolean"},"defaultCapacity":{"type":"integer","minimum":1,"maximum":10000},"waitlistEnabled":{"type":"boolean"},"metadataSchema":{"type":"object"},"outcomeOptions":{"type":"array","maxItems":20,"items":{"type":"object"}},"outcomeRequired":{"type":"boolean"},"defaultInviteMethod":{"type":"string","enum":["events_api","smart_invite","auto"]},"isActive":{"type":"boolean"},"sortOrder":{"type":"integer","minimum":0}},"description":"All fields are optional - only provided fields will be updated"},"ValidateMetadataRequest":{"type":"object","required":["metadata"],"properties":{"metadata":{"type":"object","description":"Metadata object to validate against the event type's JSON schema","example":{"propertyId":"prop-123","expectedAttendees":25}}}},"CreateTypedEventRequest":{"type":"object","required":["summary","startTime","duration"],"properties":{"eventTypeCode":{"type":"string","maxLength":100,"description":"Event type code to use for this event. If provided, inherits event type defaults."},"summary":{"type":"string","minLength":1,"maxLength":500,"description":"Event title"},"startTime":{"type":"string","format":"date-time","description":"Event start time (ISO 8601)"},"duration":{"type":"integer","minimum":5,"maximum":1440,"description":"Event duration in minutes"},"description":{"type":"string","maxLength":5000},"location":{"type":"string","maxLength":500},"timezone":{"type":"string","maxLength":100,"example":"Europe/Berlin"},"bufferBefore":{"type":"integer","minimum":0,"maximum":120,"description":"Override event type's default buffer before"},"bufferAfter":{"type":"integer","minimum":0,"maximum":120,"description":"Override event type's default buffer after"},"maxCapacity":{"type":"integer","minimum":1,"maximum":10000,"description":"Override event type's default capacity"},"waitlistEnabled":{"type":"boolean"},"maxWaitlist":{"type":"integer","minimum":0,"maximum":10000},"eventMetadata":{"type":"object","description":"Custom metadata validated against event type's schema"},"attendees":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/CalendarAttendee"}},"reminders":{"type":"array","maxItems":5,"items":{"type":"object","properties":{"minutes":{"type":"integer"},"method":{"type":"string","enum":["popup","email","sms"]}}}},"inviteMethod":{"type":"string","enum":["events_api","smart_invite","auto"],"description":"Override event type's default invite method"},"taskId":{"type":"string","format":"uuid","description":"Link to existing task"},"createTask":{"type":"boolean","description":"Automatically create a task for this event"},"projectId":{"type":"string","format":"uuid","description":"Project ID if creating a task"},"sectionId":{"type":"string","format":"uuid","description":"Section ID if creating a task"},"workflowId":{"type":"string","format":"uuid","description":"Workflow ID if creating a task"},"entityType":{"type":"string","maxLength":100,"description":"Entity type for task linking (e.g., \"property\")"},"entityId":{"type":"string","maxLength":50,"description":"Entity ID for task linking"},"assigneeUserId":{"type":"string","maxLength":50,"description":"User ID to assign the created task to"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority level"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"],"description":"Initial task status"},"sourceService":{"type":"string","maxLength":100,"description":"Source service identifier"},"sourceServiceTaskId":{"type":"string","maxLength":255,"description":"Task ID in the source service"},"sourceServiceMetadata":{"type":"object","description":"Additional metadata from the source service"},"calendarId":{"type":"string","description":"Target calendar ID"}}},"RecordOutcomeRequest":{"type":"object","required":["outcome"],"properties":{"outcome":{"type":"string","minLength":1,"maxLength":100,"description":"Outcome code from the event type's outcome options","example":"successful_viewing"},"outcomeNotes":{"type":"string","maxLength":5000,"description":"Additional notes about the outcome"},"followUpRequired":{"type":"boolean","description":"Whether follow-up action is needed"},"followUpDate":{"type":"string","format":"date-time","description":"When follow-up should occur (ISO 8601)"},"followUpNotes":{"type":"string","maxLength":2000,"description":"Notes for the follow-up"},"createFollowUpTask":{"type":"boolean","description":"Automatically create a follow-up task"},"additionalMetadata":{"type":"object","description":"Additional structured data about the outcome"}}},"AttendeeOutcome":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"calendarEventId":{"type":"string","format":"uuid"},"attendeeEmail":{"type":"string","format":"email","example":"viewer@example.com"},"attendeeDisplayName":{"type":"string","nullable":true,"example":"Jane Doe"},"outcome":{"type":"string","example":"interested"},"outcomeNotes":{"type":"string","nullable":true},"outcomeMetadata":{"type":"object","nullable":true},"recordedAt":{"type":"string","format":"date-time"},"recordedBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CreateAttendeeOutcomeRequest":{"type":"object","required":["attendeeEmail","outcome"],"properties":{"attendeeEmail":{"type":"string","format":"email","example":"viewer@example.com"},"attendeeDisplayName":{"type":"string","example":"Jane Doe"},"outcome":{"type":"string","minLength":1,"maxLength":100,"example":"interested"},"outcomeNotes":{"type":"string","maxLength":5000},"outcomeMetadata":{"type":"object"}}},"BatchAttendeeOutcomeRequest":{"type":"object","required":["outcomes"],"properties":{"outcomes":{"type":"array","maxItems":200,"items":{"$ref":"#/components/schemas/CreateAttendeeOutcomeRequest"}}}},"BatchAttendeeOutcomeResponse":{"type":"object","properties":{"total":{"type":"integer"},"succeeded":{"type":"integer"},"failed":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"attendeeEmail":{"type":"string"},"success":{"type":"boolean"},"outcome":{"$ref":"#/components/schemas/AttendeeOutcome"},"error":{"type":"string","nullable":true}}}}}},"UpdateAttendeeOutcomeRequest":{"type":"object","properties":{"outcome":{"type":"string","minLength":1,"maxLength":100},"outcomeNotes":{"type":"string","maxLength":5000},"outcomeMetadata":{"type":"object"}}},"AttendeeOutcomeSummary":{"type":"object","properties":{"eventId":{"type":"string","format":"uuid"},"totalRecorded":{"type":"integer"},"summary":{"type":"array","items":{"type":"object","properties":{"outcome":{"type":"string"},"count":{"type":"integer"}}}}}},"EventRegistration":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"calendarEventId":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email","description":"Registrant email"},"displayName":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"partySize":{"type":"integer","minimum":1,"description":"Number of attendees in party","example":1},"status":{"type":"string","enum":["confirmed","waitlisted","cancelled","declined"]},"registrationSource":{"type":"string","enum":["api","public_link","manual","import"]},"registeredAt":{"type":"string","format":"date-time"},"registeredBy":{"type":"string","format":"uuid","nullable":true},"waitlistPosition":{"type":"integer","nullable":true,"description":"Position in waitlist (1-indexed)"},"promotedFromWaitlist":{"type":"boolean"},"promotedAt":{"type":"string","format":"date-time","nullable":true},"checkedIn":{"type":"boolean"},"checkedInAt":{"type":"string","format":"date-time","nullable":true},"checkedInBy":{"type":"string","format":"uuid","nullable":true},"checkInMethod":{"type":"string","enum":["manual","qr_code","self_service"],"nullable":true},"calendarInviteSent":{"type":"boolean"},"smartInviteId":{"type":"string","nullable":true},"rsvpStatus":{"type":"string","nullable":true},"registrationMetadata":{"type":"object","nullable":true},"internalNotes":{"type":"string","nullable":true},"registrantNotes":{"type":"string","nullable":true},"cancelledAt":{"type":"string","format":"date-time","nullable":true},"cancellationReason":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CreateRegistrationRequest":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","maxLength":255,"description":"Attendee email address"},"displayName":{"type":"string","maxLength":100,"description":"Attendee display name"},"phone":{"type":"string","maxLength":50,"description":"Attendee phone number"},"partySize":{"type":"integer","minimum":1,"maximum":100,"default":1,"description":"Number of people in attendee's party"},"metadata":{"type":"object","description":"Additional registration metadata"},"sendInvite":{"type":"boolean","default":true,"description":"Whether to send Smart Invite calendar invitation"},"source":{"type":"string","maxLength":100,"description":"Registration source (e.g., 'web', 'mobile', 'api')","example":"web"}}},"RegistrationResponse":{"type":"object","properties":{"success":{"type":"boolean"},"registration":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"displayName":{"type":"string"},"status":{"type":"string","enum":["confirmed","waitlisted"]},"waitlistPosition":{"type":"integer","nullable":true}}},"event":{"type":"object","properties":{"eventId":{"type":"string"},"summary":{"type":"string"},"startTime":{"type":"string","format":"date-time"},"endTime":{"type":"string","format":"date-time"},"location":{"type":"string","nullable":true}}},"capacity":{"type":"object","properties":{"maxCapacity":{"type":"integer"},"confirmedCount":{"type":"integer"},"waitlistCount":{"type":"integer"},"spotsRemaining":{"type":"integer"}}},"calendarInviteSent":{"type":"boolean"}}},"BulkRegistrationRequest":{"type":"object","required":["registrations"],"properties":{"registrations":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/CreateRegistrationRequest"},"description":"Array of registration requests to process"},"continueOnError":{"type":"boolean","default":true,"description":"Continue processing if individual registrations fail"}}},"BulkRegistrationResponse":{"type":"object","properties":{"success":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"success":{"type":"boolean"},"registration":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"waitlistPosition":{"type":"integer","nullable":true}}},"error":{"type":"string","nullable":true}}}},"summary":{"type":"object","properties":{"total":{"type":"integer"},"confirmed":{"type":"integer"},"waitlisted":{"type":"integer"},"failed":{"type":"integer"}}}}},"CheckInRequest":{"type":"object","properties":{"registrationId":{"type":"string","format":"uuid","description":"Registration ID for pre-registered attendees"},"email":{"type":"string","format":"email","description":"Email for walk-in attendees or registration lookup"},"displayName":{"type":"string","maxLength":100,"description":"Name for walk-in attendees"},"checkInMethod":{"type":"string","enum":["manual","qr_code","self_service"],"default":"manual","description":"Method used for check-in"},"createWalkIn":{"type":"boolean","default":false,"description":"Create walk-in registration if no existing registration found"}}},"CheckInResponse":{"type":"object","properties":{"success":{"type":"boolean"},"registration":{"$ref":"#/components/schemas/EventRegistration"},"isNewRegistration":{"type":"boolean","description":"True if this was a walk-in registration"},"event":{"type":"object","properties":{"eventId":{"type":"string"},"summary":{"type":"string"},"checkedInCount":{"type":"integer"},"totalRegistrations":{"type":"integer"}}}}},"CancelRegistrationRequest":{"type":"object","properties":{"cancellationReason":{"type":"string","maxLength":500,"description":"Reason for cancellation"},"notifyOrganizer":{"type":"boolean","default":true,"description":"Whether to notify event organizer"}}},"CancelRegistrationResponse":{"type":"object","properties":{"success":{"type":"boolean"},"promotedRegistration":{"$ref":"#/components/schemas/EventRegistration","nullable":true,"description":"Registration promoted from waitlist (if any)"},"notificationSent":{"type":"boolean"}}},"UpdateRegistrationRequest":{"type":"object","properties":{"displayName":{"type":"string","maxLength":100},"phone":{"type":"string","maxLength":50},"partySize":{"type":"integer","minimum":1,"maximum":100},"metadata":{"type":"object"}}},"EventRegistrationSummary":{"type":"object","properties":{"eventId":{"type":"string"},"summary":{"type":"string"},"startTime":{"type":"string","format":"date-time"},"endTime":{"type":"string","format":"date-time"},"location":{"type":"string","nullable":true},"maxCapacity":{"type":"integer","nullable":true},"waitlistEnabled":{"type":"boolean"},"confirmedCount":{"type":"integer"},"waitlistCount":{"type":"integer"},"checkedInCount":{"type":"integer"},"walkInCount":{"type":"integer"},"cancelledCount":{"type":"integer"},"spotsRemaining":{"type":"integer","nullable":true},"attendanceRate":{"type":"number","nullable":true,"description":"Percentage of confirmed who checked in"},"registrations":{"type":"object","properties":{"confirmed":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}},"waitlisted":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}},"checkedIn":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}},"cancelled":{"type":"array","items":{"$ref":"#/components/schemas/EventRegistration"}}}}}},"RegistrationStatistics":{"type":"object","properties":{"eventId":{"type":"string"},"totals":{"type":"object","properties":{"registrations":{"type":"integer"},"confirmed":{"type":"integer"},"waitlisted":{"type":"integer"},"cancelled":{"type":"integer"},"checkedIn":{"type":"integer"},"walkIns":{"type":"integer"},"noShows":{"type":"integer"}}},"rates":{"type":"object","properties":{"confirmationRate":{"type":"number","description":"Percentage confirmed"},"attendanceRate":{"type":"number","description":"Percentage who checked in"},"noShowRate":{"type":"number","description":"Percentage who did not show"},"cancellationRate":{"type":"number","description":"Percentage cancelled"},"waitlistConversionRate":{"type":"number","description":"Percentage promoted from waitlist"}}},"bySource":{"type":"object","additionalProperties":{"type":"integer"},"description":"Count by registration source"},"byPartySize":{"type":"object","additionalProperties":{"type":"integer"},"description":"Count by party size"}}},"WaitlistPromotionResult":{"type":"object","properties":{"promoted":{"type":"boolean"},"registration":{"$ref":"#/components/schemas/EventRegistration","nullable":true},"previousPosition":{"type":"integer","nullable":true},"calendarInviteSent":{"type":"boolean"},"notificationSent":{"type":"boolean"}}},"CreateCalendarEventRequest":{"type":"object","required":["taskId"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of the task to create calendar event for","example":"123e4567-e89b-12d3-a456-426614174000"},"calendarId":{"type":"string","description":"Calendar ID (defaults to primary calendar)","example":"primary"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Event attendees","maxItems":50},"location":{"type":"string","nullable":true,"description":"Meeting location","maxLength":500,"example":"123 Main St, Property Viewing"},"reminders":{"type":"array","items":{"$ref":"#/components/schemas/CalendarReminder"},"description":"Event reminders","maxItems":5},"customTitle":{"type":"string","nullable":true,"description":"Custom event title (overrides task title)","maxLength":255,"example":"Property Viewing with Client"},"customDescription":{"type":"string","nullable":true,"description":"Custom event description (overrides task description)","maxLength":2000,"example":"Meeting with property owner and potential buyer"}}},"CalendarAvailabilityRequest":{"type":"object","required":["participants","duration","timeframe"],"properties":{"participants":{"type":"array","items":{"type":"string","format":"email"},"description":"Email addresses of participants to check availability for","minItems":1,"maxItems":20,"example":["user1@example.com","user2@example.com"]},"duration":{"type":"integer","minimum":15,"maximum":480,"description":"Meeting duration in minutes","example":60},"timeframe":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time","description":"Start of availability check window","example":"2024-01-15T09:00:00Z"},"end":{"type":"string","format":"date-time","description":"End of availability check window","example":"2024-01-15T17:00:00Z"}},"description":"Time window to check for availability"},"workingHours":{"type":"object","nullable":true,"properties":{"start":{"type":"string","pattern":"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Working hours start time (HH:MM format)","example":"09:00"},"end":{"type":"string","pattern":"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$","description":"Working hours end time (HH:MM format)","example":"17:00"},"timezone":{"type":"string","description":"Timezone for working hours","example":"America/New_York"}},"description":"Working hours preferences"}}},"CalendarAvailabilityResponse":{"type":"object","required":["availableSlots"],"properties":{"availableSlots":{"type":"array","items":{"type":"object","required":["start","end","participants"],"properties":{"start":{"type":"string","format":"date-time","description":"Available slot start time","example":"2024-01-15T10:00:00Z"},"end":{"type":"string","format":"date-time","description":"Available slot end time","example":"2024-01-15T11:00:00Z"},"participants":{"type":"array","items":{"type":"object","required":["email","available"],"properties":{"email":{"type":"string","format":"email","description":"Participant email","example":"user1@example.com"},"available":{"type":"boolean","description":"Whether participant is available during this slot","example":true}}},"description":"Participant availability for this slot"}}},"description":"Available time slots"},"requestedDuration":{"type":"integer","description":"Requested meeting duration in minutes","example":60},"timeframe":{"type":"object","required":["start","end"],"properties":{"start":{"type":"string","format":"date-time","description":"Start of checked timeframe","example":"2024-01-15T09:00:00Z"},"end":{"type":"string","format":"date-time","description":"End of checked timeframe","example":"2024-01-15T17:00:00Z"}},"description":"Timeframe that was checked"}}},"CreateMeetingInvitationRequest":{"type":"object","required":["taskId","organizer","attendees"],"properties":{"taskId":{"type":"string","format":"uuid","description":"ID of the task to create meeting for","example":"123e4567-e89b-12d3-a456-426614174000"},"organizer":{"type":"string","format":"email","description":"Meeting organizer email address","example":"organizer@example.com"},"attendees":{"type":"array","items":{"$ref":"#/components/schemas/CalendarAttendee"},"description":"Meeting attendees","minItems":1,"maxItems":50},"location":{"type":"string","nullable":true,"description":"Meeting location","maxLength":500,"example":"123 Main St, Conference Room A"},"agenda":{"type":"string","nullable":true,"description":"Meeting agenda","maxLength":2000,"example":"Discuss property details and schedule viewing"},"calendarId":{"type":"string","description":"Calendar to create event in","example":"primary"}}},"CalendarList":{"type":"array","items":{"type":"object","required":["calendarId","name","readOnly"],"properties":{"calendarId":{"type":"string","description":"Calendar identifier","example":"primary"},"name":{"type":"string","description":"Calendar display name","example":"Primary Calendar"},"readOnly":{"type":"boolean","description":"Whether calendar is read-only","example":false},"primary":{"type":"boolean","description":"Whether this is the primary calendar","example":true},"color":{"type":"string","nullable":true,"description":"Calendar color (hex format)","pattern":"^#[0-9A-Fa-f]{6}$","example":"#3174ad"}}},"description":"List of available calendars"},"CalendarError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["CRONOFY_TOKEN_INVALID","CALENDAR_NOT_FOUND","ATTENDEE_UNAVAILABLE","EVENT_CONFLICT","RATE_LIMIT_EXCEEDED","CALENDAR_FEATURES_DISABLED","INVALID_EVENT_DATA","EXTERNAL_API_ERROR"],"description":"Calendar-specific error code","example":"CRONOFY_TOKEN_INVALID"},"message":{"type":"string","description":"Human-readable error message","example":"Calendar authentication failed. Please check your Cronofy token."},"details":{"type":"object","description":"Additional error context","additionalProperties":true,"example":{"cronofyError":"invalid_token","suggestion":"Refresh your Cronofy access token"}}}}}},"CounterProposalAction":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["accept","decline"],"description":"Action to take on the counter-proposal"}}},"SmartInviteCallback":{"type":"object","required":["smart_invite"],"properties":{"smart_invite":{"type":"object","required":["smart_invite_id","recipient"],"properties":{"smart_invite_id":{"type":"string","description":"Unique Smart Invite identifier (format: org_{orgId}_event_{eventId}_{hash})"},"recipient":{"type":"object","required":["email","status"],"properties":{"email":{"type":"string","format":"email","description":"Attendee email address"},"status":{"type":"string","enum":["accepted","tentative","declined"],"description":"RSVP response status"},"comment":{"type":"string","description":"Optional comment from attendee"},"proposal":{"type":"object","description":"Counter-proposal for alternative time","properties":{"start":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"tzid":{"type":"string"}}},"end":{"type":"object","properties":{"time":{"type":"string","format":"date-time"},"tzid":{"type":"string"}}}}}}}}}}},"CronofyWebhook":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["event.created","event.updated","event.deleted","invitation.created","invitation.updated"],"description":"Type of webhook event"},"event":{"type":"object","description":"Calendar event data (for event.* types)","properties":{"event_id":{"type":"string"},"summary":{"type":"string"},"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"location":{"type":"string"}}},"invitation":{"type":"object","description":"Invitation data (for invitation.* types)","properties":{"event_id":{"type":"string","description":"Calendar event ID"},"attendee_email":{"type":"string","format":"email","description":"Attendee email address"},"status":{"type":"string","enum":["accepted","declined","tentative"],"description":"Invitation response status"}}},"changes_since":{"type":"string","format":"date-time","description":"Timestamp of changes"}}},"WorkflowTemplate":{"type":"object","required":["id","organizationId","code","name","category","versionMajor","versionMinor","isActive","validFrom","publishEvents","createdAt","createdBy","updatedAt","updatedBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow template identifier","example":"550e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier that owns this template","example":"550e8400-e29b-41d4-a716-446655440000"},"code":{"type":"string","description":"Unique template code for identification and versioning","maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","example":"property-acquisition-commercial-v2"},"name":{"type":"string","description":"Human-readable template name","maxLength":255,"example":"Commercial Property Acquisition v2.1"},"description":{"type":"string","nullable":true,"description":"Detailed template description and purpose","example":"Enhanced commercial property acquisition process with digital due diligence and compliance automation"},"category":{"type":"string","nullable":true,"description":"Template category for organization and filtering","maxLength":100,"enum":["real-estate","tenant-management","maintenance","compliance","financial","marketing"],"example":"real-estate"},"versionMajor":{"type":"integer","description":"Major version number for breaking changes","minimum":1,"default":1,"example":2},"versionMinor":{"type":"integer","description":"Minor version number for incremental updates","minimum":0,"default":0,"example":1},"isActive":{"type":"boolean","description":"Whether template is active and available for new workflow creation","default":true,"example":true},"validFrom":{"type":"string","format":"date","description":"Date from which template becomes valid and usable","example":"2024-01-01"},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Date until which template remains valid (null for indefinite)","example":null},"publishEvents":{"type":"boolean","description":"Whether workflow events should be published to event topics","default":true,"example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic ID for workflow event publishing","example":"550e8400-e29b-41d4-a716-446655440010"},"rules":{"type":"object","nullable":true,"description":"Template configuration rules and behavior settings","additionalProperties":true,"properties":{"autoAdvance":{"type":"boolean","description":"Automatically advance workflow through stages when conditions are met","example":false},"requireAllStages":{"type":"boolean","description":"All stages must be completed for workflow completion","example":true},"allowParallelStages":{"type":"boolean","description":"Allow multiple stages to run in parallel","example":false},"maxDurationDays":{"type":"integer","minimum":1,"description":"Maximum allowed duration for workflow completion","example":90},"approvalRequired":{"type":"boolean","description":"Require explicit approval for workflow progression","example":true}},"example":{"autoAdvance":false,"requireAllStages":true,"allowParallelStages":false,"maxDurationDays":90,"approvalRequired":true,"digitalFirst":true}},"metadata":{"type":"object","nullable":true,"description":"Additional template metadata and configuration","additionalProperties":true,"properties":{"complexity":{"type":"string","enum":["low","medium","high"],"description":"Template complexity level","example":"high"},"averageDuration":{"type":"string","description":"Expected average completion time","example":"75 days"},"targetEntityTypes":{"type":"array","items":{"type":"string"},"description":"Entity types this template can be applied to","example":["commercial_property"]},"requiredRoles":{"type":"array","items":{"type":"string"},"description":"Roles required for template execution","example":["acquisition_manager","legal_counsel","technical_assessor"]},"complianceLevel":{"type":"string","description":"Required compliance level","example":"enhanced"}},"example":{"complexity":"high","averageDuration":"75 days","targetEntityTypes":["commercial_property"],"requiredRoles":["acquisition_manager","legal_counsel","technical_assessor"],"complianceLevel":"enhanced"}},"stageCount":{"type":"integer","description":"Total number of stages in this template (computed field)","minimum":0,"example":7},"workflowCount":{"type":"integer","description":"Number of workflow instances created from this template (computed field)","minimum":0,"example":23},"workflowTemplateStages":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowTemplateStage"},"description":"Ordered list of stage definitions for this template"},"eventTopic":{"type":"object","nullable":true,"description":"Associated Pub/Sub topic for event publishing","properties":{"id":{"type":"string","format":"uuid","description":"Topic identifier","example":"550e8400-e29b-41d4-a716-446655440010"},"topicName":{"type":"string","description":"Topic name for event publishing","example":"property-acquisition-events"}},"example":{"id":"550e8400-e29b-41d4-a716-446655440010","topicName":"property-acquisition-events"}},"workflows":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Workflow instance identifier"},"name":{"type":"string","description":"Workflow instance name"},"status":{"type":"string","enum":["DRAFT","ACTIVE","PAUSED","COMPLETED","CANCELLED"],"description":"Current workflow status"}}},"description":"Sample of workflow instances created from this template"},"createdAt":{"type":"string","format":"date-time","description":"Template creation timestamp","example":"2024-01-15T09:00:00.000Z"},"createdBy":{"type":"string","description":"User identifier who created the template","maxLength":255,"example":"system@apart.no"},"updatedAt":{"type":"string","format":"date-time","description":"Last template update timestamp","example":"2024-01-20T14:30:00.000Z"},"updatedBy":{"type":"string","description":"User identifier who last updated the template","maxLength":255,"example":"admin@apart.no"}}},"AddTemplateStageRequest":{"type":"object","required":["stageDefinitionId","sequenceOrder"],"properties":{"stageDefinitionId":{"type":"string","format":"uuid","description":"Stage definition to add to template"},"sequenceOrder":{"type":"integer","minimum":1,"maximum":100,"description":"Order of this stage in workflow (1-100)"},"isMilestone":{"type":"boolean","default":false,"description":"Whether this stage is a workflow milestone"},"isBlocking":{"type":"boolean","default":false,"description":"Whether this stage blocks workflow progression"},"isOptional":{"type":"boolean","default":false,"description":"Whether this stage can be skipped"},"defaultAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Default assignee type"},"defaultAssigneeId":{"type":"string","maxLength":50,"description":"Default assignee ID"},"overrideDurationDays":{"type":"integer","minimum":1,"maximum":365,"description":"Override stage definition's default duration"},"overrideEscalationDays":{"type":"integer","minimum":1,"maximum":365,"description":"Override stage definition's escalation timing"},"taskCreationTiming":{"type":"string","enum":["UPFRONT","ON_STAGE_START"],"description":"When to create tasks (for HYBRID strategy)"},"entryConditions":{"type":"object","additionalProperties":true,"description":"Conditions to enter stage"},"exitConditions":{"type":"object","additionalProperties":true,"description":"Conditions to exit stage"},"startOnWorkflowStart":{"type":"boolean","default":false,"description":"Auto-transition to IN_PROGRESS when workflow starts (for parallel execution)"},"stageType":{"type":"string","enum":["TASK","WORKFLOW","OPERATION","GATEWAY","CUSTOM","COMPLETION"],"default":"TASK","description":"Stage type"},"referencedWorkflowTemplateId":{"type":"string","format":"uuid","description":"Required for WORKFLOW stage type - template to instantiate as child"},"waitForCompletion":{"type":"boolean","default":true,"description":"For WORKFLOW stages - wait for child completion"},"completionTriggerStageDefinitionId":{"type":"string","format":"uuid","nullable":true,"description":"Stage definition in child template that triggers parent completion. When set with waitForCompletion=true, the parent stage completes when this specific child stage completes instead of waiting for the entire child workflow."},"autoAdvanceOnCompletion":{"type":"boolean","default":false,"description":"Auto-advance to next stage after completion"},"aggregateChildProgress":{"type":"boolean","default":false,"description":"Aggregate child workflow progress into parent"},"blockOnChildFailure":{"type":"boolean","default":true,"description":"Block parent if child workflow fails"},"allowMultipleChildren":{"type":"boolean","default":false,"description":"Allow multiple child workflows"}}},"UpdateTemplateStageRequest":{"type":"object","description":"All fields optional. Cannot change stageDefinitionId or sequenceOrder (use reorder endpoint).","properties":{"isMilestone":{"type":"boolean"},"isBlocking":{"type":"boolean"},"isOptional":{"type":"boolean"},"defaultAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"]},"defaultAssigneeId":{"type":"string","maxLength":50},"overrideDurationDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true},"overrideEscalationDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true},"taskCreationTiming":{"type":"string","enum":["UPFRONT","ON_STAGE_START"]},"entryConditions":{"type":"object","additionalProperties":true},"exitConditions":{"type":"object","additionalProperties":true},"startOnWorkflowStart":{"type":"boolean"},"stageType":{"type":"string","enum":["TASK","WORKFLOW","OPERATION","GATEWAY","CUSTOM","COMPLETION"]},"referencedWorkflowTemplateId":{"type":"string","format":"uuid","nullable":true},"waitForCompletion":{"type":"boolean"},"completionTriggerStageDefinitionId":{"type":"string","format":"uuid","nullable":true,"description":"Stage definition in child template that triggers parent completion"},"autoAdvanceOnCompletion":{"type":"boolean"},"aggregateChildProgress":{"type":"boolean"},"blockOnChildFailure":{"type":"boolean"},"allowMultipleChildren":{"type":"boolean"}}},"WorkflowTemplateStage":{"type":"object","required":["id","organizationId","templateId","stageDefinitionId","sequenceOrder","isMilestone","isBlocking","isOptional","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique template stage identifier","example":"550e8400-e29b-41d4-a716-446655440020"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"templateId":{"type":"string","format":"uuid","description":"Parent workflow template identifier","example":"550e8400-e29b-41d4-a716-446655440001"},"stageDefinitionId":{"type":"string","format":"uuid","description":"Referenced stage definition identifier","example":"550e8400-e29b-41d4-a716-446655440030"},"sequenceOrder":{"type":"integer","description":"Order of this stage within the template sequence","minimum":1,"example":1},"isMilestone":{"type":"boolean","description":"Whether this stage represents a significant milestone","default":false,"example":false},"isBlocking":{"type":"boolean","description":"Whether this stage blocks workflow progression until completed","default":true,"example":true},"isOptional":{"type":"boolean","description":"Whether this stage can be skipped","default":false,"example":false},"defaultAssigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Default assignment type for stages created from this template","example":"ROLE"},"defaultAssigneeId":{"type":"string","nullable":true,"description":"Default assignee identifier","maxLength":50,"example":"legal_counsel"},"overrideDurationDays":{"type":"integer","nullable":true,"description":"Override default stage duration in days","minimum":1,"example":10},"overrideEscalationDays":{"type":"integer","nullable":true,"description":"Override default escalation timing in days","minimum":1,"example":7},"entryConditions":{"type":"object","nullable":true,"description":"Conditions that must be met for stage entry","additionalProperties":true,"example":{"requiredDocuments":["property_valuation","legal_review"],"approvalRequired":true}},"exitConditions":{"type":"object","nullable":true,"description":"Conditions that must be met for stage completion","additionalProperties":true,"example":{"documentsApproved":true,"tasksCompleted":100}},"stageType":{"type":"string","enum":["TASK","WORKFLOW","OPERATION","GATEWAY","CUSTOM"],"default":"TASK","description":"Stage type determines the behavior when the stage is activated:\n- TASK: Creates tasks from task templates (default behavior)\n- WORKFLOW: Instantiates a child workflow from the referenced workflow template\n- OPERATION: Reserved for future use (automated operations)\n- GATEWAY: Reserved for future use (conditional routing)\n- CUSTOM: Reserved for future use (custom implementations)","example":"TASK"},"referencedWorkflowTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Required when stageType is WORKFLOW. References the workflow template to instantiate as a child workflow when this stage activates. The referenced template must exist and be active. Use case: Create nested approval workflows or sub-processes within a main workflow.","example":"550e8400-e29b-41d4-a716-446655440099"},"waitForCompletion":{"type":"boolean","default":true,"nullable":true,"description":"For WORKFLOW stage types, determines parent stage behavior:\n- true (default): Parent stage waits for child workflow to complete before marking as complete\n- false: Fire-and-forget - parent stage completes immediately after instantiating child workflow\n\nThis enables both blocking (inspection must complete before moving forward) and non-blocking (trigger background process) workflows.","example":true},"completionTriggerStageDefinitionId":{"type":"string","format":"uuid","nullable":true,"description":"For WORKFLOW stage types with waitForCompletion=true. References a stage definition in the child template. When this specific child stage completes, the parent stage is unblocked while the child workflow continues running independently. Provides a middle ground between wait-for-all and fire-and-forget.","example":null},"stageName":{"type":"string","description":"Name of the stage (from stage definition)","example":"Legal Due Diligence"},"stageDefinition":{"type":"object","description":"Referenced stage definition details","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"defaultDurationDays":{"type":"integer"}}},"referencedWorkflowTemplate":{"type":"object","nullable":true,"description":"Details of the referenced workflow template (for WORKFLOW stage types)","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"code":{"type":"string"},"description":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time","description":"Template stage creation timestamp","example":"2024-01-15T09:00:00.000Z"}}},"CreateContextTypeRequest":{"type":"object","required":["code","name","apiBaseUrl","endpointPattern"],"properties":{"code":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-zA-Z0-9_]+$","description":"Unique identifier code for this context type. Must be alphanumeric with underscores only. Used in API calls and configurations.","example":"property_management_system"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for this context type","example":"Property Management System Integration"},"description":{"type":"string","nullable":true,"maxLength":1000,"description":"Detailed description of what this context type is used for and what data it provides","example":"Integration with the property management system to fetch property details, ownership information, and transaction history"},"apiBaseUrl":{"type":"string","format":"uri","minLength":1,"description":"Base URL of the external API. Should not include the endpoint path.","example":"https://api.propertymanagement.com"},"httpMethod":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"default":"GET","description":"Default HTTP method for operations of this context type","example":"GET"},"endpointPattern":{"type":"string","minLength":1,"description":"URL pattern template for constructing endpoint paths. Use placeholders like {entityId} for dynamic values.","example":"/api/v1/properties/{propertyId}"},"authenticationType":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC","INTERNAL"],"default":"NONE","description":"Authentication method required by the external API","example":"BEARER"},"authenticationConfig":{"type":"object","nullable":true,"description":"Configuration for authentication including header names, token prefixes, etc.","example":{"headerName":"Authorization","tokenPrefix":"Bearer ","tokenLocation":"header"}},"requestFormat":{"type":"string","enum":["URL_PARAMS","JSON_BODY","FORM_DATA"],"default":"URL_PARAMS","description":"How to format request parameters when calling the API","example":"JSON_BODY"},"requestTemplate":{"type":"object","nullable":true,"description":"Template for request body structure with parameter placeholders","example":{"query":{"filters":{},"sort":"createdAt:desc"}}},"headersConfig":{"type":"object","nullable":true,"description":"Static headers to include in all requests to this API","example":{"Content-Type":"application/json","Accept":"application/json","X-API-Version":"v1"}},"responseSchema":{"type":"object","nullable":true,"description":"JSON Schema describing the expected response structure for validation","example":{"type":"object","properties":{"data":{"type":"object"},"status":{"type":"string"}}}},"dataPath":{"type":"string","nullable":true,"description":"JSON path to extract the actual data from the response (e.g., 'data.result' or 'items')","example":"data.property"},"responseMappingConfig":{"type":"object","nullable":true,"description":"Configuration for mapping external API response fields to internal context data structure"},"supportsWriteOperations":{"type":"boolean","default":false,"description":"Whether this context type supports write operations (CREATE, UPDATE, DELETE) in addition to read operations","example":true},"writeHttpMethods":{"type":"array","items":{"type":"string","enum":["POST","PUT","DELETE","PATCH"]},"default":[],"description":"HTTP methods allowed for write operations. Required if supportsWriteOperations is true.","example":["POST","PUT","DELETE"]},"actionTriggers":{"type":"object","nullable":true,"description":"Configuration for automatic action triggers based on events or conditions"},"responseHandling":{"type":"object","nullable":true,"description":"Configuration for handling responses including retry policies, error handling, and timeout settings","example":{"onFailure":{"retryPolicy":{"maxRetries":3,"backoffMultiplier":2}},"timeout":30000}}}},"UpdateContextTypeRequest":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable name","minLength":1,"maxLength":255,"example":"Customer API"},"description":{"type":"string","nullable":true,"description":"Context type description","example":"Integration with CRM system"},"apiBaseUrl":{"type":"string","format":"uri","description":"Base URL for API","example":"https://api.example.com/v1"},"httpMethod":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method","example":"GET"},"endpointPattern":{"type":"string","description":"URL pattern with placeholders","example":"/customers/{externalEntityId}"},"authenticationType":{"type":"string","enum":["NONE","BEARER","API_KEY","BASIC","INTERNAL"],"description":"Authentication method","example":"BEARER"},"authenticationConfig":{"type":"object","nullable":true,"description":"Authentication configuration","additionalProperties":true},"requestFormat":{"type":"string","enum":["URL_PARAMS","JSON_BODY","FORM_DATA"],"description":"Request data format","example":"JSON_BODY"},"requestTemplate":{"type":"object","nullable":true,"description":"Request body template","additionalProperties":true},"headersConfig":{"type":"object","nullable":true,"description":"Additional headers","additionalProperties":{"type":"string"}},"responseSchema":{"type":"object","nullable":true,"description":"JSON schema for validation","additionalProperties":true},"dataPath":{"type":"string","nullable":true,"description":"JSONPath to extract data","example":"$.data"},"responseMappingConfig":{"type":"object","nullable":true,"description":"Response mapping configuration","additionalProperties":true},"supportsWriteOperations":{"type":"boolean","description":"Supports write operations","example":true},"writeHttpMethods":{"type":"array","items":{"type":"string","enum":["POST","PUT","DELETE","PATCH"]},"description":"Allowed write methods","example":["POST","PUT"]},"actionTriggers":{"type":"object","nullable":true,"description":"Event triggers","additionalProperties":true},"responseHandling":{"type":"object","nullable":true,"description":"Response handling configuration","additionalProperties":true},"isActive":{"type":"boolean","description":"Active status","example":true}}},"CreateEntityContextRequest":{"type":"object","required":["contextTypeCode","externalEntityId"],"properties":{"contextTypeCode":{"type":"string","minLength":1,"description":"Code of the context type to attach to this entity","example":"property_management_system"},"externalEntityId":{"type":"string","minLength":1,"description":"ID of the entity in the external system. Used to construct API requests.","example":"PROP-12345"},"customEndpoint":{"type":"string","nullable":true,"description":"Custom endpoint override for this specific entity context. If not provided, uses the context type's endpoint pattern.","example":"/api/v2/properties/PROP-12345/details"},"customRequestParams":{"type":"object","nullable":true,"description":"Custom request parameters specific to this entity context","example":{"include":"ownership,transactions,documents","format":"detailed"}},"customHeaders":{"type":"object","nullable":true,"description":"Custom headers specific to this entity context, in addition to context type headers","example":{"X-Property-Access-Level":"full","X-Client-ID":"client-abc"}}}},"UpdateEntityContextRequest":{"type":"object","properties":{"externalEntityId":{"type":"string","description":"External entity identifier","example":"customer-456"},"customEndpoint":{"type":"string","nullable":true,"description":"Custom endpoint override","example":"/customers/custom/{externalEntityId}"},"customRequestParams":{"type":"object","nullable":true,"description":"Custom request parameters","additionalProperties":true},"customHeaders":{"type":"object","nullable":true,"description":"Custom headers","additionalProperties":{"type":"string"}}}},"LiveContextData":{"type":"object","required":["id","contextTypeId","externalEntityId","success"],"properties":{"id":{"type":"string","format":"uuid","description":"Entity context ID","example":"123e4567-e89b-12d3-a456-426614174000"},"contextTypeId":{"type":"string","format":"uuid","description":"Context type ID","example":"456e7890-e89b-12d3-a456-426614174111"},"contextTypeCode":{"type":"string","description":"Context type code","example":"crm_customer"},"contextTypeName":{"type":"string","description":"Context type name","example":"CRM Customer API"},"externalEntityId":{"type":"string","description":"External entity identifier","example":"customer-123"},"success":{"type":"boolean","description":"Fetch success status","example":true},"data":{"description":"Live data from external API","nullable":true},"error":{"type":"string","nullable":true,"description":"Error message if fetch failed"},"fetchedAt":{"type":"string","format":"date-time","description":"Data fetch timestamp","example":"2024-01-20T16:15:00.000Z"},"responseTime":{"type":"integer","description":"Response time in milliseconds","example":250}}},"ExecuteActionRequest":{"type":"object","required":["action","entityType","entityData"],"properties":{"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Type of action to perform on the external system","example":"CREATE"},"entityType":{"type":"string","description":"Type of entity being manipulated in the external system","example":"property"},"entityId":{"type":"string","nullable":true,"description":"ID of the entity in the Tasks system (for tracking and correlation)","example":"550e8400-e29b-41d4-a716-446655440000"},"entityData":{"type":"object","description":"Data to send to the external system for the action","example":{"name":"New Property","address":"123 Main St","type":"residential","bedrooms":3,"bathrooms":2}},"dryRun":{"type":"boolean","default":false,"description":"If true, validates the action without actually executing it on the external system","example":false},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"default":"MEDIUM","nullable":true,"description":"Priority level for async action execution queue","example":"HIGH"}}},"ExecuteActionResponse":{"type":"object","required":["actionLogId","status"],"properties":{"actionLogId":{"type":"string","format":"uuid","description":"Action log ID","example":"123e4567-e89b-12d3-a456-426614174000"},"status":{"type":"string","enum":["SUCCESS","FAILED","RETRYING"],"description":"Execution status","example":"SUCCESS"},"externalId":{"type":"string","nullable":true,"description":"External system ID","example":"ext-123"},"retryAfter":{"type":"string","format":"date-time","nullable":true,"description":"Retry timestamp"}}},"TestActionRequest":{"type":"object","required":["action","entityType","entityId","entityData"],"properties":{"action":{"type":"string","enum":["CREATE","UPDATE","DELETE"],"description":"Action type","example":"CREATE"},"entityType":{"type":"string","description":"Entity type","example":"customer"},"entityId":{"type":"string","description":"Entity ID","example":"customer-123"},"entityData":{"type":"object","description":"Entity data","additionalProperties":true},"authToken":{"type":"string","nullable":true,"description":"Optional auth token for testing"}}},"TestActionResponse":{"type":"object","required":["success","validationResults"],"properties":{"success":{"type":"boolean","description":"Test success","example":true},"validationResults":{"type":"object","required":["requestValid","authenticationValid","endpointReachable"],"properties":{"requestValid":{"type":"boolean","example":true},"authenticationValid":{"type":"boolean","example":true},"endpointReachable":{"type":"boolean","example":true}}},"mockResponse":{"type":"object","nullable":true,"description":"Mock response data"},"errors":{"type":"array","items":{"type":"string"},"description":"Validation errors"},"warnings":{"type":"array","items":{"type":"string"},"description":"Validation warnings"}}},"ActionHistoryResponse":{"type":"object","required":["actions","pagination"],"properties":{"actions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contextTypeId":{"type":"string","format":"uuid"},"contextTypeName":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"actionType":{"type":"string","enum":["CREATE","UPDATE","DELETE"]},"status":{"type":"string"},"errorMessage":{"type":"string","nullable":true},"retryCount":{"type":"integer"},"executedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}},"pagination":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"},"totalPages":{"type":"integer"}}}}},"RetryActionRequest":{"type":"object","properties":{"force":{"type":"boolean","description":"Force retry even if max retries exceeded","example":false},"resetRetryCount":{"type":"boolean","description":"Reset retry counter","example":false}}},"RetryActionResponse":{"type":"object","required":["actionLogId","newStatus","retryCount"],"properties":{"actionLogId":{"type":"string","format":"uuid"},"newStatus":{"type":"string","example":"PENDING"},"retryCount":{"type":"integer","example":1},"estimatedCompletionTime":{"type":"string","format":"date-time"}}},"ActionDetailsResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"contextType":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"code":{"type":"string"},"name":{"type":"string"},"apiBaseUrl":{"type":"string"}}},"entityType":{"type":"string"},"entityId":{"type":"string"},"actionType":{"type":"string"},"status":{"type":"string"},"requestData":{"type":"object"},"responseData":{"type":"object","nullable":true},"errorMessage":{"type":"string","nullable":true},"retryCount":{"type":"integer"},"executedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"ActionMetricsResponse":{"type":"object","properties":{"timeRange":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"},"days":{"type":"integer"}}},"metrics":{"type":"object","properties":{"totalActions":{"type":"integer"},"successfulActions":{"type":"integer"},"failedActions":{"type":"integer"},"retryingActions":{"type":"integer"},"successRate":{"type":"string"},"averageRetryCount":{"type":"number"}}}}},"PaginatedOperationsResponse":{"type":"object","required":["items","total","page","pageSize","hasMore"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ContextOperation"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"hasMore":{"type":"boolean"}}},"ExecuteOperationRequest":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","enum":["workflow","stage","task"],"description":"Entity type","example":"workflow"},"entityId":{"type":"string","format":"uuid","description":"Entity ID","example":"123e4567-e89b-12d3-a456-426614174000"},"parameters":{"type":"object","nullable":true,"description":"Operation parameters","additionalProperties":true},"options":{"type":"object","nullable":true,"properties":{"async":{"type":"boolean","description":"Async execution"},"retryOnFailure":{"type":"boolean","description":"Enable retries"},"maxRetries":{"type":"integer","description":"Max retry attempts"},"timeoutMs":{"type":"integer","description":"Timeout in milliseconds"}}}}},"ExecuteOperationResponse":{"type":"object","properties":{"executionId":{"type":"string","format":"uuid"},"status":{"type":"string"},"result":{"description":"Operation result"},"executionTime":{"type":"integer","description":"Execution time in ms"}}},"PaginatedExecutionLogsResponse":{"type":"object","required":["items","total","page","pageSize","hasMore"],"properties":{"items":{"type":"array","items":{"type":"object"}},"total":{"type":"integer"},"page":{"type":"integer"},"pageSize":{"type":"integer"},"hasMore":{"type":"boolean"}}},"ExecutionLogResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"operationId":{"type":"string","format":"uuid"},"operation":{"type":"object"},"entityType":{"type":"string"},"entityId":{"type":"string","format":"uuid"},"triggerEvent":{"type":"string","nullable":true},"requestUrl":{"type":"string"},"requestMethod":{"type":"string"},"requestHeaders":{"type":"object"},"requestBody":{"type":"object"},"responseStatus":{"type":"integer","nullable":true},"responseHeaders":{"type":"object","nullable":true},"responseBody":{"type":"object","nullable":true},"responseTimeMs":{"type":"integer","nullable":true},"status":{"type":"string"},"errorMessage":{"type":"string","nullable":true},"errorCode":{"type":"string","nullable":true},"retryCount":{"type":"integer"},"maxRetries":{"type":"integer"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"FormSubmissionRequest":{"type":"object","required":["level","entityId","formData"],"properties":{"level":{"type":"string","enum":["workflow","stage","task"],"description":"Context data level","example":"workflow"},"entityId":{"type":"string","format":"uuid","description":"Entity ID"},"formData":{"type":"object","description":"Form field data","additionalProperties":true},"contextKey":{"type":"string","nullable":true,"description":"Context key for storage"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata","additionalProperties":true}}},"FormSubmissionResponse":{"type":"object","properties":{"submissionId":{"type":"string"},"contextKey":{"type":"string"},"storedAt":{"type":"string","format":"date-time"}}},"FormDataResponse":{"type":"object","properties":{"contextKey":{"type":"string"},"data":{"type":"object"},"retrievedAt":{"type":"string","format":"date-time"}}},"AggregateFormDataRequest":{"type":"object","required":["criteria"],"properties":{"criteria":{"type":"object","description":"Aggregation criteria","additionalProperties":true},"aggregationType":{"type":"string","description":"Aggregation type","example":"summary"},"groupBy":{"type":"array","items":{"type":"string"},"description":"Fields to group by"}}},"AggregatedFormDataResponse":{"type":"object","properties":{"summary":{"type":"string"},"criteria":{"type":"object"},"aggregationType":{"type":"string"},"groupBy":{"type":"array","items":{"type":"string"}},"timestamp":{"type":"string","format":"date-time"}}},"UpdateWorkflowTemplateRequest":{"type":"object","properties":{"name":{"type":"string","description":"Template name","minLength":1,"maxLength":255,"example":"Property Acquisition Workflow"},"description":{"type":"string","nullable":true,"description":"Template description","example":"Standard workflow for property acquisition including due diligence and legal review"},"category":{"type":"string","nullable":true,"description":"Template category for organization","maxLength":100,"example":"real_estate"},"isActive":{"type":"boolean","description":"Whether the template is active and available for use","example":true},"validUntil":{"type":"string","format":"date","nullable":true,"description":"Date until which the template is valid","example":"2025-12-31"},"rules":{"type":"object","nullable":true,"description":"Business rules and validation logic","additionalProperties":true,"example":{"maxDuration":90,"requiredApprovals":2}},"publishEvents":{"type":"boolean","description":"Whether to publish events for workflow actions","example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the Pub/Sub topic for events","example":"550e8400-e29b-41d4-a716-446655440020"},"formTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Form template ID for collecting initialization data. Set to null to remove form template.","example":"650e8400-f29c-51e5-b817-556655441234"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata for the template","additionalProperties":true,"example":{"department":"Real Estate","region":"Norway"}},"taskCreationStrategy":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"nullable":true,"description":"Strategy for when tasks are created during workflow instantiation. UPFRONT: all tasks created immediately (default), ON_STAGE_START: tasks created when each stage starts, HYBRID: per-stage configuration","example":"UPFRONT"},"assignmentInheritanceStrategy":{"allOf":[{"$ref":"#/components/schemas/AssignmentInheritanceStrategy"}],"nullable":true,"description":"Strategy for dynamically assigning tasks during workflow instantiation"},"supportedEntityTypes":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Entity types this workflow template supports","example":["property","deal","contract"]}}},"InstantiateWorkflowRequest":{"type":"object","required":["name","entityType","entityId"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Name of the workflow instance","example":"123 Main St Commercial Acquisition"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Optional description of the workflow instance"},"entityType":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","description":"Type of the entity this workflow is associated with","example":"commercial_property"},"entityId":{"type":"string","minLength":1,"maxLength":255,"description":"ID of the entity this workflow is associated with","example":"prop-12345"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of the workflow owner (oversight/accountability)","example":"USER"},"ownerId":{"type":"string","minLength":1,"maxLength":50,"description":"ID of the workflow owner","example":"user-789"},"assigneeType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of the workflow assignee (primary executor). Distinct from owner.","example":"ROLE"},"assigneeId":{"type":"string","minLength":1,"maxLength":50,"description":"ID of the workflow assignee. Defaults to template assignee, then owner.","example":"acquisition-manager"},"assigneeEntityType":{"type":"string","maxLength":100,"description":"Entity type for assignee resolution. Defaults to entityType if not provided.","example":"property"},"assigneeEntityId":{"type":"string","maxLength":50,"description":"Entity ID for assignee resolution. Defaults to entityId if not provided.","example":"prop-12345"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Optional due date for the workflow","example":"2024-03-31T17:00:00.000Z"},"context":{"type":"object","additionalProperties":true,"description":"Optional context data for the workflow","example":{"propertyAddress":"123 Main St","estimatedValue":5000000}},"initializationData":{"type":"object","additionalProperties":true,"description":"Initialization data for template variable interpolation and assignment inheritance","example":{"legalCounsel":"user-456","technicalAssessor":"user-789"}},"assigneeResolutionParameters":{"type":"object","additionalProperties":{"oneOf":[{"type":"string","maxLength":500},{"type":"number"},{"type":"boolean"}]},"maxProperties":20,"propertyNames":{"pattern":"^[a-zA-Z0-9_-]+$","maxLength":50},"description":"Dynamic parameters for assignee resolution","example":{"businessRole":"SALES_REP","region":"EU"}},"taskCreationStrategyOverride":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"description":"Override template's task creation strategy for this instantiation","example":"ON_STAGE_START"},"instantiateAndStart":{"type":"boolean","default":false,"description":"When true, workflow is instantiated and started atomically","example":false},"startAtStage":{"type":"string","minLength":1,"maxLength":100,"description":"Stage definition code to start the workflow at. All stages before this stage will be created as COMPLETED with their tasks also marked COMPLETED. Implies instantiateAndStart: true.","example":"financial-review"},"attachmentMetadata":{"type":"array","maxItems":10,"items":{"type":"object","properties":{"externalDocumentId":{"type":"string","maxLength":50,"description":"External document identifier for the attachment"}}},"description":"Optional metadata for file attachments (corresponds to multipart files)"},"entityLinks":{"type":"array","maxItems":20,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","minLength":1,"maxLength":100,"description":"Type of entity to link"},"entityId":{"type":"string","minLength":1,"maxLength":50,"description":"ID of entity to link"},"linkType":{"type":"string","enum":["related","reference","associated"],"default":"related","description":"Type of relationship"},"metadata":{"type":"object","description":"Optional metadata for the link"}}},"description":"Optional entity links to create with workflow","example":[{"entityType":"property","entityId":"prop-123","linkType":"related"},{"entityType":"client","entityId":"buyer-456","linkType":"related","metadata":{"role":"buyer"}}]}}},"Workflow":{"type":"object","required":["id","organizationId","workflowNumber","name","status","entityType","entityId","totalStages","completedStages","publishEvents","createdAt","createdBy","updatedAt","updatedBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow instance identifier","example":"workflow-789e0123-e89b-12d3-a456-426614174333"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this workflow","example":"550e8400-e29b-41d4-a716-446655440000"},"workflowNumber":{"type":"string","description":"Auto-generated workflow number in format WF-YYYY-NNN","pattern":"^WF-\\d{4}-\\d{3}$","example":"WF-2024-087"},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the template this workflow was created from","example":"550e8400-e29b-41d4-a716-446655440001"},"name":{"type":"string","description":"Workflow instance name","maxLength":255,"example":"Trondheim Waterfront Commercial Complex Acquisition"},"description":{"type":"string","nullable":true,"description":"Detailed workflow description","maxLength":2000,"example":"Acquisition of prime waterfront commercial development with mixed-use potential"},"status":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"],"description":"Current workflow status: DRAFT (newly created), ACTIVE (in progress), ON_HOLD (paused), COMPLETED (finished), CANCELLED (terminated), ARCHIVED (completed and archived)","example":"DRAFT"},"currentStageId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the currently active stage","example":"stage-001"},"entityType":{"type":"string","description":"Type of business entity this workflow is associated with","maxLength":100,"examples":["property_acquisition","tenant_onboarding","property_maintenance","financial_approval"],"example":"property_acquisition"},"entityId":{"type":"string","description":"Business entity identifier","maxLength":50,"example":"trondheim-waterfront-2024-001"},"assigneeEntityType":{"type":"string","nullable":true,"maxLength":100,"description":"Entity type used for assignee resolution when assigneeType is ROLE. Allows the workflow to be about one entity (entityType/entityId) while assignees are resolved against a different entity. If null, defaults to entityType.","examples":["property","project","client","tenant"],"example":"property"},"assigneeEntityId":{"type":"string","nullable":true,"maxLength":50,"description":"Entity ID used for assignee resolution when assigneeType is ROLE. This ID is passed to the Apart API to determine which position/user holds the specified role for this entity. If null, defaults to entityId.","example":"prop-456"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the workflow was started (moved from DRAFT to ACTIVE)","example":"2024-03-01T09:00:00.000Z"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Workflow completion due date","example":"2024-09-30T23:59:59.000Z"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the workflow was completed","example":"2024-08-15T16:30:00.000Z"},"ownerType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of workflow owner","example":"ROLE"},"ownerId":{"type":"string","nullable":true,"description":"Workflow owner identifier","maxLength":50,"example":"senior-acquisition-manager"},"totalStages":{"type":"integer","description":"Total number of stages in this workflow","minimum":0,"example":6},"completedStages":{"type":"integer","description":"Number of completed stages","minimum":0,"example":0},"progressPercentage":{"type":"number","format":"decimal","nullable":true,"description":"Workflow completion percentage (0.00 to 100.00)","minimum":0,"maximum":100,"example":0},"publishEvents":{"type":"boolean","description":"Whether this workflow publishes events to Pub/Sub","default":true,"example":true},"eventTopicId":{"type":"string","format":"uuid","nullable":true,"description":"Pub/Sub topic ID for event publishing","example":"550e8400-e29b-41d4-a716-446655440010"},"context":{"type":"object","nullable":true,"description":"Business context data for this workflow instance","additionalProperties":true,"example":{"propertyValue":85000000,"propertyType":"commercial-mixed-use","location":"Trondheim Waterfront District, Norway","urgencyLevel":"high","environmentalReview":true}},"metadata":{"type":"object","nullable":true,"description":"Additional workflow metadata","additionalProperties":true},"template":{"type":"object","nullable":true,"description":"Information about the template this workflow was created from","properties":{"id":{"type":"string","format":"uuid","description":"Template identifier","example":"550e8400-e29b-41d4-a716-446655440001"},"code":{"type":"string","description":"Template code","example":"property-acquisition-commercial-v2"},"name":{"type":"string","description":"Template name","example":"Commercial Property Acquisition v2.1"},"category":{"type":"string","nullable":true,"description":"Template category","example":"real-estate"}}},"workflowStages":{"type":"array","items":{"$ref":"#/components/schemas/WorkflowStage"},"description":"Ordered list of workflow stages"},"createdAt":{"type":"string","format":"date-time","description":"Workflow creation timestamp","example":"2024-02-28T10:30:00.000Z"},"createdBy":{"type":"string","description":"User who created the workflow","maxLength":255,"example":"api-user@apart.no"},"updatedAt":{"type":"string","format":"date-time","description":"Last workflow update timestamp","example":"2024-02-28T10:30:00.000Z"},"updatedBy":{"type":"string","description":"User who last updated the workflow","maxLength":255,"example":"api-user@apart.no"}}},"WorkflowStage":{"type":"object","required":["id","organizationId","workflowId","stageDefinitionId","stageCode","stageName","sequenceOrder","status","isMilestone","isBlocking","isOptional","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique workflow stage identifier","example":"stage-001"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"workflowId":{"type":"string","format":"uuid","description":"Parent workflow identifier","example":"workflow-789e0123-e89b-12d3-a456-426614174333"},"stageDefinitionId":{"type":"string","format":"uuid","description":"Stage definition identifier","example":"550e8400-e29b-41d4-a716-446655440201"},"stageCode":{"type":"string","description":"Stage code from definition","maxLength":50,"example":"legal-due-diligence"},"stageName":{"type":"string","description":"Stage name from definition","maxLength":255,"example":"Legal Due Diligence Review"},"sequenceOrder":{"type":"integer","description":"Order of this stage in the workflow","minimum":1,"example":1},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","SKIPPED","FAILED","BLOCKED"],"description":"Current stage status: PENDING (not ready), READY (ready to start), IN_PROGRESS (executing), COMPLETED (finished), SKIPPED (bypassed), FAILED (error), BLOCKED (waiting for dependencies)","example":"PENDING"},"isMilestone":{"type":"boolean","description":"Whether this stage is a milestone","default":false,"example":false},"isBlocking":{"type":"boolean","description":"Whether this stage blocks workflow progression","default":true,"example":true},"isOptional":{"type":"boolean","description":"Whether this stage can be skipped","default":false,"example":false},"scheduledAt":{"type":"string","format":"date-time","nullable":true,"description":"When the stage is scheduled to start","example":"2024-03-10T09:00:00.000Z"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Stage completion due date","example":"2024-03-15T17:00:00.000Z"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the stage was started","example":"2024-03-10T10:15:00.000Z"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the stage was completed","example":"2024-03-14T16:30:00.000Z"},"assignedToType":{"type":"string","enum":["ROLE","POSITION","USER"],"nullable":true,"description":"Type of stage assignee","example":"ROLE"},"assignedToId":{"type":"string","nullable":true,"description":"Stage assignee identifier","maxLength":50,"example":"legal-counsel"},"assignedToName":{"type":"string","nullable":true,"description":"Display name of stage assignee","maxLength":255,"example":"Legal Counsel Team"},"assignedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the stage was assigned","example":"2024-03-10T09:00:00.000Z"},"skipReason":{"type":"string","nullable":true,"description":"Reason for skipping this stage (if applicable)","maxLength":500},"failureReason":{"type":"string","nullable":true,"description":"Reason for stage failure (if applicable)","maxLength":500},"completionNotes":{"type":"string","nullable":true,"description":"Notes added upon stage completion","maxLength":1000},"context":{"type":"object","nullable":true,"description":"Stage-specific context data","additionalProperties":true},"metadata":{"type":"object","nullable":true,"description":"Additional stage metadata","additionalProperties":true},"createdAt":{"type":"string","format":"date-time","description":"Stage creation timestamp","example":"2024-02-28T10:30:00.000Z"},"createdBy":{"type":"string","description":"User who created the stage","maxLength":255,"example":"system"}}},"CreateStageDefinitionRequest":{"type":"object","required":["code","name"],"properties":{"code":{"type":"string","minLength":1,"maxLength":50,"pattern":"^[a-zA-Z0-9_-]+$","description":"Unique code for the stage definition","example":"legal-review-enhanced"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable stage name","example":"Enhanced Legal Due Diligence"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed description of the stage","example":"Comprehensive legal review with compliance checks"},"category":{"type":"string","maxLength":100,"nullable":true,"description":"Category for organizing stage definitions","example":"legal"},"isSystemStage":{"type":"boolean","default":false,"description":"Whether this is a system-managed stage (cannot be modified)","example":false},"canBeSkipped":{"type":"boolean","default":true,"description":"Whether this stage can be skipped in workflows","example":false},"requiresAssignment":{"type":"boolean","default":true,"description":"Whether this stage requires assignment to a user/role","example":true},"primaryService":{"type":"string","maxLength":100,"nullable":true,"description":"Primary service or department responsible for this stage","example":"legal-department"},"defaultDurationDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true,"description":"Default expected duration in days","example":12},"escalationAfterDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true,"description":"Days after which to escalate if not completed","example":15},"autoAssignmentRules":{"type":"object","additionalProperties":true,"description":"Rules for automatic assignment","example":{"defaultRole":"senior-legal-counsel","fallbackRole":"legal-manager","workloadBalancing":true,"skillsRequired":["property-law","compliance"]}},"metadata":{"type":"object","additionalProperties":true,"description":"Custom metadata for the stage definition","example":{"complexity":"high","priority":"critical"}}}},"UpdateStageDefinitionRequest":{"type":"object","description":"All fields optional for update. Code and isSystemStage cannot be changed.","properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable stage name"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed description"},"category":{"type":"string","maxLength":100,"nullable":true,"description":"Category"},"canBeSkipped":{"type":"boolean","description":"Whether stage can be skipped"},"requiresAssignment":{"type":"boolean","description":"Whether assignment is required"},"primaryService":{"type":"string","maxLength":100,"nullable":true,"description":"Primary service/department"},"defaultDurationDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true,"description":"Default duration in days"},"escalationAfterDays":{"type":"integer","minimum":1,"maximum":365,"nullable":true,"description":"Escalation timing"},"autoAssignmentRules":{"type":"object","additionalProperties":true,"description":"Assignment rules"},"metadata":{"type":"object","additionalProperties":true,"description":"Custom metadata"}}},"UpdateStageTaskTemplatesRequest":{"oneOf":[{"type":"object","required":["taskTemplateIds"],"properties":{"taskTemplateIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Replace all task templates with this list"}},"additionalProperties":false},{"type":"object","properties":{"add":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Task template IDs to add"},"remove":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Task template IDs to remove"}},"additionalProperties":false}]},"StageDefinition":{"type":"object","required":["id","organizationId","code","name","isSystemStage","canBeSkipped","requiresAssignment","createdAt","createdBy"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique stage definition identifier","example":"stage-def-001"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier","example":"550e8400-e29b-41d4-a716-446655440000"},"code":{"type":"string","maxLength":50,"description":"Unique code for the stage definition","example":"initial-review"},"name":{"type":"string","maxLength":255,"description":"Human-readable name","example":"Initial Review"},"description":{"type":"string","nullable":true,"description":"Detailed description","example":"First review stage of the process"},"category":{"type":"string","maxLength":100,"nullable":true,"description":"Category for organizing stages","example":"review"},"isSystemStage":{"type":"boolean","description":"Whether this is a system-provided stage definition","default":false,"example":false},"canBeSkipped":{"type":"boolean","description":"Whether this stage can be skipped","default":false,"example":true},"requiresAssignment":{"type":"boolean","description":"Whether this stage requires assignment","default":true,"example":true},"primaryService":{"type":"string","maxLength":100,"nullable":true,"description":"Primary service associated with this stage","example":"review-service"},"defaultDurationDays":{"type":"integer","nullable":true,"minimum":1,"description":"Default duration in days","example":5},"escalationAfterDays":{"type":"integer","nullable":true,"minimum":1,"description":"Days before escalation","example":7},"autoAssignmentRules":{"type":"object","nullable":true,"description":"Automatic assignment rules","additionalProperties":true,"example":{"defaultRole":"reviewer","fallbackRole":"manager"}},"metadata":{"type":"object","nullable":true,"description":"Additional metadata","additionalProperties":true,"example":{"complexity":"medium","priority":"high"}},"createdAt":{"type":"string","format":"date-time","description":"Stage definition creation timestamp","example":"2024-02-28T10:30:00.000Z"},"createdBy":{"type":"string","description":"User who created the definition","maxLength":255,"example":"admin@example.com"},"updatedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last update timestamp","example":"2024-03-01T14:20:00.000Z"},"updatedBy":{"type":"string","nullable":true,"description":"User who last updated the definition","maxLength":255,"example":"manager@example.com"}}},"Event":{"type":"object","required":["id","organizationId","eventTypeCode","eventSource","aggregateType","aggregateId","eventData","publishingStatus","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique event identifier","example":"123e4567-e89b-12d3-a456-426614174000"},"organizationId":{"type":"string","format":"uuid","description":"Organization identifier - all events are organization-scoped","example":"org-123e4567-e89b-12d3-a456-426614174000"},"eventTypeCode":{"type":"string","maxLength":100,"description":"Event type code defining the nature of the event","example":"project.created","enum":["project.created","project.updated","project.deleted","project.status_changed","project.archived","project.restored","task.created","task.updated","task.deleted","task.assigned","task.completed","task.status_changed","workflow.created","workflow.started","workflow.paused","workflow.resumed","workflow.completed","workflow.cancelled","workflow-stage.started","workflow-stage.completed","workflow-stage.skipped","workflow-stage.failed","attachment.uploaded","attachment.downloaded","attachment.deleted","attachment.virus_scanned","section.created","section.updated","section.deleted","service.registered","service.updated","service.deactivated","dependency.created","dependency.updated","dependency.deleted"]},"eventSource":{"type":"string","enum":["USER","SYSTEM","WEBHOOK","SCHEDULE"],"description":"Source that triggered the event","example":"USER"},"correlationId":{"type":"string","format":"uuid","nullable":true,"description":"Correlation ID for tracking related events across services","example":"987fcdeb-51a2-43d7-b456-426614174000"},"aggregateType":{"type":"string","maxLength":50,"description":"Type of the aggregate root entity","example":"project","enum":["project","task","workflow","workflow-stage","attachment","section","service","dependency"]},"aggregateId":{"type":"string","format":"uuid","description":"Identifier of the aggregate root entity","example":"456e7890-e89b-12d3-a456-426614174000"},"entityType":{"type":"string","maxLength":100,"nullable":true,"description":"Type of the specific entity (may differ from aggregate type)","example":"project"},"entityId":{"type":"string","maxLength":50,"nullable":true,"description":"Identifier of the specific entity","example":"456e7890-e89b-12d3-a456-426614174000"},"eventData":{"type":"object","description":"Event payload containing current state and change details","example":{"projectId":"456e7890-e89b-12d3-a456-426614174000","name":"Leilighet Storgata 15","description":"Salg av leilighet i Oslo sentrum","status":"ACTIVE","startDate":"2024-02-01","endDate":"2024-06-30","ownerId":"user-123","metadata":{"propertyType":"apartment","rooms":3,"size":85}}},"previousData":{"type":"object","nullable":true,"description":"Previous state of the entity before the change (for update events)","example":{"name":"Untitled Project","status":"DRAFT","description":null}},"actorId":{"type":"string","maxLength":50,"nullable":true,"description":"Identifier of the actor who performed the action","example":"user-123"},"actorType":{"type":"string","maxLength":50,"nullable":true,"description":"Type of actor (USER, SYSTEM, SERVICE)","example":"USER","enum":["USER","SYSTEM","SERVICE","WORKFLOW"]},"actorName":{"type":"string","maxLength":255,"nullable":true,"description":"Display name of the actor","example":"Lars Andersen"},"version":{"type":"string","maxLength":10,"description":"Event schema version","example":"1.0","default":"1.0"},"publishingStatus":{"type":"string","maxLength":50,"description":"Status of event publication to external systems","example":"PUBLISHED","enum":["PENDING","PUBLISHED","FAILED","PARTIAL"],"default":"PENDING"},"publishingError":{"type":"string","nullable":true,"description":"Error message if publishing failed","example":"Topic not found: org-12345678-project-events"},"publishedAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp when event was successfully published","example":"2024-02-15T10:35:00.000Z"},"publishedToTopics":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Array of topic IDs where event was published","example":["topic-123e4567-e89b-12d3-a456-426614174000"]},"createdAt":{"type":"string","format":"date-time","description":"Event creation timestamp","example":"2024-02-15T10:30:00.000Z"},"idempotencyKey":{"type":"string","maxLength":255,"nullable":true,"description":"Idempotency key to prevent duplicate event creation","example":"project-create-456e7890-20240215103000"},"eventType":{"type":"object","nullable":true,"description":"Event type metadata","properties":{"name":{"type":"string","description":"Human-readable event type name","example":"Project Created"},"category":{"type":"string","description":"Event category for grouping","example":"PROJECT_LIFECYCLE"}}},"eventPublications":{"type":"array","items":{"$ref":"#/components/schemas/EventPublication"},"description":"Publication details for each topic"}}},"TemplateRequirements":{"type":"object","required":["templateId","templateCode","templateName","templateType","version","isActive","createdAt","updatedAt"],"properties":{"templateId":{"type":"string","format":"uuid","description":"Unique identifier for the template","example":"550e8400-e29b-41d4-a716-446655440001"},"templateCode":{"type":"string","description":"Template code identifier","example":"property-acquisition-commercial-v2"},"templateName":{"type":"string","description":"Human-readable template name","example":"Commercial Property Acquisition v2.1"},"templateType":{"type":"string","enum":["WORKFLOW","TASK"],"description":"Type of template","example":"WORKFLOW"},"version":{"type":"object","required":["major","minor"],"properties":{"major":{"type":"integer","description":"Major version number","example":2},"minor":{"type":"integer","description":"Minor version number","example":1}},"description":"Template version information"},"isActive":{"type":"boolean","description":"Whether the template is active and can be used","example":true},"supportedEntityTypes":{"type":"array","items":{"type":"string"},"description":"Entity types this workflow template supports","example":["commercial_property","residential_property"]},"supportedContexts":{"type":"array","items":{"type":"string"},"description":"Context types this task template supports","example":["property_crm","inspection_system"]},"initializationRequirements":{"type":"object","description":"Requirements for initializing the template","properties":{"schema":{"type":"object","description":"JSON Schema for initialization data validation","example":{"type":"object","required":["property_address","acquisition_type"],"properties":{"property_address":{"type":"string","minLength":1,"description":"Full property address"},"acquisition_type":{"type":"string","enum":["purchase","lease","development"],"description":"Type of property acquisition"}}}},"uiSchema":{"type":"object","description":"UI Schema for form rendering","example":{"property_address":{"ui:widget":"textarea","ui:placeholder":"Enter full property address"}}},"contextRequirements":{"type":"array","items":{"type":"object","properties":{"contextType":{"type":"string","description":"Required context type"},"required":{"type":"boolean","description":"Whether this context is required"},"description":{"type":"string","description":"Description of the context requirement"}}},"description":"Context requirements for the template"}}},"formTemplateId":{"type":"string","format":"uuid","description":"Associated form template ID","example":"550e8400-e29b-41d4-a716-446655440002"},"formSchema":{"type":"object","description":"Form schema from associated form template"},"metadata":{"type":"object","description":"Additional template metadata"},"createdAt":{"type":"string","format":"date-time","description":"Template creation timestamp","example":"2024-01-15T09:00:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"Template last update timestamp","example":"2024-01-20T14:30:00.000Z"}}},"ValidationRequest":{"type":"object","required":["initializationData"],"properties":{"initializationData":{"type":"object","description":"Data to validate against template requirements","example":{"property_address":"123 Main St, Oslo, Norway","acquisition_type":"purchase","budget":5000000}},"contextData":{"type":"object","description":"Optional context data for validation","example":{"user_role":"acquisition_manager","region":"oslo"}},"entityType":{"type":"string","description":"Entity type for workflow templates","example":"commercial_property"},"entityId":{"type":"string","description":"Entity ID for workflow templates","example":"property-123"}}},"ValidationResponse":{"type":"object","required":["isValid","errors","warnings"],"properties":{"isValid":{"type":"boolean","description":"Whether the validation passed","example":true},"errors":{"type":"array","items":{"type":"object","required":["field","code","message"],"properties":{"field":{"type":"string","description":"Field that failed validation","example":"property_address"},"code":{"type":"string","description":"Error code","example":"REQUIRED_FIELD_MISSING"},"message":{"type":"string","description":"Human-readable error message","example":"Property address is required"},"value":{"description":"Value that caused the error","example":null},"constraint":{"description":"Validation constraint that was violated","example":"required"}}},"description":"Validation errors"},"warnings":{"type":"array","items":{"type":"object","required":["field","code","message"],"properties":{"field":{"type":"string","description":"Field that triggered warning"},"code":{"type":"string","description":"Warning code"},"message":{"type":"string","description":"Warning message"}}},"description":"Validation warnings"},"resolvedData":{"type":"object","description":"Resolved initialization data after validation"}}},"PreviewRequest":{"type":"object","required":["initializationData"],"properties":{"initializationData":{"type":"object","description":"Data to use for preview generation","example":{"property_address":"123 Main St, Oslo, Norway","acquisition_type":"purchase"}},"entityType":{"type":"string","description":"Entity type for workflow templates","example":"commercial_property"},"entityId":{"type":"string","description":"Entity ID for workflow templates","example":"property-123"},"workflowName":{"type":"string","description":"Custom workflow name","example":"Oslo Commercial Property Acquisition"},"taskTitle":{"type":"string","description":"Custom task title","example":"Property Inspection - 123 Main St"}}},"InstantiationPreview":{"type":"object","required":["templateId","templateType","willCreate","warnings","recommendations"],"properties":{"templateId":{"type":"string","format":"uuid","description":"Template ID used for preview"},"templateType":{"type":"string","enum":["WORKFLOW","TASK"],"description":"Type of template"},"willCreate":{"type":"object","description":"Preview of what will be created","properties":{"workflow":{"type":"object","properties":{"name":{"type":"string","description":"Workflow name"},"description":{"type":"string","description":"Workflow description"},"entityType":{"type":"string","description":"Entity type"},"entityId":{"type":"string","description":"Entity ID"},"estimatedStages":{"type":"integer","description":"Number of stages that will be created"},"estimatedTasks":{"type":"integer","description":"Number of tasks that will be created"},"estimatedDurationDays":{"type":"integer","description":"Estimated duration in days"}}},"tasks":{"type":"array","items":{"type":"object","properties":{"templateId":{"type":"string","format":"uuid","description":"Task template ID"},"name":{"type":"string","description":"Task name"},"description":{"type":"string","description":"Task description"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority"},"estimatedDurationMinutes":{"type":"integer","description":"Estimated duration in minutes"},"assigneeType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Assignee type"},"assigneeId":{"type":"string","description":"Assignee ID"},"assigneeName":{"type":"string","description":"Assignee display name"},"dependsOn":{"type":"array","items":{"type":"string"},"description":"Task dependencies"}}},"description":"Tasks that will be created"},"stages":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Stage name"},"description":{"type":"string","description":"Stage description"},"sequenceOrder":{"type":"integer","description":"Stage sequence order"},"isOptional":{"type":"boolean","description":"Whether stage is optional"},"isBlocking":{"type":"boolean","description":"Whether stage blocks workflow progress"},"estimatedTasks":{"type":"integer","description":"Number of tasks in this stage"}}},"description":"Workflow stages that will be created"}}},"warnings":{"type":"array","items":{"type":"string"},"description":"Preview warnings"},"recommendations":{"type":"array","items":{"type":"string"},"description":"Preview recommendations"}}},"WorkflowInstantiationRequest":{"type":"object","required":["name","entityType","entityId"],"properties":{"name":{"type":"string","description":"Name for the workflow instance","example":"Oslo Commercial Property Acquisition"},"description":{"type":"string","description":"Optional description for the workflow","example":"Acquisition process for commercial property at 123 Main St"},"entityType":{"type":"string","description":"Type of entity this workflow is associated with. Must match one of the template supported entity types.","example":"commercial_property"},"entityId":{"type":"string","description":"ID of entity this workflow is associated with","example":"property-123"},"ownerType":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of the workflow owner","example":"USER"},"ownerId":{"type":"string","description":"ID of the workflow owner","example":"user-456"},"dueDate":{"type":"string","format":"date-time","description":"When the workflow should be completed","example":"2024-05-01T17:00:00.000Z"},"context":{"type":"object","description":"Optional context data for the workflow. Used for assignment inheritance with CONTEXT_BASED mode.","example":{"user_role":"acquisition_manager","region":"oslo"}},"initializationData":{"type":"object","description":"Optional initialization data for workflow template instantiation. Used for template variable interpolation and assignment inheritance. Must match the template initialization requirements schema if provided.","example":{"property_address":"123 Main St, Oslo, Norway","acquisition_type":"purchase","budget":5000000}},"assigneeResolutionParameters":{"type":"object","description":"Dynamic parameters for assignee resolution (e.g., businessRole, region)","example":{"businessRole":"SALES_REP","region":"EU"}},"taskCreationStrategyOverride":{"type":"string","enum":["UPFRONT","ON_STAGE_START","HYBRID"],"description":"Override the template's task creation strategy for this instantiation","example":"UPFRONT"},"instantiateAndStart":{"type":"boolean","description":"When true, workflow will be instantiated and immediately started in a single atomic operation. Default: false (workflow created in DRAFT status)","example":false},"attachmentMetadata":{"type":"array","maxItems":10,"items":{"type":"object","properties":{"externalDocumentId":{"type":"string","description":"External document identifier for the attachment","example":"doc-external-123"}}},"description":"Optional metadata for attachments being uploaded with the workflow. Each entry corresponds to an attachment file at the same index."},"entityLinks":{"type":"array","maxItems":20,"items":{"type":"object","required":["entityType","entityId"],"properties":{"entityType":{"type":"string","description":"Type of the entity to link","example":"property"},"entityId":{"type":"string","description":"ID of the entity to link","example":"prop-trondheim-001"},"linkType":{"type":"string","enum":["related","reference","associated"],"description":"Type of relationship. Defaults to \"related\".","example":"related"},"metadata":{"type":"object","description":"Optional metadata for the entity link","example":{"role":"subject_property","priority":"high"}}}},"description":"Optional entity links to create alongside the workflow (Issue #446). Atomically creates bidirectional relationships. Duplicates are automatically deduplicated. Maximum 20 links per request."},"approvalChainOverrides":{"$ref":"#/components/schemas/ApprovalChainOverrides"}}},"ApprovalChainOverrides":{"type":"array","maxItems":10,"items":{"type":"object","required":["step","approverType","approverId"],"properties":{"step":{"type":"integer","minimum":1,"description":"Step number in the template approval chain to override","example":1},"approverType":{"type":"string","enum":["USER","POSITION","ROLE"],"description":"Type of approver override. USER/POSITION sets the resolved approver directly; ROLE substitutes a different role ID for resolution.","example":"POSITION"},"approverId":{"type":"string","description":"ID of the approver override","example":"position-manager-oslo"},"approverName":{"type":"string","description":"Optional display name for the approver","example":"Oslo Regional Manager"}}},"description":"Override specific approval chain steps at instantiation time. USER/POSITION overrides set the resolved approver directly, bypassing ROLE resolution. ROLE overrides substitute a different role ID for normal resolution. Maximum 10 overrides per request."},"TaskInstantiationRequest":{"type":"object","required":["initializationData"],"properties":{"initializationData":{"type":"object","description":"Data to initialize the task template with","example":{"property_address":"123 Main St, Oslo, Norway","inspection_type":"pre_purchase"}},"projectId":{"type":"string","format":"uuid","description":"Project to create the task in","example":"550e8400-e29b-41d4-a716-446655440003"},"sectionId":{"type":"string","format":"uuid","description":"Section to create the task in","example":"550e8400-e29b-41d4-a716-446655440004"},"workflowId":{"type":"string","format":"uuid","description":"Workflow to associate the task with","example":"550e8400-e29b-41d4-a716-446655440005"},"workflowStageId":{"type":"string","format":"uuid","description":"Workflow stage to associate the task with","example":"550e8400-e29b-41d4-a716-446655440006"},"taskTitle":{"type":"string","description":"Custom title for the task","example":"Property Inspection - 123 Main St"},"taskDescription":{"type":"string","description":"Custom description for the task","example":"Comprehensive pre-purchase inspection of commercial property"},"entityType":{"type":"string","description":"Type of entity this task is associated with","example":"property"},"entityId":{"type":"string","description":"ID of entity this task is associated with","example":"property-123"},"assigneeOverride":{"type":"object","required":["type","id"],"properties":{"type":{"type":"string","enum":["USER","ROLE","POSITION"],"description":"Type of assignee override","example":"USER"},"id":{"type":"string","description":"ID of assignee override","example":"user-789"}},"description":"Override the template default assignee"},"dueDate":{"type":"string","format":"date-time","description":"When the task should be completed","example":"2024-02-15T17:00:00.000Z"},"contextData":{"type":"object","description":"Optional context data for the task","example":{"inspection_priority":"high","special_requirements":"structural_assessment"}},"skipValidation":{"type":"boolean","description":"Skip initialization data validation","example":false},"approvalChainOverrides":{"$ref":"#/components/schemas/ApprovalChainOverrides"}}},"InstantiationResult":{"type":"object","required":["success","created","errors","warnings"],"properties":{"success":{"type":"boolean","description":"Whether the instantiation was successful","example":true},"workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Created workflow ID","example":"550e8400-e29b-41d4-a716-446655440007"},"workflowNumber":{"type":"string","description":"Generated workflow number","example":"WF-202402-0001"},"name":{"type":"string","description":"Workflow name","example":"Oslo Commercial Property Acquisition"},"status":{"type":"string","enum":["DRAFT","ACTIVE","ON_HOLD","COMPLETED","CANCELLED","ARCHIVED"],"description":"Workflow status","example":"ACTIVE"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp","example":"2024-02-01T09:00:00.000Z"}},"description":"Created workflow information (for workflow instantiation)"},"task":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Created task ID","example":"550e8400-e29b-41d4-a716-446655440008"},"title":{"type":"string","description":"Task title","example":"Property Inspection - 123 Main St"},"status":{"type":"string","enum":["PENDING","READY","IN_PROGRESS","COMPLETED","CANCELLED","BLOCKED","FAILED"],"description":"Task status","example":"PENDING"},"createdAt":{"type":"string","format":"date-time","description":"Creation timestamp","example":"2024-02-01T09:00:00.000Z"}},"description":"Created task information (for task instantiation)"},"created":{"type":"object","required":["workflowCount","stageCount","taskCount"],"properties":{"workflowCount":{"type":"integer","description":"Number of workflows created","example":1},"stageCount":{"type":"integer","description":"Number of stages created","example":7},"taskCount":{"type":"integer","description":"Number of tasks created","example":15},"attachmentCount":{"type":"integer","description":"Number of attachments uploaded (multipart/form-data only)","example":2}},"description":"Summary of created entities"},"attachments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Attachment ID","example":"550e8400-e29b-41d4-a716-446655440009"},"originalFilename":{"type":"string","description":"Original filename","example":"contract.pdf"},"fileSize":{"type":"integer","description":"File size in bytes","example":2048576},"mimeType":{"type":"string","description":"MIME type","example":"application/pdf"},"downloadUrl":{"type":"string","format":"uri","description":"Signed download URL (temporary)","example":"https://storage.googleapis.com/bucket/contract.pdf?signed=..."}}},"description":"Uploaded attachments (multipart/form-data only)"},"errors":{"type":"array","items":{"type":"object","required":["field","code","message"],"properties":{"field":{"type":"string","description":"Field that caused the error"},"code":{"type":"string","description":"Error code"},"message":{"type":"string","description":"Error message"}}},"description":"Instantiation errors"},"warnings":{"type":"array","items":{"type":"string"},"description":"Instantiation warnings"}}},"AssignmentType":{"type":"string","enum":["ROLE","POSITION","USER"],"description":"Type of assignment identifier","example":"ROLE"},"MultiMatchBehavior":{"type":"string","enum":["FIRST","PENDING_MANUAL","FAIL"],"description":"\nHow to handle when multiple assignees match a role resolution:\n- `FIRST`: Take the first match automatically\n- `PENDING_MANUAL`: Mark for manual selection by user\n- `FAIL`: Reject the assignment completely\n        ","example":"FIRST"},"AssignmentResolutionStatus":{"type":"string","enum":["RESOLVED","PENDING_MANUAL","FAILED","NO_RESOLVER"],"description":"\nStatus of assignment resolution:\n- `RESOLVED`: Successfully resolved to a specific assignee\n- `PENDING_MANUAL`: Multiple matches found, requires manual selection\n- `FAILED`: Resolution failed (no matches or error)\n- `NO_RESOLVER`: No resolver configuration exists for this assignment type\n        ","example":"RESOLVED"},"AssignmentTypeResolverConfig":{"type":"object","required":["id","organizationId","assignmentType","resolutionTargetType","isDefault","priority","multiMatchBehavior","createdAt","updatedAt"],"description":"\nConfiguration for resolving assignments to actual assignees.\n\n## Multi-Resolver Support\nOrganizations can have multiple resolvers per assignment type, each targeting\nspecific role identifiers. For example:\n- \"Letting Officer\" role → resolves to POSITION (internal employee)\n- \"Applicant\" role → resolves to USER (external user via Context Operation)\n\n## Resolution Lookup Order\n1. Exact match on (organization, assignmentType, assignmentIdentifier)\n2. Default resolver (isDefault=true) for the assignment type\n3. Legacy resolver with null identifier\n        ","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the resolver configuration","example":"550e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this configuration","example":"550e8400-e29b-41d4-a716-446655440002"},"assignmentType":{"$ref":"#/components/schemas/AssignmentType","description":"The assignment type this resolver matches on"},"assignmentIdentifier":{"type":"string","nullable":true,"maxLength":100,"description":"Specific role identifier (e.g., \"Applicant\", \"Letting Officer\"). Null for default/catch-all resolvers.","example":"Applicant"},"resolutionTargetType":{"$ref":"#/components/schemas/AssignmentType","description":"What type this resolver produces (POSITION for employees, USER for external users)","example":"USER"},"isDefault":{"type":"boolean","description":"When true, this resolver is used as fallback when no specific identifier match is found","example":false},"priority":{"type":"integer","minimum":0,"maximum":1000,"description":"Higher priority resolvers are matched first when multiple resolvers exist (0-1000)","example":100},"resolutionOperationId":{"type":"string","format":"uuid","nullable":true,"description":"Optional Context Operation to use for custom resolution logic (required for USER target type)","example":"550e8400-e29b-41d4-a716-446655440003"},"parameterConfig":{"type":"object","nullable":true,"description":"Configuration for operation parameters","example":{"parameters":{"applicationId":{"source":"context","contextPath":"workflow.applicationId"},"entityId":{"source":"entity","entityField":"entityId"}}}},"responseMapping":{"type":"object","nullable":true,"description":"Mapping from operation response to assignment data","example":{"assigneeId":"data.userId","assigneeName":"data.applicantName"}},"multiMatchBehavior":{"$ref":"#/components/schemas/MultiMatchBehavior"},"createdAt":{"type":"string","format":"date-time","description":"When the configuration was created","example":"2025-01-15T10:30:00.000Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the configuration was last updated","example":"2025-01-15T14:45:00.000Z"}}},"CreateAssignmentTypeResolverRequest":{"type":"object","description":"\nRequest body for creating or updating an assignment type resolver.\n\n## Multi-Resolver Configuration Examples\n\n**Internal Employee (Letting Officer)**:\n```json\n{\n  \"resolutionTargetType\": \"POSITION\",\n  \"isDefault\": false,\n  \"priority\": 100,\n  \"multiMatchBehavior\": \"FIRST\"\n}\n```\n\n**External User (Applicant)**:\n```json\n{\n  \"resolutionTargetType\": \"USER\",\n  \"isDefault\": false,\n  \"priority\": 100,\n  \"resolutionOperationId\": \"operation-uuid\",\n  \"responseMapping\": {\n    \"assigneeId\": \"data.userId\",\n    \"assigneeName\": \"data.applicantName\"\n  }\n}\n```\n        ","properties":{"assignmentIdentifier":{"type":"string","maxLength":100,"description":"Specific role identifier (e.g., \"Applicant\", \"Letting Officer\")","example":"Applicant"},"resolutionTargetType":{"$ref":"#/components/schemas/AssignmentType","description":"What type this resolver produces (POSITION for employees, USER for external users)","default":"POSITION"},"isDefault":{"type":"boolean","description":"When true, this resolver is used as fallback when no specific identifier match is found","default":false},"priority":{"type":"integer","minimum":0,"maximum":1000,"description":"Higher priority resolvers are matched first (0-1000)","default":0},"resolutionOperationId":{"type":"string","format":"uuid","nullable":true,"description":"Context Operation ID for custom resolution (required for USER target type)","example":"550e8400-e29b-41d4-a716-446655440003"},"parameterConfig":{"type":"object","nullable":true,"description":"Operation parameter configuration","example":{"parameters":{"applicationId":{"source":"context","contextPath":"workflow.applicationId"}}}},"responseMapping":{"type":"object","nullable":true,"description":"Response to assignment mapping","example":{"assigneeId":"data.userId","assigneeName":"data.applicantName"}},"multiMatchBehavior":{"$ref":"#/components/schemas/MultiMatchBehavior"}}},"UpdateAssignmentTypeResolverRequest":{"type":"object","description":"Request body for updating an assignment type resolver. All fields are optional.","properties":{"resolutionTargetType":{"$ref":"#/components/schemas/AssignmentType","description":"What type this resolver produces"},"isDefault":{"type":"boolean","description":"When true, this resolver is used as fallback"},"priority":{"type":"integer","minimum":0,"maximum":1000,"description":"Higher priority resolvers are matched first (0-1000)"},"resolutionOperationId":{"type":"string","format":"uuid","nullable":true,"description":"Context Operation ID for custom resolution"},"parameterConfig":{"type":"object","nullable":true,"description":"Operation parameter configuration"},"responseMapping":{"type":"object","nullable":true,"description":"Response to assignment mapping"},"multiMatchBehavior":{"$ref":"#/components/schemas/MultiMatchBehavior"}}},"AssignmentResolutionResult":{"type":"object","required":["status"],"properties":{"status":{"$ref":"#/components/schemas/AssignmentResolutionStatus"},"assigneeType":{"$ref":"#/components/schemas/AssignmentType","nullable":true,"description":"Resolved assignee type (only if status is RESOLVED)"},"assigneeId":{"type":"string","nullable":true,"description":"Resolved assignee ID (only if status is RESOLVED)","example":"position-123"},"assigneeName":{"type":"string","nullable":true,"description":"Resolved assignee display name","example":"John Doe - Property Manager"},"positions":{"type":"array","nullable":true,"description":"Multiple matching positions (only if status is PENDING_MANUAL)","items":{"type":"object","properties":{"contactId":{"type":"string","description":"Contact/user ID","example":"contact-456"},"positionId":{"type":"string","description":"Position ID","example":"position-789"},"businessRole":{"type":"string","description":"Business role name","example":"Property Manager"},"name":{"type":"string","description":"Person name","example":"Jane Smith"},"email":{"type":"string","format":"email","nullable":true,"description":"Contact email","example":"jane.smith@example.com"}}}},"resolvedFrom":{"type":"object","nullable":true,"description":"Metadata about resolution source","properties":{"source":{"type":"string","enum":["context_operation","apart_api","direct","default"],"description":"Where the resolution came from","example":"apart_api"},"operationId":{"type":"string","format":"uuid","nullable":true,"description":"Context operation ID if used"},"entityType":{"type":"string","nullable":true,"description":"Entity type used in resolution","example":"property"},"entityId":{"type":"string","nullable":true,"description":"Entity ID used in resolution","example":"property-123"},"timestamp":{"type":"string","format":"date-time","description":"When resolution occurred"}}},"resolutionLog":{"type":"object","nullable":true,"description":"Detailed execution log for debugging","properties":{"requestTimestamp":{"type":"string","format":"date-time","description":"When resolution was requested"},"resolutionTimestamp":{"type":"string","format":"date-time","description":"When resolution completed"},"executionTimeMs":{"type":"integer","description":"Execution time in milliseconds","example":245},"steps":{"type":"array","description":"Step-by-step execution trace","items":{"type":"object","properties":{"step":{"type":"string","description":"Step name","example":"APART_API_CALL"},"timestamp":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["success","failed","skipped"]},"details":{"type":"object","additionalProperties":true},"error":{"type":"string","nullable":true}}}}}},"error":{"type":"object","nullable":true,"description":"Error details if resolution failed","properties":{"code":{"type":"string","description":"Error code","example":"MISSING_CONTEXT"},"message":{"type":"string","description":"Error message","example":"Entity ID and API key required for role resolution"},"details":{"type":"object","additionalProperties":true,"description":"Additional error context"}}}}},"PreviewResolutionRequest":{"type":"object","required":["assignmentType","assignmentId"],"properties":{"assignmentType":{"$ref":"#/components/schemas/AssignmentType"},"assignmentId":{"type":"string","description":"The assignment identifier (role name, position ID, or user ID)","example":"property_manager"},"entityType":{"type":"string","nullable":true,"description":"Type of entity for context (e.g., property, contract)","example":"property"},"entityId":{"type":"string","nullable":true,"description":"External entity ID for resolution","example":"prop-456"},"workflowContext":{"type":"object","nullable":true,"additionalProperties":true,"description":"Workflow context data for resolution"},"contextData":{"type":"object","nullable":true,"additionalProperties":true,"description":"Additional context data for resolution"}}},"WorkflowDataSchemaInput":{"type":"object","description":"Input schema for creating or updating workflow data schemas","required":["schemaCode","schemaVersion","entityDefinitions","validationRules"],"properties":{"schemaCode":{"type":"string","minLength":1,"maxLength":100,"pattern":"^[a-zA-Z0-9_-]+$","description":"Unique identifier code for the schema. Use uppercase with underscores (e.g., PROPERTY_INSPECTION, CUSTOMER_ONBOARDING).","example":"PROPERTY_INSPECTION"},"schemaVersion":{"type":"string","minLength":1,"maxLength":20,"pattern":"^[0-9]+\\.[0-9]+\\.[0-9]+$","description":"Semantic version number for the schema (MAJOR.MINOR.PATCH). Use for tracking schema evolution and migrations.","example":"1.0.0"},"workflowTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Optional association with a workflow template. When set, this schema is the default for workflows created from this template.","example":"550e8400-e29b-41d4-a716-446655440000"},"entityDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/EntityDefinition"},"minItems":1,"maxItems":50,"description":"Array of entity definitions that define the structure of data. Each entity represents a logical grouping of related fields."},"validationRules":{"type":"array","items":{"$ref":"#/components/schemas/ValidationRule"},"maxItems":100,"description":"Global validation rules that apply across entities. For field-specific validation, use the validation array within FieldDefinition."},"computedFields":{"type":"array","items":{"$ref":"#/components/schemas/ComputedField"},"nullable":true,"maxItems":20,"description":"Computed fields are automatically calculated based on other field values using formulas. Updated when dependencies change."},"stateTransitions":{"type":"array","items":{"$ref":"#/components/schemas/StateTransition"},"nullable":true,"maxItems":20,"description":"State transition rules that define how data can move between different states with conditions and actions."},"isActive":{"type":"boolean","description":"Whether this schema version is currently active and available for use. Only one version per schemaCode should be active.","default":true}}},"WorkflowDataSchema":{"type":"object","required":["id","organizationId","schemaCode","schemaVersion","entityDefinitions","isActive","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the schema","example":"550e8400-e29b-41d4-a716-446655440001"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this schema","example":"550e8400-e29b-41d4-a716-446655440002"},"workflowTemplateId":{"type":"string","format":"uuid","nullable":true,"description":"Associated workflow template ID","example":"550e8400-e29b-41d4-a716-446655440003"},"schemaCode":{"type":"string","maxLength":100,"description":"Unique code identifier for the schema","example":"PROPERTY_INSPECTION_V1"},"schemaVersion":{"type":"string","maxLength":50,"description":"Version of the schema for migration tracking","example":"1.2.0"},"entityDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/EntityDefinition"},"description":"Entity definitions that make up this schema","minItems":1},"validationRules":{"type":"array","items":{"$ref":"#/components/schemas/ValidationRule"},"description":"Global validation rules for data validation","default":[]},"computedFields":{"type":"array","items":{"$ref":"#/components/schemas/ComputedField"},"description":"Computed fields with formulas and dependencies","default":[]},"stateTransitions":{"type":"array","items":{"$ref":"#/components/schemas/StateTransition"},"description":"State transition rules for workflow progression","default":[]},"isActive":{"type":"boolean","description":"Whether this schema version is currently active","example":true},"createdAt":{"type":"string","format":"date-time","description":"When the schema was created","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the schema was last updated","example":"2024-01-20T14:45:00Z"},"instanceCount":{"type":"integer","minimum":0,"description":"Number of active instances using this schema","example":15}},"additionalProperties":false},"EntityDefinition":{"type":"object","description":"Defines an entity structure with fields, relationships, and constraints","required":["name","fields"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-zA-Z][a-zA-Z0-9_]*$","description":"Entity name using PascalCase convention. Must be unique within the schema.","example":"PropertyDetails"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Human-readable description of what this entity represents.","example":"Detailed information about a property including specifications and amenities"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/FieldDefinition"},"minItems":1,"description":"Array of field definitions for this entity."},"relationships":{"type":"array","items":{"type":"object","required":["name","type","targetEntity"],"properties":{"name":{"type":"string","maxLength":255,"description":"Name of the relationship","example":"owner"},"type":{"type":"string","enum":["one-to-one","one-to-many","many-to-many"],"description":"Type of relationship cardinality","example":"many-to-one"},"targetEntity":{"type":"string","maxLength":255,"description":"Name of the target entity (must exist in schema)","example":"Person"},"foreignKey":{"type":"string","maxLength":255,"nullable":true,"description":"Foreign key field name for the relationship","example":"ownerId"},"cascadeDelete":{"type":"boolean","nullable":true,"description":"Whether to cascade delete related entities","default":false}}},"nullable":true,"description":"Relationships to other entities in the schema."},"constraints":{"type":"array","items":{"type":"object","required":["type","fields"],"properties":{"type":{"type":"string","enum":["unique","check","foreign_key","not_null"],"description":"Type of constraint"},"fields":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Fields involved in the constraint"},"condition":{"type":"string","nullable":true,"description":"SQL-like condition for check constraints"}}},"nullable":true,"description":"Entity-level constraints for data integrity."}},"additionalProperties":false},"FieldDefinition":{"type":"object","description":"Defines a single field within an entity including its type, validation, and metadata","required":["name","type","required"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-zA-Z][a-zA-Z0-9_]*$","description":"Field name using camelCase convention. Must be unique within the entity.","example":"propertyType"},"type":{"type":"string","enum":["string","number","boolean","date","datetime","email","url","phone","json","array","file","currency","percentage","duration"],"description":"Data type of the field. Specialized types (email, url, phone, currency, etc.) include built-in validation and formatting.","example":"string"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Human-readable description explaining the field's purpose and expected values.","example":"Type of property: residential, commercial, or industrial"},"required":{"type":"boolean","description":"Whether this field must have a value. Required fields are validated on create and update operations.","example":true},"defaultValue":{"nullable":true,"description":"Default value assigned when field is not provided. Type must match the field type.","example":"residential"},"validation":{"type":"array","items":{"$ref":"#/components/schemas/ValidationRule"},"nullable":true,"description":"Field-specific validation rules applied in addition to type validation.","example":[{"type":"enum","config":{"values":["residential","commercial","industrial"]},"message":"Property type must be residential, commercial, or industrial"}]},"metadata":{"type":"object","additionalProperties":true,"nullable":true,"description":"Custom metadata for UI rendering, categorization, or application-specific purposes.","example":{"displayOrder":1,"category":"basic_info","sensitive":false,"uiWidget":"dropdown"}}},"additionalProperties":false},"RelationshipDefinition":{"type":"object","required":["name","type","targetEntity"],"properties":{"name":{"type":"string","maxLength":100,"description":"Name of the relationship","example":"owner"},"type":{"type":"string","enum":["one_to_one","one_to_many","many_to_one","many_to_many"],"description":"Type of relationship","example":"many_to_one"},"targetEntity":{"type":"string","maxLength":100,"description":"Name of the target entity","example":"Person"},"description":{"type":"string","maxLength":500,"description":"Description of the relationship","example":"Property owner information"}},"additionalProperties":false},"ValidationRule":{"type":"object","description":"Validation rule for field or entity-level data validation","required":["type","config"],"properties":{"type":{"type":"string","enum":["required","min_length","max_length","pattern","email","url","range","enum","jsonlogic","custom"],"description":"Type of validation rule. Use 'jsonlogic' for complex conditional validation.","example":"pattern"},"config":{"type":"object","additionalProperties":true,"description":"Configuration specific to the validation type. Contents vary by rule type.","examples":{"min_length":{"minLength":5},"max_length":{"maxLength":100},"pattern":{"pattern":"^[A-Z][0-9]{4}$"},"range":{"min":0,"max":100},"enum":{"values":["option1","option2","option3"]},"jsonlogic":{"rule":{">":[{"var":"age"},18]}}}},"message":{"type":"string","maxLength":500,"nullable":true,"description":"Custom error message shown when validation fails. Use placeholders like {fieldName}, {minLength}, etc.","example":"Property code must start with a capital letter followed by 4 digits"},"errorCode":{"type":"string","maxLength":100,"nullable":true,"description":"Machine-readable error code for programmatic error handling.","example":"INVALID_PROPERTY_CODE_FORMAT"}},"additionalProperties":false},"ComputedField":{"type":"object","description":"Field with a value calculated from other fields using a formula","required":["name","type","formula","dependencies"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"pattern":"^[a-zA-Z][a-zA-Z0-9_]*$","description":"Name of the computed field. Use camelCase convention.","example":"totalSquareFootage"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Explanation of what this computed field calculates.","example":"Total square footage calculated from length, width, and number of floors"},"type":{"type":"string","enum":["string","number","boolean","date","datetime","currency","percentage"],"description":"Expected return type of the formula evaluation.","example":"number"},"formula":{"$ref":"#/components/schemas/FormulaDefinition","description":"The formula definition including type, expression, and optional parameters."},"dependencies":{"type":"array","items":{"type":"string"},"minItems":1,"description":"List of field names that this computed field depends on. Triggers recalculation when dependencies change.","example":["length","width","floors"]},"updateTriggers":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Events that should trigger recalculation beyond dependency changes.","example":["on_save","on_workflow_status_change"]}},"additionalProperties":false},"FormulaDefinition":{"type":"object","description":"Formula for computing field values","required":["type","expression"],"properties":{"type":{"type":"string","enum":["expression","aggregation","lookup","custom"],"description":"Type of formula: 'expression' for mathematical formulas, 'aggregation' for sum/avg/etc., 'lookup' for referencing other entities, 'custom' for custom functions.","example":"expression"},"expression":{"type":"string","minLength":1,"description":"The formula expression. Use {fieldName} placeholders for field references. Mathematical operators: +, -, *, /, %, ^. Functions: sum(), avg(), min(), max(), round(), etc.","example":"{length} * {width} * {floors}"},"parameters":{"type":"object","additionalProperties":true,"nullable":true,"description":"Additional parameters for formula evaluation like precision, rounding mode, units, etc.","example":{"precision":2,"roundingMode":"half_up","units":"square_feet"}}},"additionalProperties":false},"StateTransition":{"type":"object","description":"Defines allowed state transitions with conditions and actions","required":["name","from","to"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Human-readable name for this transition.","example":"Submit for Review"},"from":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Array of source states from which this transition is allowed.","example":["draft","rejected"]},"to":{"type":"string","minLength":1,"description":"Target state after successful transition.","example":"pending_review"},"conditions":{"type":"array","items":{"type":"object","required":["type","config"],"properties":{"type":{"type":"string","enum":["field_value","expression","external_check"],"description":"Type of condition: field_value for simple field checks, expression for JSONLogic conditions, external_check for API calls."},"config":{"type":"object","additionalProperties":true,"description":"Configuration for the condition type."}}},"nullable":true,"description":"Conditions that must be met for the transition to be allowed."},"actions":{"type":"array","items":{"type":"object","required":["type","config"],"properties":{"type":{"type":"string","enum":["set_field","send_notification","call_webhook","create_task"],"description":"Type of action to execute during transition."},"config":{"type":"object","additionalProperties":true,"description":"Configuration for the action type."}}},"nullable":true,"description":"Actions to execute when transition occurs."},"autoTransition":{"type":"boolean","nullable":true,"description":"Whether this transition should occur automatically when conditions are met.","default":false},"timeout":{"type":"number","minimum":0,"nullable":true,"description":"Optional timeout in milliseconds for automatic transition.","example":3600000}},"additionalProperties":false},"WorkflowDataInstanceInput":{"type":"object","description":"Input schema for creating or updating workflow data instances","required":["workflowId","schemaId","currentData"],"properties":{"workflowId":{"type":"string","format":"uuid","description":"The workflow instance that this data belongs to. Each workflow can have one data instance per schema.","example":"550e8400-e29b-41d4-a716-446655440001"},"schemaId":{"type":"string","format":"uuid","description":"The schema that defines the structure and validation rules for this data. Must be an active schema.","example":"550e8400-e29b-41d4-a716-446655440002"},"currentData":{"type":"object","additionalProperties":true,"description":"The structured data conforming to the schema. Will be validated against entity definitions and validation rules.","example":{"propertyType":"residential","address":"123 Main St","squareFootage":2500,"bedrooms":3,"bathrooms":2,"yearBuilt":2020}},"reason":{"type":"string","maxLength":500,"nullable":true,"description":"Optional reason for the data update. Stored in history for audit purposes.","example":"Updated property details after inspection"}}},"WorkflowDataInstance":{"type":"object","required":["id","organizationId","workflowId","schemaId","currentData","dataHistory","lastValidated","validationState","checksum","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the data instance","example":"550e8400-e29b-41d4-a716-446655440005"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this instance","example":"550e8400-e29b-41d4-a716-446655440002"},"workflowId":{"type":"string","format":"uuid","description":"Associated workflow instance","example":"550e8400-e29b-41d4-a716-446655440006"},"schemaId":{"type":"string","format":"uuid","description":"Schema used to validate this data","example":"550e8400-e29b-41d4-a716-446655440001"},"currentData":{"type":"object","additionalProperties":true,"description":"Current state of the structured data","example":{"propertyType":"residential","address":"123 Main St","squareFootage":2500,"bedrooms":3,"bathrooms":2}},"dataHistory":{"type":"array","items":{"$ref":"#/components/schemas/DataInstanceHistoryEntry"},"description":"Complete history of data changes","minItems":1},"lastValidated":{"type":"string","format":"date-time","description":"When the data was last validated","example":"2024-01-20T09:15:00Z"},"validationState":{"$ref":"#/components/schemas/ValidationState"},"checksum":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 checksum of current data for integrity verification","example":"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"},"createdAt":{"type":"string","format":"date-time","description":"When the instance was created","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the instance was last updated","example":"2024-01-20T14:45:00Z"},"workflow":{"type":"object","description":"Associated workflow summary","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"workflowNumber":{"type":"string"}}}},"additionalProperties":false},"DataInstanceHistoryEntry":{"type":"object","required":["timestamp","changes","reason","version"],"properties":{"timestamp":{"type":"string","format":"date-time","description":"When this change occurred","example":"2024-01-20T14:45:00Z"},"changes":{"type":"array","items":{"$ref":"#/components/schemas/FieldChange"},"description":"List of field changes in this update"},"reason":{"type":"string","maxLength":500,"description":"Reason for the change","example":"Updated property details after inspection"},"version":{"type":"integer","minimum":1,"description":"Version number of this change","example":3},"userId":{"type":"string","format":"uuid","description":"User who made the change","example":"550e8400-e29b-41d4-a716-446655440007"}},"additionalProperties":false},"FieldChange":{"type":"object","required":["field","changeType"],"properties":{"field":{"type":"string","description":"Name of the field that changed","example":"squareFootage"},"oldValue":{"description":"Previous value of the field","example":2400},"newValue":{"description":"New value of the field","example":2500},"changeType":{"type":"string","enum":["create","update","delete"],"description":"Type of change","example":"update"}},"additionalProperties":false},"ValidationState":{"type":"object","required":["isValid","errors","warnings","lastValidated","validatedBy"],"properties":{"isValid":{"type":"boolean","description":"Whether the data passes all validations","example":true},"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"Validation errors (must be empty for valid data)"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"Validation warnings (non-blocking issues)"},"lastValidated":{"type":"string","format":"date-time","description":"When validation was last performed","example":"2024-01-20T09:15:00Z"},"validatedBy":{"type":"string","description":"System or service that performed validation","example":"workflow-data-validation-service"}},"additionalProperties":false},"ValidationError":{"type":"object","required":["message","code","rule","severity"],"properties":{"field":{"type":"string","description":"Field that failed validation","example":"email"},"message":{"type":"string","description":"Human-readable error message","example":"Email address must be in a valid format"},"code":{"type":"string","description":"Machine-readable error code","example":"INVALID_EMAIL_FORMAT"},"rule":{"type":"string","description":"Validation rule that was violated","example":"pattern"},"severity":{"type":"string","enum":["error","warning"],"description":"Severity of the validation issue","example":"error"},"context":{"type":"object","additionalProperties":true,"description":"Additional context about the validation failure","example":{"pattern":"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$","actualValue":"invalid-email"}}},"additionalProperties":false},"DataValidationResult":{"type":"object","required":["isValid","data"],"properties":{"isValid":{"type":"boolean","description":"Whether the provided data is valid","example":true},"data":{"type":"object","additionalProperties":true,"description":"The validated data (potentially transformed)","example":{"propertyType":"residential","address":"123 Main St","squareFootage":2500}},"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"Validation errors if any"},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"},"description":"Validation warnings if any"}},"additionalProperties":false},"CreateSchemaRequest":{"type":"object","required":["schemaCode","schemaVersion","entityDefinitions"],"properties":{"workflowTemplateId":{"type":"string","format":"uuid","description":"Optional workflow template to associate with","example":"550e8400-e29b-41d4-a716-446655440003"},"schemaCode":{"type":"string","maxLength":100,"pattern":"^[A-Z][A-Z0-9_]*$","description":"Unique code for the schema (uppercase with underscores)","example":"PROPERTY_INSPECTION_V1"},"schemaVersion":{"type":"string","maxLength":50,"pattern":"^\\d+\\.\\d+\\.\\d+$","description":"Semantic version of the schema","example":"1.0.0"},"entityDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/EntityDefinition"},"description":"Entity definitions for the schema","minItems":1},"validationRules":{"type":"array","items":{"$ref":"#/components/schemas/ValidationRule"},"description":"Global validation rules","default":[]},"computedFields":{"type":"array","items":{"$ref":"#/components/schemas/ComputedField"},"description":"Computed field definitions","default":[]},"stateTransitions":{"type":"array","items":{"$ref":"#/components/schemas/StateTransition"},"description":"State transition rules","default":[]}},"additionalProperties":false,"example":{"schemaCode":"PROPERTY_INSPECTION_V1","schemaVersion":"1.0.0","entityDefinitions":[{"name":"PropertyDetails","fields":[{"name":"address","type":"string","required":true,"description":"Property address"},{"name":"propertyType","type":"string","required":true,"validation":[{"name":"Property Type Enum","type":"enum","config":{"values":["residential","commercial","industrial"]}}]}]}]}},"UpdateSchemaRequest":{"type":"object","properties":{"entityDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/EntityDefinition"},"description":"Updated entity definitions"},"validationRules":{"type":"array","items":{"$ref":"#/components/schemas/ValidationRule"},"description":"Updated validation rules"},"computedFields":{"type":"array","items":{"$ref":"#/components/schemas/ComputedField"},"description":"Updated computed fields"},"stateTransitions":{"type":"array","items":{"$ref":"#/components/schemas/StateTransition"},"description":"Updated state transitions"},"isActive":{"type":"boolean","description":"Whether to activate or deactivate the schema"}},"additionalProperties":false},"CreateInstanceRequest":{"type":"object","required":["workflowId","schemaId","currentData"],"properties":{"workflowId":{"type":"string","format":"uuid","description":"Workflow instance to associate with","example":"550e8400-e29b-41d4-a716-446655440006"},"schemaId":{"type":"string","format":"uuid","description":"Schema to validate against","example":"550e8400-e29b-41d4-a716-446655440001"},"currentData":{"type":"object","additionalProperties":true,"description":"Initial data for the instance","example":{"propertyType":"residential","address":"123 Main St","squareFootage":2500}}},"additionalProperties":false},"UpdateInstanceRequest":{"type":"object","required":["currentData"],"properties":{"currentData":{"type":"object","additionalProperties":true,"description":"Updated data for the instance","example":{"propertyType":"residential","address":"123 Main St","squareFootage":2600,"lastInspected":"2024-01-20T14:45:00Z"}},"reason":{"type":"string","maxLength":500,"description":"Reason for the update","example":"Updated square footage after re-measurement"}},"additionalProperties":false},"ValidateDataRequest":{"type":"object","required":["data","entityDefinitions"],"properties":{"data":{"type":"object","additionalProperties":true,"description":"Data to validate","example":{"email":"user@example.com","age":25,"status":"active"}},"entityDefinitions":{"type":"array","items":{"$ref":"#/components/schemas/EntityDefinition"},"description":"Schema entities to validate against","minItems":1},"validationLevel":{"type":"string","enum":["strict","lenient"],"default":"strict","description":"Level of validation strictness","example":"strict"}},"additionalProperties":false}},"WorkflowDataModelConfig":{"type":"object","required":["enable_data_model_sync","mapping_strategy"],"properties":{"enable_data_model_sync":{"type":"boolean","description":"Whether to enable synchronization between form data and workflow data model","example":true},"data_schema_code":{"type":"string","nullable":true,"minLength":1,"maxLength":100,"description":"Code identifier for the data schema to use","example":"contact-schema"},"data_schema_id":{"type":"string","format":"uuid","nullable":true,"description":"UUID of the data schema to use","example":"123e4567-e89b-12d3-a456-426614174000"},"mapping_strategy":{"type":"string","enum":["explicit","convention","auto"],"description":"Strategy to use for mapping form fields to data model fields","example":"convention"},"form_field_mappings":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Explicit mappings from form field names to data model field paths","example":{"first_name":"person.firstName","last_name":"person.lastName","email_address":"contact.email"}},"auto_create_instance":{"type":"boolean","nullable":true,"description":"Whether to automatically create a data instance if one does not exist","example":true},"merge_strategy":{"type":"string","enum":["replace","merge","append"],"nullable":true,"description":"Strategy for merging new form data with existing data model data","example":"merge"},"validate_before_sync":{"type":"boolean","nullable":true,"description":"Whether to validate form data against the schema before syncing","example":true}},"example":{"enable_data_model_sync":true,"data_schema_code":"contact-schema","mapping_strategy":"convention","auto_create_instance":true,"merge_strategy":"merge","validate_before_sync":true}},"HistoricalSyncResult":{"type":"object","required":["processed","synced","failed"],"properties":{"processed":{"type":"integer","minimum":0,"description":"Total number of tasks processed for historical sync","example":25},"synced":{"type":"integer","minimum":0,"description":"Number of tasks successfully synced to data model","example":23},"failed":{"type":"integer","minimum":0,"description":"Number of tasks that failed to sync","example":2}},"example":{"processed":25,"synced":23,"failed":2}},"FormDataSyncStatus":{"type":"object","required":["hasDataInstance","lastSyncAt","instanceId"],"properties":{"hasDataInstance":{"type":"boolean","description":"Whether a data instance exists for this workflow","example":true},"lastSyncAt":{"type":"string","format":"date-time","nullable":true,"description":"Timestamp of the last data sync","example":"2024-01-15T10:30:00.000Z"},"instanceId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the data instance if it exists","example":"987e6543-e21b-12d3-a456-426614174000"}},"example":{"hasDataInstance":true,"lastSyncAt":"2024-01-15T10:30:00.000Z","instanceId":"987e6543-e21b-12d3-a456-426614174000"}},"TaskAssignmentOverride":{"type":"object","description":"Task-level assignment inheritance override configuration","required":["enabled","strategy"],"properties":{"enabled":{"type":"boolean","description":"Whether this task should use inheritance override"},"strategy":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","NEVER_INHERIT"],"description":"Assignment strategy to use for this specific task"}}},"AssignmentInheritanceStrategy":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","HYBRID"],"description":"Assignment inheritance mode for workflow tasks","example":"WORKFLOW_OWNER"},"rules":{"type":"object","properties":{"byTaskCode":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","HYBRID"]},"description":"Task-specific inheritance modes by task template code","example":{"REVIEW_TASK":"STAGE_DEFAULT","APPROVAL_TASK":"WORKFLOW_OWNER"}},"byRole":{"type":"object","additionalProperties":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED","HYBRID"]},"description":"Role-specific inheritance modes by assignee type","example":{"ROLE":"STAGE_DEFAULT","POSITION":"WORKFLOW_OWNER"}},"fallback":{"type":"string","enum":["WORKFLOW_OWNER","STAGE_DEFAULT","CONTEXT_BASED","TEMPLATE_DEFINED"],"description":"Fallback mode when no specific rule matches","example":"TEMPLATE_DEFINED"}},"description":"Rules for HYBRID mode to determine which strategy to use for specific tasks or roles"},"contextMapping":{"type":"object","required":["source","field","type"],"properties":{"source":{"type":"string","enum":["initializationData","entityContext"],"description":"Source of context data for assignment resolution","example":"initializationData"},"field":{"type":"string","description":"Field name in the context data that contains assignee information","example":"assignedAgent"},"type":{"type":"string","enum":["USER","POSITION"],"description":"Type of assignment target","example":"USER"}},"description":"Context mapping configuration for CONTEXT_BASED mode"}},"description":"Configuration for how task assignments should inherit from workflow context, stage defaults, or other sources","examples":[{"mode":"WORKFLOW_OWNER","description":"All tasks assigned to workflow owner (personal workflows)"},{"mode":"STAGE_DEFAULT","description":"Tasks inherit from their stage default assignee"},{"mode":"CONTEXT_BASED","contextMapping":{"source":"initializationData","field":"primaryAgent","type":"USER"},"description":"Assign tasks based on initialization data field"},{"mode":"HYBRID","rules":{"byTaskCode":{"REVIEW_TASK":"STAGE_DEFAULT","APPROVAL_TASK":"WORKFLOW_OWNER"},"fallback":"TEMPLATE_DEFINED"},"description":"Mixed strategy based on task codes with fallback"}]},"VariablesSchemaResponse":{"type":"object","required":["version","mode","schema","capabilities"],"properties":{"version":{"type":"string","description":"API version","example":"1.0"},"mode":{"type":"string","enum":["data_model","legacy"],"description":"Variables system mode - data_model for modern workflows with structured schemas, legacy for form-based workflows","example":"data_model"},"schema":{"type":"object","description":"Schema definitions for all available variable sources","properties":{"entities":{"type":"object","description":"Entity schema definitions from workflow data models","additionalProperties":true,"example":{"Customer":{"name":{"type":"string","required":true},"email":{"type":"email","required":true},"phone":{"type":"phone","required":false}}}},"workflow":{"type":"object","description":"Standard workflow field schemas","additionalProperties":true,"example":{"id":{"type":"string","description":"Workflow ID"},"name":{"type":"string","description":"Workflow name"},"status":{"type":"string","description":"Workflow status"}}},"computed":{"type":"object","description":"Computed field schemas (data_model mode only)","additionalProperties":true,"example":{"fullContact":{"type":"string","formula":"{Customer.name} <{Customer.email}>"}}},"context":{"type":"object","description":"Context data schemas","additionalProperties":true,"example":{"workflow":{"type":"object","description":"Workflow-level context"},"stage":{"type":"object","description":"Stage-level context"}}},"forms":{"type":"object","description":"Form field schemas from task templates","additionalProperties":true,"example":{"task-123":{"taskName":"Customer Information","schema":{"fields":[{"name":"customerName","type":"text","required":true}]}}}}}},"capabilities":{"type":"object","required":["supportsComputed","supportsValidation","supportsExternalSync"],"description":"System capabilities for this workflow","properties":{"supportsComputed":{"type":"boolean","description":"Whether computed fields are supported","example":true},"supportsValidation":{"type":"boolean","description":"Whether data validation is supported","example":true},"supportsExternalSync":{"type":"boolean","description":"Whether external system synchronization is supported","example":true}}}}},"ShareToken":{"type":"object","required":["id","token","entityType","entityId","permissions","createdBy","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the share token"},"token":{"type":"string","description":"The share token string"},"entityType":{"type":"string","enum":["task","project","workflow"],"description":"Type of entity being shared"},"entityId":{"type":"string","format":"uuid","description":"ID of the shared entity"},"permissions":{"type":"array","items":{"type":"string","enum":["read","update","comment","complete"]},"description":"Permissions granted by this token"},"cascadeAccess":{"type":"boolean","description":"Whether access cascades to child entities","default":false},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"When the token expires"},"maxUses":{"type":"integer","nullable":true,"description":"Maximum number of times the token can be used"},"useCount":{"type":"integer","description":"Number of times the token has been used","default":0},"isActive":{"type":"boolean","description":"Whether the token is currently active","default":true},"recipientEmail":{"type":"string","format":"email","nullable":true,"description":"Email of the intended recipient"},"recipientName":{"type":"string","nullable":true,"description":"Name of the intended recipient"},"shareMessage":{"type":"string","nullable":true,"description":"Message included with the share"},"createdBy":{"type":"string","format":"uuid","description":"ID of the user who created the token"},"createdByName":{"type":"string","description":"Name of the user who created the token"},"createdAt":{"type":"string","format":"date-time","description":"When the token was created"},"updatedAt":{"type":"string","format":"date-time","description":"When the token was last updated"},"lastAccessedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the token was last accessed"},"metadata":{"type":"object","nullable":true,"description":"Additional metadata for the token"}}},"VariablesDataResponse":{"type":"object","required":["version","mode","data","metadata"],"properties":{"version":{"type":"string","description":"API version","example":"1.0"},"mode":{"type":"string","enum":["data_model","legacy"],"description":"Variables system mode","example":"data_model"},"data":{"type":"object","description":"Runtime variable data from all sources","properties":{"entities":{"type":"object","description":"Entity data from workflow data models","additionalProperties":true,"example":{"customer":{"name":"John Doe","email":"john.doe@example.com","phone":"+1-555-123-4567"}}},"workflow":{"type":"object","description":"Standard workflow data","additionalProperties":true,"example":{"id":"123e4567-e89b-12d3-a456-426614174000","name":"Customer Onboarding","status":"in_progress","workflowNumber":"WF-2024-001"}},"computed":{"type":"object","description":"Computed field values","additionalProperties":true,"example":{"fullContact":"John Doe <john.doe@example.com>","isHighPriority":true}},"context":{"type":"object","description":"Context data values","additionalProperties":true,"example":{"salesRep":"Alice Johnson","region":"North America"}},"forms":{"type":"object","description":"Form submission data","additionalProperties":true,"example":{"task-456":{"taskName":"Identity Verification","data":{"documentType":"passport","verified":true},"submittedAt":"2024-01-15T14:22:33Z"}}}}},"metadata":{"type":"object","required":["lastUpdated","dataVersion","validationStatus","sources"],"description":"Metadata about the variables data","properties":{"lastUpdated":{"type":"string","format":"date-time","description":"When the data was last updated","example":"2024-01-15T14:22:33Z"},"dataVersion":{"type":"string","description":"Version identifier for the data","example":"1234567890"},"validationStatus":{"type":"string","enum":["valid","invalid","unknown"],"description":"Overall data validation status","example":"valid"},"sources":{"type":"array","items":{"type":"string","enum":["data_model","forms","context","workflow"]},"description":"Data sources included in response","example":["data_model","workflow","context","forms"]}}}}},"QueryVariablesRequest":{"type":"object","description":"Request body for advanced workflow variables querying","properties":{"options":{"type":"object","nullable":true,"description":"Query options for controlling data inclusion and behavior","properties":{"includeComputed":{"type":"boolean","description":"Include computed field values"},"includeContext":{"type":"boolean","description":"Include context data"},"includeForms":{"type":"boolean","description":"Include form submission data"},"includeWorkflow":{"type":"boolean","description":"Include workflow metadata"},"fields":{"type":"array","items":{"type":"string"},"description":"Specific fields to include (whitelist)"},"excludeFields":{"type":"array","items":{"type":"string"},"description":"Fields to exclude (blacklist)"},"sources":{"type":"array","items":{"type":"string","enum":["data_model","forms","context","workflow"]},"description":"Data sources to query"},"useCache":{"type":"boolean","description":"Enable caching"},"refreshCache":{"type":"boolean","description":"Force cache refresh"},"validateData":{"type":"boolean","description":"Enable data validation"},"includeValidationDetails":{"type":"boolean","description":"Include validation details"}}},"filters":{"type":"array","items":{"type":"object","properties":{"entityType":{"type":"string","description":"Filter by entity type"},"fieldPath":{"type":"string","description":"Dot-notation field path (e.g., 'PropertyDetails.address')"},"valuePattern":{"type":"string","description":"Pattern to match against field values"},"lastModifiedSince":{"type":"string","format":"date-time","description":"Filter data modified after this date"},"source":{"type":"string","enum":["data_model","forms","context","workflow"],"description":"Filter by data source"}}},"nullable":true,"description":"Array of filters to apply to the query"}}},"QueryVariablesResponse":{"allOf":[{"$ref":"#/components/schemas/VariablesDataResponse"},{"type":"object","required":["query"],"properties":{"query":{"type":"object","required":["options","executedAt","executionTimeMs"],"description":"Query execution information","properties":{"options":{"type":"object","description":"Query options that were applied","additionalProperties":true,"example":{"includeComputed":true,"sources":["data_model","workflow"]}},"filters":{"type":"array","description":"Filters that were applied","items":{"type":"object","additionalProperties":true},"example":[{"source":"workflow","fieldPath":"status","valuePattern":"active"}]},"executedAt":{"type":"string","format":"date-time","description":"When the query was executed","example":"2024-01-15T16:45:22.123Z"},"executionTimeMs":{"type":"number","minimum":0,"description":"Query execution time in milliseconds","example":45}}}}}],"example":{"version":"1.0","mode":"data_model","data":{"entities":{"customer":{"name":"Jane Smith","email":"jane.smith@example.com"}},"workflow":{"name":"Property Purchase","status":"active"}},"metadata":{"lastUpdated":"2024-01-15T16:45:22Z","dataVersion":"9876543210","validationStatus":"valid","sources":["data_model","workflow"]},"query":{"options":{"includeComputed":true,"sources":["data_model","workflow"]},"filters":[{"source":"workflow","fieldPath":"status","valuePattern":"active"}],"executedAt":"2024-01-15T16:45:22.123Z","executionTimeMs":45}}},"CreateShareTokenRequest":{"type":"object","required":["entityType","entityId","permissions"],"properties":{"entityType":{"type":"string","enum":["task","project","workflow"],"description":"Type of entity to share","example":"task"},"entityId":{"type":"string","format":"uuid","description":"ID of entity to share","example":"789e0123-e89b-12d3-a456-426614174333"},"permissions":{"type":"array","items":{"type":"string","enum":["read","comment","update","complete"]},"minItems":1,"maxItems":4,"uniqueItems":true,"description":"Permissions to grant. Read permission is always required.","example":["read","comment","update"]},"cascadeAccess":{"type":"boolean","description":"Whether to allow access to child entities","default":true,"example":true},"expiresAt":{"type":"string","format":"date-time","description":"When the share token should expire (max 1 year)","example":"2024-12-31T23:59:59.000Z"},"maxUses":{"type":"integer","minimum":1,"maximum":10000,"description":"Maximum number of times token can be used","example":100},"recipientEmail":{"type":"string","format":"email","maxLength":255,"description":"Email of intended recipient","example":"recipient@example.com"},"recipientName":{"type":"string","minLength":1,"maxLength":255,"description":"Name of intended recipient","example":"Jane Smith"},"shareMessage":{"type":"string","maxLength":1000,"description":"Custom message for the recipient","example":"Please review and complete this task by Friday."},"metadata":{"type":"object","additionalProperties":true,"description":"Additional metadata for the share token"}},"additionalProperties":false},"SharedEntity":{"type":"object","required":["id","entityType","data","permissions","cascadeAccess","shareContext"],"properties":{"id":{"type":"string","format":"uuid","description":"ID of the shared entity","example":"789e0123-e89b-12d3-a456-426614174333"},"entityType":{"type":"string","enum":["task","project","workflow"],"description":"Type of shared entity","example":"task"},"data":{"type":"object","additionalProperties":true,"description":"Entity data (task, project, or workflow details)"},"permissions":{"type":"array","items":{"type":"string","enum":["read","comment","update","complete"]},"description":"Available permissions for this share","example":["read","comment","update"]},"cascadeAccess":{"type":"boolean","description":"Whether cascade access is enabled","example":true},"shareContext":{"type":"object","required":["createdAt"],"properties":{"recipientName":{"type":"string","nullable":true,"description":"Name of intended recipient","example":"Jane Smith"},"shareMessage":{"type":"string","nullable":true,"description":"Message from sharer","example":"Please review this task"},"createdBy":{"type":"string","nullable":true,"description":"Name of person who shared","example":"John Doe"},"createdAt":{"type":"string","format":"date-time","description":"When share was created","example":"2024-01-15T10:30:00.000Z"}}},"children":{"type":"array","items":{"type":"object","required":["id","entityType","name","permissions"],"properties":{"id":{"type":"string","format":"uuid","description":"ID of child entity","example":"456e7890-e89b-12d3-a456-426614174222"},"entityType":{"type":"string","enum":["task","project","workflow"],"description":"Type of child entity","example":"task"},"name":{"type":"string","description":"Name of child entity","example":"Related Task"},"status":{"type":"string","nullable":true,"description":"Status of child entity","example":"TODO"},"permissions":{"type":"array","items":{"type":"string","enum":["read","comment","update","complete"]},"description":"Inherited permissions for child","example":["read","comment"]}}},"description":"Child entities accessible through cascade"}}},"PortalTokenRequest":{"type":"object","required":["externalUserId","externalUserEmail","externalUserName"],"properties":{"externalUserId":{"type":"string","maxLength":255,"description":"Unique identifier for the external user in the client system","example":"user123@example.com"},"externalUserEmail":{"type":"string","format":"email","maxLength":255,"description":"Email address of the external user","example":"john.doe@example.com"},"externalUserName":{"type":"string","maxLength":255,"description":"Display name of the external user","example":"John Doe"},"expiresInDays":{"type":"integer","minimum":1,"maximum":365,"default":30,"description":"Number of days until token expires","example":30},"entityId":{"type":"string","format":"uuid","description":"Optional entity ID to scope token access","example":"550e8400-e29b-41d4-a716-446655440020"},"notes":{"type":"string","maxLength":1000,"description":"Optional notes about the token purpose","example":"Access for customer John Doe for Q1 operations"}}},"PortalTokenResponse":{"type":"object","required":["data","usage"],"properties":{"data":{"type":"object","required":["id","token","expiresAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the token","example":"550e8400-e29b-41d4-a716-446655440030"},"token":{"type":"string","description":"JWT token for portal authentication","example":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"expiresAt":{"type":"string","format":"date-time","description":"Token expiration timestamp","example":"2024-02-15T10:30:00Z"}}},"usage":{"type":"object","required":["url","header"],"properties":{"url":{"type":"string","format":"uri","description":"Portal base URL for external users","example":"https://a.api.apart.tech/api/v1/portal"},"header":{"type":"string","description":"HTTP header name for token","example":"X-Portal-Token"},"instructions":{"type":"string","description":"Human-readable usage instructions","example":"Include the token in the X-Portal-Token header when making API requests"}}},"message":{"type":"string","description":"Success message","example":"Portal token generated successfully"}}},"PortalTokenListResponse":{"type":"object","required":["data","total"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","userId","portalCode","issuedAt","expiresAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Token ID","example":"550e8400-e29b-41d4-a716-446655440030"},"userId":{"type":"string","description":"External user identifier","example":"user123@propertymanagement.com"},"portalCode":{"type":"string","description":"Portal code this token belongs to","example":"PROPERTY_OWNERS"},"issuedAt":{"type":"string","format":"date-time","description":"When token was issued","example":"2024-01-15T10:30:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"Token expiration","example":"2024-02-15T10:30:00Z"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last time token was used","example":"2024-01-20T14:15:00Z"},"metadata":{"type":"object","nullable":true,"description":"Additional token metadata","example":{"notes":"Property owner access for Q1"}}}}},"total":{"type":"integer","description":"Total number of tokens","example":5}}},"PortalProfile":{"type":"object","required":["user","portal","token","access"],"properties":{"user":{"type":"object","required":["id","portalCode"],"properties":{"id":{"type":"string","description":"External user identifier","example":"user123@propertymanagement.com"},"portalCode":{"type":"string","description":"Portal code","example":"PROPERTY_OWNERS"},"permissions":{"type":"array","items":{"type":"string"},"description":"User permissions","example":["view_tasks","comment","complete_tasks"]}}},"portal":{"type":"object","properties":{"name":{"type":"string","description":"Portal name","example":"Property Owners Portal"},"description":{"type":"string","nullable":true,"description":"Portal description","example":"Portal for property owners to manage their properties and tasks"},"isActive":{"type":"boolean","description":"Whether portal is active","example":true}}},"token":{"type":"object","properties":{"issuedAt":{"type":"string","format":"date-time","description":"When token was issued","example":"2024-01-15T10:30:00Z"},"expiresAt":{"type":"string","format":"date-time","description":"When token expires","example":"2024-02-15T10:30:00Z"},"lastUsedAt":{"type":"string","format":"date-time","nullable":true,"description":"Last time token was used","example":"2024-01-16T14:20:00Z"}}},"access":{"type":"object","required":["visibleTasks","visibleProjects"],"properties":{"visibleTasks":{"type":"integer","description":"Number of visible tasks","example":42},"visibleProjects":{"type":"integer","description":"Number of visible projects","example":3}}}}},"PortalTask":{"type":"object","required":["id","title","status","priority","projectId"],"properties":{"id":{"type":"string","format":"uuid","description":"Task ID","example":"550e8400-e29b-41d4-a716-446655440001"},"title":{"type":"string","description":"Task title","example":"Schedule property inspection"},"description":{"type":"string","nullable":true,"description":"Task description","example":"Coordinate with tenant for quarterly inspection"},"status":{"type":"string","enum":["TODO","IN_PROGRESS","BLOCKED","COMPLETED"],"description":"Current task status","example":"TODO"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority","example":"MEDIUM"},"projectId":{"type":"string","format":"uuid","description":"Parent project ID","example":"550e8400-e29b-41d4-a716-446655440000"},"projectName":{"type":"string","description":"Parent project name","example":"Q1 Property Maintenance"},"dueDate":{"type":"string","format":"date-time","nullable":true,"description":"Task due date","example":"2024-02-01T09:00:00Z"},"createdAt":{"type":"string","format":"date-time","description":"Task creation timestamp","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp","example":"2024-01-20T14:15:00Z"},"canRespond":{"type":"boolean","description":"Whether user can add comments to this task","example":true},"canComplete":{"type":"boolean","description":"Whether user can mark this task as complete","example":true},"commentsCount":{"type":"integer","description":"Number of comments on this task","example":3}}},"PortalProject":{"type":"object","required":["id","name","status","tasksCount"],"properties":{"id":{"type":"string","format":"uuid","description":"Project ID","example":"550e8400-e29b-41d4-a716-446655440000"},"name":{"type":"string","description":"Project name","example":"Q1 Property Maintenance"},"description":{"type":"string","nullable":true,"description":"Project description","example":"Quarterly maintenance tasks for all properties"},"status":{"type":"string","enum":["ACTIVE","COMPLETED","ARCHIVED"],"description":"Project status","example":"ACTIVE"},"tasksCount":{"type":"object","required":["total","pending","completed"],"properties":{"total":{"type":"integer","description":"Total visible tasks in project","example":12},"pending":{"type":"integer","description":"Pending tasks count","example":8},"completed":{"type":"integer","description":"Completed tasks count","example":4}}},"createdAt":{"type":"string","format":"date-time","description":"Project creation timestamp","example":"2024-01-01T00:00:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp","example":"2024-01-20T14:15:00Z"}}},"PortalComment":{"type":"object","required":["id","content","authorType","createdAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Comment ID","example":"550e8400-e29b-41d4-a716-446655440050"},"content":{"type":"string","description":"Comment text content","example":"I can schedule the inspection for next Tuesday morning."},"authorType":{"type":"string","description":"Type of comment author","example":"PORTAL_USER"},"authorId":{"type":"string","nullable":true,"description":"Author identifier","example":"user123@propertymanagement.com"},"authorName":{"type":"string","nullable":true,"description":"Author display name","example":"John Doe"},"createdAt":{"type":"string","format":"date-time","description":"Comment creation timestamp","example":"2024-01-20T14:15:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"Last update timestamp","example":"2024-01-20T14:15:00Z"},"canEdit":{"type":"boolean","description":"Whether current user can edit this comment","example":true},"canDelete":{"type":"boolean","description":"Whether current user can delete this comment","example":true}}},"TaskCompletionRequest":{"type":"object","properties":{"completion_notes":{"type":"string","nullable":true,"maxLength":2000,"description":"Optional notes about task completion","example":"Inspection completed successfully. All systems operational."},"metadata":{"type":"object","nullable":true,"description":"Optional metadata including completion form data","additionalProperties":true,"properties":{"completion_form":{"type":"object","description":"Structured form data submitted on completion","properties":{"form_type":{"type":"string","description":"Type of form submitted","example":"inspection_checklist"},"form_version":{"type":"string","nullable":true,"description":"Version of the form template","example":"1.2"},"submitted_at":{"type":"string","format":"date-time","description":"When the form was submitted (ISO 8601)","example":"2024-01-25T15:30:00.000Z"},"submitted_by":{"type":"string","description":"User ID who submitted the form","example":"user-123"},"data":{"type":"object","description":"Form field values","additionalProperties":true,"example":{"inspectionResult":"passed","notes":"All items checked and verified"}}},"required":["form_type","submitted_at","submitted_by","data"]}}}}},"CommentRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":2000,"description":"Comment text content","example":"I can schedule the inspection for next Tuesday morning."}}},"CommentUpdateRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":2000,"description":"Updated comment text","example":"I can schedule the inspection for Wednesday morning instead."}}},"PortalTaskCreateRequest":{"type":"object","required":["title","project_id"],"properties":{"title":{"type":"string","minLength":1,"maxLength":500,"description":"Task title","example":"Complete property inspection for unit 203"},"description":{"type":"string","maxLength":5000,"description":"Task description with detailed information","example":"Conduct quarterly inspection of unit 203, including:\n- Check all appliances\n- Test smoke detectors\n- Inspect for maintenance issues\n- Document any tenant concerns"},"project_id":{"type":"string","format":"uuid","description":"ID of the project this task belongs to","example":"550e8400-e29b-41d4-a716-446655440000"},"section_id":{"type":"string","format":"uuid","nullable":true,"description":"Optional section within the project","example":"550e8400-e29b-41d4-a716-446655440010"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"default":"MEDIUM","description":"Task priority level","example":"HIGH"},"due_date":{"type":"string","format":"date-time","nullable":true,"description":"Task due date","example":"2024-02-15T10:00:00Z"}}},"PortalTaskUpdateRequest":{"type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":500,"description":"Updated task title","example":"Complete property inspection for unit 203 (Rescheduled)"},"description":{"type":"string","maxLength":5000,"nullable":true,"description":"Updated task description","example":"Updated inspection checklist with additional safety requirements"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Updated priority level","example":"URGENT"},"status":{"type":"string","enum":["PENDING","TODO","IN_PROGRESS","BLOCKED","COMPLETED","CANCELLED"],"description":"Updated task status","example":"IN_PROGRESS"},"due_date":{"type":"string","format":"date-time","nullable":true,"description":"Updated due date","example":"2024-02-20T14:00:00Z"}}},"PortalProjectCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Project name","example":"Q1 2024 Property Maintenance - Building A"},"description":{"type":"string","maxLength":5000,"nullable":true,"description":"Project description","example":"Quarterly maintenance schedule for Building A, including all routine inspections, repairs, and tenant requests."},"entity_type":{"type":"string","nullable":true,"description":"Type of entity this project is associated with","example":"PROPERTY"},"entity_id":{"type":"string","nullable":true,"description":"ID of the associated entity","example":"prop_123456"}}},"PortalWorkflowCreateRequest":{"type":"object","required":["workflow_template_id","name"],"properties":{"workflow_template_id":{"type":"string","format":"uuid","description":"ID of the workflow template to instantiate","example":"550e8400-e29b-41d4-a716-446655440100"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Name for the workflow instance","example":"Lease Renewal Process - Unit 203"},"entity_type":{"type":"string","nullable":true,"description":"Type of entity this workflow is associated with","example":"LEASE"},"entity_id":{"type":"string","nullable":true,"description":"ID of the associated entity","example":"lease_789012"},"variables":{"type":"object","nullable":true,"description":"Template variables to populate","example":{"tenant_name":"John Smith","unit_number":"203","lease_end_date":"2024-06-30"}}}},"PortalWorkflow":{"type":"object","required":["id","name","status","created_at"],"properties":{"id":{"type":"string","format":"uuid","description":"Workflow ID","example":"550e8400-e29b-41d4-a716-446655440200"},"name":{"type":"string","description":"Workflow name","example":"Lease Renewal Process - Unit 203"},"description":{"type":"string","nullable":true,"description":"Workflow description","example":"Standard lease renewal workflow for residential units"},"status":{"type":"string","enum":["PENDING","ACTIVE","PAUSED","COMPLETED","CANCELLED"],"description":"Current workflow status","example":"ACTIVE"},"entity_type":{"type":"string","nullable":true,"description":"Associated entity type","example":"LEASE"},"entity_id":{"type":"string","nullable":true,"description":"Associated entity ID","example":"lease_789012"},"created_at":{"type":"string","format":"date-time","description":"Workflow creation timestamp","example":"2024-01-15T10:30:00Z"},"started_at":{"type":"string","format":"date-time","nullable":true,"description":"When workflow was started","example":"2024-01-15T11:00:00Z"},"completed_at":{"type":"string","format":"date-time","nullable":true,"description":"When workflow was completed","example":"2024-02-01T15:30:00Z"},"_count":{"type":"object","properties":{"workflow_stages":{"type":"integer","description":"Number of stages in this workflow","example":5}}},"workflow_stages":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Stage ID","example":"550e8400-e29b-41d4-a716-446655440250"},"name":{"type":"string","description":"Stage name","example":"Document Preparation"},"order":{"type":"integer","description":"Stage order","example":1},"status":{"type":"string","enum":["PENDING","IN_PROGRESS","COMPLETED","SKIPPED"],"description":"Stage status","example":"COMPLETED"},"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Task ID","example":"550e8400-e29b-41d4-a716-446655440300"},"title":{"type":"string","description":"Task title","example":"Prepare lease renewal agreement"},"status":{"type":"string","enum":["PENDING","TODO","IN_PROGRESS","BLOCKED","COMPLETED"],"description":"Task status","example":"COMPLETED"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","URGENT"],"description":"Task priority","example":"HIGH"}}}}}}}}},"CompletionAction":{"type":"object","required":["id","organizationId","workflowTemplateStageId","code","name","trigger","actionType","executionOrder","isEnabled","onError","version","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the completion action","example":"550e8400-e29b-41d4-a716-446655440010"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this action","example":"550e8400-e29b-41d4-a716-446655440002"},"workflowTemplateStageId":{"type":"string","format":"uuid","description":"Workflow template stage this action belongs to","example":"550e8400-e29b-41d4-a716-446655440003"},"code":{"type":"string","maxLength":100,"description":"Unique code identifier for the action","example":"CLOSE_OPTIONAL_TASKS"},"name":{"type":"string","maxLength":255,"description":"Human-readable name for the action","example":"Close Open Tasks from Optional Stages"},"description":{"type":"string","maxLength":1000,"nullable":true,"description":"Detailed description of what this action does","example":"Automatically closes all open tasks from optional workflow stages when entering the completion stage"},"trigger":{"type":"string","enum":["on_stage_entry","on_stage_completion"],"description":"When this action should be executed","example":"on_stage_entry"},"actionType":{"type":"string","enum":["close_tasks","archive_attachments","generate_summary","webhook","event"],"description":"Type of action to execute","example":"close_tasks"},"executionOrder":{"type":"integer","minimum":1,"description":"Order in which this action should be executed relative to other actions","example":1},"isEnabled":{"type":"boolean","description":"Whether this action is currently enabled","example":true},"conditions":{"type":"array","nullable":true,"items":{"$ref":"#/components/schemas/CompletionActionCondition"},"description":"Conditions that must be met for this action to execute","example":[{"field":"statistics.openTasks","operator":"gt","value":0}]},"closeTaskStatus":{"type":"string","nullable":true,"enum":["COMPLETED","CANCELLED"],"description":"Status to set when closing tasks (for close_tasks action type)","example":"CANCELLED"},"archiveDestination":{"type":"string","nullable":true,"maxLength":500,"description":"Destination path for archived attachments (for archive_attachments action type)","example":"gs://bucket/archived/workflows/"},"archiveIncludeTypes":{"type":"array","items":{"type":"string"},"description":"File types to include in archive (empty = all types)","example":["pdf","docx","xlsx"],"default":[]},"summaryIncludeFields":{"type":"object","nullable":true,"additionalProperties":true,"description":"Fields to include in generated summary (for generate_summary action type)","example":{"includeTimeline":true,"includeParticipants":true,"includeMetrics":true}},"webhookEndpoint":{"type":"string","nullable":true,"format":"uri","maxLength":2000,"description":"URL to call for webhook action type","example":"https://api.example.com/webhooks/workflow-completion"},"webhookMethod":{"type":"string","nullable":true,"enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method for webhook request","example":"POST"},"webhookHeaders":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Static headers to include in webhook request","example":{"X-Custom-Header":"value","Content-Type":"application/json"}},"webhookHeaderMapping":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Dynamic header mapping from context fields","example":{"X-Workflow-Id":"workflow.id","X-Organization-Id":"auth.organizationId"}},"webhookSigningSecret":{"type":"string","nullable":true,"maxLength":255,"description":"Secret for signing webhook payloads","example":"[REDACTED]"},"authType":{"type":"string","nullable":true,"enum":["pass_through","pass_through_with_fallback","api_key","none"],"description":"Authentication type for webhook requests","example":"api_key"},"authApiKey":{"type":"string","nullable":true,"maxLength":500,"description":"API key for webhook authentication","example":"[REDACTED]"},"authHeaderName":{"type":"string","nullable":true,"maxLength":100,"description":"Header name for API key authentication","example":"X-API-Key","default":"X-API-Key"},"payloadMapping":{"type":"object","nullable":true,"additionalProperties":true,"description":"Custom payload structure mapping from context fields","example":{"workflowId":"workflow.id","status":"workflow.status","metrics":"statistics"}},"eventCode":{"type":"string","nullable":true,"maxLength":100,"description":"Event type code to publish (for event action type)","example":"workflow.completion"},"eventData":{"type":"object","nullable":true,"additionalProperties":true,"description":"Additional data to include in published event","example":{"category":"workflow","priority":"high"}},"onError":{"type":"string","enum":["log","fail_stage","retry"],"description":"Behavior when action execution fails","example":"log","default":"log"},"retryMaxAttempts":{"type":"integer","minimum":0,"maximum":10,"description":"Maximum number of retry attempts on failure","example":3,"default":3},"retryBackoffMs":{"type":"integer","minimum":100,"maximum":60000,"description":"Backoff time in milliseconds between retries","example":1000,"default":1000},"timeoutMs":{"type":"integer","minimum":1000,"maximum":300000,"description":"Timeout in milliseconds for action execution","example":30000,"default":30000},"version":{"type":"integer","minimum":1,"description":"Version number for optimistic locking","example":1},"createdAt":{"type":"string","format":"date-time","description":"When the action was created","example":"2024-01-15T10:30:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the action was last updated","example":"2024-01-20T14:45:00Z"},"deletedAt":{"type":"string","format":"date-time","nullable":true,"description":"When the action was soft deleted (null if active)","example":null}},"additionalProperties":false},"CompletionActionCondition":{"type":"object","required":["field","operator","value"],"properties":{"field":{"type":"string","description":"Context field path to evaluate (e.g., \"statistics.openTasks\", \"workflow.status\")","example":"statistics.openTasks"},"operator":{"type":"string","enum":["eq","==","ne","!=","gt",">","gte",">=","lt","<","lte","<=","in","contains"],"description":"Comparison operator","example":"gt"},"value":{"description":"Value to compare against (type depends on field being evaluated)","example":0}},"additionalProperties":false},"CompletionActionExecutionLog":{"type":"object","required":["id","organizationId","completionActionId","workflowId","workflowStageId","trigger","executionId","batchId","actionType","status","retryCount","maxRetries","queuedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the execution log","example":"550e8400-e29b-41d4-a716-446655440020"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this log","example":"550e8400-e29b-41d4-a716-446655440002"},"completionActionId":{"type":"string","format":"uuid","description":"ID of the completion action that was executed","example":"550e8400-e29b-41d4-a716-446655440010"},"workflowId":{"type":"string","format":"uuid","description":"ID of the workflow where action was executed","example":"550e8400-e29b-41d4-a716-446655440011"},"workflowStageId":{"type":"string","format":"uuid","description":"ID of the workflow stage where action was executed","example":"550e8400-e29b-41d4-a716-446655440012"},"trigger":{"type":"string","enum":["on_stage_entry","on_stage_completion"],"description":"Trigger that caused this execution","example":"on_stage_entry"},"executionId":{"type":"string","format":"uuid","description":"Unique ID for this execution attempt","example":"550e8400-e29b-41d4-a716-446655440030"},"batchId":{"type":"string","format":"uuid","description":"ID linking multiple actions executed together","example":"550e8400-e29b-41d4-a716-446655440031"},"actionType":{"type":"string","enum":["close_tasks","archive_attachments","generate_summary","webhook","event"],"description":"Type of action that was executed","example":"close_tasks"},"status":{"type":"string","enum":["success","failure","timeout","skipped"],"description":"Execution result status","example":"success"},"tasksClosedCount":{"type":"integer","nullable":true,"minimum":0,"description":"Number of tasks closed (for close_tasks action)","example":3},"tasksClosedIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"IDs of tasks that were closed","example":["task-1","task-2","task-3"],"default":[]},"attachmentsArchivedCount":{"type":"integer","nullable":true,"minimum":0,"description":"Number of attachments archived (for archive_attachments action)","example":5},"archiveReference":{"type":"string","nullable":true,"maxLength":500,"description":"Reference path to archived files","example":"gs://bucket/archived/workflows/wf-123/2024-01-15/"},"pendingArchive":{"type":"boolean","description":"Whether archive operation is pending future implementation","example":false,"default":false},"summaryId":{"type":"string","format":"uuid","nullable":true,"description":"ID of generated workflow summary (for generate_summary action)","example":"550e8400-e29b-41d4-a716-446655440040"},"requestUrl":{"type":"string","nullable":true,"format":"uri","maxLength":2000,"description":"URL that was called (for webhook action)","example":"https://api.example.com/webhooks/workflow-completion"},"requestMethod":{"type":"string","nullable":true,"enum":["GET","POST","PUT","PATCH","DELETE"],"description":"HTTP method used (for webhook action)","example":"POST"},"requestHeaders":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Headers sent with request (sensitive headers redacted)","example":{"Content-Type":"application/json","X-API-Key":"[REDACTED]"}},"requestBody":{"type":"object","nullable":true,"additionalProperties":true,"description":"Body sent with request","example":{"workflowId":"wf-123","status":"completed"}},"responseStatus":{"type":"integer","nullable":true,"minimum":100,"maximum":599,"description":"HTTP response status code (for webhook action)","example":200},"responseHeaders":{"type":"object","nullable":true,"additionalProperties":{"type":"string"},"description":"Headers received in response","example":{"content-type":"application/json"}},"responseBody":{"nullable":true,"description":"Body received in response","example":{"success":true,"message":"Webhook processed successfully"}},"responseTimeMs":{"type":"integer","nullable":true,"minimum":0,"description":"Response time in milliseconds (for webhook action)","example":123},"errorMessage":{"type":"string","nullable":true,"maxLength":2000,"description":"Error message if execution failed","example":"Connection timeout after 30 seconds"},"errorCode":{"type":"string","nullable":true,"maxLength":100,"description":"Error code for programmatic handling","example":"TIMEOUT"},"retryCount":{"type":"integer","minimum":0,"description":"Number of times this execution was retried","example":0},"maxRetries":{"type":"integer","minimum":0,"description":"Maximum retry attempts configured","example":3},"nextRetryAt":{"type":"string","format":"date-time","nullable":true,"description":"When next retry will be attempted (if applicable)","example":"2024-01-15T10:31:00Z"},"queuedAt":{"type":"string","format":"date-time","description":"When execution was queued","example":"2024-01-15T10:30:00Z"},"startedAt":{"type":"string","format":"date-time","nullable":true,"description":"When execution started","example":"2024-01-15T10:30:01Z"},"completedAt":{"type":"string","format":"date-time","nullable":true,"description":"When execution completed","example":"2024-01-15T10:30:03Z"},"triggeredBy":{"type":"string","format":"uuid","description":"User ID who triggered this execution","example":"user-123"}},"additionalProperties":false},"WorkflowSummary":{"type":"object","required":["id","organizationId","workflowId","workflowCode","workflowName","startedAt","completedAt","totalDurationMinutes","totalStages","completedStages","skippedStages","totalTasks","completedTasks","cancelledTasks","autoClosedTasks","participantCount","createdAt","updatedAt"],"properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the summary","example":"550e8400-e29b-41d4-a716-446655440040"},"organizationId":{"type":"string","format":"uuid","description":"Organization that owns this summary","example":"550e8400-e29b-41d4-a716-446655440002"},"workflowId":{"type":"string","format":"uuid","description":"ID of the workflow this summary is for","example":"550e8400-e29b-41d4-a716-446655440011"},"workflowCode":{"type":"string","maxLength":100,"description":"Workflow number/code for reference","example":"WF-2024-001"},"workflowName":{"type":"string","maxLength":255,"description":"Name of the workflow","example":"Property Acquisition Workflow"},"templateId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the workflow template used","example":"550e8400-e29b-41d4-a716-446655440003"},"templateCode":{"type":"string","maxLength":100,"nullable":true,"description":"Code of the workflow template used","example":"PROPERTY_ACQUISITION"},"templateName":{"type":"string","maxLength":255,"nullable":true,"description":"Name of the workflow template used","example":"Property Acquisition Template"},"entityType":{"type":"string","maxLength":100,"nullable":true,"description":"Type of entity this workflow was linked to","example":"property"},"entityId":{"type":"string","maxLength":255,"nullable":true,"description":"ID of entity this workflow was linked to","example":"prop-123"},"startedAt":{"type":"string","format":"date-time","description":"When the workflow started","example":"2024-01-15T10:00:00Z"},"completedAt":{"type":"string","format":"date-time","description":"When the workflow completed","example":"2024-01-20T16:30:00Z"},"totalDurationMinutes":{"type":"integer","minimum":0,"description":"Total duration of workflow execution in minutes","example":7830},"totalStages":{"type":"integer","minimum":0,"description":"Total number of stages in the workflow","example":5},"completedStages":{"type":"integer","minimum":0,"description":"Number of stages completed","example":4},"skippedStages":{"type":"integer","minimum":0,"description":"Number of stages skipped","example":1},"totalTasks":{"type":"integer","minimum":0,"description":"Total number of tasks in the workflow","example":25},"completedTasks":{"type":"integer","minimum":0,"description":"Number of tasks completed normally","example":20},"cancelledTasks":{"type":"integer","minimum":0,"description":"Number of tasks cancelled manually","example":2},"autoClosedTasks":{"type":"integer","minimum":0,"description":"Number of tasks auto-closed by completion actions","example":3},"ownerId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the workflow owner","example":"user-123"},"assigneeId":{"type":"string","format":"uuid","nullable":true,"description":"ID of the workflow assignee","example":"user-456"},"participantCount":{"type":"integer","minimum":0,"description":"Number of participants in the workflow","example":8},"archivedAttachmentRefs":{"type":"object","nullable":true,"additionalProperties":true,"description":"References to archived attachments","example":{"archivePath":"gs://bucket/archived/wf-123","fileCount":12}},"createdAt":{"type":"string","format":"date-time","description":"When the summary was created","example":"2024-01-20T16:31:00Z"},"updatedAt":{"type":"string","format":"date-time","description":"When the summary was last updated","example":"2024-01-20T16:31:00Z"}},"additionalProperties":false},"WebhookRegistrationInput":{"type":"object","required":["endpoint","events"],"description":"Schema for creating or updating webhook registrations","properties":{"endpoint":{"type":"string","format":"uri","description":"The HTTPS URL where webhook events will be delivered. Must be publicly accessible.","example":"https://myapp.com/webhooks/tasks","minLength":1,"maxLength":2048},"events":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Array of event type codes to subscribe to. Supports wildcards (e.g., 'task.*').","example":["task.created","task.updated","task.completed"]},"config":{"type":"object","nullable":true,"description":"Optional webhook delivery configuration","properties":{"retryPolicy":{"type":"object","properties":{"maxRetries":{"type":"integer","minimum":0,"maximum":10,"default":3,"description":"Maximum delivery retry attempts"},"backoffMultiplier":{"type":"number","minimum":1,"default":2,"description":"Exponential backoff multiplier for retries"}}},"timeout":{"type":"integer","minimum":1000,"maximum":30000,"default":5000,"description":"Request timeout in milliseconds"},"verifySSL":{"type":"boolean","default":true,"description":"Whether to verify SSL certificates"}}}}},"EntityWebhookInput":{"type":"object","required":["entityType","entityId","allowedActions"],"description":"Schema for creating entity-specific webhooks","properties":{"entityType":{"type":"string","enum":["workflow","task","project"],"description":"The type of entity this webhook is for"},"entityId":{"type":"string","minLength":1,"description":"The unique identifier of the entity"},"allowedActions":{"type":"array","items":{"type":"string","enum":["complete","progress","fail","update"]},"minItems":1,"uniqueItems":true,"description":"Actions that can be triggered via this webhook"},"targetField":{"type":"string","nullable":true,"description":"Optional field name to update (for 'update' action)"},"isPublic":{"type":"boolean","default":false,"description":"Whether webhook can be called without authentication"},"expiresAt":{"type":"string","format":"date-time","nullable":true,"description":"Optional expiration timestamp"},"metadata":{"type":"object","nullable":true,"description":"Optional metadata for tracking context","additionalProperties":true}}},"EntityWebhookPayload":{"type":"object","required":["action"],"description":"Schema for calling entity webhooks","properties":{"action":{"type":"string","enum":["complete","progress","fail","update"],"description":"The action to perform (must be in allowedActions)"},"data":{"type":"object","nullable":true,"description":"Optional data payload for the action","additionalProperties":true},"metadata":{"type":"object","nullable":true,"description":"Optional metadata for logging","additionalProperties":true}}},"EventInput":{"type":"object","required":["eventTypeCode","eventSource","aggregateType","aggregateId","eventData"],"description":"Schema for publishing custom events","properties":{"eventTypeCode":{"type":"string","description":"Valid event type code from the system","example":"task.created"},"eventSource":{"type":"string","enum":["USER","SYSTEM","WEBHOOK","SCHEDULE"],"description":"The source that triggered this event"},"aggregateType":{"type":"string","description":"The aggregate type this event relates to","example":"task"},"aggregateId":{"type":"string","description":"The ID of the aggregate instance"},"eventData":{"type":"object","description":"Event-specific data payload","additionalProperties":true},"previousData":{"type":"object","nullable":true,"description":"State before the change (for update events)","additionalProperties":true},"correlationId":{"type":"string","format":"uuid","nullable":true,"description":"Correlation ID for tracking related events"},"entityType":{"type":"string","nullable":true,"description":"Specific entity type if different from aggregate"},"entityId":{"type":"string","nullable":true,"description":"Specific entity ID"},"actorId":{"type":"string","nullable":true,"description":"ID of the user or system that triggered the event"},"actorType":{"type":"string","nullable":true,"description":"Type of actor (USER or SYSTEM)"},"actorName":{"type":"string","nullable":true,"description":"Human-readable name of the actor"},"idempotencyKey":{"type":"string","nullable":true,"description":"Unique key to prevent duplicate events"}}},"WebhookSignatureValidation":{"type":"object","required":["payload","signature","secret"],"description":"Schema for validating webhook signatures","properties":{"payload":{"type":"string","description":"Raw request body as string (not parsed JSON)"},"signature":{"type":"string","description":"Signature from X-Webhook-Signature header (format: sha256=<hex>)","pattern":"^sha256=[a-f0-9]{64}$"},"secret":{"type":"string","description":"Webhook secret for signature verification","minLength":64,"maxLength":64}}}},"security":[{"ApiKeyAuth":[]},{"BearerAuth":[]}],"tags":[{"name":"Health","description":"Service health and status endpoints"},{"name":"Organizations","description":"Organization management and information"},{"name":"Projects","description":"Project management - create, organize, and track projects"},{"name":"Tasks","description":"Task management - create, assign, and track individual tasks"},{"name":"Task Templates","description":"🎯 Task template management for automated task creation, role-based assignments, approval workflows, and standardized checklists. Create reusable templates that automatically generate tasks during workflow instantiation."},{"name":"Task Template Context Triggers","description":"⚡ Context System V2 trigger management for task templates. Configure triggers that automatically execute context operations when specific task events occur for tasks created from templates."},{"name":"FormTemplates","description":"📝 JSON schema-based form template management with comprehensive validation, versioning, and category organization. Design reusable forms for structured data collection."},{"name":"Forms","description":"📝 Dynamic task forms with Norwegian real estate support. Apply form templates to tasks and collect structured data with real-time validation."},{"name":"Translations","description":"🌐 Multi-language translation system with Norwegian/English support for real estate workflows. Organized by namespace with bulk import capabilities."},{"name":"Context Types","description":"🔗 External API integration configurations for live data enrichment. Define connections to property management systems, CRMs, and other external services with multiple authentication methods."},{"name":"Entity Context","description":"🔗 Universal context attachment system for projects, workflows, tasks, and sections. Fetch live data from external APIs with error handling and security protection."},{"name":"Calendar","description":"📅 Calendar integration with Cronofy for task-calendar synchronization, meeting scheduling, and availability checking. Automate property viewing workflows and team coordination with professional calendar management."},{"name":"Calendar Webhooks","description":"📅 Real-time calendar webhook processing for bidirectional synchronization between calendar events and task management system. Handles Cronofy webhook events including event creation, updates, deletions, and invitation responses with HMAC-SHA256 security validation. Supports property viewing appointments, team coordination, and compliance tracking with organization-scoped event processing."},{"name":"Calendar Event Types","description":"📅 Organization-defined event type configurations. Define event types with defaults for duration, capacity, buffer times, outcome tracking, metadata schemas, and Smart Invite preferences."},{"name":"Event Registrations","description":"📅 Event registration and check-in system. Register attendees for capacity-managed events, manage waitlists, track check-ins, and send Smart Invite calendar invitations automatically."},{"name":"Attendee Outcomes","description":"📅 Per-attendee outcome recording for calendar events. Track individual outcomes for group viewings, consultations, and other multi-attendee events independently of the event-level outcome."},{"name":"Dependencies","description":"Dependency management - create relationships between tasks and workflow stages for scheduling and constraint handling"},{"name":"Attachments","description":"File attachment management - upload, download, and organize files linked to projects and tasks with Google Cloud Storage integration"},{"name":"Workflows","description":"Complex workflow orchestration with multi-stage business process automation"},{"name":"Workflow Templates","description":"Reusable workflow templates for standardized business processes"},{"name":"Workflow Stages","description":"Individual stages within workflows with task management and dependencies"},{"name":"Stage Definitions","description":"Template definitions for workflow stages with task templates and configuration"},{"name":"Template Requirements","description":"Dynamic template requirements discovery and instantiation system for workflows and tasks"},{"name":"Comments","description":"Comment system for collaborative task and project management"},{"name":"Events","description":"Real-time event tracking and audit trail for all system activities"},{"name":"Pub/Sub Topics","description":"Google Pub/Sub topic management for event distribution"},{"name":"Pub/Sub Subscriptions","description":"Google Pub/Sub subscription management for event consumption"},{"name":"Service Registration","description":"Service registration and discovery for microservice architecture"},{"name":"Workflow Data Schemas","description":"📊 Schema-driven data model management for workflows. Define structured data schemas with validation rules, computed fields, and state transitions for workflow templates."},{"name":"Workflow Data Instances","description":"📋 Data instance management for workflow execution. Store, validate, and track structured data throughout workflow lifecycle with complete audit history."},{"name":"Variables","description":"🔗 Unified workflow variables retrieval system. Access comprehensive data from workflow data models, forms, context, and metadata for template population and external integrations."},{"name":"Webhooks","description":"Webhook management for event notifications. Register, configure, and monitor webhooks for real-time event delivery to external systems."},{"name":"Entity Webhooks","description":"Entity-specific webhook endpoints for targeted event delivery. Create public webhook URLs for workflows, tasks, and projects with action-based processing."},{"name":"Event Types","description":"Event type configurations and categories. Query available event types for workflow triggers and system events."},{"name":"Entity Sharing","description":"🔗 Secure entity sharing system for external collaboration. Share tasks, projects, and workflows via token-based links with granular permissions and cascade access to child entities."},{"name":"Portal Administration","description":"👥 Portal token management for admins. Generate, list, and revoke access tokens for external users with configurable expiration and entity scoping."},{"name":"Portal Access","description":"🚪 External user endpoints for portal-based access. View tasks, projects, and add comments through token-authenticated portal system with visibility-based access control."},{"name":"Portal Views","description":"🎯 External-facing portal endpoints for viewing workflows and phases. Provides translated, filtered, and progress-tracked views of workflow execution for portal users with appropriate visibility controls."},{"name":"Portal View Configuration","description":"⚙️ Portal view configuration management. Configure field visibility, entity labels, and display settings for portal-specific views of workflows, tasks, and projects."},{"name":"Completion Actions","description":"🎬 Configurable actions executed when workflows enter or complete COMPLETION stages. Automate task closing, summary generation, webhooks, and event publishing with conditional execution and retry logic."},{"name":"Workflow Summaries","description":"📊 Workflow execution summaries with statistics, timelines, and participant information. Generated automatically during workflow completion for analytics and reporting."},{"name":"Recurring Definitions","description":"Standalone recurring definitions that automatically create tasks or workflows from templates on configurable schedules. Supports daily, weekly, monthly, quarterly, yearly, and custom intervals with timezone-aware scheduling."}]}