From 6d10785477b19fe9c91d99885415e3f62f738cab Mon Sep 17 00:00:00 2001 From: Kostenko Nikita <244571@niuitmo.ru> Date: Mon, 31 Aug 2026 20:52:54 +0300 Subject: [PATCH 1/4] feat(scm): add GitLab provider support Add GitLab PAT and OAuth integrations, nested namespace support, merge request sync, releases and tags, milestone release attachments, webhooks, UI configuration, migrations, documentation, and tests. --- .gitignore | 5 + api/openapi.json | 9534 +++++++---------- api/openapi.yaml | 8314 +++++++------- docs/gitlab-scm.md | 50 + frontend/src/lib/api/scm.js | 11 + .../dialogs/CreatePRFromBranchModal.svelte | 16 +- .../lib/features/items/ItemSCMLinks.svelte | 5 +- .../milestones/MilestoneDetail.svelte | 18 +- .../milestones/MilestoneReleaseModal.svelte | 114 +- .../src/lib/locales/en/adminOperations.js | 8 + frontend/src/lib/locales/en/misc.js | 3 + .../src/lib/locales/ru/adminOperations.js | 8 + frontend/src/lib/locales/ru/misc.js | 4 +- .../lib/settings/SCMProviderManager.svelte | 41 +- .../workspaces/WorkspaceSCMSettings.svelte | 98 +- internal/database/gitlab_schema_test.go | 36 + internal/database/migrations.go | 90 + internal/database/schema/milestones.sql | 9 + .../database/schema/milestones_existing.sql | 6 + .../schema/milestones_existing_postgres.sql | 6 + .../database/schema/milestones_postgres.sql | 9 + internal/database/schema/scm.sql | 31 +- internal/database/schema/scm_postgres.sql | 31 +- internal/handlers/milestones.go | 172 +- internal/handlers/scm_gitlab_webhooks.go | 309 + internal/handlers/scm_item_links.go | 40 +- internal/handlers/scm_providers.go | 6 +- internal/handlers/scm_providers_oauth.go | 51 + internal/handlers/scm_workspace.go | 17 + internal/models/integration.go | 13 + internal/models/workspace.go | 34 +- internal/routes/scm.go | 5 + internal/scm/credentials.go | 13 + internal/scm/gitea.go | 12 +- internal/scm/github.go | 12 +- internal/scm/gitlab.go | 808 ++ internal/scm/gitlab_test.go | 120 + internal/scm/issue_sync.go | 7 +- internal/scm/milestone_attach.go | 7 +- internal/scm/pr_review_events.go | 4 +- internal/scm/sync.go | 207 +- internal/scm/types.go | 43 +- internal/server/server.go | 2 +- internal/services/action_create_milestone.go | 15 +- internal/services/agent_pr_service.go | 10 +- internal/services/binding_service.go | 46 +- internal/services/planning_milestones.go | 207 +- .../planning_milestones_release_test.go | 78 + internal/utils/repository_path.go | 14 + internal/utils/repository_path_test.go | 29 + 50 files changed, 10236 insertions(+), 10492 deletions(-) create mode 100644 docs/gitlab-scm.md create mode 100644 internal/database/gitlab_schema_test.go create mode 100644 internal/handlers/scm_gitlab_webhooks.go create mode 100644 internal/scm/gitlab.go create mode 100644 internal/scm/gitlab_test.go create mode 100644 internal/services/planning_milestones_release_test.go create mode 100644 internal/utils/repository_path.go create mode 100644 internal/utils/repository_path_test.go diff --git a/.gitignore b/.gitignore index b3d0ad77e..f1503bec1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,10 @@ cx # Test sources live in the adjacent private core-tests repository and are # overlaid onto this checkout by its runners. *_test.go +!/internal/database/gitlab_schema_test.go +!/internal/scm/gitlab_test.go +!/internal/services/planning_milestones_release_test.go +!/internal/utils/repository_path_test.go *_test.sh *.test.js *.test.ts @@ -189,6 +193,7 @@ blog/ !/docs/WI-531-public-forms-backend-api-audit.md !/docs/WI-523-public-forms-completion.md !/docs/xray-jira-test-case-import.md +!/docs/gitlab-scm.md /.codehamr /.agents/skills/donate-trace /skills-lock.json diff --git a/api/openapi.json b/api/openapi.json index 6a8ddb17b..98eedf035 100644 --- a/api/openapi.json +++ b/api/openapi.json @@ -15,115 +15,208 @@ }, "type": "object" }, - "health.livenessResponse": { + "dto.AssetCategoryResponse": { "properties": { - "status": { + "asset_count": { + "type": "integer" + }, + "children_count": { + "type": "integer" + }, + "created_at": { + "type": "string" + }, + "descendants_count": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "has_children": { + "type": "boolean" + }, + "id": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "parent_id": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "set_id": { + "type": "integer" + }, + "updated_at": { "type": "string" } }, "type": "object" }, - "health.readinessResponse": { + "dto.AssetCategorySummary": { "properties": { - "database": { + "id": { + "type": "integer" + }, + "name": { "type": "string" }, - "status": { + "path": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.AdminGroupCreateRequest": { + "dto.AssetCreateRequest": { "properties": { + "asset_tag": { + "type": "string" + }, + "asset_type_id": { + "type": "integer" + }, + "category_id": { + "type": "integer" + }, + "custom_field_values": { + "additionalProperties": {}, + "type": "object" + }, "description": { "type": "string" }, - "name": { + "status_id": { + "type": "integer" + }, + "title": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.AdminGroupResponse": { + "dto.AssetImportJobResponse": { "properties": { + "asset_type_id": { + "type": "integer" + }, + "completed_at": { + "type": "string" + }, "created_at": { "type": "string" }, - "description": { + "created_rows": { + "type": "integer" + }, + "error_message": { "type": "string" }, + "error_rows": { + "type": "integer" + }, "id": { "type": "integer" }, - "member_count": { + "processed_rows": { "type": "integer" }, - "name": { + "set_id": { + "type": "integer" + }, + "started_at": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" + "status": { + "type": "string" + }, + "total_rows": { + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.AdminGroupUpdateRequest": { + "dto.AssetLinks": { "properties": { - "description": { + "self": { "type": "string" }, - "name": { + "set": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.AdminUserResponse": { + "dto.AssetResponse": { "properties": { - "avatar_url": { + "_links": { + "$ref": "#/components/schemas/dto.AssetLinks" + }, + "asset_tag": { "type": "string" }, + "asset_type": { + "$ref": "#/components/schemas/dto.AssetTypeSummary" + }, + "asset_type_id": { + "type": "integer" + }, + "category": { + "$ref": "#/components/schemas/dto.AssetCategorySummary" + }, + "category_id": { + "type": "integer" + }, "created_at": { "type": "string" }, - "email": { - "type": "string" + "created_by": { + "type": "integer" }, - "first_name": { - "type": "string" + "creator": { + "$ref": "#/components/schemas/dto.UserSummary" }, - "full_name": { - "type": "string" + "custom_field_values": { + "additionalProperties": {}, + "type": "object" }, - "group_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "description": { + "type": "string" }, "id": { "type": "integer" }, - "is_active": { - "type": "boolean" + "linked_item_count": { + "description": "LinkedItemCount is the number of item↔asset links for this asset\n(0 when the underlying query didn't ask for the rollup).", + "type": "integer" }, - "language": { - "type": "string" + "set": { + "allOf": [ + { + "$ref": "#/components/schemas/dto.AssetSetSummary" + } + ], + "description": "Nested summaries — populated from the row's joined columns when the\nunderlying query asks for them, otherwise omitted." }, - "last_name": { - "type": "string" + "set_id": { + "type": "integer" }, - "timezone": { + "status": { + "$ref": "#/components/schemas/dto.AssetStatusSummary" + }, + "status_id": { + "type": "integer" + }, + "title": { "type": "string" }, - "username": { + "updated_at": { "type": "string" }, "warnings": { + "description": "Warnings carries non-fatal anomalies surfaced by the query layer\n(e.g. corrupt custom_field_values JSON). Always serialized as an\narray (never null) so CLI consumers don't need to null-check.", "items": { "type": "string" }, @@ -132,302 +225,307 @@ }, "type": "object" }, - "internal_restapi_v1_handlers.AdminUserUpdateRequest": { + "dto.AssetSetLinks": { "properties": { - "email": { + "assets": { "type": "string" }, - "first_name": { + "categories": { "type": "string" }, - "is_active": { - "type": "boolean" + "self": { + "type": "string" }, - "last_name": { + "statuses": { + "type": "string" + }, + "types": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.AgentRunResponse": { + "dto.AssetSetResponse": { "properties": { - "ended_at": { + "_links": { + "$ref": "#/components/schemas/dto.AssetSetLinks" + }, + "asset_count": { + "type": "integer" + }, + "asset_type_count": { + "type": "integer" + }, + "created_at": { "type": "string" }, - "error": { + "created_by": { + "type": "integer" + }, + "description": { "type": "string" }, "id": { "type": "integer" }, - "item_id": { - "type": "integer" + "is_default": { + "type": "boolean" }, - "job_kind": { + "name": { "type": "string" }, - "queued_at": { + "updated_at": { "type": "string" }, - "started_at": { + "user_permission": { "type": "string" + } + }, + "type": "object" + }, + "dto.AssetSetSummary": { + "properties": { + "id": { + "type": "integer" }, - "status": { + "name": { "type": "string" - }, - "workspace_id": { - "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.AuditLogEntryResponse": { + "dto.AssetStatusResponse": { "properties": { - "action_type": { + "color": { "type": "string" }, - "details": { - "additionalProperties": {}, - "type": "object" - }, - "error_message": { + "created_at": { "type": "string" }, - "id": { - "type": "integer" - }, - "ip_address": { + "description": { "type": "string" }, - "resource_id": { + "display_order": { "type": "integer" }, - "resource_name": { - "type": "string" - }, - "resource_type": { - "type": "string" + "id": { + "type": "integer" }, - "success": { + "is_default": { "type": "boolean" }, - "timestamp": { - "type": "string" - }, - "user_agent": { + "name": { "type": "string" }, - "user_id": { + "set_id": { "type": "integer" }, - "username": { + "updated_at": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.AuditLogStreamResponse": { + "dto.AssetStatusSummary": { "properties": { - "entries": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AuditLogEntryResponse" - }, - "type": "array" - }, - "has_more": { - "type": "boolean" + "color": { + "type": "string" }, - "next_after_id": { + "id": { "type": "integer" + }, + "name": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.CollectionListResponse": { + "dto.AssetTypeFieldResponse": { "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.CollectionResponse" - }, - "type": "array" - }, - "total": { + "custom_field_id": { "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.CollectionResponse": { - "properties": { - "created_at": { - "type": "string" }, - "description": { - "type": "string" - }, - "id": { + "display_order": { "type": "integer" }, - "name": { + "field_description": { "type": "string" }, - "slug": { + "field_name": { "type": "string" }, - "updated_at": { + "field_type": { "type": "string" }, - "workspace_id": { + "id": { "type": "integer" + }, + "is_required": { + "type": "boolean" + }, + "options": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.CustomFieldResponse": { + "dto.AssetTypeResponse": { "properties": { + "asset_count": { + "type": "integer" + }, + "color": { + "type": "string" + }, + "created_at": { + "type": "string" + }, "description": { "type": "string" }, "display_order": { "type": "integer" }, - "field_type": { + "fields": { + "items": { + "$ref": "#/components/schemas/dto.AssetTypeFieldResponse" + }, + "type": "array" + }, + "icon": { "type": "string" }, "id": { "type": "integer" }, + "is_active": { + "type": "boolean" + }, "name": { "type": "string" }, - "options": { - "description": "JSON string", - "type": "string" + "set_id": { + "type": "integer" }, - "required": { - "type": "boolean" + "updated_at": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.ErrorResponse": { + "dto.AssetTypeSummary": { "properties": { - "code": { - "description": "Machine-readable error code", + "color": { "type": "string" }, - "details": { - "description": "Additional error details" - }, - "error": { - "description": "Human-readable message", + "icon": { "type": "string" }, - "request_id": { - "description": "Request correlation ID", + "id": { + "type": "integer" + }, + "name": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.ItemTypeResponse": { + "dto.AssetUpdateRequest": { "properties": { - "color": { - "type": "string" - }, - "description": { + "asset_tag": { "type": "string" }, - "hierarchy_level": { + "asset_type_id": { "type": "integer" }, - "icon": { - "type": "string" - }, - "id": { + "category_id": { "type": "integer" }, - "is_default": { - "type": "boolean" + "custom_field_values": { + "additionalProperties": {}, + "type": "object" }, - "name": { + "description": { "type": "string" }, - "sort_order": { + "status_id": { "type": "integer" + }, + "title": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.IterationCreateRequest": { + "dto.AttachmentResponse": { "properties": { - "description": { + "created_at": { "type": "string" }, - "end_date": { + "download_url": { "type": "string" }, - "is_global": { - "type": "boolean" + "file_size": { + "type": "integer" }, - "name": { + "filename": { "type": "string" }, - "start_date": { + "has_thumbnail": { + "type": "boolean" + }, + "id": { + "type": "integer" + }, + "item_id": { + "type": "integer" + }, + "mime_type": { "type": "string" }, - "status": { + "original_filename": { "type": "string" }, - "type_id": { - "type": "integer" + "thumbnail_url": { + "type": "string" }, - "workspace_id": { - "type": "integer" + "uploader": { + "$ref": "#/components/schemas/dto.UserSummary" + } + }, + "type": "object" + }, + "dto.CommentCreateRequest": { + "properties": { + "content": { + "type": "string" } }, "required": [ - "end_date", - "name", - "start_date" + "content" ], "type": "object" }, - "internal_restapi_v1_handlers.IterationResponse": { + "dto.CommentResponse": { "properties": { - "created_at": { + "author": { + "$ref": "#/components/schemas/dto.UserSummary" + }, + "content": { "type": "string" }, - "description": { + "content_html": { "type": "string" }, - "end_date": { + "created_at": { "type": "string" }, "id": { "type": "integer" }, - "is_global": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "start_date": { - "type": "string" - }, - "status": { - "type": "string" - }, - "type_color": { - "type": "string" - }, - "type_id": { + "item_id": { "type": "integer" }, - "type_name": { - "type": "string" - }, "updated_at": { "type": "string" }, @@ -436,533 +534,583 @@ "type": "string" }, "type": "array" - }, - "workspace_id": { - "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.IterationUpdateRequest": { + "dto.CommentUpdateRequest": { "properties": { - "description": { - "type": "string" - }, - "end_date": { - "type": "string" - }, - "name": { - "type": "string" - }, - "start_date": { - "type": "string" - }, - "status": { + "content": { "type": "string" - }, - "type_id": { - "nullable": true, - "type": "integer" } }, + "required": [ + "content" + ], "type": "object" }, - "internal_restapi_v1_handlers.MilestoneCreateRequest": { + "dto.EnforcedTemplateSummary": { "properties": { - "category_id": { - "type": "integer" - }, - "description": { - "type": "string" + "applied": { + "type": "boolean" }, "name": { "type": "string" }, - "status": { - "type": "string" - }, - "target_date": { - "type": "string" + "template_id": { + "type": "integer" } }, - "required": [ - "name" - ], "type": "object" }, - "internal_restapi_v1_handlers.MilestoneProgressItemResponse": { + "dto.HistoryResponse": { "properties": { - "assignee_avatar": { + "changed_at": { "type": "string" }, - "assignee_name": { + "field_name": { "type": "string" }, "id": { "type": "integer" }, - "item_number": { + "item_id": { "type": "integer" }, - "priority_color": { - "type": "string" - }, - "priority_name": { + "new_value": { "type": "string" }, - "status_color": { + "old_value": { "type": "string" }, - "status_name": { + "resolved_new_value": { "type": "string" }, - "title": { + "resolved_old_value": { "type": "string" }, - "workspace_id": { - "type": "integer" - }, - "workspace_key": { - "type": "string" + "user": { + "$ref": "#/components/schemas/dto.UserSummary" } }, "type": "object" }, - "internal_restapi_v1_handlers.MilestoneProgressResponse": { + "dto.ItemCreateRequest": { "properties": { - "category_color": { - "type": "string" - }, - "completed_items": { + "assignee_id": { "type": "integer" }, - "description": { - "type": "string" - }, - "items_by_category": { - "additionalProperties": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressItemResponse" - }, - "type": "array" - }, + "custom_fields": { + "additionalProperties": {}, "type": "object" }, - "milestone_id": { - "type": "integer" - }, - "milestone_name": { + "description": { "type": "string" }, - "percent_complete": { - "type": "number" - }, - "status": { + "due_date": { "type": "string" }, - "status_breakdown": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse" - }, - "type": "array" - }, - "target_date": { + "end_date": { "type": "string" }, - "total_items": { - "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.MilestoneResponse": { - "properties": { - "category_color": { - "type": "string" + "is_task": { + "type": "boolean" }, - "category_id": { + "item_type_id": { "type": "integer" }, - "category_name": { - "type": "string" - }, - "created_at": { - "type": "string" + "iteration_id": { + "type": "integer" }, - "description": { - "type": "string" + "milestone_ids": { + "items": { + "type": "integer" + }, + "type": "array" }, - "id": { + "parent_id": { "type": "integer" }, - "is_global": { - "type": "boolean" - }, - "name": { - "type": "string" + "priority_id": { + "type": "integer" }, - "position": { + "project_id": { "type": "integer" }, - "status": { + "start_date": { "type": "string" }, - "target_date": { - "type": "string" + "status_id": { + "description": "Optional create-time placement. If omitted, the item uses the workflow initial status.\nIf provided, it must be the initial status or directly reachable from the initial status\nwithout workflow conditions, validators, or approval gates.", + "type": "integer" }, - "updated_at": { + "title": { + "maxLength": 255, "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" - }, "workspace_id": { "type": "integer" } }, + "required": [ + "title", + "workspace_id" + ], "type": "object" }, - "internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse": { + "dto.ItemLinks": { "properties": { - "category_color": { + "attachments": { "type": "string" }, - "category_name": { + "children": { "type": "string" }, - "is_completed": { - "type": "boolean" + "comments": { + "type": "string" }, - "item_count": { - "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.MilestoneUpdateRequest": { - "properties": { - "category_id": { - "nullable": true, - "type": "integer" + "history": { + "type": "string" }, - "description": { + "parent": { "type": "string" }, - "name": { + "self": { "type": "string" }, - "status": { + "transitions": { "type": "string" }, - "target_date": { - "nullable": true, + "workspace": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.PaginatedResponse": { - "properties": { - "data": {}, - "pagination": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginationMeta" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.PriorityResponse": { + "dto.ItemResponse": { "properties": { - "color": { + "_links": { + "allOf": [ + { + "$ref": "#/components/schemas/dto.ItemLinks" + } + ], + "description": "HATEOAS links" + }, + "assignee": { + "$ref": "#/components/schemas/dto.UserSummary" + }, + "attachments": { + "items": { + "$ref": "#/components/schemas/dto.AttachmentResponse" + }, + "type": "array" + }, + "children": { + "items": { + "$ref": "#/components/schemas/dto.ItemResponse" + }, + "type": "array" + }, + "comments": { + "description": "Expanded collections (populated based on ?expand= parameter)", + "items": { + "$ref": "#/components/schemas/dto.CommentResponse" + }, + "type": "array" + }, + "completed_at": { "type": "string" }, + "created_at": { + "description": "Timestamps", + "type": "string" + }, + "creator": { + "$ref": "#/components/schemas/dto.UserSummary" + }, + "custom_fields": { + "additionalProperties": {}, + "type": "object" + }, "description": { "type": "string" }, - "icon": { + "description_html": { + "type": "string" + }, + "due_date": { + "type": "string" + }, + "end_date": { "type": "string" }, + "enforced_template": { + "allOf": [ + { + "$ref": "#/components/schemas/dto.EnforcedTemplateSummary" + } + ], + "description": "EnforcedTemplate echoes the mandatory work item template the item's type\nenforces (WI-438), populated only on the create response so non-UI callers\nlearn the expected structure even when they supplied their own\ndescription. Omitted when the type enforces no mandatory template." + }, + "history": { + "items": { + "$ref": "#/components/schemas/dto.HistoryResponse" + }, + "type": "array" + }, "id": { "type": "integer" }, - "is_default": { + "is_task": { "type": "boolean" }, - "name": { + "item_type": { + "$ref": "#/components/schemas/dto.ItemTypeSummary" + }, + "iteration": { + "$ref": "#/components/schemas/dto.IterationSummary" + }, + "key": { + "description": "e.g., \"PROJ-123\"", "type": "string" }, - "sort_order": { + "milestones": { + "items": { + "$ref": "#/components/schemas/dto.MilestoneSummary" + }, + "type": "array" + }, + "parent_id": { + "description": "Hierarchy. ParentID is the raw DB id. ParentKey is the parent's\nready-to-display key (e.g. \"WI-120\"), computed server-side from the\nparent's own workspace — clients must render this rather than building a\nkey from ParentID, which is a DB id in a different namespace and may even\npoint into another workspace. ParentKey and ParentTitle are populated\nonly on permission-checked single-item reads, and only when the caller\nmay view the parent (see ItemHandler.setParentSummary); they are omitted\nfrom list responses and withheld across a workspace boundary the caller\ncannot see.", "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.StatusCategoryResponse": { - "properties": { - "color": { - "type": "string" }, - "description": { + "parent_key": { "type": "string" }, - "id": { - "type": "integer" + "parent_title": { + "type": "string" }, - "is_completed": { - "type": "boolean" + "priority": { + "$ref": "#/components/schemas/dto.PrioritySummary" }, - "is_default": { - "type": "boolean" + "project": { + "$ref": "#/components/schemas/dto.ProjectSummary" }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.StatusResponse": { - "properties": { - "category_color": { + "start_date": { "type": "string" }, - "category_id": { - "type": "integer" + "status": { + "allOf": [ + { + "$ref": "#/components/schemas/dto.StatusSummary" + } + ], + "description": "Related entities (populated based on ?expand= parameter)" }, - "category_name": { + "title": { "type": "string" }, - "description": { + "transitions": { + "items": { + "$ref": "#/components/schemas/dto.TransitionResponse" + }, + "type": "array" + }, + "updated_at": { "type": "string" }, - "id": { - "type": "integer" + "workspace": { + "$ref": "#/components/schemas/dto.WorkspaceSummary" }, - "is_completed": { - "type": "boolean" + "workspace_id": { + "type": "integer" }, - "is_default": { - "type": "boolean" + "workspace_item_number": { + "type": "integer" }, - "name": { + "workspace_key": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.TUIPreferencesResponse": { + "dto.ItemTypeChangeRequest": { "properties": { - "last_workspace_id": { + "target_item_type_id": { "type": "integer" }, - "split_ratio": { - "type": "number" - }, - "theme": { - "type": "string" + "target_status_id": { + "type": "integer" } }, + "required": [ + "target_item_type_id" + ], "type": "object" }, - "internal_restapi_v1_handlers.UserResponse": { + "dto.ItemTypeSummary": { "properties": { - "avatar_url": { - "type": "string" - }, - "created_at": { + "builtin_key": { "type": "string" }, - "email": { + "color": { "type": "string" }, - "first_name": { - "type": "string" + "hierarchy_level": { + "type": "integer" }, - "full_name": { + "icon": { "type": "string" }, "id": { "type": "integer" }, - "is_active": { - "type": "boolean" + "name": { + "type": "string" + } + }, + "type": "object" + }, + "dto.ItemUpdateRequest": { + "properties": { + "assignee_id": { + "type": "integer" }, - "is_agent": { - "type": "boolean" + "custom_fields": { + "additionalProperties": {}, + "type": "object" }, - "language": { + "description": { "type": "string" }, - "last_name": { + "due_date": { "type": "string" }, - "timezone": { + "end_date": { "type": "string" }, - "username": { - "type": "string" + "is_task": { + "type": "boolean" }, - "warnings": { + "item_type_id": { + "type": "integer" + }, + "iteration_id": { + "type": "integer" + }, + "milestone_ids": { "items": { - "type": "string" + "type": "integer" }, "type": "array" + }, + "parent_id": { + "type": "integer" + }, + "priority_id": { + "type": "integer" + }, + "project_id": { + "type": "integer" + }, + "start_date": { + "type": "string" + }, + "title": { + "maxLength": 255, + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.WorkflowResponse": { + "dto.IterationSummary": { "properties": { - "created_at": { - "type": "string" - }, - "description": { + "end_date": { "type": "string" }, "id": { "type": "integer" }, - "is_default": { - "type": "boolean" - }, "name": { "type": "string" }, - "transitions": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse" - }, - "type": "array" + "start_date": { + "type": "string" }, - "updated_at": { + "status": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.WorkspaceCreateRequest": { + "dto.MilestoneSummary": { "properties": { - "color": { + "id": { + "type": "integer" + }, + "name": { "type": "string" }, - "description": { + "status": { "type": "string" }, - "icon": { + "target_date": { + "type": "string" + } + }, + "type": "object" + }, + "dto.PageLinks": { + "properties": { + "history": { "type": "string" }, - "key": { - "maxLength": 10, - "minLength": 2, + "permissions": { "type": "string" }, - "name": { - "maxLength": 100, + "self": { "type": "string" }, - "template_workspace_id": { - "type": "integer" + "workspace": { + "type": "string" } }, - "required": [ - "key", - "name" - ], "type": "object" }, - "internal_restapi_v1_handlers.WorkspaceResponse": { + "dto.PageResponse": { "properties": { - "active": { - "type": "boolean" + "_links": { + "$ref": "#/components/schemas/dto.PageLinks" }, - "color": { + "archived_at": { "type": "string" }, - "created_at": { + "archived_by": { + "type": "integer" + }, + "content": { "type": "string" }, - "description": { + "content_hash": { "type": "string" }, - "icon": { + "created_at": { + "type": "string" + }, + "created_by": { + "type": "integer" + }, + "depth": { + "type": "integer" + }, + "excerpt": { "type": "string" }, "id": { "type": "integer" }, - "internal_comments_enabled": { + "inherit_permissions": { "type": "boolean" }, - "is_personal": { + "is_home": { "type": "boolean" }, - "is_template": { - "type": "boolean" + "labels": { + "description": "Labels carries the workspace page-labels currently attached to the\npage. Populated by the service layer when the page-label repository\nis wired; always serialized as an array (never null) so CLI/JSON\nconsumers don't need to null-check.", + "items": { + "$ref": "#/components/schemas/models.PageLabel" + }, + "type": "array" }, - "key": { + "metadata": { + "additionalProperties": {}, + "type": "object" + }, + "parent_id": { + "type": "integer" + }, + "path": { "type": "string" }, - "name": { + "slug": { + "type": "string" + }, + "title": { "type": "string" }, "updated_at": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" + "updated_by": { + "type": "integer" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse": { + "dto.PageRevisionResponse": { "properties": { - "color": { + "change_summary": { "type": "string" }, - "configuration_set_name": { + "change_type": { "type": "string" }, - "description": { + "content": { "type": "string" }, - "icon": { + "created_at": { + "type": "string" + }, + "created_by": { + "type": "integer" + }, + "depth": { + "type": "integer" + }, + "excerpt": { "type": "string" }, "id": { "type": "integer" }, - "item_count": { + "page_id": { "type": "integer" }, - "name": { + "parent_id": { + "type": "integer" + }, + "path": { "type": "string" }, - "template_count": { + "revision_number": { "type": "integer" + }, + "slug": { + "type": "string" + }, + "title": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.WorkspaceUpdateRequest": { + "dto.PrioritySummary": { "properties": { - "active": { - "type": "boolean" - }, - "color": { + "builtin_key": { "type": "string" }, - "description": { + "color": { "type": "string" }, "icon": { "type": "string" }, - "is_template": { - "type": "boolean" + "id": { + "type": "integer" }, "name": { "type": "string" @@ -970,178 +1118,129 @@ }, "type": "object" }, - "internal_restapi_v1_handlers.actionDefinitionRequest": { + "dto.ProjectSummary": { "properties": { - "description": { + "id": { + "type": "integer" + }, + "name": { + "type": "string" + } + }, + "type": "object" + }, + "dto.StatusSummary": { + "properties": { + "builtin_key": { "type": "string" }, - "edges": { - "items": { - "$ref": "#/components/schemas/models.ActionEdge" - }, - "type": "array" + "category_builtin_key": { + "type": "string" }, - "name": { + "category_color": { "type": "string" }, - "nodes": { - "items": { - "$ref": "#/components/schemas/models.ActionNode" - }, - "type": "array" + "category_id": { + "type": "integer" }, - "trigger_config": { + "category_name": { "type": "string" }, - "trigger_type": { - "$ref": "#/components/schemas/models.ActionTriggerType" + "id": { + "type": "integer" + }, + "is_completed": { + "type": "boolean" + }, + "name": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.agentSkillListResponse": { + "dto.TransitionRequest": { "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.agentSkillSummary" - }, - "type": "array" + "to_status_id": { + "type": "integer" } }, + "required": [ + "to_status_id" + ], "type": "object" }, - "internal_restapi_v1_handlers.agentSkillSummary": { + "dto.TransitionResponse": { "properties": { - "description": { - "type": "string" - }, - "enabled": { + "from_all_statuses": { "type": "boolean" }, + "from_status": { + "$ref": "#/components/schemas/dto.StatusSummary" + }, + "from_status_id": { + "type": "integer" + }, "id": { "type": "integer" }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.batchItemLinksResponse": { - "properties": { - "has_more_links": { - "type": "boolean" - }, - "incoming": { - "items": { - "$ref": "#/components/schemas/models.ItemLink" - }, - "type": "array" - }, - "item_id": { - "type": "integer" + "to_status": { + "$ref": "#/components/schemas/dto.StatusSummary" }, - "next_after_link_id": { + "to_status_id": { "type": "integer" - }, - "outgoing": { - "items": { - "$ref": "#/components/schemas/models.ItemLink" - }, - "type": "array" } }, "type": "object" }, - "internal_restapi_v1_handlers.capabilityDTO": { + "dto.TransitionResultResponse": { "properties": { - "capability_type": { - "$ref": "#/components/schemas/models.CapabilityType" + "item": { + "$ref": "#/components/schemas/dto.ItemResponse" }, - "id": { + "new_status_id": { "type": "integer" }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.catalogResponse": { - "properties": { - "capabilities": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.capabilityDTO" - }, - "type": "array" - }, - "nodes": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.nodeTypeDTO" - }, - "type": "array" - }, - "scope": { - "type": "string" + "no_op": { + "type": "boolean" }, - "triggers": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.triggerTypeDTO" - }, - "type": "array" + "old_status_id": { + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.createWorklogRequest": { + "dto.UserSummary": { "properties": { - "date": { - "type": "string" - }, - "description": { + "avatar_url": { "type": "string" }, - "duration": { + "email": { "type": "string" }, - "duration_minutes": { - "type": "integer" - }, - "end_time": { + "first_name": { "type": "string" }, - "item_id": { - "type": "integer" - }, - "item_key": { + "full_name": { "type": "string" }, - "project_id": { + "id": { "type": "integer" }, - "start_time": { + "last_name": { "type": "string" }, - "timezone": { + "username": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.diagramListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.ItemDiagram" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.diagramWriteRequest": { + "dto.WorkspaceSummary": { "properties": { - "diagram_data": { + "id": { + "type": "integer" + }, + "key": { "type": "string" }, "name": { @@ -1150,84 +1249,46 @@ }, "type": "object" }, - "internal_restapi_v1_handlers.itemChangeResponse": { + "handlers.AdminGroupCreateRequest": { "properties": { - "change_type": { + "description": { "type": "string" }, - "item_id": { - "type": "integer" + "name": { + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.itemChangesResponse": { + "handlers.AdminGroupResponse": { "properties": { - "changes": { - "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.itemChangeResponse" - }, - "type": "array" - }, - "has_more": { - "type": "boolean" + "created_at": { + "type": "string" }, - "next_cursor": { + "description": { "type": "string" }, - "reset_required": { - "type": "boolean" + "id": { + "type": "integer" }, - "watermark": { - "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.itemLabelAddRequest": { - "properties": { - "label_id": { + "member_count": { "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.itemLabelSetRequest": { - "properties": { - "label_ids": { - "items": { - "type": "integer" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.labelCreateRequest": { - "properties": { - "color": { - "type": "string" }, "name": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.labelListResponse": { - "properties": { - "items": { + }, + "warnings": { "items": { - "$ref": "#/components/schemas/models.Label" + "type": "string" }, "type": "array" } }, "type": "object" }, - "internal_restapi_v1_handlers.labelUpdateRequest": { + "handlers.AdminGroupUpdateRequest": { "properties": { - "color": { + "description": { "type": "string" }, "name": { @@ -1236,2481 +1297,1176 @@ }, "type": "object" }, - "internal_restapi_v1_handlers.linkCreateRequest": { + "handlers.AdminUserResponse": { "properties": { - "link_type_id": { - "type": "integer" + "avatar_url": { + "type": "string" }, - "source_id": { - "type": "integer" + "created_at": { + "type": "string" }, - "source_type": { + "email": { "type": "string" }, - "target_id": { - "type": "integer" + "first_name": { + "type": "string" }, - "target_type": { + "full_name": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.milestoneReorderRequest": { - "properties": { - "category_id": { - "type": "integer" }, - "ordered_ids": { + "group_ids": { "items": { "type": "integer" }, "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.nodeTypeDTO": { - "properties": { - "category": { - "type": "string" }, - "config_schema": { - "type": "object" + "id": { + "type": "integer" }, - "description": { + "is_active": { + "type": "boolean" + }, + "language": { "type": "string" }, - "is_iterator": { - "type": "boolean" + "last_name": { + "type": "string" }, - "label": { + "timezone": { "type": "string" }, - "outputs": { + "username": { + "type": "string" + }, + "warnings": { "items": { "type": "string" }, "type": "array" - }, - "type": { - "$ref": "#/components/schemas/models.ActionNodeType" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageCreateRequest": { + "handlers.AdminUserUpdateRequest": { "properties": { - "content": { + "email": { "type": "string" }, - "is_home": { - "type": "boolean" - }, - "metadata": { - "additionalProperties": {}, - "type": "object" + "first_name": { + "type": "string" }, - "parent_id": { - "type": "integer" + "is_active": { + "type": "boolean" }, - "title": { + "last_name": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageDiagramCreateRequest": { + "handlers.AgentRunResponse": { "properties": { - "excalidraw": { - "type": "object" + "ended_at": { + "type": "string" }, - "expected_content_hash": { + "error": { "type": "string" }, - "mermaid": { + "id": { + "type": "integer" + }, + "item_id": { + "type": "integer" + }, + "job_kind": { "type": "string" }, - "name": { + "queued_at": { "type": "string" }, - "placement": { + "started_at": { + "type": "string" + }, + "status": { "type": "string" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageDiagramListResponse": { + "handlers.AuditLogEntryResponse": { "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/services.PageDiagram" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageDiagramUpdateRequest": { - "properties": { - "excalidraw": { + "action_type": { + "type": "string" + }, + "details": { + "additionalProperties": {}, "type": "object" }, - "expected_content_hash": { + "error_message": { "type": "string" }, - "mermaid": { + "id": { + "type": "integer" + }, + "ip_address": { "type": "string" }, - "name": { + "resource_id": { + "type": "integer" + }, + "resource_name": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageGrantPermissionRequest": { - "properties": { - "permission_level": { + }, + "resource_type": { "type": "string" }, - "principal_id": { + "success": { + "type": "boolean" + }, + "timestamp": { + "type": "string" + }, + "user_agent": { + "type": "string" + }, + "user_id": { "type": "integer" }, - "principal_type": { + "username": { "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageHistoryListResponse": { + "handlers.CollectionListResponse": { "properties": { "items": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse" + "$ref": "#/components/schemas/handlers.CollectionResponse" }, "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageLabelAddRequest": { - "properties": { - "label_id": { + }, + "total": { "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageLabelCreateRequest": { + "handlers.CollectionResponse": { "properties": { - "color": { + "created_at": { + "type": "string" + }, + "description": { "type": "string" }, + "id": { + "type": "integer" + }, "name": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageLabelListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.PageLabel" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageLabelSetRequest": { - "properties": { - "label_ids": { - "items": { - "type": "integer" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageLabelUpdateRequest": { - "properties": { - "color": { + }, + "slug": { "type": "string" }, - "name": { + "updated_at": { "type": "string" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageListWithLabelsResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.PageLabel" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageMoveRequest": { + "handlers.CustomFieldResponse": { "properties": { - "destination_workspace_id": { - "type": "integer" + "description": { + "type": "string" }, - "next_sibling_id": { + "display_order": { "type": "integer" }, - "parent_id": { - "type": "integer" + "field_type": { + "type": "string" }, - "prev_sibling_id": { + "id": { "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pagePermissionsResponse": { - "properties": { - "acl": { - "items": { - "$ref": "#/components/schemas/models.PagePermission" - }, - "type": "array" }, - "effective_level": { + "name": { "type": "string" }, - "inherit_permissions": { - "type": "boolean" + "options": { + "description": "JSON string", + "type": "string" }, - "page_id": { - "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.pageSetInheritanceRequest": { - "properties": { - "inherit_permissions": { + "required": { "type": "boolean" } }, "type": "object" }, - "internal_restapi_v1_handlers.pageUpdateRequest": { + "handlers.ErrorResponse": { "properties": { - "content": { - "type": "string" - }, - "expected_content_hash": { + "code": { + "description": "Machine-readable error code", "type": "string" }, - "metadata": { - "additionalProperties": {}, - "type": "object" + "details": { + "description": "Additional error details" }, - "title": { + "error": { + "description": "Human-readable message", "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.recurrenceForceGenerateResponse": { - "properties": { - "instances_generated": { - "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.recurrenceInstanceListResponse": { - "properties": { - "instances": { - "items": { - "$ref": "#/components/schemas/models.RecurrenceInstance" - }, - "type": "array" }, - "pagination": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginationMeta" + "request_id": { + "description": "Request correlation ID", + "type": "string" } }, "type": "object" }, - "internal_restapi_v1_handlers.rrulePreviewResponse": { + "handlers.ItemTypeResponse": { "properties": { - "dtstart": { + "builtin_key": { "type": "string" }, - "occurrences": { - "items": { - "type": "string" - }, - "type": "array" - }, - "rrule": { + "color": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.startTimerRequest": { - "properties": { + }, "description": { "type": "string" }, - "item_id": { + "hierarchy_level": { "type": "integer" }, - "project_id": { + "icon": { + "type": "string" + }, + "id": { "type": "integer" }, - "workspace_id": { + "is_default": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "sort_order": { "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.templateCreateRequest": { + "handlers.IterationCreateRequest": { "properties": { - "description_body": { + "description": { "type": "string" }, - "is_active": { + "end_date": { + "type": "string" + }, + "is_global": { "type": "boolean" }, - "item_type_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "name": { + "type": "string" }, - "mode": { + "start_date": { "type": "string" }, - "name": { + "status": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.templateListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.ItemTemplate" - }, - "type": "array" }, - "mandatory_template_id": { - "description": "MandatoryTemplateID is set when the request filtered by item_type_id and\nthat type has an active mandatory template, so callers (create modal, CLI)\ncan flag it without re-deriving the invariant.", + "type_id": { + "type": "integer" + }, + "workspace_id": { "type": "integer" } }, + "required": [ + "end_date", + "name", + "start_date" + ], "type": "object" }, - "internal_restapi_v1_handlers.templateUpdateRequest": { + "handlers.IterationResponse": { "properties": { - "description_body": { + "created_at": { "type": "string" }, - "is_active": { - "type": "boolean" - }, - "item_type_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "description": { + "type": "string" }, - "mode": { + "end_date": { "type": "string" }, + "id": { + "type": "integer" + }, + "is_global": { + "type": "boolean" + }, "name": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.testResultUpdateRequest": { - "properties": { - "actual_result": { - "type": "string" }, - "notes": { + "start_date": { "type": "string" }, "status": { "type": "string" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.testRunCreateRequest": { - "properties": { - "assignee_id": { - "type": "integer" }, - "name": { + "type_color": { "type": "string" }, - "set_id": { + "type_id": { "type": "integer" }, - "template_id": { - "type": "integer" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.timeProjectResponse": { - "properties": { - "category_color": { + "type_name": { "type": "string" }, - "category_id": { - "type": "integer" - }, - "category_name": { + "updated_at": { "type": "string" }, - "color": { - "type": "string" + "warnings": { + "items": { + "type": "string" + }, + "type": "array" }, - "customer_id": { + "workspace_id": { "type": "integer" - }, - "customer_name": { - "type": "string" - }, + } + }, + "type": "object" + }, + "handlers.IterationUpdateRequest": { + "properties": { "description": { "type": "string" }, - "hourly_rate": { - "type": "number" - }, - "id": { - "type": "integer" + "end_date": { + "type": "string" }, "name": { "type": "string" }, - "settings": { - "additionalProperties": {}, - "type": "object" + "start_date": { + "type": "string" }, "status": { "type": "string" }, - "total_hours": { - "type": "number" + "type_id": { + "nullable": true, + "type": "integer" } }, "type": "object" }, - "internal_restapi_v1_handlers.triggerTypeDTO": { + "handlers.MilestoneCreateRequest": { "properties": { - "config_schema": { - "type": "object" + "category_id": { + "type": "integer" }, "description": { "type": "string" }, - "label": { + "name": { "type": "string" }, - "type": { - "$ref": "#/components/schemas/models.ActionTriggerType" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.updateWorklogRequest": { - "properties": { - "description": { + "status": { + "type": "string" + }, + "target_date": { "type": "string" } }, + "required": [ + "name" + ], "type": "object" }, - "internal_restapi_v1_handlers.validateActionResponse": { - "properties": { - "errors": { - "items": { - "$ref": "#/components/schemas/actioncatalog.ValidationError" - }, - "type": "array" - } - }, - "type": "object" - }, - "internal_restapi_v1_handlers.worklogResponse": { + "handlers.MilestoneProgressItemResponse": { "properties": { - "created_at": { - "type": "integer" - }, - "customer_id": { - "type": "integer" - }, - "customer_name": { + "assignee_avatar": { "type": "string" }, - "date": { - "type": "integer" - }, - "description": { + "assignee_name": { "type": "string" }, - "duration_minutes": { - "type": "integer" - }, - "end_time": { - "type": "integer" - }, "id": { "type": "integer" }, - "item_id": { + "item_number": { "type": "integer" }, - "item_title": { + "priority_builtin_key": { "type": "string" }, - "project_id": { - "type": "integer" + "priority_color": { + "type": "string" }, - "project_max_hours": { - "type": "number" + "priority_name": { + "type": "string" }, - "project_name": { + "status_builtin_key": { "type": "string" }, - "project_total_hours": { - "type": "number" + "status_color": { + "type": "string" }, - "start_time": { - "type": "integer" + "status_name": { + "type": "string" }, - "updated_at": { - "type": "integer" + "title": { + "type": "string" }, "workspace_id": { "type": "integer" }, - "workspace_item_number": { - "type": "integer" - }, "workspace_key": { "type": "string" } }, "type": "object" }, - "models.APIToken": { + "handlers.MilestoneProgressResponse": { "properties": { - "created_at": { - "type": "string" - }, - "expires_at": { + "category_color": { "type": "string" }, - "id": { + "completed_items": { "type": "integer" }, - "is_temporary": { - "description": "True for SSH session tokens", - "type": "boolean" - }, - "last_used_at": { + "description": { "type": "string" }, - "name": { - "description": "Human-readable name for the token", - "type": "string" + "items_by_category": { + "additionalProperties": { + "items": { + "$ref": "#/components/schemas/handlers.MilestoneProgressItemResponse" + }, + "type": "array" + }, + "type": "object" }, - "permissions": { - "description": "JSON array of permissions", - "type": "string" + "milestone_id": { + "type": "integer" }, - "token_prefix": { - "description": "First few characters for identification", + "milestone_name": { "type": "string" }, - "updated_at": { - "type": "string" + "percent_complete": { + "type": "number" }, - "user_email": { - "description": "Joined fields", + "status": { "type": "string" }, - "user_id": { - "type": "integer" + "status_breakdown": { + "items": { + "$ref": "#/components/schemas/handlers.MilestoneStatusBreakdownResponse" + }, + "type": "array" }, - "user_name": { + "target_date": { "type": "string" + }, + "total_items": { + "type": "integer" } }, "type": "object" }, - "models.Action": { + "handlers.MilestoneResponse": { "properties": { - "actor_name": { + "category_color": { "type": "string" }, - "actor_user_id": { - "description": "ActorUserID overrides the execution actor. NULL means the action runs under\nthe triggering user's permissions. Setting this field requires the global\naction.set_actor permission because it grants cross-workspace impersonation.", + "category_id": { "type": "integer" }, - "allowed_role_ids": { - "description": "AllowedRoleIDs restricts a manual action to members of these workspace\nroles. An empty list means every workspace editor may trigger it.", - "items": { - "type": "integer" - }, - "type": "array" - }, - "created_at": { + "category_name": { "type": "string" }, - "created_by": { - "type": "integer" - }, - "creator_name": { - "description": "Joined fields for API responses", + "created_at": { "type": "string" }, "description": { "type": "string" }, - "edges": { - "items": { - "$ref": "#/components/schemas/models.ActionEdge" - }, - "type": "array" - }, "id": { "type": "integer" }, - "is_enabled": { + "is_global": { "type": "boolean" }, "name": { "type": "string" }, - "nodes": { - "items": { - "$ref": "#/components/schemas/models.ActionNode" - }, - "type": "array" + "position": { + "type": "integer" }, - "trigger_config": { - "description": "JSON with trigger-specific conditions", + "status": { + "type": "string" + }, + "target_date": { "type": "string" }, - "trigger_type": { - "$ref": "#/components/schemas/models.ActionTriggerType" - }, "updated_at": { "type": "string" }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + }, "workspace_id": { "type": "integer" } }, "type": "object" }, - "models.ActionEdge": { + "handlers.MilestoneStatusBreakdownResponse": { "properties": { - "action_id": { - "type": "integer" - }, - "created_at": { + "category_builtin_key": { "type": "string" }, - "edge_type": { - "description": "default, true, false (for conditions)", + "category_color": { "type": "string" }, - "id": { - "type": "integer" - }, - "source_handle": { + "category_name": { "type": "string" }, - "source_node_id": { - "type": "integer" - }, - "target_handle": { - "type": "string" + "is_completed": { + "type": "boolean" }, - "target_node_id": { + "item_count": { "type": "integer" } }, "type": "object" }, - "models.ActionNode": { + "handlers.MilestoneUpdateRequest": { "properties": { - "action_id": { + "category_id": { + "nullable": true, "type": "integer" }, - "created_at": { + "description": { "type": "string" }, - "id": { - "type": "integer" - }, - "node_config": { - "description": "JSON configuration for the node", + "name": { "type": "string" }, - "node_type": { - "$ref": "#/components/schemas/models.ActionNodeType" - }, - "position_x": { - "type": "number" - }, - "position_y": { - "type": "number" + "status": { + "type": "string" }, - "updated_at": { + "target_date": { + "nullable": true, "type": "string" } }, "type": "object" }, - "models.ActionNodeType": { - "enum": [ - "trigger", - "set_field", - "set_status", - "add_comment", - "notify_user", - "condition", - "update_asset", - "create_asset", - "round_robin_assign", - "ai_extract", - "ai_agent", - "container_run", - "http_request", - "transition_item", - "related_items", - "create_milestone" - ], - "type": "string", - "x-enum-varnames": [ - "ActionNodeTrigger", - "ActionNodeSetField", - "ActionNodeSetStatus", - "ActionNodeAddComment", - "ActionNodeNotifyUser", - "ActionNodeCondition", - "ActionNodeUpdateAsset", - "ActionNodeCreateAsset", - "ActionNodeRoundRobinAssign", - "ActionNodeAIExtract", - "ActionNodeAIAgent", - "ActionNodeContainerRun", - "ActionNodeHTTPRequest", - "ActionNodeTransitionItem", - "ActionNodeRelatedItems", - "ActionNodeCreateMilestone" - ] - }, - "models.ActionTriggerType": { - "enum": [ - "status_transition", - "item_created", - "item_updated", - "item_linked", - "manual", - "scm_tag_created", - "scm_release_branch_created", - "scm_pr_linked", - "scm_pr_merged" - ], - "type": "string", - "x-enum-varnames": [ - "ActionTriggerStatusTransition", - "ActionTriggerItemCreated", - "ActionTriggerItemUpdated", - "ActionTriggerItemLinked", - "ActionTriggerManual", - "ActionTriggerSCMTagCreated", - "ActionTriggerSCMReleaseBranchCreated", - "ActionTriggerSCMPRLinked", - "ActionTriggerSCMPRMerged" - ] + "handlers.PaginatedResponse": { + "properties": { + "data": {}, + "pagination": { + "$ref": "#/components/schemas/restapi.PaginationMeta" + } + }, + "type": "object" }, - "models.ActiveTimer": { + "handlers.PriorityResponse": { "properties": { - "created_at": { - "description": "Unix timestamp", - "type": "integer" + "builtin_key": { + "type": "string" }, - "customer_name": { + "color": { "type": "string" }, "description": { "type": "string" }, + "icon": { + "type": "string" + }, "id": { "type": "integer" }, - "item_id": { - "description": "Optional link to work item", - "type": "integer" + "is_default": { + "type": "boolean" }, - "item_title": { + "name": { "type": "string" }, - "project_id": { + "sort_order": { "type": "integer" - }, - "project_name": { + } + }, + "type": "object" + }, + "handlers.StatusCategoryResponse": { + "properties": { + "builtin_key": { "type": "string" }, - "start_time_utc": { - "description": "Unix timestamp in UTC", - "type": "integer" + "color": { + "type": "string" }, - "user_id": { - "type": "integer" + "description": { + "type": "string" }, - "workspace_id": { + "id": { "type": "integer" }, - "workspace_item_number": { - "type": "integer" + "is_completed": { + "type": "boolean" }, - "workspace_key": { - "type": "string" + "is_default": { + "type": "boolean" }, - "workspace_name": { + "name": { "type": "string" } }, "type": "object" }, - "models.Attachment": { + "handlers.StatusResponse": { "properties": { - "created_at": { + "builtin_key": { "type": "string" }, - "file_size": { - "type": "integer" - }, - "filename": { - "description": "Stored filename (UUID-based)", + "category_builtin_key": { "type": "string" }, - "has_thumbnail": { - "description": "Whether thumbnail was generated", - "type": "boolean" - }, - "id": { - "type": "integer" + "category_color": { + "type": "string" }, - "item_id": { + "category_id": { "type": "integer" }, - "mime_type": { + "category_name": { "type": "string" }, - "original_filename": { - "description": "Original user filename", + "description": { "type": "string" }, - "uploaded_by": { + "id": { "type": "integer" }, - "uploader_email": { - "type": "string" + "is_completed": { + "type": "boolean" }, - "uploader_name": { - "description": "Joined fields for API responses", + "is_default": { + "type": "boolean" + }, + "name": { "type": "string" } }, "type": "object" }, - "models.AttachmentUploadResponse": { + "handlers.TUIPreferencesResponse": { "properties": { - "attachment": { - "$ref": "#/components/schemas/models.Attachment" + "last_workspace_id": { + "type": "integer" }, - "message": { - "type": "string" + "split_ratio": { + "type": "number" }, - "success": { - "type": "boolean" + "theme": { + "type": "string" } }, "type": "object" }, - "models.CalendarScheduleEntry": { + "handlers.WorkflowResponse": { "properties": { - "created_at": { + "builtin_key": { "type": "string" }, - "duration_minutes": { - "description": "Duration in minutes, optional", - "type": "integer" - }, - "notes": { + "created_at": { "type": "string" }, - "scheduled_date": { - "description": "YYYY-MM-DD format", + "description": { "type": "string" }, - "scheduled_time": { - "description": "HH:MM format, optional", + "id": { + "type": "integer" + }, + "is_default": { + "type": "boolean" + }, + "name": { "type": "string" }, - "user_id": { - "type": "integer" + "transitions": { + "items": { + "$ref": "#/components/schemas/dto.TransitionResponse" + }, + "type": "array" }, - "workspace_id": { - "description": "User's personal workspace ID", - "type": "integer" + "updated_at": { + "type": "string" } }, "type": "object" }, - "models.CapabilityType": { - "enum": [ - "docker_environment", - "http_client", - "llm_connection", - "runner_pool" - ], - "type": "string", - "x-enum-varnames": [ - "CapabilityDockerEnvironment", - "CapabilityHTTPClient", - "CapabilityLLMConnection", - "CapabilityRunnerPool" - ] - }, - "models.CreateRecurrenceRequest": { + "handlers.WorkspaceCreateRequest": { "properties": { - "copy_assignee": { - "type": "boolean" - }, - "copy_custom_fields": { - "type": "boolean" - }, - "copy_description": { - "type": "boolean" - }, - "copy_priority": { - "type": "boolean" - }, - "dtend": { + "color": { "type": "string" }, - "dtstart": { - "description": "ISO 8601 format", + "description": { "type": "string" }, - "lead_time_days": { - "type": "integer" + "icon": { + "type": "string" }, - "rrule": { + "key": { + "maxLength": 10, + "minLength": 2, "type": "string" }, - "status_on_create": { - "type": "integer" + "name": { + "maxLength": 100, + "type": "string" }, - "template_item_id": { + "template_workspace_id": { "type": "integer" - }, - "timezone": { - "type": "string" } }, + "required": [ + "key", + "name" + ], "type": "object" }, - "models.Item": { + "handlers.WorkspaceResponse": { "properties": { - "assignee_avatar": { - "description": "Avatar URL of assigned user", - "type": "string" + "active": { + "type": "boolean" }, - "assignee_email": { - "description": "Email of assigned user", + "color": { "type": "string" }, - "assignee_id": { - "description": "User assignment fields", - "type": "integer" + "created_at": { + "type": "string" }, - "assignee_name": { - "description": "User information for API responses", + "description": { "type": "string" }, - "calendar_data": { - "items": { - "$ref": "#/components/schemas/models.CalendarScheduleEntry" - }, - "type": "array" + "icon": { + "type": "string" }, - "channel_id": { - "description": "Portal submission tracking fields (immutable once set)", + "id": { "type": "integer" }, - "channel_name": { - "description": "Portal submission tracking joined fields", - "type": "string" + "internal_comments_enabled": { + "type": "boolean" }, - "children": { - "description": "For tree representations", - "items": { - "$ref": "#/components/schemas/models.Item" - }, - "type": "array" + "is_personal": { + "type": "boolean" }, - "completed_at": { - "type": "string" + "is_template": { + "type": "boolean" }, - "created_at": { + "key": { "type": "string" }, - "creator_email": { - "description": "Email of creator (internal user or portal customer)", + "name": { "type": "string" }, - "creator_id": { - "description": "Internal user who created this item", - "type": "integer" - }, - "creator_name": { - "description": "Full name of creator (internal user or portal customer)", + "updated_at": { "type": "string" }, - "creator_portal_customer_email": { - "description": "Email of portal customer creator", + "warnings": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.WorkspaceTemplateSummaryResponse": { + "properties": { + "color": { "type": "string" }, - "creator_portal_customer_id": { - "description": "Portal customer who created this item (for portal submissions)", - "type": "integer" - }, - "creator_portal_customer_name": { - "description": "Name of portal customer creator", + "configuration_set_name": { "type": "string" }, - "custom_field_values": { - "additionalProperties": {}, - "type": "object" - }, "description": { "type": "string" }, - "due_date": { - "description": "Due date for item completion", + "icon": { "type": "string" }, - "effective_project_id": { - "description": "EffectiveProjectID is the resolved project after walking InheritProject\nup the parent chain. Consumers that need \"which time-tracking project\napplies to this item\" should read this, not ProjectID directly.", + "id": { "type": "integer" }, - "effective_project_name": { - "type": "string" - }, - "end_date": { - "description": "End date for item", - "type": "string" - }, - "estimate_minutes": { - "description": "Time estimate in minutes (compared against logged worklog time)", + "item_count": { "type": "integer" }, - "frac_index": { - "description": "Manual sorting field", + "name": { "type": "string" }, - "id": { + "template_count": { "type": "integer" - }, - "inherit_project": { - "description": "If true, ProjectID is ignored and the parent item's effective project is used", - "type": "boolean" - }, - "is_task": { - "description": "Flag to mark this item as a task (checklist item)", + } + }, + "type": "object" + }, + "handlers.WorkspaceUpdateRequest": { + "properties": { + "active": { "type": "boolean" }, - "item_type_id": { - "description": "Optional, defaults to workspace's default item type", - "type": "integer" + "color": { + "type": "string" }, - "item_type_name": { + "description": { "type": "string" }, - "iteration_end_date": { + "icon": { "type": "string" }, - "iteration_id": { - "description": "Optional iteration assignment", - "type": "integer" + "is_template": { + "type": "boolean" }, - "iteration_name": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "handlers.actionDefinitionRequest": { + "properties": { + "description": { "type": "string" }, - "labels": { - "description": "Global item labels", + "edges": { "items": { - "$ref": "#/components/schemas/models.Label" + "$ref": "#/components/schemas/models.ActionEdge" }, "type": "array" }, - "last_active_at": { - "description": "Recency for the board \"Bubble Mode\" sort. Bumped on activity (comments,\nedits, transitions) but not on manual frac_index reorder.", + "name": { "type": "string" }, - "milestones": { + "nodes": { "items": { - "$ref": "#/components/schemas/models.Milestone" + "$ref": "#/components/schemas/models.ActionNode" }, "type": "array" }, - "parent_id": { - "description": "Hierarchy fields", - "type": "integer" - }, - "parent_title": { + "trigger_config": { "type": "string" }, - "parent_workspace_item_number": { - "description": "Parent's workspace-scoped number, for rendering the parent key", - "type": "integer" - }, - "personal_labels": { + "trigger_type": { + "$ref": "#/components/schemas/models.ActionTriggerType" + } + }, + "type": "object" + }, + "handlers.agentSkillListResponse": { + "properties": { + "items": { "items": { - "$ref": "#/components/schemas/models.PersonalLabel" + "$ref": "#/components/schemas/handlers.agentSkillSummary" }, "type": "array" - }, - "priority_color": { + } + }, + "type": "object" + }, + "handlers.agentSkillSummary": { + "properties": { + "description": { "type": "string" }, - "priority_icon": { - "type": "string" + "enabled": { + "type": "boolean" }, - "priority_id": { - "description": "Foreign key to priorities table", + "id": { "type": "integer" }, - "priority_name": { + "name": { "type": "string" + } + }, + "type": "object" + }, + "handlers.batchItemLinksResponse": { + "properties": { + "has_more_links": { + "type": "boolean" }, - "project_id": { - "description": "Time-tracking project membership. \"Project\" in Windshift always refers\nto a row in time_projects; both ProjectID and TimeProjectID below are\nFKs to that table, serving different roles:\n ProjectID - the project this item belongs to (the bucket\n worklogs default to). Can be inherited from the\n parent item; see InheritProject.\n TimeProjectID - overrides the project used when logging time on\n this specific item (independent of the bucket the\n item belongs to).\nEffectiveProjectID (below) is the resolved value after applying\ninheritance, and is what consumers should read.", + "incoming": { + "items": { + "$ref": "#/components/schemas/models.ItemLink" + }, + "type": "array" + }, + "item_id": { "type": "integer" }, - "project_inheritance_mode": { - "description": "\"none\" | \"inherit\" | \"direct\"", - "type": "string" + "next_after_link_id": { + "type": "integer" }, - "project_name": { - "description": "Name of the time-tracking project this item belongs to (joined from time_projects via ProjectID)", - "type": "string" - }, - "related_work_item_id": { - "description": "Personal task relationship (for linking personal workspace tasks to work items)", - "type": "integer" - }, - "related_work_item_number": { - "type": "integer" - }, - "related_work_item_title": { - "description": "Related work item joined fields (for personal tasks)", - "type": "string" - }, - "related_work_item_workspace_id": { - "type": "integer" - }, - "related_work_item_workspace_key": { - "type": "string" - }, - "reporter_avatar": { - "description": "Avatar URL of reporter", - "type": "string" - }, - "reporter_email": { - "description": "Email of reporter", - "type": "string" - }, - "reporter_id": { - "description": "User who reported this item (from Jira import)", - "type": "integer" - }, - "reporter_name": { - "description": "Full name of reporter", - "type": "string" - }, - "request_type_id": { - "description": "Request type used for submission", - "type": "integer" - }, - "request_type_name": { - "description": "Name of the request type", - "type": "string" - }, - "start_date": { - "description": "Start date for item", - "type": "string" - }, - "status_color": { - "description": "Color from the status category (joined field)", - "type": "string" - }, - "status_id": { - "description": "Foreign key to statuses table", - "type": "integer" - }, - "status_name": { - "description": "Name from statuses table (joined field)", - "type": "string" - }, - "status_since": { - "description": "StatusSince is when the item last entered its current status, derived from\nitem_history (falls back to created_at when there is no recorded change).", - "type": "string" - }, - "story_points": { - "description": "Estimation", - "type": "number" - }, - "time_project_id": { - "type": "integer" - }, - "time_project_name": { - "description": "Name of the time-tracking project overriding worklog defaults (joined from time_projects via TimeProjectID)", - "type": "string" - }, - "title": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "virtual_field_data": { - "additionalProperties": {}, - "type": "object" - }, - "workspace_id": { - "type": "integer" - }, - "workspace_item_number": { - "description": "Workspace-specific sequential number for display keys", - "type": "integer" - }, - "workspace_key": { - "type": "string" - }, - "workspace_name": { - "description": "Joined fields for API responses", - "type": "string" - } - }, - "type": "object" - }, - "models.ItemDiagram": { - "properties": { - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "creator_email": { - "type": "string" - }, - "creator_name": { - "description": "Joined fields for API responses", - "type": "string" - }, - "diagram_data": { - "description": "JSON with elements, appState, files", - "type": "string" - }, - "id": { - "type": "integer" - }, - "item_id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "updated_by": { - "type": "integer" - }, - "updated_by_email": { - "type": "string" - }, - "updated_by_name": { - "type": "string" - } - }, - "type": "object" - }, - "models.ItemLink": { - "properties": { - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "created_by_name": { - "type": "string" - }, - "custom_field_id": { - "type": "integer" - }, - "custom_field_name": { - "description": "Custom field link metadata", - "type": "string" - }, - "id": { - "type": "integer" - }, - "link_type_color": { - "type": "string" - }, - "link_type_forward_label": { - "type": "string" - }, - "link_type_id": { - "type": "integer" - }, - "link_type_name": { - "description": "Joined fields for API responses", - "type": "string" - }, - "link_type_reverse_label": { - "type": "string" - }, - "source_id": { - "type": "integer" - }, - "source_item_number": { - "description": "SourceItemNumber is the workspace-scoped item number (the \"74\" in\n\"WI-74\"). Display the user-facing key as\nSourceWorkspaceKey + \"-\" + SourceItemNumber, never SourceID — that\nfield is the global DB id and looks wrong (e.g. \"WI-149\") in UI.", - "type": "integer" - }, - "source_item_type_color": { - "type": "string" - }, - "source_item_type_icon": { - "type": "string" - }, - "source_item_type_id": { - "type": "integer" - }, - "source_item_type_name": { - "type": "string" - }, - "source_status_color": { - "type": "string" - }, - "source_status_id": { - "description": "Source item details", - "type": "integer" - }, - "source_status_name": { - "type": "string" - }, - "source_title": { - "type": "string" - }, - "source_type": { - "description": "\"item\" or \"test_case\"", - "type": "string" - }, - "source_workspace_id": { - "type": "integer" - }, - "source_workspace_key": { - "type": "string" - }, - "target_id": { - "type": "integer" - }, - "target_item_number": { - "description": "TargetItemNumber: see SourceItemNumber.", - "type": "integer" - }, - "target_item_type_color": { - "type": "string" - }, - "target_item_type_icon": { - "type": "string" - }, - "target_item_type_id": { - "type": "integer" - }, - "target_item_type_name": { - "type": "string" - }, - "target_status_color": { - "type": "string" - }, - "target_status_id": { - "description": "Target item details", - "type": "integer" - }, - "target_status_name": { - "type": "string" - }, - "target_title": { - "type": "string" - }, - "target_type": { - "description": "\"item\" or \"test_case\"", - "type": "string" - }, - "target_workspace_id": { - "type": "integer" - }, - "target_workspace_key": { - "type": "string" - } - }, - "type": "object" - }, - "models.ItemTemplate": { - "properties": { - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "description_body": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "is_active": { - "type": "boolean" - }, - "item_type_ids": { - "items": { - "type": "integer" - }, - "type": "array" - }, - "mode": { - "type": "string" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "updated_by": { - "type": "integer" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.Label": { - "properties": { - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - } - }, - "type": "object" - }, - "models.LinkType": { - "properties": { - "active": { - "type": "boolean" - }, - "allowed_entity_types": { - "description": "nil = all types allowed; e.g. [\"item\",\"test_case\"]", - "items": { - "type": "string" - }, - "type": "array" - }, - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "forward_label": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "is_system": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "reverse_label": { - "type": "string" - }, - "updated_at": { - "type": "string" - } - }, - "type": "object" - }, - "models.Milestone": { - "properties": { - "category_color": { - "type": "string" - }, - "category_id": { - "type": "integer" - }, - "category_name": { - "description": "Joined fields for API responses", - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "external_key": { - "description": "Stable upsert key set by automation (e.g. tag short-name); unique per workspace when set", - "type": "string" - }, - "id": { - "type": "integer" - }, - "is_global": { - "description": "false=local to workspace, true=global (shared)", - "type": "boolean" - }, - "latest_release": { - "$ref": "#/components/schemas/models.MilestoneRelease" - }, - "name": { - "type": "string" - }, - "position": { - "description": "Manual sort order (drag-and-drop), scoped per (is_global, workspace_id, category_id)", - "type": "integer" - }, - "releases": { - "items": { - "$ref": "#/components/schemas/models.MilestoneRelease" - }, - "type": "array" - }, - "status": { - "description": "planning, in-progress, completed, cancelled", - "type": "string" - }, - "target_date": { - "description": "Date in YYYY-MM-DD format, nullable", - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "description": "NULL if global, set if local to workspace", - "type": "integer" - }, - "workspace_name": { - "type": "string" - } - }, - "type": "object" - }, - "models.MilestoneRelease": { - "properties": { - "body": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "is_draft": { - "type": "boolean" - }, - "is_prerelease": { - "type": "boolean" - }, - "milestone_id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "scm_connection_id": { - "description": "Visible only to users with connection workspace access", - "type": "integer" - }, - "scm_release_id": { - "type": "string" - }, - "scm_release_url": { - "type": "string" - }, - "scm_repository": { - "description": "\"owner/repo\"; same visibility as SCMConnectionID", - "type": "string" - }, - "tag_name": { - "type": "string" - }, - "target_commitish": { - "type": "string" - } - }, - "type": "object" - }, - "models.PageLabel": { - "properties": { - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.PagePermission": { - "properties": { - "granted_at": { - "type": "string" - }, - "granted_by": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "page_id": { - "type": "integer" - }, - "permission_level": { - "type": "string" - }, - "principal_id": { - "type": "integer" - }, - "principal_type": { - "type": "string" - } - }, - "type": "object" - }, - "models.PersonalLabel": { - "properties": { - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "user_id": { - "description": "NULL for global labels, user_id for user-specific labels", - "type": "integer" - } - }, - "type": "object" - }, - "models.RRulePreviewRequest": { - "properties": { - "count": { - "description": "Number of occurrences to preview (default 10)", - "type": "integer" - }, - "dtstart": { - "type": "string" - }, - "rrule": { - "type": "string" - } - }, - "type": "object" - }, - "models.RecurrenceInstance": { - "properties": { - "created_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "instance_item_id": { - "type": "integer" - }, - "item_status": { - "type": "string" - }, - "item_title": { - "type": "string" - }, - "recurrence_rule_id": { - "type": "integer" - }, - "scheduled_date": { - "type": "string" - }, - "sequence_number": { - "type": "integer" - } - }, - "type": "object" - }, - "models.RecurrenceRule": { - "properties": { - "copy_assignee": { - "type": "boolean" - }, - "copy_custom_fields": { - "type": "boolean" - }, - "copy_description": { - "type": "boolean" - }, - "copy_priority": { - "type": "boolean" - }, - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "creator_name": { - "type": "string" - }, - "dtend": { - "type": "string" - }, - "dtstart": { - "description": "Recurrence start date", - "type": "string" - }, - "id": { - "type": "integer" - }, - "instance_count": { - "type": "integer" - }, - "is_active": { - "type": "boolean" - }, - "last_generated_until": { - "type": "string" - }, - "lead_time_days": { - "type": "integer" - }, - "next_generation_check": { - "type": "string" - }, - "next_occurrence": { - "type": "string" - }, - "rrule": { - "description": "e.g., \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"", - "type": "string" - }, - "status_on_create": { - "type": "integer" - }, - "template_item_id": { - "type": "integer" - }, - "template_title": { - "type": "string" - }, - "timezone": { - "description": "IANA timezone", - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - }, - "workspace_key": { - "type": "string" - }, - "workspace_name": { - "type": "string" - } - }, - "type": "object" - }, - "models.SkillPageReference": { - "properties": { - "id": { - "type": "integer" - }, - "title": { - "type": "string" - } - }, - "type": "object" - }, - "models.TestCase": { - "properties": { - "created_at": { - "type": "string" - }, - "estimated_duration": { - "description": "in seconds", - "type": "integer" - }, - "folder_id": { - "type": "integer" - }, - "folder_name": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "labels": { - "items": { - "$ref": "#/components/schemas/models.TestLabel" - }, - "type": "array" - }, - "name": { - "type": "string" - }, - "preconditions": { - "type": "string" - }, - "priority": { - "description": "low, medium, high, critical", - "type": "string" - }, - "sort_order": { - "type": "integer" - }, - "status": { - "description": "active, inactive, draft", - "type": "string" - }, - "test_steps": { - "items": { - "$ref": "#/components/schemas/models.TestStep" - }, - "type": "array" - }, - "title": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.TestFolder": { - "properties": { - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "parent_id": { - "type": "integer" - }, - "sort_order": { - "type": "integer" - }, - "test_case_count": { - "type": "integer" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.TestLabel": { - "properties": { - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.TestRun": { - "properties": { - "assignee_avatar": { - "type": "string" - }, - "assignee_email": { - "type": "string" - }, - "assignee_id": { - "description": "User assigned to execute this run", - "type": "integer" - }, - "assignee_name": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "ended_at": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "set_id": { - "type": "integer" - }, - "started_at": { - "type": "string" - }, - "template_id": { - "description": "Optional reference to template", - "type": "integer" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.TestRunTemplate": { - "properties": { - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "set_id": { - "type": "integer" - }, - "set_name": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" + "outgoing": { + "items": { + "$ref": "#/components/schemas/models.ItemLink" + }, + "type": "array" } }, "type": "object" }, - "models.TestSet": { + "handlers.capabilityDTO": { "properties": { - "created_at": { - "type": "string" - }, - "description": { - "type": "string" - }, - "failed_runs": { - "type": "integer" + "capability_type": { + "$ref": "#/components/schemas/models.CapabilityType" }, "id": { "type": "integer" }, - "last_run_date": { - "type": "string" - }, - "last_run_status": { - "type": "string" - }, - "milestone_id": { - "type": "integer" - }, - "milestone_name": { - "type": "string" - }, "name": { "type": "string" - }, - "successful_runs": { - "type": "integer" - }, - "test_case_count": { - "type": "integer" - }, - "total_runs": { - "type": "integer" - }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "models.TestStep": { - "properties": { - "action": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "data": { - "type": "string" - }, - "expected": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "step_number": { - "type": "integer" - }, - "test_case_id": { - "type": "integer" - }, - "updated_at": { - "type": "string" - } - }, - "type": "object" - }, - "models.UpdateRecurrenceRequest": { - "properties": { - "copy_assignee": { - "type": "boolean" - }, - "copy_custom_fields": { - "type": "boolean" - }, - "copy_description": { - "type": "boolean" - }, - "copy_priority": { - "type": "boolean" - }, - "dtend": { - "type": "string" - }, - "dtstart": { - "type": "string" - }, - "is_active": { - "type": "boolean" - }, - "lead_time_days": { - "type": "integer" - }, - "rrule": { - "type": "string" - }, - "status_on_create": { - "type": "integer" - }, - "timezone": { - "type": "string" } }, "type": "object" }, - "models.WorkspaceAgentSkill": { + "handlers.catalogResponse": { "properties": { - "body": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "created_by_user_id": { - "description": "CreatedByUserID is a soft audit ref; nil when the creator was deleted.", - "type": "integer" - }, - "description": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "id": { - "type": "integer" - }, - "name": { - "type": "string" - }, - "pages": { - "description": "Pages are the workspace pages referenced by this skill (WI-517). On the\nadmin surface they round-trip so the editor can render the current\nselection; on the agent-facing `ws skill get` surface their markdown is\ninlined into Body instead. nil/omitted when the skill references none.", + "capabilities": { "items": { - "$ref": "#/components/schemas/models.SkillPageReference" + "$ref": "#/components/schemas/handlers.capabilityDTO" }, "type": "array" }, - "updated_at": { - "type": "string" - }, - "workspace_id": { - "type": "integer" - } - }, - "type": "object" - }, - "services.PageDiagram": { - "properties": { - "attachment_id": { - "type": "integer" - }, - "content_hash": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "kind": { - "type": "string" - }, - "name": { - "type": "string" - }, - "page_id": { - "type": "integer" - }, - "payload": { - "type": "object" - }, - "revision_number": { - "type": "integer" - } - }, - "type": "object" - }, - "services.TestRunDetail": { - "properties": { - "results": { + "nodes": { "items": { - "$ref": "#/components/schemas/services.TestRunResultWithCaseTitle" + "$ref": "#/components/schemas/handlers.nodeTypeDTO" }, "type": "array" }, - "run": { - "$ref": "#/components/schemas/models.TestRun" - }, - "step_results": { - "additionalProperties": { - "$ref": "#/components/schemas/services.TestRunStepResult" - }, - "type": "object" + "scope": { + "type": "string" }, - "test_cases": { + "triggers": { "items": { - "$ref": "#/components/schemas/models.TestCase" + "$ref": "#/components/schemas/handlers.triggerTypeDTO" }, "type": "array" } }, "type": "object" }, - "services.TestRunResultWithCaseTitle": { + "handlers.createWorklogRequest": { "properties": { - "actual_result": { + "date": { "type": "string" }, - "created_at": { + "description": { "type": "string" }, - "executed_at": { + "duration": { "type": "string" }, - "id": { + "duration_minutes": { "type": "integer" }, - "notes": { + "end_time": { "type": "string" }, - "run_id": { + "item_id": { "type": "integer" }, - "status": { - "description": "\"passed\", \"failed\", \"blocked\", \"skipped\", \"not_run\"", + "item_key": { "type": "string" }, - "test_case_id": { + "project_id": { "type": "integer" }, - "test_case_title": { + "start_time": { "type": "string" }, - "updated_at": { + "timezone": { "type": "string" } }, "type": "object" }, - "services.TestRunStepResult": { + "handlers.diagramListResponse": { "properties": { - "actual_result": { - "type": "string" - }, - "executed_at": { + "items": { + "items": { + "$ref": "#/components/schemas/models.ItemDiagram" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.diagramWriteRequest": { + "properties": { + "diagram_data": { "type": "string" }, - "item_id": { - "type": "integer" - }, - "notes": { + "name": { "type": "string" - }, - "status": { + } + }, + "type": "object" + }, + "handlers.itemChangeResponse": { + "properties": { + "change_type": { "type": "string" }, - "step_id": { + "item_id": { "type": "integer" - }, - "test_case_id": { + } + }, + "type": "object" + }, + "handlers.itemLabelAddRequest": { + "properties": { + "label_id": { "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi.ErrorResponse": { + "handlers.itemLabelSetRequest": { "properties": { - "code": { - "description": "Machine-readable error code", - "type": "string" - }, - "details": { - "description": "Additional error details" - }, - "error": { - "description": "Human-readable message", + "label_ids": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.labelCreateRequest": { + "properties": { + "color": { "type": "string" }, - "request_id": { - "description": "Request correlation ID", + "name": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi.PaginatedResponse": { + "handlers.labelListResponse": { "properties": { - "data": {}, - "pagination": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginationMeta" + "items": { + "items": { + "$ref": "#/components/schemas/models.Label" + }, + "type": "array" } }, "type": "object" }, - "windshift_internal_restapi.PaginationMeta": { + "handlers.labelUpdateRequest": { "properties": { - "has_more": { - "type": "boolean" - }, - "limit": { - "type": "integer" - }, - "page": { - "type": "integer" - }, - "total": { - "type": "integer" + "color": { + "type": "string" }, - "total_pages": { - "type": "integer" + "name": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetCategoryResponse": { + "handlers.linkCreateRequest": { "properties": { - "asset_count": { - "type": "integer" - }, - "children_count": { - "type": "integer" - }, - "created_at": { - "type": "string" - }, - "descendants_count": { + "link_type_id": { "type": "integer" }, - "description": { - "type": "string" - }, - "has_children": { - "type": "boolean" - }, - "id": { + "source_id": { "type": "integer" }, - "name": { + "source_type": { "type": "string" }, - "parent_id": { + "target_id": { "type": "integer" }, - "path": { + "target_type": { "type": "string" - }, - "set_id": { + } + }, + "type": "object" + }, + "handlers.milestoneReorderRequest": { + "properties": { + "category_id": { "type": "integer" }, - "updated_at": { - "type": "string" + "ordered_ids": { + "items": { + "type": "integer" + }, + "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetCategorySummary": { + "handlers.nodeTypeDTO": { "properties": { - "id": { - "type": "integer" + "category": { + "type": "string" }, - "name": { + "config_schema": { + "type": "object" + }, + "description": { "type": "string" }, - "path": { + "is_iterator": { + "type": "boolean" + }, + "label": { "type": "string" + }, + "outputs": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "$ref": "#/components/schemas/models.ActionNodeType" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetCreateRequest": { + "handlers.pageCreateRequest": { "properties": { - "asset_tag": { + "content": { "type": "string" }, - "asset_type_id": { - "type": "integer" - }, - "category_id": { - "type": "integer" + "is_home": { + "type": "boolean" }, - "custom_field_values": { + "metadata": { "additionalProperties": {}, "type": "object" }, - "description": { - "type": "string" - }, - "status_id": { + "parent_id": { "type": "integer" }, "title": { @@ -3719,1679 +2475,1487 @@ }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetImportJobResponse": { + "handlers.pageDiagramListResponse": { "properties": { - "asset_type_id": { - "type": "integer" - }, - "completed_at": { - "type": "string" - }, - "created_at": { + "items": { + "items": { + "$ref": "#/components/schemas/services.PageDiagram" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.pageGrantPermissionRequest": { + "properties": { + "permission_level": { "type": "string" }, - "created_rows": { + "principal_id": { "type": "integer" }, - "error_message": { + "principal_type": { "type": "string" - }, - "error_rows": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "processed_rows": { - "type": "integer" - }, - "set_id": { + } + }, + "type": "object" + }, + "handlers.pageHistoryListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/dto.PageRevisionResponse" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.pageLabelAddRequest": { + "properties": { + "label_id": { "type": "integer" - }, - "started_at": { + } + }, + "type": "object" + }, + "handlers.pageLabelCreateRequest": { + "properties": { + "color": { "type": "string" }, - "status": { + "name": { "type": "string" - }, - "total_rows": { - "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetLinks": { + "handlers.pageLabelListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/models.PageLabel" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.pageLabelSetRequest": { + "properties": { + "label_ids": { + "items": { + "type": "integer" + }, + "type": "array" + } + }, + "type": "object" + }, + "handlers.pageLabelUpdateRequest": { "properties": { - "self": { + "color": { "type": "string" }, - "set": { + "name": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetResponse": { + "handlers.pageListResponse": { "properties": { - "_links": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetLinks" - }, - "asset_tag": { - "type": "string" - }, - "asset_type": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeSummary" - }, - "asset_type_id": { - "type": "integer" - }, - "category": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategorySummary" - }, - "category_id": { - "type": "integer" - }, - "created_at": { - "type": "string" - }, - "created_by": { - "type": "integer" - }, - "creator": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - }, - "custom_field_values": { - "additionalProperties": {}, - "type": "object" - }, - "description": { - "type": "string" - }, - "id": { - "type": "integer" - }, - "linked_item_count": { - "description": "LinkedItemCount is the number of item↔asset links for this asset\n(0 when the underlying query didn't ask for the rollup).", - "type": "integer" - }, - "set": { - "allOf": [ - { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetSummary" - } - ], - "description": "Nested summaries — populated from the row's joined columns when the\nunderlying query asks for them, otherwise omitted." - }, - "set_id": { - "type": "integer" - }, - "status": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusSummary" - }, - "status_id": { - "type": "integer" - }, - "title": { - "type": "string" - }, - "updated_at": { - "type": "string" - }, - "warnings": { - "description": "Warnings carries non-fatal anomalies surfaced by the query layer\n(e.g. corrupt custom_field_values JSON). Always serialized as an\narray (never null) so CLI consumers don't need to null-check.", + "items": { "items": { - "type": "string" + "$ref": "#/components/schemas/dto.PageResponse" }, "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetSetLinks": { + "handlers.pageListWithLabelsResponse": { "properties": { - "assets": { - "type": "string" - }, - "categories": { - "type": "string" - }, - "self": { - "type": "string" - }, - "statuses": { - "type": "string" - }, - "types": { - "type": "string" + "items": { + "items": { + "$ref": "#/components/schemas/models.PageLabel" + }, + "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetSetResponse": { + "handlers.pageMoveRequest": { "properties": { - "_links": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetLinks" - }, - "asset_count": { + "destination_workspace_id": { "type": "integer" }, - "asset_type_count": { + "next_sibling_id": { "type": "integer" }, - "created_at": { - "type": "string" - }, - "created_by": { + "parent_id": { "type": "integer" }, - "description": { - "type": "string" - }, - "id": { + "prev_sibling_id": { "type": "integer" + } + }, + "type": "object" + }, + "handlers.pagePermissionsResponse": { + "properties": { + "acl": { + "items": { + "$ref": "#/components/schemas/models.PagePermission" + }, + "type": "array" }, - "is_default": { - "type": "boolean" - }, - "name": { + "effective_level": { "type": "string" }, - "updated_at": { - "type": "string" + "inherit_permissions": { + "type": "boolean" }, - "user_permission": { - "type": "string" + "page_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetSetSummary": { + "handlers.pageSetInheritanceRequest": { "properties": { - "id": { - "type": "integer" - }, - "name": { - "type": "string" + "inherit_permissions": { + "type": "boolean" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetStatusResponse": { + "handlers.pageUpdateRequest": { "properties": { - "color": { - "type": "string" - }, - "created_at": { + "content": { "type": "string" }, - "description": { + "expected_content_hash": { "type": "string" }, - "display_order": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "is_default": { - "type": "boolean" + "metadata": { + "additionalProperties": {}, + "type": "object" }, - "name": { + "title": { "type": "string" - }, - "set_id": { + } + }, + "type": "object" + }, + "handlers.recurrenceForceGenerateResponse": { + "properties": { + "instances_generated": { "type": "integer" + } + }, + "type": "object" + }, + "handlers.recurrenceInstanceListResponse": { + "properties": { + "instances": { + "items": { + "$ref": "#/components/schemas/models.RecurrenceInstance" + }, + "type": "array" }, - "updated_at": { - "type": "string" + "pagination": { + "$ref": "#/components/schemas/restapi.PaginationMeta" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetStatusSummary": { + "handlers.rrulePreviewResponse": { "properties": { - "color": { + "dtstart": { "type": "string" }, - "id": { - "type": "integer" + "occurrences": { + "items": { + "type": "string" + }, + "type": "array" }, - "name": { + "rrule": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetTypeFieldResponse": { + "handlers.startTimerRequest": { "properties": { - "custom_field_id": { - "type": "integer" - }, - "display_order": { - "type": "integer" - }, - "field_description": { - "type": "string" - }, - "field_name": { - "type": "string" - }, - "field_type": { + "description": { "type": "string" }, - "id": { + "item_id": { "type": "integer" }, - "is_required": { - "type": "boolean" + "project_id": { + "type": "integer" }, - "options": { - "type": "string" + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetTypeResponse": { + "handlers.templateCreateRequest": { "properties": { - "asset_count": { - "type": "integer" - }, - "color": { - "type": "string" - }, - "created_at": { - "type": "string" - }, - "description": { + "description_body": { "type": "string" }, - "display_order": { - "type": "integer" + "is_active": { + "type": "boolean" }, - "fields": { + "item_type_ids": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeFieldResponse" + "type": "integer" }, "type": "array" }, - "icon": { + "mode": { "type": "string" }, - "id": { + "name": { + "type": "string" + } + }, + "type": "object" + }, + "handlers.templateListResponse": { + "properties": { + "items": { + "items": { + "$ref": "#/components/schemas/models.ItemTemplate" + }, + "type": "array" + }, + "mandatory_template_id": { + "description": "MandatoryTemplateID is set when the request filtered by item_type_id and\nthat type has an active mandatory template, so callers (create modal, CLI)\ncan flag it without re-deriving the invariant.", "type": "integer" + } + }, + "type": "object" + }, + "handlers.templateUpdateRequest": { + "properties": { + "description_body": { + "type": "string" }, "is_active": { "type": "boolean" }, - "name": { + "item_type_ids": { + "items": { + "type": "integer" + }, + "type": "array" + }, + "mode": { "type": "string" }, - "set_id": { - "type": "integer" - }, - "updated_at": { + "name": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetTypeSummary": { + "handlers.testResultUpdateRequest": { "properties": { - "color": { + "actual_result": { "type": "string" }, - "icon": { + "notes": { "type": "string" }, - "id": { - "type": "integer" - }, - "name": { + "status": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AssetUpdateRequest": { + "handlers.testRunCreateRequest": { "properties": { - "asset_tag": { - "type": "string" - }, - "asset_type_id": { - "type": "integer" - }, - "category_id": { + "assignee_id": { "type": "integer" }, - "custom_field_values": { - "additionalProperties": {}, - "type": "object" - }, - "description": { + "name": { "type": "string" }, - "status_id": { + "set_id": { "type": "integer" }, - "title": { - "type": "string" + "template_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.AttachmentResponse": { + "handlers.timeProjectResponse": { "properties": { - "created_at": { + "category_color": { "type": "string" }, - "download_url": { + "category_id": { + "type": "integer" + }, + "category_name": { "type": "string" }, - "file_size": { + "color": { + "type": "string" + }, + "customer_id": { "type": "integer" }, - "filename": { + "customer_name": { "type": "string" }, - "has_thumbnail": { - "type": "boolean" + "description": { + "type": "string" }, - "id": { - "type": "integer" + "hourly_rate": { + "type": "number" }, - "item_id": { + "id": { "type": "integer" }, - "mime_type": { + "name": { "type": "string" }, - "original_filename": { - "type": "string" + "settings": { + "additionalProperties": {}, + "type": "object" }, - "thumbnail_url": { + "status": { "type": "string" }, - "uploader": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.CommentCreateRequest": { - "properties": { - "content": { - "type": "string" + "total_hours": { + "type": "number" } }, - "required": [ - "content" - ], "type": "object" }, - "windshift_internal_restapi_v1_dto.CommentResponse": { + "handlers.triggerTypeDTO": { "properties": { - "author": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - }, - "content": { - "type": "string" + "config_schema": { + "type": "object" }, - "created_at": { + "description": { "type": "string" }, - "id": { - "type": "integer" - }, - "item_id": { - "type": "integer" - }, - "updated_at": { + "label": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" + "type": { + "$ref": "#/components/schemas/models.ActionTriggerType" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.CommentUpdateRequest": { + "handlers.updateWorklogRequest": { "properties": { - "content": { + "description": { "type": "string" } }, - "required": [ - "content" - ], "type": "object" }, - "windshift_internal_restapi_v1_dto.EnforcedTemplateSummary": { + "handlers.validateActionResponse": { "properties": { - "applied": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "template_id": { - "type": "integer" + "errors": { + "items": { + "$ref": "#/components/schemas/actioncatalog.ValidationError" + }, + "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.HistoryResponse": { + "handlers.worklogResponse": { "properties": { - "changed_at": { - "type": "string" - }, - "field_name": { - "type": "string" - }, - "id": { + "created_at": { "type": "integer" }, - "item_id": { + "customer_id": { "type": "integer" }, - "new_value": { - "type": "string" - }, - "old_value": { + "customer_name": { "type": "string" }, - "resolved_new_value": { - "type": "string" + "date": { + "type": "integer" }, - "resolved_old_value": { + "description": { "type": "string" }, - "user": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.ItemCreateRequest": { - "properties": { - "assignee_id": { + "duration_minutes": { "type": "integer" }, - "custom_fields": { - "additionalProperties": {}, - "type": "object" + "end_time": { + "type": "integer" }, - "description": { - "type": "string" + "id": { + "type": "integer" }, - "due_date": { - "type": "string" + "item_id": { + "type": "integer" }, - "end_date": { + "item_title": { "type": "string" }, - "is_task": { - "type": "boolean" - }, - "item_type_id": { + "project_id": { "type": "integer" }, - "iteration_id": { - "type": "integer" + "project_max_hours": { + "type": "number" }, - "milestone_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "project_name": { + "type": "string" }, - "parent_id": { - "type": "integer" + "project_total_hours": { + "type": "number" }, - "priority_id": { + "start_time": { "type": "integer" }, - "project_id": { + "updated_at": { "type": "integer" }, - "start_date": { - "type": "string" + "workspace_id": { + "type": "integer" }, - "status_id": { - "description": "Optional create-time placement. If omitted, the item uses the workflow initial status.\nIf provided, it must be the initial status or directly reachable from the initial status\nwithout workflow conditions, validators, or approval gates.", + "workspace_item_number": { "type": "integer" }, - "title": { - "maxLength": 255, + "workspace_key": { + "type": "string" + } + }, + "type": "object" + }, + "health.livenessResponse": { + "properties": { + "status": { + "type": "string" + } + }, + "type": "object" + }, + "health.readinessResponse": { + "properties": { + "database": { "type": "string" }, - "workspace_id": { - "type": "integer" + "status": { + "type": "string" } }, - "required": [ - "title", - "workspace_id" - ], "type": "object" }, - "windshift_internal_restapi_v1_dto.ItemLinks": { + "models.APIToken": { "properties": { - "attachments": { + "created_at": { "type": "string" }, - "children": { + "expires_at": { "type": "string" }, - "comments": { + "id": { + "type": "integer" + }, + "is_temporary": { + "description": "True for SSH session tokens", + "type": "boolean" + }, + "last_used_at": { "type": "string" }, - "history": { + "name": { + "description": "Human-readable name for the token", "type": "string" }, - "parent": { + "permissions": { + "description": "JSON array of permissions", "type": "string" }, - "self": { + "token_prefix": { + "description": "First few characters for identification", + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "user_email": { + "description": "Joined fields", "type": "string" }, - "transitions": { - "type": "string" + "user_id": { + "type": "integer" }, - "workspace": { + "user_name": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.ItemResponse": { + "models.Action": { "properties": { - "_links": { - "allOf": [ - { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemLinks" - } - ], - "description": "HATEOAS links" - }, - "assignee": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - }, - "attachments": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AttachmentResponse" - }, - "type": "array" + "actor_name": { + "type": "string" }, - "children": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" - }, - "type": "array" + "actor_user_id": { + "description": "ActorUserID overrides the execution actor. NULL means the action runs under\nthe triggering user's permissions. Setting this field requires the global\naction.set_actor permission because it grants cross-workspace impersonation.", + "type": "integer" }, - "comments": { - "description": "Expanded collections (populated based on ?expand= parameter)", + "allowed_role_ids": { + "description": "AllowedRoleIDs restricts a manual action to members of these workspace\nroles. An empty list means every workspace editor may trigger it.", "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse" + "type": "integer" }, "type": "array" }, - "completed_at": { - "type": "string" - }, "created_at": { - "description": "Timestamps", "type": "string" }, - "creator": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary" - }, - "custom_fields": { - "additionalProperties": {}, - "type": "object" - }, - "description": { - "type": "string" + "created_by": { + "type": "integer" }, - "due_date": { + "creator_name": { + "description": "Joined fields for API responses", "type": "string" }, - "end_date": { + "description": { "type": "string" }, - "enforced_template": { - "allOf": [ - { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.EnforcedTemplateSummary" - } - ], - "description": "EnforcedTemplate echoes the mandatory work item template the item's type\nenforces (WI-438), populated only on the create response so non-UI callers\nlearn the expected structure even when they supplied their own\ndescription. Omitted when the type enforces no mandatory template." - }, - "history": { + "edges": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.HistoryResponse" + "$ref": "#/components/schemas/models.ActionEdge" }, "type": "array" }, "id": { "type": "integer" }, - "is_task": { + "is_enabled": { "type": "boolean" }, - "item_type": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemTypeSummary" - }, - "iteration": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.IterationSummary" - }, - "key": { - "description": "e.g., \"PROJ-123\"", + "name": { "type": "string" }, - "milestones": { + "nodes": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.MilestoneSummary" + "$ref": "#/components/schemas/models.ActionNode" }, "type": "array" }, - "parent_id": { - "description": "Hierarchy. ParentID is the raw DB id. ParentKey is the parent's\nready-to-display key (e.g. \"WI-120\"), computed server-side from the\nparent's own workspace — clients must render this rather than building a\nkey from ParentID, which is a DB id in a different namespace and may even\npoint into another workspace. ParentKey and ParentTitle are populated\nonly on permission-checked single-item reads, and only when the caller\nmay view the parent (see ItemHandler.setParentSummary); they are omitted\nfrom list responses and withheld across a workspace boundary the caller\ncannot see.", - "type": "integer" - }, - "parent_key": { - "type": "string" - }, - "parent_title": { - "type": "string" - }, - "priority": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PrioritySummary" - }, - "project": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ProjectSummary" - }, - "start_date": { - "type": "string" - }, - "status": { - "allOf": [ - { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary" - } - ], - "description": "Related entities (populated based on ?expand= parameter)" - }, - "title": { + "trigger_config": { + "description": "JSON with trigger-specific conditions", "type": "string" }, - "transitions": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse" - }, - "type": "array" + "trigger_type": { + "$ref": "#/components/schemas/models.ActionTriggerType" }, "updated_at": { "type": "string" }, - "workspace": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.WorkspaceSummary" - }, "workspace_id": { "type": "integer" - }, - "workspace_item_number": { - "type": "integer" - }, - "workspace_key": { - "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.ItemTypeChangeRequest": { + "models.ActionEdge": { "properties": { - "target_item_type_id": { + "action_id": { "type": "integer" }, - "target_status_id": { - "type": "integer" - } - }, - "required": [ - "target_item_type_id" - ], - "type": "object" - }, - "windshift_internal_restapi_v1_dto.ItemTypeSummary": { - "properties": { - "color": { + "created_at": { "type": "string" }, - "hierarchy_level": { + "edge_type": { + "description": "default, true, false (for conditions)", + "type": "string" + }, + "id": { "type": "integer" }, - "icon": { + "source_handle": { "type": "string" }, - "id": { + "source_node_id": { "type": "integer" }, - "name": { + "target_handle": { "type": "string" + }, + "target_node_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.ItemUpdateRequest": { + "models.ActionNode": { "properties": { - "assignee_id": { + "action_id": { "type": "integer" }, - "custom_fields": { - "additionalProperties": {}, - "type": "object" - }, - "description": { - "type": "string" - }, - "due_date": { - "type": "string" - }, - "end_date": { + "created_at": { "type": "string" }, - "is_task": { - "type": "boolean" - }, - "item_type_id": { - "type": "integer" - }, - "iteration_id": { + "id": { "type": "integer" }, - "milestone_ids": { - "items": { - "type": "integer" - }, - "type": "array" - }, - "parent_id": { - "type": "integer" + "node_config": { + "description": "JSON configuration for the node", + "type": "string" }, - "priority_id": { - "type": "integer" + "node_type": { + "$ref": "#/components/schemas/models.ActionNodeType" }, - "project_id": { - "type": "integer" + "position_x": { + "type": "number" }, - "start_date": { - "type": "string" + "position_y": { + "type": "number" }, - "title": { - "maxLength": 255, + "updated_at": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.IterationSummary": { + "models.ActionNodeType": { + "enum": [ + "trigger", + "set_field", + "set_status", + "add_comment", + "notify_user", + "condition", + "update_asset", + "create_asset", + "round_robin_assign", + "ai_extract", + "ai_agent", + "container_run", + "http_request", + "transition_item", + "related_items", + "create_milestone" + ], + "type": "string", + "x-enum-varnames": [ + "ActionNodeTrigger", + "ActionNodeSetField", + "ActionNodeSetStatus", + "ActionNodeAddComment", + "ActionNodeNotifyUser", + "ActionNodeCondition", + "ActionNodeUpdateAsset", + "ActionNodeCreateAsset", + "ActionNodeRoundRobinAssign", + "ActionNodeAIExtract", + "ActionNodeAIAgent", + "ActionNodeContainerRun", + "ActionNodeHTTPRequest", + "ActionNodeTransitionItem", + "ActionNodeRelatedItems", + "ActionNodeCreateMilestone" + ] + }, + "models.ActionTriggerType": { + "enum": [ + "status_transition", + "item_created", + "item_updated", + "item_linked", + "manual", + "scm_tag_created", + "scm_release_branch_created", + "scm_pr_linked", + "scm_pr_merged" + ], + "type": "string", + "x-enum-varnames": [ + "ActionTriggerStatusTransition", + "ActionTriggerItemCreated", + "ActionTriggerItemUpdated", + "ActionTriggerItemLinked", + "ActionTriggerManual", + "ActionTriggerSCMTagCreated", + "ActionTriggerSCMReleaseBranchCreated", + "ActionTriggerSCMPRLinked", + "ActionTriggerSCMPRMerged" + ] + }, + "models.ActiveTimer": { "properties": { - "end_date": { - "type": "string" - }, - "id": { + "created_at": { + "description": "Unix timestamp", "type": "integer" }, - "name": { + "customer_name": { "type": "string" }, - "start_date": { + "description": { "type": "string" }, - "status": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.MilestoneSummary": { - "properties": { "id": { "type": "integer" }, - "name": { - "type": "string" - }, - "status": { - "type": "string" - }, - "target_date": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.PageLinks": { - "properties": { - "history": { - "type": "string" - }, - "permissions": { - "type": "string" - }, - "self": { - "type": "string" - }, - "workspace": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.PageResponse": { - "properties": { - "_links": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageLinks" - }, - "archived_at": { - "type": "string" - }, - "archived_by": { + "item_id": { + "description": "Optional link to work item", "type": "integer" }, - "content": { + "item_title": { "type": "string" }, - "content_hash": { - "type": "string" + "project_id": { + "type": "integer" }, - "created_at": { + "project_name": { "type": "string" }, - "created_by": { + "start_time_utc": { + "description": "Unix timestamp in UTC", "type": "integer" }, - "depth": { + "user_id": { "type": "integer" }, - "excerpt": { - "type": "string" - }, - "id": { + "workspace_id": { "type": "integer" }, - "inherit_permissions": { - "type": "boolean" - }, - "is_home": { - "type": "boolean" - }, - "labels": { - "description": "Labels carries the workspace page-labels currently attached to the\npage. Populated by the service layer when the page-label repository\nis wired; always serialized as an array (never null) so CLI/JSON\nconsumers don't need to null-check.", - "items": { - "$ref": "#/components/schemas/models.PageLabel" - }, - "type": "array" - }, - "metadata": { - "additionalProperties": {}, - "type": "object" - }, - "parent_id": { + "workspace_item_number": { "type": "integer" }, - "path": { - "type": "string" - }, - "slug": { - "type": "string" - }, - "title": { + "workspace_key": { "type": "string" }, - "updated_at": { + "workspace_name": { "type": "string" - }, - "updated_by": { - "type": "integer" - }, - "workspace_id": { - "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.PageRevisionResponse": { + "models.Attachment": { "properties": { - "change_summary": { - "type": "string" - }, - "change_type": { - "type": "string" - }, - "content": { - "type": "string" - }, "created_at": { "type": "string" }, - "created_by": { - "type": "integer" - }, - "depth": { + "file_size": { "type": "integer" }, - "excerpt": { + "filename": { + "description": "Stored filename (UUID-based)", "type": "string" }, + "has_thumbnail": { + "description": "Whether thumbnail was generated", + "type": "boolean" + }, "id": { "type": "integer" }, - "page_id": { + "item_id": { "type": "integer" }, - "parent_id": { - "type": "integer" + "mime_type": { + "type": "string" }, - "path": { + "original_filename": { + "description": "Original user filename", "type": "string" }, - "revision_number": { + "uploaded_by": { "type": "integer" }, - "slug": { + "uploader_email": { "type": "string" }, - "title": { + "uploader_name": { + "description": "Joined fields for API responses", "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.PrioritySummary": { + "models.AttachmentUploadResponse": { "properties": { - "color": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "integer" + "attachment": { + "$ref": "#/components/schemas/models.Attachment" }, - "name": { + "message": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.ProjectSummary": { - "properties": { - "id": { - "type": "integer" }, - "name": { - "type": "string" + "success": { + "type": "boolean" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.StatusSummary": { + "models.CalendarScheduleEntry": { "properties": { - "category_color": { + "created_at": { "type": "string" }, - "category_id": { + "duration_minutes": { + "description": "Duration in minutes, optional", "type": "integer" }, - "category_name": { + "notes": { "type": "string" }, - "id": { - "type": "integer" - }, - "is_completed": { - "type": "boolean" - }, - "name": { + "scheduled_date": { + "description": "YYYY-MM-DD format", "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.TransitionRequest": { - "properties": { - "to_status_id": { - "type": "integer" - } - }, - "required": [ - "to_status_id" - ], - "type": "object" - }, - "windshift_internal_restapi_v1_dto.TransitionResponse": { - "properties": { - "from_status": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary" }, - "from_status_id": { - "type": "integer" + "scheduled_time": { + "description": "HH:MM format, optional", + "type": "string" }, - "id": { + "user_id": { "type": "integer" }, - "to_status": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary" - }, - "to_status_id": { + "workspace_id": { + "description": "User's personal workspace ID", "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.TransitionResultResponse": { + "models.CapabilityType": { + "enum": [ + "docker_environment", + "http_client", + "llm_connection", + "runner_pool" + ], + "type": "string", + "x-enum-varnames": [ + "CapabilityDockerEnvironment", + "CapabilityHTTPClient", + "CapabilityLLMConnection", + "CapabilityRunnerPool" + ] + }, + "models.CreateRecurrenceRequest": { "properties": { - "item": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "copy_assignee": { + "type": "boolean" }, - "new_status_id": { - "type": "integer" + "copy_custom_fields": { + "type": "boolean" }, - "no_op": { + "copy_description": { "type": "boolean" }, - "old_status_id": { - "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_dto.UserSummary": { - "properties": { - "avatar_url": { - "type": "string" + "copy_priority": { + "type": "boolean" }, - "email": { + "dtend": { "type": "string" }, - "first_name": { + "dtstart": { + "description": "ISO 8601 format", "type": "string" }, - "full_name": { + "lead_time_days": { + "type": "integer" + }, + "rrule": { "type": "string" }, - "id": { + "status_on_create": { "type": "integer" }, - "last_name": { - "type": "string" + "template_item_id": { + "type": "integer" }, - "username": { + "timezone": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_dto.WorkspaceSummary": { + "models.Item": { "properties": { - "id": { - "type": "integer" + "assignee_avatar": { + "description": "Avatar URL of assigned user", + "type": "string" }, - "key": { + "assignee_email": { + "description": "Email of assigned user", "type": "string" }, - "name": { + "assignee_id": { + "description": "User assignment fields", + "type": "integer" + }, + "assignee_name": { + "description": "User information for API responses", "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AdminGroupCreateRequest": { - "properties": { - "description": { + }, + "calendar_data": { + "items": { + "$ref": "#/components/schemas/models.CalendarScheduleEntry" + }, + "type": "array" + }, + "channel_id": { + "description": "Portal submission tracking fields (immutable once set)", + "type": "integer" + }, + "channel_name": { + "description": "Portal submission tracking joined fields", "type": "string" }, - "name": { + "children": { + "description": "For tree representations", + "items": { + "$ref": "#/components/schemas/models.Item" + }, + "type": "array" + }, + "completed_at": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AdminGroupResponse": { - "properties": { + }, "created_at": { "type": "string" }, - "description": { + "creator_email": { + "description": "Email of creator (internal user or portal customer)", "type": "string" }, - "id": { + "creator_id": { + "description": "Internal user who created this item", "type": "integer" }, - "member_count": { + "creator_name": { + "description": "Full name of creator (internal user or portal customer)", + "type": "string" + }, + "creator_portal_customer_email": { + "description": "Email of portal customer creator", + "type": "string" + }, + "creator_portal_customer_id": { + "description": "Portal customer who created this item (for portal submissions)", "type": "integer" }, - "name": { + "creator_portal_customer_name": { + "description": "Name of portal customer creator", "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AdminGroupUpdateRequest": { - "properties": { + "custom_field_values": { + "additionalProperties": {}, + "type": "object" + }, "description": { "type": "string" }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AdminUserResponse": { - "properties": { - "avatar_url": { + "description_html": { "type": "string" }, - "created_at": { + "due_date": { + "description": "Due date for item completion", "type": "string" }, - "email": { - "type": "string" + "effective_project_id": { + "description": "EffectiveProjectID is the resolved project after walking InheritProject\nup the parent chain. Consumers that need \"which time-tracking project\napplies to this item\" should read this, not ProjectID directly.", + "type": "integer" }, - "first_name": { + "effective_project_name": { "type": "string" }, - "full_name": { + "end_date": { + "description": "End date for item", "type": "string" }, - "group_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "estimate_minutes": { + "description": "Time estimate in minutes (compared against logged worklog time)", + "type": "integer" + }, + "frac_index": { + "description": "Manual sorting field", + "type": "string" }, "id": { "type": "integer" }, - "is_active": { + "inherit_project": { + "description": "If true, ProjectID is ignored and the parent item's effective project is used", "type": "boolean" }, - "language": { + "is_task": { + "description": "Flag to mark this item as a task (checklist item)", + "type": "boolean" + }, + "item_type_builtin_key": { "type": "string" }, - "last_name": { + "item_type_id": { + "description": "Optional, defaults to workspace's default item type", + "type": "integer" + }, + "item_type_name": { "type": "string" }, - "timezone": { + "iteration_end_date": { "type": "string" }, - "username": { + "iteration_id": { + "description": "Optional iteration assignment", + "type": "integer" + }, + "iteration_name": { "type": "string" }, - "warnings": { + "labels": { + "description": "Global item labels", "items": { - "type": "string" + "$ref": "#/components/schemas/models.Label" }, "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AdminUserUpdateRequest": { - "properties": { - "email": { + }, + "last_active_at": { + "description": "Recency for the board \"Bubble Mode\" sort. Bumped on activity (comments,\nedits, transitions) but not on manual frac_index reorder.", "type": "string" }, - "first_name": { + "milestones": { + "items": { + "$ref": "#/components/schemas/models.Milestone" + }, + "type": "array" + }, + "parent_id": { + "description": "Hierarchy fields", + "type": "integer" + }, + "parent_title": { "type": "string" }, - "is_active": { - "type": "boolean" + "parent_workspace_item_number": { + "description": "Parent's workspace-scoped number, for rendering the parent key", + "type": "integer" }, - "last_name": { + "personal_labels": { + "items": { + "$ref": "#/components/schemas/models.PersonalLabel" + }, + "type": "array" + }, + "priority_builtin_key": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AgentRunResponse": { - "properties": { - "ended_at": { + }, + "priority_color": { "type": "string" }, - "error": { + "priority_icon": { "type": "string" }, - "id": { + "priority_id": { + "description": "Foreign key to priorities table", "type": "integer" }, - "item_id": { + "priority_name": { + "type": "string" + }, + "project_id": { + "description": "Time-tracking project membership. \"Project\" in Windshift always refers\nto a row in time_projects; both ProjectID and TimeProjectID below are\nFKs to that table, serving different roles:\n ProjectID - the project this item belongs to (the bucket\n worklogs default to). Can be inherited from the\n parent item; see InheritProject.\n TimeProjectID - overrides the project used when logging time on\n this specific item (independent of the bucket the\n item belongs to).\nEffectiveProjectID (below) is the resolved value after applying\ninheritance, and is what consumers should read.", "type": "integer" }, - "job_kind": { + "project_inheritance_mode": { + "description": "\"none\" | \"inherit\" | \"direct\"", "type": "string" }, - "queued_at": { + "project_name": { + "description": "Name of the time-tracking project this item belongs to (joined from time_projects via ProjectID)", "type": "string" }, - "started_at": { - "type": "string" + "related_work_item_id": { + "description": "Personal task relationship (for linking personal workspace tasks to work items)", + "type": "integer" }, - "status": { + "related_work_item_number": { + "type": "integer" + }, + "related_work_item_title": { + "description": "Related work item joined fields (for personal tasks)", "type": "string" }, - "workspace_id": { + "related_work_item_workspace_id": { "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AuditLogEntryResponse": { - "properties": { - "action_type": { + }, + "related_work_item_workspace_key": { "type": "string" }, - "details": { - "additionalProperties": {}, - "type": "object" + "reporter_avatar": { + "description": "Avatar URL of reporter", + "type": "string" }, - "error_message": { + "reporter_email": { + "description": "Email of reporter", "type": "string" }, - "id": { + "reporter_id": { + "description": "User who reported this item (from Jira import)", "type": "integer" }, - "ip_address": { + "reporter_name": { + "description": "Full name of reporter", "type": "string" }, - "resource_id": { + "request_type_id": { + "description": "Request type used for submission", "type": "integer" }, - "resource_name": { + "request_type_name": { + "description": "Name of the request type", "type": "string" }, - "resource_type": { + "start_date": { + "description": "Start date for item", "type": "string" }, - "success": { - "type": "boolean" - }, - "timestamp": { + "status_builtin_key": { + "description": "Stable key for translating built-in statuses", "type": "string" }, - "user_agent": { + "status_color": { + "description": "Color from the status category (joined field)", "type": "string" }, - "user_id": { + "status_id": { + "description": "Foreign key to statuses table", "type": "integer" }, - "username": { + "status_name": { + "description": "Name from statuses table (joined field)", "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.AuditLogStreamResponse": { - "properties": { - "entries": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.AuditLogEntryResponse" - }, - "type": "array" - }, - "has_more": { - "type": "boolean" - }, - "next_after_id": { - "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.CollectionListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionResponse" - }, - "type": "array" }, - "total": { - "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.CollectionResponse": { - "properties": { - "created_at": { + "status_since": { + "description": "StatusSince is when the item last entered its current status, derived from\nitem_history (falls back to created_at when there is no recorded change).", "type": "string" }, - "description": { - "type": "string" + "story_points": { + "description": "Estimation", + "type": "number" }, - "id": { + "time_project_id": { "type": "integer" }, - "name": { + "time_project_name": { + "description": "Name of the time-tracking project overriding worklog defaults (joined from time_projects via TimeProjectID)", "type": "string" }, - "slug": { + "title": { "type": "string" }, "updated_at": { "type": "string" }, + "virtual_field_data": { + "additionalProperties": {}, + "type": "object" + }, "workspace_id": { "type": "integer" + }, + "workspace_item_number": { + "description": "Workspace-specific sequential number for display keys", + "type": "integer" + }, + "workspace_key": { + "type": "string" + }, + "workspace_name": { + "description": "Joined fields for API responses", + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.CustomFieldResponse": { + "models.ItemDiagram": { "properties": { - "description": { + "created_at": { "type": "string" }, - "display_order": { + "created_by": { "type": "integer" }, - "field_type": { + "creator_email": { + "type": "string" + }, + "creator_name": { + "description": "Joined fields for API responses", + "type": "string" + }, + "diagram_data": { + "description": "JSON with elements, appState, files", "type": "string" }, "id": { "type": "integer" }, - "name": { - "type": "string" + "item_id": { + "type": "integer" }, - "options": { - "description": "JSON string", + "name": { "type": "string" }, - "required": { - "type": "boolean" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.ErrorResponse": { - "properties": { - "code": { - "description": "Machine-readable error code", + "updated_at": { "type": "string" }, - "details": { - "description": "Additional error details" + "updated_by": { + "type": "integer" }, - "error": { - "description": "Human-readable message", + "updated_by_email": { "type": "string" }, - "request_id": { - "description": "Request correlation ID", + "updated_by_name": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.ItemTypeResponse": { + "models.ItemLink": { "properties": { - "color": { - "type": "string" - }, - "description": { + "created_at": { "type": "string" }, - "hierarchy_level": { + "created_by": { "type": "integer" }, - "icon": { + "created_by_name": { "type": "string" }, - "id": { + "custom_field_id": { "type": "integer" }, - "is_default": { - "type": "boolean" - }, - "name": { + "custom_field_name": { + "description": "Custom field link metadata", "type": "string" }, - "sort_order": { + "id": { "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.IterationCreateRequest": { - "properties": { - "description": { - "type": "string" }, - "end_date": { + "link_type_color": { "type": "string" }, - "is_global": { - "type": "boolean" - }, - "name": { + "link_type_forward_label": { "type": "string" }, - "start_date": { + "link_type_id": { + "type": "integer" + }, + "link_type_name": { + "description": "Joined fields for API responses", "type": "string" }, - "status": { + "link_type_reverse_label": { "type": "string" }, - "type_id": { + "source_id": { "type": "integer" }, - "workspace_id": { + "source_item_number": { + "description": "SourceItemNumber is the workspace-scoped item number (the \"74\" in\n\"WI-74\"). Display the user-facing key as\nSourceWorkspaceKey + \"-\" + SourceItemNumber, never SourceID — that\nfield is the global DB id and looks wrong (e.g. \"WI-149\") in UI.", "type": "integer" - } - }, - "required": [ - "end_date", - "name", - "start_date" - ], - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.IterationResponse": { - "properties": { - "created_at": { - "type": "string" }, - "description": { + "source_item_type_color": { "type": "string" }, - "end_date": { + "source_item_type_icon": { "type": "string" }, - "id": { + "source_item_type_id": { "type": "integer" }, - "is_global": { - "type": "boolean" + "source_item_type_name": { + "type": "string" }, - "name": { + "source_status_color": { "type": "string" }, - "start_date": { + "source_status_id": { + "description": "Source item details", + "type": "integer" + }, + "source_status_name": { "type": "string" }, - "status": { + "source_title": { "type": "string" }, - "type_color": { + "source_type": { + "description": "\"item\" or \"test_case\"", "type": "string" }, - "type_id": { + "source_workspace_id": { "type": "integer" }, - "type_name": { - "type": "string" - }, - "updated_at": { + "source_workspace_key": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" + "target_id": { + "type": "integer" }, - "workspace_id": { + "target_item_number": { + "description": "TargetItemNumber: see SourceItemNumber.", "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.IterationUpdateRequest": { - "properties": { - "description": { - "type": "string" }, - "end_date": { + "target_item_type_color": { "type": "string" }, - "name": { + "target_item_type_icon": { "type": "string" }, - "start_date": { + "target_item_type_id": { + "type": "integer" + }, + "target_item_type_name": { "type": "string" }, - "status": { + "target_status_color": { "type": "string" }, - "type_id": { - "nullable": true, - "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.MilestoneCreateRequest": { - "properties": { - "category_id": { + "target_status_id": { + "description": "Target item details", "type": "integer" }, - "description": { + "target_status_name": { "type": "string" }, - "name": { + "target_title": { "type": "string" }, - "status": { + "target_type": { + "description": "\"item\" or \"test_case\"", "type": "string" }, - "target_date": { + "target_workspace_id": { + "type": "integer" + }, + "target_workspace_key": { "type": "string" } }, - "required": [ - "name" - ], "type": "object" }, - "windshift_internal_restapi_v1_handlers.MilestoneProgressItemResponse": { + "models.ItemTemplate": { "properties": { - "assignee_avatar": { + "created_at": { "type": "string" }, - "assignee_name": { + "created_by": { + "type": "integer" + }, + "description_body": { "type": "string" }, "id": { "type": "integer" }, - "item_number": { - "type": "integer" + "is_active": { + "type": "boolean" }, - "priority_color": { - "type": "string" + "item_type_ids": { + "items": { + "type": "integer" + }, + "type": "array" }, - "priority_name": { + "mode": { "type": "string" }, - "status_color": { + "name": { "type": "string" }, - "status_name": { + "updated_at": { "type": "string" }, - "title": { - "type": "string" + "updated_by": { + "type": "integer" }, "workspace_id": { "type": "integer" - }, - "workspace_key": { - "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.MilestoneProgressResponse": { + "models.Label": { "properties": { - "category_color": { + "color": { "type": "string" }, - "completed_items": { - "type": "integer" - }, - "description": { + "created_at": { "type": "string" }, - "items_by_category": { - "additionalProperties": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.MilestoneProgressItemResponse" - }, - "type": "array" - }, - "type": "object" - }, - "milestone_id": { + "id": { "type": "integer" }, - "milestone_name": { + "name": { "type": "string" }, - "percent_complete": { - "type": "number" - }, - "status": { + "updated_at": { "type": "string" + } + }, + "type": "object" + }, + "models.LinkType": { + "properties": { + "active": { + "type": "boolean" }, - "status_breakdown": { + "allowed_entity_types": { + "description": "nil = all types allowed; e.g. [\"item\",\"test_case\"]", "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse" + "type": "string" }, "type": "array" }, - "target_date": { + "builtin_key": { "type": "string" }, - "total_items": { + "color": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "forward_label": { + "type": "string" + }, + "id": { "type": "integer" + }, + "is_system": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "reverse_label": { + "type": "string" + }, + "updated_at": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.MilestoneResponse": { + "models.Milestone": { "properties": { "category_color": { "type": "string" @@ -5400,6 +3964,7 @@ "type": "integer" }, "category_name": { + "description": "Joined fields for API responses", "type": "string" }, "created_at": { @@ -5408,1204 +3973,1033 @@ "description": { "type": "string" }, + "external_key": { + "description": "Stable upsert key set by automation (e.g. tag short-name); unique per workspace when set", + "type": "string" + }, "id": { "type": "integer" }, "is_global": { + "description": "false=local to workspace, true=global (shared)", "type": "boolean" }, + "latest_release": { + "$ref": "#/components/schemas/models.MilestoneRelease" + }, "name": { "type": "string" }, "position": { + "description": "Manual sort order (drag-and-drop), scoped per (is_global, workspace_id, category_id)", "type": "integer" }, + "releases": { + "items": { + "$ref": "#/components/schemas/models.MilestoneRelease" + }, + "type": "array" + }, "status": { + "description": "planning, in-progress, completed, cancelled", "type": "string" }, "target_date": { + "description": "Date in YYYY-MM-DD format, nullable", "type": "string" }, "updated_at": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" - }, "workspace_id": { + "description": "NULL if global, set if local to workspace", "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse": { - "properties": { - "category_color": { - "type": "string" }, - "category_name": { + "workspace_name": { "type": "string" - }, - "is_completed": { - "type": "boolean" - }, - "item_count": { - "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.MilestoneUpdateRequest": { + "models.MilestoneRelease": { "properties": { - "category_id": { - "nullable": true, - "type": "integer" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "status": { - "type": "string" + "assets": { + "items": { + "$ref": "#/components/schemas/models.SCMReleaseAsset" + }, + "type": "array" }, - "target_date": { - "nullable": true, - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.PaginatedResponse": { - "properties": { - "data": {}, - "pagination": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginationMeta" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.PriorityResponse": { - "properties": { - "color": { + "body": { "type": "string" }, - "description": { + "created_at": { "type": "string" }, - "icon": { - "type": "string" + "created_by": { + "type": "integer" }, "id": { "type": "integer" }, - "is_default": { + "is_draft": { "type": "boolean" }, - "name": { - "type": "string" - }, - "sort_order": { - "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.StatusCategoryResponse": { - "properties": { - "color": { - "type": "string" + "is_prerelease": { + "type": "boolean" }, - "description": { + "last_synced_at": { "type": "string" }, - "id": { + "milestone_id": { "type": "integer" }, - "is_completed": { - "type": "boolean" - }, - "is_default": { - "type": "boolean" - }, "name": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.StatusResponse": { - "properties": { - "category_color": { - "type": "string" }, - "category_id": { - "type": "integer" - }, - "category_name": { + "release_status": { "type": "string" }, - "description": { + "released_at": { "type": "string" }, - "id": { + "scm_connection_id": { + "description": "Visible only to users with connection workspace access", "type": "integer" }, - "is_completed": { - "type": "boolean" + "scm_release_id": { + "type": "string" }, - "is_default": { - "type": "boolean" + "scm_release_url": { + "type": "string" }, - "name": { + "scm_repository": { + "description": "\"owner/repo\"; same visibility as SCMConnectionID", "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.TUIPreferencesResponse": { - "properties": { - "last_workspace_id": { - "type": "integer" }, - "split_ratio": { - "type": "number" + "tag_name": { + "type": "string" }, - "theme": { + "tag_url": { + "type": "string" + }, + "target_commitish": { "type": "string" + }, + "workspace_repository_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.UserResponse": { + "models.PageLabel": { "properties": { - "avatar_url": { + "color": { "type": "string" }, "created_at": { "type": "string" }, - "email": { - "type": "string" + "id": { + "type": "integer" }, - "first_name": { + "name": { "type": "string" }, - "full_name": { + "updated_at": { "type": "string" }, - "id": { + "workspace_id": { "type": "integer" + } + }, + "type": "object" + }, + "models.PagePermission": { + "properties": { + "granted_at": { + "type": "string" }, - "is_active": { - "type": "boolean" + "granted_by": { + "type": "integer" }, - "is_agent": { - "type": "boolean" + "id": { + "type": "integer" }, - "language": { - "type": "string" + "page_id": { + "type": "integer" }, - "last_name": { + "permission_level": { "type": "string" }, - "timezone": { - "type": "string" + "principal_id": { + "type": "integer" }, - "username": { + "principal_type": { "type": "string" - }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.WorkflowResponse": { + "models.PersonalLabel": { "properties": { - "created_at": { + "color": { "type": "string" }, - "description": { + "created_at": { "type": "string" }, "id": { "type": "integer" }, - "is_default": { - "type": "boolean" - }, "name": { "type": "string" }, - "transitions": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse" - }, - "type": "array" - }, "updated_at": { "type": "string" + }, + "user_id": { + "description": "NULL for global labels, user_id for user-specific labels", + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.WorkspaceCreateRequest": { + "models.RRulePreviewRequest": { "properties": { - "color": { + "count": { + "description": "Number of occurrences to preview (default 10)", + "type": "integer" + }, + "dtstart": { "type": "string" }, - "description": { + "rrule": { + "type": "string" + } + }, + "type": "object" + }, + "models.RecurrenceInstance": { + "properties": { + "created_at": { "type": "string" }, - "icon": { + "id": { + "type": "integer" + }, + "instance_item_id": { + "type": "integer" + }, + "item_status": { "type": "string" }, - "key": { - "maxLength": 10, - "minLength": 2, + "item_title": { "type": "string" }, - "name": { - "maxLength": 100, + "recurrence_rule_id": { + "type": "integer" + }, + "scheduled_date": { "type": "string" }, - "template_workspace_id": { + "sequence_number": { "type": "integer" } }, - "required": [ - "key", - "name" - ], "type": "object" }, - "windshift_internal_restapi_v1_handlers.WorkspaceResponse": { + "models.RecurrenceRule": { "properties": { - "active": { + "copy_assignee": { "type": "boolean" }, - "color": { - "type": "string" + "copy_custom_fields": { + "type": "boolean" + }, + "copy_description": { + "type": "boolean" + }, + "copy_priority": { + "type": "boolean" }, "created_at": { "type": "string" }, - "description": { + "created_by": { + "type": "integer" + }, + "creator_name": { "type": "string" }, - "icon": { + "dtend": { + "type": "string" + }, + "dtstart": { + "description": "Recurrence start date", "type": "string" }, "id": { "type": "integer" }, - "internal_comments_enabled": { - "type": "boolean" - }, - "is_personal": { - "type": "boolean" + "instance_count": { + "type": "integer" }, - "is_template": { + "is_active": { "type": "boolean" }, - "key": { + "last_generated_until": { "type": "string" }, - "name": { - "type": "string" + "lead_time_days": { + "type": "integer" }, - "updated_at": { + "next_generation_check": { "type": "string" }, - "warnings": { - "items": { - "type": "string" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse": { - "properties": { - "color": { + "next_occurrence": { "type": "string" }, - "configuration_set_name": { + "rrule": { + "description": "e.g., \"FREQ=WEEKLY;BYDAY=MO,WE,FR\"", "type": "string" }, - "description": { + "status_on_create": { + "type": "integer" + }, + "template_item_id": { + "type": "integer" + }, + "template_title": { "type": "string" }, - "icon": { + "timezone": { + "description": "IANA timezone", "type": "string" }, - "id": { - "type": "integer" + "updated_at": { + "type": "string" }, - "item_count": { + "workspace_id": { "type": "integer" }, - "name": { + "workspace_key": { "type": "string" }, - "template_count": { - "type": "integer" + "workspace_name": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.WorkspaceUpdateRequest": { + "models.SCMReleaseAsset": { "properties": { - "active": { - "type": "boolean" - }, - "color": { + "direct_url": { "type": "string" }, - "description": { + "format": { "type": "string" }, - "icon": { + "kind": { "type": "string" }, - "is_template": { - "type": "boolean" + "link_type": { + "type": "string" }, "name": { "type": "string" + }, + "url": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.actionDefinitionRequest": { + "models.SkillActivationUsage": { "properties": { - "description": { - "type": "string" + "bytes": { + "type": "integer" }, - "edges": { - "items": { - "$ref": "#/components/schemas/models.ActionEdge" - }, - "type": "array" + "estimated_tokens": { + "type": "integer" }, - "name": { - "type": "string" + "max_bytes": { + "type": "integer" }, - "nodes": { - "items": { - "$ref": "#/components/schemas/models.ActionNode" - }, - "type": "array" + "max_tokens": { + "type": "integer" }, - "trigger_config": { - "type": "string" + "page_prefix_bytes": { + "type": "integer" }, - "trigger_type": { - "$ref": "#/components/schemas/models.ActionTriggerType" + "page_prefix_runes": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.agentSkillListResponse": { + "models.SkillPageReference": { "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.agentSkillSummary" - }, - "type": "array" + "activation_bytes": { + "type": "integer" + }, + "activation_runes": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "page_updated_at": { + "type": "string" + }, + "snapshot_at": { + "type": "string" + }, + "snapshot_title": { + "type": "string" + }, + "stale": { + "type": "boolean" + }, + "title": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.agentSkillSummary": { + "models.TestCase": { "properties": { - "description": { + "created_at": { + "type": "string" + }, + "estimated_duration": { + "description": "in seconds", + "type": "integer" + }, + "folder_id": { + "type": "integer" + }, + "folder_name": { "type": "string" }, - "enabled": { - "type": "boolean" - }, "id": { "type": "integer" }, + "labels": { + "items": { + "$ref": "#/components/schemas/models.TestLabel" + }, + "type": "array" + }, "name": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.capabilityDTO": { - "properties": { - "capability_type": { - "$ref": "#/components/schemas/models.CapabilityType" }, - "id": { + "preconditions": { + "type": "string" + }, + "priority": { + "description": "low, medium, high, critical", + "type": "string" + }, + "sort_order": { "type": "integer" }, - "name": { + "status": { + "description": "active, inactive, draft", "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.catalogResponse": { - "properties": { - "capabilities": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.capabilityDTO" - }, - "type": "array" }, - "nodes": { + "test_steps": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.nodeTypeDTO" + "$ref": "#/components/schemas/models.TestStep" }, "type": "array" }, - "scope": { + "title": { "type": "string" }, - "triggers": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.triggerTypeDTO" - }, - "type": "array" + "updated_at": { + "type": "string" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.createWorklogRequest": { + "models.TestFolder": { "properties": { - "date": { + "created_at": { "type": "string" }, "description": { "type": "string" }, - "duration": { - "type": "string" - }, - "duration_minutes": { + "id": { "type": "integer" }, - "end_time": { + "name": { "type": "string" }, - "item_id": { + "parent_id": { "type": "integer" }, - "item_key": { - "type": "string" + "sort_order": { + "type": "integer" }, - "project_id": { + "test_case_count": { "type": "integer" }, - "start_time": { + "updated_at": { "type": "string" }, - "timezone": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.diagramListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.ItemDiagram" - }, - "type": "array" + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.diagramWriteRequest": { + "models.TestLabel": { "properties": { - "diagram_data": { + "color": { "type": "string" }, + "created_at": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "integer" + }, "name": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.itemChangeResponse": { - "properties": { - "change_type": { + }, + "updated_at": { "type": "string" }, - "item_id": { + "workspace_id": { "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.itemChangesResponse": { + "models.TestRun": { "properties": { - "changes": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.itemChangeResponse" - }, - "type": "array" + "assignee_avatar": { + "type": "string" }, - "has_more": { - "type": "boolean" + "assignee_email": { + "type": "string" }, - "next_cursor": { + "assignee_id": { + "description": "User assigned to execute this run", + "type": "integer" + }, + "assignee_name": { "type": "string" }, - "reset_required": { - "type": "boolean" + "created_at": { + "type": "string" }, - "watermark": { + "ended_at": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.itemLabelAddRequest": { - "properties": { - "label_id": { + }, + "id": { "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.itemLabelSetRequest": { - "properties": { - "label_ids": { - "items": { - "type": "integer" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.labelCreateRequest": { - "properties": { - "color": { - "type": "string" }, "name": { "type": "string" + }, + "set_id": { + "type": "integer" + }, + "started_at": { + "type": "string" + }, + "template_id": { + "description": "Optional reference to template", + "type": "integer" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.labelListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.Label" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.labelUpdateRequest": { + "models.TestRunTemplate": { "properties": { - "color": { + "created_at": { "type": "string" }, - "name": { + "description": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.linkCreateRequest": { - "properties": { - "link_type_id": { - "type": "integer" }, - "source_id": { + "id": { "type": "integer" }, - "source_type": { + "name": { "type": "string" }, - "target_id": { + "set_id": { "type": "integer" }, - "target_type": { + "set_name": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.milestoneReorderRequest": { - "properties": { - "category_id": { - "type": "integer" }, - "ordered_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "updated_at": { + "type": "string" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.nodeTypeDTO": { + "models.TestSet": { "properties": { - "category": { + "created_at": { "type": "string" }, - "config_schema": { - "type": "object" - }, "description": { "type": "string" }, - "is_iterator": { - "type": "boolean" + "failed_runs": { + "type": "integer" }, - "label": { + "id": { + "type": "integer" + }, + "last_run_date": { "type": "string" }, - "outputs": { - "items": { - "type": "string" - }, - "type": "array" + "last_run_status": { + "type": "string" }, - "type": { - "$ref": "#/components/schemas/models.ActionNodeType" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageCreateRequest": { - "properties": { - "content": { + "milestone_id": { + "type": "integer" + }, + "milestone_name": { "type": "string" }, - "is_home": { - "type": "boolean" + "name": { + "type": "string" + }, + "successful_runs": { + "type": "integer" }, - "metadata": { - "additionalProperties": {}, - "type": "object" + "test_case_count": { + "type": "integer" }, - "parent_id": { + "total_runs": { "type": "integer" }, - "title": { + "updated_at": { "type": "string" + }, + "workspace_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest": { + "models.TestStep": { "properties": { - "excalidraw": { - "type": "object" + "action": { + "type": "string" }, - "expected_content_hash": { + "created_at": { "type": "string" }, - "mermaid": { + "data": { "type": "string" }, - "name": { + "expected": { "type": "string" }, - "placement": { + "id": { + "type": "integer" + }, + "step_number": { + "type": "integer" + }, + "test_case_id": { + "type": "integer" + }, + "updated_at": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.pageDiagramListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/services.PageDiagram" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest": { + "models.UpdateRecurrenceRequest": { "properties": { - "excalidraw": { - "type": "object" + "copy_assignee": { + "type": "boolean" }, - "expected_content_hash": { - "type": "string" + "copy_custom_fields": { + "type": "boolean" }, - "mermaid": { - "type": "string" + "copy_description": { + "type": "boolean" }, - "name": { + "copy_priority": { + "type": "boolean" + }, + "dtend": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageGrantPermissionRequest": { - "properties": { - "permission_level": { + }, + "dtstart": { "type": "string" }, - "principal_id": { + "is_active": { + "type": "boolean" + }, + "lead_time_days": { "type": "integer" }, - "principal_type": { + "rrule": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageHistoryListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageLabelAddRequest": { - "properties": { - "label_id": { + }, + "status_on_create": { "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageLabelCreateRequest": { - "properties": { - "color": { - "type": "string" }, - "name": { + "timezone": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.pageLabelListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.PageLabel" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageLabelSetRequest": { - "properties": { - "label_ids": { - "items": { - "type": "integer" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageLabelUpdateRequest": { + "models.WorkspaceAgentSkill": { "properties": { - "color": { + "body": { "type": "string" }, - "name": { + "created_at": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageListResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageListWithLabelsResponse": { - "properties": { - "items": { - "items": { - "$ref": "#/components/schemas/models.PageLabel" - }, - "type": "array" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageMoveRequest": { - "properties": { - "destination_workspace_id": { - "type": "integer" }, - "next_sibling_id": { + "created_by_user_id": { + "description": "CreatedByUserID is a soft audit ref; nil when the creator was deleted.", "type": "integer" }, - "parent_id": { - "type": "integer" + "description": { + "type": "string" }, - "prev_sibling_id": { + "enabled": { + "type": "boolean" + }, + "id": { "type": "integer" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pagePermissionsResponse": { - "properties": { - "acl": { + }, + "name": { + "type": "string" + }, + "pages": { + "description": "Pages are the workspace pages referenced by this skill (WI-517). On the\nadmin surface they round-trip with snapshot review state; the exact saved\ncontent is rendered into a run grant. nil/omitted when there are none.", "items": { - "$ref": "#/components/schemas/models.PagePermission" + "$ref": "#/components/schemas/models.SkillPageReference" }, "type": "array" }, - "effective_level": { + "updated_at": { "type": "string" }, - "inherit_permissions": { - "type": "boolean" + "usage": { + "$ref": "#/components/schemas/models.SkillActivationUsage" }, - "page_id": { + "workspace_id": { "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.pageSetInheritanceRequest": { - "properties": { - "inherit_permissions": { - "type": "boolean" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.pageUpdateRequest": { + "restapi.ErrorResponse": { "properties": { - "content": { + "code": { + "description": "Machine-readable error code", "type": "string" }, - "expected_content_hash": { - "type": "string" + "details": { + "description": "Additional error details" }, - "metadata": { - "additionalProperties": {}, - "type": "object" + "error": { + "description": "Human-readable message", + "type": "string" }, - "title": { + "request_id": { + "description": "Request correlation ID", "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.recurrenceForceGenerateResponse": { + "restapi.PaginatedResponse": { "properties": { - "instances_generated": { - "type": "integer" + "data": {}, + "pagination": { + "$ref": "#/components/schemas/restapi.PaginationMeta" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.recurrenceInstanceListResponse": { + "restapi.PaginationMeta": { "properties": { - "instances": { - "items": { - "$ref": "#/components/schemas/models.RecurrenceInstance" - }, - "type": "array" + "has_more": { + "type": "boolean" }, - "pagination": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginationMeta" + "limit": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "total": { + "type": "integer" + }, + "total_pages": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.rrulePreviewResponse": { + "services.PageDiagram": { "properties": { - "dtstart": { + "attachment_id": { + "type": "integer" + }, + "content_hash": { "type": "string" }, - "occurrences": { - "items": { - "type": "string" - }, - "type": "array" + "created_at": { + "type": "string" }, - "rrule": { + "kind": { "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.startTimerRequest": { - "properties": { - "description": { + }, + "name": { "type": "string" }, - "item_id": { + "page_id": { "type": "integer" }, - "project_id": { - "type": "integer" + "payload": { + "type": "object" }, - "workspace_id": { + "revision_number": { "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.templateCreateRequest": { + "services.TestRunDetail": { "properties": { - "description_body": { - "type": "string" - }, - "is_active": { - "type": "boolean" - }, - "item_type_ids": { + "results": { "items": { - "type": "integer" + "$ref": "#/components/schemas/services.TestRunResultWithCaseTitle" }, "type": "array" }, - "mode": { - "type": "string" + "run": { + "$ref": "#/components/schemas/models.TestRun" }, - "name": { - "type": "string" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.templateListResponse": { - "properties": { - "items": { + "step_results": { + "additionalProperties": { + "$ref": "#/components/schemas/services.TestRunStepResult" + }, + "type": "object" + }, + "test_cases": { "items": { - "$ref": "#/components/schemas/models.ItemTemplate" + "$ref": "#/components/schemas/models.TestCase" }, "type": "array" - }, - "mandatory_template_id": { - "description": "MandatoryTemplateID is set when the request filtered by item_type_id and\nthat type has an active mandatory template, so callers (create modal, CLI)\ncan flag it without re-deriving the invariant.", - "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.templateUpdateRequest": { + "services.TestRunResultWithCaseTitle": { "properties": { - "description_body": { + "actual_result": { "type": "string" }, - "is_active": { - "type": "boolean" + "created_at": { + "type": "string" }, - "item_type_ids": { - "items": { - "type": "integer" - }, - "type": "array" + "executed_at": { + "type": "string" }, - "mode": { + "id": { + "type": "integer" + }, + "notes": { "type": "string" }, - "name": { + "run_id": { + "type": "integer" + }, + "status": { + "description": "\"passed\", \"failed\", \"blocked\", \"skipped\", \"not_run\"", + "type": "string" + }, + "test_case_id": { + "type": "integer" + }, + "test_case_title": { + "type": "string" + }, + "updated_at": { "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.testResultUpdateRequest": { + "services.TestRunStepResult": { "properties": { "actual_result": { "type": "string" }, + "executed_at": { + "type": "string" + }, + "item_id": { + "type": "integer" + }, "notes": { "type": "string" }, "status": { "type": "string" + }, + "step_id": { + "type": "integer" + }, + "test_case_id": { + "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.testRunCreateRequest": { + "windshift_internal_restapi_v1_handlers.AuditLogStreamResponse": { "properties": { - "assignee_id": { - "type": "integer" - }, - "name": { - "type": "string" + "entries": { + "items": { + "$ref": "#/components/schemas/handlers.AuditLogEntryResponse" + }, + "type": "array" }, - "set_id": { - "type": "integer" + "has_more": { + "type": "boolean" }, - "template_id": { + "next_after_id": { "type": "integer" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.timeProjectResponse": { + "windshift_internal_restapi_v1_handlers.UserResponse": { "properties": { - "category_color": { + "agent_presence": { "type": "string" }, - "category_id": { - "type": "integer" - }, - "category_name": { + "avatar_url": { "type": "string" }, - "color": { + "created_at": { "type": "string" }, - "customer_id": { - "type": "integer" - }, - "customer_name": { + "email": { "type": "string" }, - "description": { + "first_name": { "type": "string" }, - "hourly_rate": { - "type": "number" + "full_name": { + "type": "string" }, "id": { "type": "integer" }, - "name": { - "type": "string" + "is_active": { + "type": "boolean" }, - "settings": { - "additionalProperties": {}, - "type": "object" + "is_agent": { + "type": "boolean" }, - "status": { + "language": { "type": "string" }, - "total_hours": { - "type": "number" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.triggerTypeDTO": { - "properties": { - "config_schema": { - "type": "object" - }, - "description": { + "last_name": { "type": "string" }, - "label": { + "timezone": { "type": "string" }, - "type": { - "$ref": "#/components/schemas/models.ActionTriggerType" - } - }, - "type": "object" - }, - "windshift_internal_restapi_v1_handlers.updateWorklogRequest": { - "properties": { - "description": { + "username": { "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "type": "array" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.validateActionResponse": { + "windshift_internal_restapi_v1_handlers.itemChangesResponse": { "properties": { - "errors": { + "changes": { "items": { - "$ref": "#/components/schemas/actioncatalog.ValidationError" + "$ref": "#/components/schemas/handlers.itemChangeResponse" }, "type": "array" + }, + "has_more": { + "type": "boolean" + }, + "next_cursor": { + "type": "string" + }, + "reset_required": { + "type": "boolean" + }, + "watermark": { + "type": "string" } }, "type": "object" }, - "windshift_internal_restapi_v1_handlers.worklogResponse": { + "windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest": { "properties": { - "created_at": { - "type": "integer" - }, - "customer_id": { - "type": "integer" + "excalidraw": { + "type": "object" }, - "customer_name": { + "expected_content_hash": { "type": "string" }, - "date": { - "type": "integer" - }, - "description": { + "mermaid": { "type": "string" }, - "duration_minutes": { - "type": "integer" - }, - "end_time": { - "type": "integer" - }, - "id": { - "type": "integer" - }, - "item_id": { - "type": "integer" - }, - "item_title": { + "name": { "type": "string" }, - "project_id": { - "type": "integer" - }, - "project_max_hours": { - "type": "number" - }, - "project_name": { + "placement": { "type": "string" + } + }, + "type": "object" + }, + "windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest": { + "properties": { + "excalidraw": { + "type": "object" }, - "project_total_hours": { - "type": "number" - }, - "start_time": { - "type": "integer" - }, - "updated_at": { - "type": "integer" - }, - "workspace_id": { - "type": "integer" + "expected_content_hash": { + "type": "string" }, - "workspace_item_number": { - "type": "integer" + "mermaid": { + "type": "string" }, - "workspace_key": { + "name": { "type": "string" } }, @@ -6665,7 +5059,7 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { @@ -6688,7 +5082,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6698,7 +5092,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6708,7 +5102,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6718,7 +5112,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6758,7 +5152,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6768,7 +5162,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6778,7 +5172,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6788,7 +5182,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6874,13 +5268,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AuditLogEntryResponse" + "$ref": "#/components/schemas/handlers.AuditLogEntryResponse" }, "type": "array" } @@ -6897,7 +5291,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6907,7 +5301,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6917,7 +5311,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6927,7 +5321,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6971,7 +5365,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AuditLogStreamResponse" + "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.AuditLogStreamResponse" } } }, @@ -6981,7 +5375,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -6991,7 +5385,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7001,7 +5395,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7011,7 +5405,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7057,13 +5451,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AdminGroupResponse" + "$ref": "#/components/schemas/handlers.AdminGroupResponse" }, "type": "array" } @@ -7080,7 +5474,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7090,7 +5484,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7100,7 +5494,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7123,7 +5517,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AdminGroupCreateRequest" + "$ref": "#/components/schemas/handlers.AdminGroupCreateRequest" } } }, @@ -7136,7 +5530,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AdminGroupResponse" + "$ref": "#/components/schemas/handlers.AdminGroupResponse" } } }, @@ -7146,7 +5540,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7156,7 +5550,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7166,7 +5560,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7176,7 +5570,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7216,7 +5610,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7226,7 +5620,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7236,7 +5630,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7246,7 +5640,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7256,7 +5650,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7290,7 +5684,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.AdminGroupUpdateRequest" + "$ref": "#/components/schemas/handlers.AdminGroupUpdateRequest" } } }, @@ -7306,7 +5700,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7316,7 +5710,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7326,7 +5720,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7336,7 +5730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7346,7 +5740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7392,13 +5786,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.AdminUserResponse" + "$ref": "#/components/schemas/handlers.AdminUserResponse" }, "type": "array" } @@ -7415,7 +5809,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7425,7 +5819,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7435,7 +5829,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7471,7 +5865,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.AdminUserUpdateRequest" + "$ref": "#/components/schemas/handlers.AdminUserUpdateRequest" } } }, @@ -7494,7 +5888,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7504,7 +5898,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7514,7 +5908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7524,7 +5918,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7534,7 +5928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -7570,7 +5964,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategoryResponse" + "$ref": "#/components/schemas/dto.AssetCategoryResponse" } } }, @@ -7580,7 +5974,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7606,7 +6000,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetResponse" + "$ref": "#/components/schemas/dto.AssetSetResponse" }, "type": "array" } @@ -7618,7 +6012,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7654,7 +6048,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetResponse" + "$ref": "#/components/schemas/dto.AssetSetResponse" } } }, @@ -7664,7 +6058,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7749,7 +6143,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.PaginatedResponse" + "$ref": "#/components/schemas/restapi.PaginatedResponse" } } }, @@ -7759,7 +6153,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7769,7 +6163,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7802,7 +6196,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetCreateRequest" + "$ref": "#/components/schemas/dto.AssetCreateRequest" } } }, @@ -7815,7 +6209,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse" + "$ref": "#/components/schemas/dto.AssetResponse" } } }, @@ -7825,7 +6219,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7835,7 +6229,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7908,7 +6302,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetImportJobResponse" + "$ref": "#/components/schemas/dto.AssetImportJobResponse" } } }, @@ -7918,7 +6312,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7928,7 +6322,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -7965,7 +6359,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategoryResponse" + "$ref": "#/components/schemas/dto.AssetCategoryResponse" }, "type": "array" } @@ -7977,7 +6371,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8014,7 +6408,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusResponse" + "$ref": "#/components/schemas/dto.AssetStatusResponse" }, "type": "array" } @@ -8026,7 +6420,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8063,7 +6457,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeResponse" + "$ref": "#/components/schemas/dto.AssetTypeResponse" }, "type": "array" } @@ -8075,7 +6469,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8111,7 +6505,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusResponse" + "$ref": "#/components/schemas/dto.AssetStatusResponse" } } }, @@ -8121,7 +6515,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8157,7 +6551,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeResponse" + "$ref": "#/components/schemas/dto.AssetTypeResponse" } } }, @@ -8167,7 +6561,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8206,7 +6600,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8240,7 +6634,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse" + "$ref": "#/components/schemas/dto.AssetResponse" } } }, @@ -8250,7 +6644,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8283,7 +6677,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetUpdateRequest" + "$ref": "#/components/schemas/dto.AssetUpdateRequest" } } }, @@ -8296,7 +6690,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse" + "$ref": "#/components/schemas/dto.AssetResponse" } } }, @@ -8306,7 +6700,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -8346,7 +6740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8393,7 +6787,7 @@ "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8403,7 +6797,7 @@ "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8413,7 +6807,7 @@ "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8423,7 +6817,7 @@ "content": { "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8470,7 +6864,7 @@ "content": { "image/jpeg": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8480,7 +6874,7 @@ "content": { "image/jpeg": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8490,7 +6884,7 @@ "content": { "image/jpeg": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8500,7 +6894,7 @@ "content": { "image/jpeg": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8544,7 +6938,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionListResponse" + "$ref": "#/components/schemas/handlers.CollectionListResponse" } } }, @@ -8554,7 +6948,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8564,7 +6958,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8574,7 +6968,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8611,7 +7005,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionResponse" + "$ref": "#/components/schemas/handlers.CollectionResponse" } } }, @@ -8621,7 +7015,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8631,7 +7025,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8641,7 +7035,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8651,7 +7045,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8661,7 +7055,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8740,13 +7134,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -8763,7 +7157,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8773,7 +7167,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8783,7 +7177,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8793,7 +7187,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8803,7 +7197,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8843,7 +7237,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8853,7 +7247,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8863,7 +7257,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8873,7 +7267,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8883,7 +7277,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8918,7 +7312,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse" + "$ref": "#/components/schemas/dto.CommentResponse" } } }, @@ -8928,7 +7322,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8938,7 +7332,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8948,7 +7342,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8958,7 +7352,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -8968,7 +7362,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9002,7 +7396,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentUpdateRequest" + "$ref": "#/components/schemas/dto.CommentUpdateRequest" } } }, @@ -9015,7 +7409,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse" + "$ref": "#/components/schemas/dto.CommentResponse" } } }, @@ -9025,7 +7419,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9035,7 +7429,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9045,7 +7439,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9055,7 +7449,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9065,7 +7459,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9091,7 +7485,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.CustomFieldResponse" + "$ref": "#/components/schemas/handlers.CustomFieldResponse" }, "type": "array" } @@ -9103,7 +7497,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9113,7 +7507,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9123,7 +7517,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9159,7 +7553,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.CustomFieldResponse" + "$ref": "#/components/schemas/handlers.CustomFieldResponse" } } }, @@ -9169,7 +7563,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9179,7 +7573,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9189,7 +7583,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9199,7 +7593,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9209,7 +7603,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9248,7 +7642,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9258,7 +7652,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9268,7 +7662,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9278,7 +7672,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9288,7 +7682,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9333,7 +7727,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9343,7 +7737,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9353,7 +7747,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9363,7 +7757,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9373,7 +7767,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9407,7 +7801,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.diagramWriteRequest" + "$ref": "#/components/schemas/handlers.diagramWriteRequest" } } }, @@ -9430,7 +7824,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9440,7 +7834,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9450,7 +7844,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9460,7 +7854,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9470,7 +7864,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9522,7 +7916,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse" + "$ref": "#/components/schemas/handlers.ItemTypeResponse" }, "type": "array" } @@ -9534,7 +7928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9544,7 +7938,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9554,7 +7948,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9590,7 +7984,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse" + "$ref": "#/components/schemas/handlers.ItemTypeResponse" } } }, @@ -9600,7 +7994,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9610,7 +8004,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9620,7 +8014,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9630,7 +8024,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9640,7 +8034,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9766,13 +8160,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -9789,7 +8183,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9799,7 +8193,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9809,7 +8203,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9819,7 +8213,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9842,7 +8236,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemCreateRequest" + "$ref": "#/components/schemas/dto.ItemCreateRequest" } } }, @@ -9855,7 +8249,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" } } }, @@ -9865,7 +8259,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9875,7 +8269,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9885,7 +8279,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9895,7 +8289,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9933,7 +8327,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -9945,7 +8339,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9955,7 +8349,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9965,7 +8359,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -9975,7 +8369,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10046,7 +8440,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10056,7 +8450,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10066,7 +8460,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10076,7 +8470,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10086,7 +8480,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10126,7 +8520,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10136,7 +8530,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10146,7 +8540,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10156,7 +8550,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10166,7 +8560,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10209,7 +8603,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" } } }, @@ -10219,7 +8613,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10229,7 +8623,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10239,7 +8633,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10249,7 +8643,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10259,7 +8653,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10293,7 +8687,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemUpdateRequest" + "$ref": "#/components/schemas/dto.ItemUpdateRequest" } } }, @@ -10306,7 +8700,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" } } }, @@ -10316,7 +8710,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10326,7 +8720,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10336,7 +8730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10346,7 +8740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10356,7 +8750,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10410,7 +8804,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.AgentRunResponse" + "$ref": "#/components/schemas/handlers.AgentRunResponse" }, "type": "array" } @@ -10422,7 +8816,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10432,7 +8826,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10442,7 +8836,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10452,7 +8846,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10489,7 +8883,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.AttachmentResponse" + "$ref": "#/components/schemas/dto.AttachmentResponse" }, "type": "array" } @@ -10501,7 +8895,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10511,7 +8905,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10521,7 +8915,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10531,7 +8925,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10541,7 +8935,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10606,7 +9000,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10616,7 +9010,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10652,7 +9046,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemTypeChangeRequest" + "$ref": "#/components/schemas/dto.ItemTypeChangeRequest" } } }, @@ -10665,7 +9059,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" } } }, @@ -10675,7 +9069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10685,7 +9079,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10695,7 +9089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10705,7 +9099,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10715,7 +9109,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10725,7 +9119,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10762,7 +9156,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -10774,7 +9168,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10784,7 +9178,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10794,7 +9188,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10804,7 +9198,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10814,7 +9208,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10876,13 +9270,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse" + "$ref": "#/components/schemas/dto.CommentResponse" }, "type": "array" } @@ -10899,7 +9293,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10909,7 +9303,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10919,7 +9313,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10929,7 +9323,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10939,7 +9333,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -10973,7 +9367,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentCreateRequest" + "$ref": "#/components/schemas/dto.CommentCreateRequest" } } }, @@ -10986,7 +9380,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse" + "$ref": "#/components/schemas/dto.CommentResponse" } } }, @@ -10996,7 +9390,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11006,7 +9400,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11016,7 +9410,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11026,7 +9420,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11036,7 +9430,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11074,7 +9468,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.diagramListResponse" + "$ref": "#/components/schemas/handlers.diagramListResponse" } } }, @@ -11084,7 +9478,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11094,7 +9488,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11104,7 +9498,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11114,7 +9508,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11124,7 +9518,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11158,7 +9552,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.diagramWriteRequest" + "$ref": "#/components/schemas/handlers.diagramWriteRequest" } } }, @@ -11181,7 +9575,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11191,7 +9585,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11201,7 +9595,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11211,7 +9605,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11221,7 +9615,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11290,7 +9684,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.HistoryResponse" + "$ref": "#/components/schemas/dto.HistoryResponse" }, "type": "array" } @@ -11302,7 +9696,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11312,7 +9706,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11322,7 +9716,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11332,7 +9726,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11342,7 +9736,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11378,7 +9772,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelListResponse" + "$ref": "#/components/schemas/handlers.labelListResponse" } } }, @@ -11388,7 +9782,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11398,7 +9792,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11408,7 +9802,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11418,7 +9812,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11428,7 +9822,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11461,7 +9855,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.itemLabelAddRequest" + "$ref": "#/components/schemas/handlers.itemLabelAddRequest" } } }, @@ -11474,7 +9868,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelListResponse" + "$ref": "#/components/schemas/handlers.labelListResponse" } } }, @@ -11484,7 +9878,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11494,7 +9888,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11504,7 +9898,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11514,7 +9908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11524,7 +9918,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11534,7 +9928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11568,7 +9962,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.itemLabelSetRequest" + "$ref": "#/components/schemas/handlers.itemLabelSetRequest" } } }, @@ -11581,7 +9975,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelListResponse" + "$ref": "#/components/schemas/handlers.labelListResponse" } } }, @@ -11591,7 +9985,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11601,7 +9995,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11611,7 +10005,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11621,7 +10015,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11631,7 +10025,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11679,7 +10073,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11689,7 +10083,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11699,7 +10093,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11709,7 +10103,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11719,7 +10113,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11767,7 +10161,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11777,7 +10171,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11787,7 +10181,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11797,7 +10191,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11836,7 +10230,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11846,7 +10240,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11856,7 +10250,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11866,7 +10260,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11876,7 +10270,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11920,7 +10314,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11930,7 +10324,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11940,7 +10334,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11950,7 +10344,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -11960,7 +10354,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12016,7 +10410,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12026,7 +10420,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12036,7 +10430,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12046,7 +10440,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12056,7 +10450,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12066,7 +10460,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12122,7 +10516,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12132,7 +10526,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12142,7 +10536,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12152,7 +10546,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12162,7 +10556,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12198,7 +10592,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.recurrenceForceGenerateResponse" + "$ref": "#/components/schemas/handlers.recurrenceForceGenerateResponse" } } }, @@ -12208,7 +10602,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12218,7 +10612,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12228,7 +10622,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12238,7 +10632,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12248,7 +10642,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12300,7 +10694,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.recurrenceInstanceListResponse" + "$ref": "#/components/schemas/handlers.recurrenceInstanceListResponse" } } }, @@ -12310,7 +10704,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12320,7 +10714,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12330,7 +10724,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12340,7 +10734,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12350,7 +10744,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12386,7 +10780,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionRequest" + "$ref": "#/components/schemas/dto.TransitionRequest" } } }, @@ -12399,7 +10793,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResultResponse" + "$ref": "#/components/schemas/dto.TransitionResultResponse" } } }, @@ -12409,7 +10803,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12419,7 +10813,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12429,7 +10823,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12439,7 +10833,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12449,7 +10843,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12459,7 +10853,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12496,7 +10890,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse" + "$ref": "#/components/schemas/dto.TransitionResponse" }, "type": "array" } @@ -12508,7 +10902,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12518,7 +10912,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12528,7 +10922,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12538,7 +10932,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12548,7 +10942,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12610,13 +11004,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" }, "type": "array" } @@ -12633,7 +11027,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12643,7 +11037,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12653,7 +11047,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12676,7 +11070,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationCreateRequest" + "$ref": "#/components/schemas/handlers.IterationCreateRequest" } } }, @@ -12689,7 +11083,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -12699,7 +11093,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12709,7 +11103,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12719,7 +11113,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12729,7 +11123,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12768,7 +11162,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12778,7 +11172,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12788,7 +11182,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12798,7 +11192,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12808,7 +11202,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12843,7 +11237,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -12853,7 +11247,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12863,7 +11257,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12873,7 +11267,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12883,7 +11277,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12893,7 +11287,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12927,7 +11321,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationUpdateRequest" + "$ref": "#/components/schemas/handlers.IterationUpdateRequest" } } }, @@ -12940,7 +11334,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -12950,7 +11344,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12960,7 +11354,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12970,7 +11364,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12980,7 +11374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -12990,7 +11384,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13029,7 +11423,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13039,7 +11433,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13064,7 +11458,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.linkCreateRequest" + "$ref": "#/components/schemas/handlers.linkCreateRequest" } } }, @@ -13087,7 +11481,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13097,7 +11491,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13107,7 +11501,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13117,7 +11511,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13127,7 +11521,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13221,13 +11615,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.batchItemLinksResponse" + "$ref": "#/components/schemas/handlers.batchItemLinksResponse" }, "type": "array" } @@ -13244,7 +11638,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13254,7 +11648,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13264,7 +11658,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13274,7 +11668,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13313,7 +11707,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13323,7 +11717,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13333,7 +11727,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13343,7 +11737,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13436,13 +11830,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" }, "type": "array" } @@ -13459,7 +11853,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13469,7 +11863,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13479,7 +11873,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13502,7 +11896,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneCreateRequest" + "$ref": "#/components/schemas/handlers.MilestoneCreateRequest" } } }, @@ -13515,7 +11909,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -13525,7 +11919,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13535,7 +11929,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13545,7 +11939,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13555,7 +11949,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13580,7 +11974,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.milestoneReorderRequest" + "$ref": "#/components/schemas/handlers.milestoneReorderRequest" } } }, @@ -13606,7 +12000,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13616,7 +12010,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13626,7 +12020,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13636,7 +12030,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13675,7 +12069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13685,7 +12079,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13695,7 +12089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13705,7 +12099,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13715,7 +12109,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13750,7 +12144,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -13760,7 +12154,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13770,7 +12164,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13780,7 +12174,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13790,7 +12184,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13800,7 +12194,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13834,7 +12228,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneUpdateRequest" + "$ref": "#/components/schemas/handlers.MilestoneUpdateRequest" } } }, @@ -13847,7 +12241,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -13857,7 +12251,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13867,7 +12261,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13877,7 +12271,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13887,7 +12281,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13897,7 +12291,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -13968,13 +12362,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -13991,7 +12385,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14001,7 +12395,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14011,7 +12405,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14021,7 +12415,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14031,7 +12425,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14069,7 +12463,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressResponse" + "$ref": "#/components/schemas/handlers.MilestoneProgressResponse" } } }, @@ -14079,7 +12473,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14089,7 +12483,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14099,7 +12493,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14109,7 +12503,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14119,7 +12513,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14209,7 +12603,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14219,7 +12613,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14229,7 +12623,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14239,7 +12633,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14265,7 +12659,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse" + "$ref": "#/components/schemas/handlers.PriorityResponse" }, "type": "array" } @@ -14277,7 +12671,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14287,7 +12681,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14297,7 +12691,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14333,7 +12727,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse" + "$ref": "#/components/schemas/handlers.PriorityResponse" } } }, @@ -14343,7 +12737,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14353,7 +12747,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14363,7 +12757,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14373,7 +12767,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14383,7 +12777,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14456,7 +12850,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.rrulePreviewResponse" + "$ref": "#/components/schemas/handlers.rrulePreviewResponse" } } }, @@ -14466,7 +12860,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14476,7 +12870,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14486,7 +12880,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14496,7 +12890,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14582,13 +12976,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -14605,7 +12999,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14615,7 +13009,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14625,7 +13019,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14635,7 +13029,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14663,7 +13057,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.StatusCategoryResponse" + "$ref": "#/components/schemas/handlers.StatusCategoryResponse" }, "type": "array" } @@ -14675,7 +13069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14685,7 +13079,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14695,7 +13089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14731,7 +13125,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.StatusCategoryResponse" + "$ref": "#/components/schemas/handlers.StatusCategoryResponse" } } }, @@ -14741,7 +13135,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14751,7 +13145,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14761,7 +13155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14771,7 +13165,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14781,7 +13175,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14808,7 +13202,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.StatusResponse" + "$ref": "#/components/schemas/handlers.StatusResponse" }, "type": "array" } @@ -14820,7 +13214,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14830,7 +13224,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14840,7 +13234,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14876,7 +13270,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.StatusResponse" + "$ref": "#/components/schemas/handlers.StatusResponse" } } }, @@ -14886,7 +13280,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14896,7 +13290,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14906,7 +13300,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14916,7 +13310,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14926,7 +13320,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14974,7 +13368,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14984,7 +13378,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -14994,7 +13388,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15004,7 +13398,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15041,7 +13435,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.timeProjectResponse" + "$ref": "#/components/schemas/handlers.timeProjectResponse" }, "type": "array" } @@ -15053,7 +13447,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15063,7 +13457,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15100,7 +13494,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.timeProjectResponse" + "$ref": "#/components/schemas/handlers.timeProjectResponse" } } }, @@ -15110,7 +13504,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15120,7 +13514,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15130,7 +13524,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15200,13 +13594,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.worklogResponse" + "$ref": "#/components/schemas/handlers.worklogResponse" }, "type": "array" } @@ -15223,7 +13617,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15233,7 +13627,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15256,7 +13650,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.createWorklogRequest" + "$ref": "#/components/schemas/handlers.createWorklogRequest" } } }, @@ -15280,7 +13674,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15290,7 +13684,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15300,7 +13694,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15340,7 +13734,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15350,7 +13744,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15360,7 +13754,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15370,7 +13764,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15404,7 +13798,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.updateWorklogRequest" + "$ref": "#/components/schemas/handlers.updateWorklogRequest" } } }, @@ -15428,7 +13822,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15438,7 +13832,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15448,7 +13842,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15458,7 +13852,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15494,7 +13888,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15519,7 +13913,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.startTimerRequest" + "$ref": "#/components/schemas/handlers.startTimerRequest" } } }, @@ -15543,7 +13937,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15553,7 +13947,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15563,7 +13957,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15573,7 +13967,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15610,7 +14004,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15620,7 +14014,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi.ErrorResponse" + "$ref": "#/components/schemas/restapi.ErrorResponse" } } }, @@ -15682,7 +14076,7 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { @@ -15705,7 +14099,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15715,7 +14109,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15725,7 +14119,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15761,7 +14155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15771,7 +14165,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15781,7 +14175,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15807,7 +14201,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse" + "$ref": "#/components/schemas/handlers.TUIPreferencesResponse" } } }, @@ -15817,7 +14211,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15827,7 +14221,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15837,7 +14231,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15860,7 +14254,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse" + "$ref": "#/components/schemas/handlers.TUIPreferencesResponse" } } }, @@ -15873,7 +14267,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse" + "$ref": "#/components/schemas/handlers.TUIPreferencesResponse" } } }, @@ -15883,7 +14277,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15893,7 +14287,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15903,7 +14297,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15913,7 +14307,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15960,7 +14354,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15970,7 +14364,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15980,7 +14374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -15990,7 +14384,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16000,7 +14394,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16026,7 +14420,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.WorkflowResponse" + "$ref": "#/components/schemas/handlers.WorkflowResponse" }, "type": "array" } @@ -16038,7 +14432,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16048,7 +14442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16058,7 +14452,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16103,7 +14497,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.WorkflowResponse" + "$ref": "#/components/schemas/handlers.WorkflowResponse" } } }, @@ -16113,7 +14507,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16123,7 +14517,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16133,7 +14527,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16143,7 +14537,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16153,7 +14547,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16190,7 +14584,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse" + "$ref": "#/components/schemas/dto.TransitionResponse" }, "type": "array" } @@ -16202,7 +14596,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16212,7 +14606,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16222,7 +14616,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16232,7 +14626,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16242,7 +14636,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16269,7 +14663,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse" + "$ref": "#/components/schemas/handlers.WorkspaceTemplateSummaryResponse" }, "type": "array" } @@ -16281,7 +14675,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16291,7 +14685,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16301,7 +14695,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16362,13 +14756,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse" + "$ref": "#/components/schemas/handlers.WorkspaceResponse" }, "type": "array" } @@ -16385,7 +14779,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16395,7 +14789,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16405,7 +14799,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16428,7 +14822,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceCreateRequest" + "$ref": "#/components/schemas/handlers.WorkspaceCreateRequest" } } }, @@ -16441,7 +14835,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse" + "$ref": "#/components/schemas/handlers.WorkspaceResponse" } } }, @@ -16451,7 +14845,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16461,7 +14855,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16471,7 +14865,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16481,7 +14875,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16491,7 +14885,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16501,7 +14895,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16511,7 +14905,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16550,7 +14944,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16560,7 +14954,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16570,7 +14964,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16580,7 +14974,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16590,7 +14984,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16625,7 +15019,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse" + "$ref": "#/components/schemas/handlers.WorkspaceResponse" } } }, @@ -16635,7 +15029,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16645,7 +15039,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16655,7 +15049,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16665,7 +15059,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16675,7 +15069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16708,7 +15102,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceUpdateRequest" + "$ref": "#/components/schemas/handlers.WorkspaceUpdateRequest" } } }, @@ -16721,7 +15115,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse" + "$ref": "#/components/schemas/handlers.WorkspaceResponse" } } }, @@ -16731,7 +15125,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16741,7 +15135,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16751,7 +15145,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16761,7 +15155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16771,7 +15165,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16808,7 +15202,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.catalogResponse" + "$ref": "#/components/schemas/handlers.catalogResponse" } } }, @@ -16818,7 +15212,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16828,7 +15222,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16838,7 +15232,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16848,7 +15242,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16897,7 +15291,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16907,7 +15301,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16917,7 +15311,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16951,7 +15345,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest" + "$ref": "#/components/schemas/handlers.actionDefinitionRequest" } } }, @@ -16974,7 +15368,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16984,7 +15378,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -16994,7 +15388,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17004,7 +15398,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17040,7 +15434,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest" + "$ref": "#/components/schemas/handlers.actionDefinitionRequest" } } }, @@ -17053,7 +15447,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.validateActionResponse" + "$ref": "#/components/schemas/handlers.validateActionResponse" } } }, @@ -17108,7 +15502,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17151,7 +15545,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest" + "$ref": "#/components/schemas/handlers.actionDefinitionRequest" } } }, @@ -17174,7 +15568,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17184,7 +15578,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17220,7 +15614,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.agentSkillListResponse" + "$ref": "#/components/schemas/handlers.agentSkillListResponse" } } }, @@ -17230,7 +15624,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17240,7 +15634,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17250,17 +15644,17 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, - "description": "Workspace not found or caller lacks item.view" + "description": "No active run snapshot for this token and workspace" }, "500": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17315,7 +15709,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17325,7 +15719,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17335,17 +15729,27 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" + } + } + }, + "description": "Skill not present in this run snapshot" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, - "description": "Skill not found in this workspace or caller lacks item.view" + "description": "Saved activation exceeds the supported budget" }, "500": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17365,7 +15769,7 @@ }, "/workspaces/{id}/assignable-users": { "get": { - "description": "Returns active users with limited fields for assignment pickers. Unlike /users this needs no global user.list permission — view access to the workspace is enough. Sensitive fields (email, timezone, language) are always stripped. Mirrors the session surface's assignable-users endpoint.", + "description": "Returns active users who can view the workspace, plus only agents with a ready workspace binding. Unlike /users this needs no global user.list permission. Sensitive fields (email, timezone, language) are always stripped. Shared by assignment and mention pickers.", "parameters": [ { "description": "Workspace ID", @@ -17395,7 +15799,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17405,7 +15809,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17415,7 +15819,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17425,7 +15829,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17462,7 +15866,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse" + "$ref": "#/components/schemas/handlers.ItemTypeResponse" }, "type": "array" } @@ -17474,7 +15878,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17484,7 +15888,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17494,7 +15898,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17504,7 +15908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17514,7 +15918,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17570,13 +15974,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -17593,7 +15997,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17603,7 +16007,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17613,7 +16017,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17623,7 +16027,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17633,7 +16037,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17705,13 +16109,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" }, "type": "array" } @@ -17728,7 +16132,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17738,7 +16142,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17748,7 +16152,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17758,7 +16162,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17768,7 +16172,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17803,7 +16207,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationCreateRequest" + "$ref": "#/components/schemas/handlers.IterationCreateRequest" } } }, @@ -17816,7 +16220,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -17826,7 +16230,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17836,7 +16240,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17846,7 +16250,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17856,7 +16260,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17866,7 +16270,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17915,7 +16319,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17925,7 +16329,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17935,7 +16339,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17945,7 +16349,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -17955,7 +16359,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18000,7 +16404,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -18010,7 +16414,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18020,7 +16424,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18030,7 +16434,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18040,7 +16444,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18050,7 +16454,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18094,7 +16498,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationUpdateRequest" + "$ref": "#/components/schemas/handlers.IterationUpdateRequest" } } }, @@ -18107,7 +16511,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.IterationResponse" + "$ref": "#/components/schemas/handlers.IterationResponse" } } }, @@ -18117,7 +16521,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18127,7 +16531,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18137,7 +16541,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18147,7 +16551,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18157,7 +16561,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18195,7 +16599,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelListResponse" + "$ref": "#/components/schemas/handlers.labelListResponse" } } }, @@ -18205,7 +16609,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18215,7 +16619,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18225,7 +16629,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18235,7 +16639,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18245,7 +16649,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18279,7 +16683,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelCreateRequest" + "$ref": "#/components/schemas/handlers.labelCreateRequest" } } }, @@ -18302,7 +16706,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18312,7 +16716,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18322,7 +16726,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18332,7 +16736,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18342,7 +16746,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18352,7 +16756,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18401,7 +16805,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18411,7 +16815,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18421,7 +16825,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18431,7 +16835,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18441,7 +16845,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18494,7 +16898,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18504,7 +16908,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18514,7 +16918,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18524,7 +16928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18534,7 +16938,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18577,7 +16981,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.labelUpdateRequest" + "$ref": "#/components/schemas/handlers.labelUpdateRequest" } } }, @@ -18600,7 +17004,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18610,7 +17014,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18620,7 +17024,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18630,7 +17034,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18640,7 +17044,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18650,7 +17054,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18721,13 +17125,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" }, "type": "array" } @@ -18744,7 +17148,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18754,7 +17158,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18764,7 +17168,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18774,7 +17178,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18784,7 +17188,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18819,7 +17223,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneCreateRequest" + "$ref": "#/components/schemas/handlers.MilestoneCreateRequest" } } }, @@ -18832,7 +17236,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -18842,7 +17246,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18852,7 +17256,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18862,7 +17266,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18872,7 +17276,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18882,7 +17286,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18919,7 +17323,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.milestoneReorderRequest" + "$ref": "#/components/schemas/handlers.milestoneReorderRequest" } } }, @@ -18945,7 +17349,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18955,7 +17359,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18965,7 +17369,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18975,7 +17379,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -18985,7 +17389,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19034,7 +17438,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19044,7 +17448,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19054,7 +17458,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19064,7 +17468,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19074,7 +17478,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19119,7 +17523,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -19129,7 +17533,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19139,7 +17543,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19149,7 +17553,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19159,7 +17563,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19169,7 +17573,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19213,7 +17617,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneUpdateRequest" + "$ref": "#/components/schemas/handlers.MilestoneUpdateRequest" } } }, @@ -19226,7 +17630,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse" + "$ref": "#/components/schemas/handlers.MilestoneResponse" } } }, @@ -19236,7 +17640,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19246,7 +17650,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19256,7 +17660,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19266,7 +17670,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19276,7 +17680,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19357,13 +17761,13 @@ "schema": { "allOf": [ { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse" + "$ref": "#/components/schemas/handlers.PaginatedResponse" }, { "properties": { "data": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" }, "type": "array" } @@ -19380,7 +17784,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19390,7 +17794,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19400,7 +17804,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19410,7 +17814,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19420,7 +17824,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19468,7 +17872,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressResponse" + "$ref": "#/components/schemas/handlers.MilestoneProgressResponse" } } }, @@ -19478,7 +17882,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19488,7 +17892,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19498,7 +17902,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19508,7 +17912,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19518,7 +17922,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19555,7 +17959,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageLabelListResponse" + "$ref": "#/components/schemas/handlers.pageLabelListResponse" } } }, @@ -19565,7 +17969,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19575,7 +17979,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19585,7 +17989,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19595,7 +17999,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19630,7 +18034,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageLabelCreateRequest" + "$ref": "#/components/schemas/handlers.pageLabelCreateRequest" } } }, @@ -19653,7 +18057,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19663,7 +18067,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19673,7 +18077,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19683,7 +18087,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19693,7 +18097,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19743,7 +18147,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19753,7 +18157,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19763,7 +18167,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19773,7 +18177,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19827,7 +18231,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19837,7 +18241,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19847,7 +18251,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19857,7 +18261,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19901,7 +18305,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageLabelUpdateRequest" + "$ref": "#/components/schemas/handlers.pageLabelUpdateRequest" } } }, @@ -19924,7 +18328,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19934,7 +18338,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19944,7 +18348,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19954,7 +18358,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -19964,7 +18368,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20002,7 +18406,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageListResponse" + "$ref": "#/components/schemas/handlers.pageListResponse" } } }, @@ -20012,7 +18416,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20022,7 +18426,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20032,7 +18436,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20042,7 +18446,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20076,7 +18480,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageCreateRequest" + "$ref": "#/components/schemas/handlers.pageCreateRequest" } } }, @@ -20089,7 +18493,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -20099,7 +18503,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20109,7 +18513,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20119,7 +18523,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20129,7 +18533,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20139,7 +18543,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20193,7 +18597,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageListResponse" + "$ref": "#/components/schemas/handlers.pageListResponse" } } }, @@ -20203,7 +18607,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20213,7 +18617,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20223,7 +18627,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20233,7 +18637,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20282,7 +18686,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20292,7 +18696,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20302,7 +18706,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20312,7 +18716,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20355,7 +18759,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -20365,7 +18769,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20375,7 +18779,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20385,7 +18789,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20395,7 +18799,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20438,7 +18842,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageUpdateRequest" + "$ref": "#/components/schemas/handlers.pageUpdateRequest" } } }, @@ -20451,7 +18855,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -20461,7 +18865,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20471,7 +18875,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20481,7 +18885,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20491,7 +18895,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20567,7 +18971,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20577,7 +18981,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20622,7 +19026,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageDiagramListResponse" + "$ref": "#/components/schemas/handlers.pageDiagramListResponse" } } }, @@ -20632,7 +19036,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20642,7 +19046,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20652,7 +19056,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20694,7 +19098,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageDiagramCreateRequest" + "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest" } } }, @@ -20717,7 +19121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20727,7 +19131,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20737,7 +19141,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20747,7 +19151,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20757,7 +19161,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20821,7 +19225,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20831,7 +19235,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20841,7 +19245,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20893,7 +19297,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageDiagramUpdateRequest" + "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest" } } }, @@ -20916,7 +19320,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20926,7 +19330,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20936,7 +19340,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20946,7 +19350,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -20956,7 +19360,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21018,7 +19422,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageHistoryListResponse" + "$ref": "#/components/schemas/handlers.pageHistoryListResponse" } } }, @@ -21028,7 +19432,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21038,7 +19442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21048,7 +19452,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21058,7 +19462,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21113,7 +19517,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse" + "$ref": "#/components/schemas/dto.PageRevisionResponse" } } }, @@ -21123,7 +19527,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21133,7 +19537,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21143,7 +19547,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21153,7 +19557,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21208,7 +19612,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -21218,7 +19622,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21228,7 +19632,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21238,7 +19642,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21248,7 +19652,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21293,7 +19697,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageSetInheritanceRequest" + "$ref": "#/components/schemas/handlers.pageSetInheritanceRequest" } } }, @@ -21306,7 +19710,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -21316,7 +19720,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21326,7 +19730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21336,7 +19740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21346,7 +19750,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21391,7 +19795,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse" + "$ref": "#/components/schemas/handlers.pageListWithLabelsResponse" } } }, @@ -21401,7 +19805,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21411,7 +19815,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21421,7 +19825,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21431,7 +19835,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21474,7 +19878,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageLabelAddRequest" + "$ref": "#/components/schemas/handlers.pageLabelAddRequest" } } }, @@ -21487,7 +19891,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse" + "$ref": "#/components/schemas/handlers.pageListWithLabelsResponse" } } }, @@ -21497,7 +19901,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21507,7 +19911,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21517,7 +19921,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21527,7 +19931,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21537,7 +19941,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21581,7 +19985,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageLabelSetRequest" + "$ref": "#/components/schemas/handlers.pageLabelSetRequest" } } }, @@ -21594,7 +19998,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse" + "$ref": "#/components/schemas/handlers.pageListWithLabelsResponse" } } }, @@ -21604,7 +20008,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21614,7 +20018,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21624,7 +20028,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21634,7 +20038,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21692,7 +20096,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21702,7 +20106,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21712,7 +20116,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21722,7 +20126,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21768,7 +20172,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageMoveRequest" + "$ref": "#/components/schemas/handlers.pageMoveRequest" } } }, @@ -21781,7 +20185,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse" + "$ref": "#/components/schemas/dto.PageResponse" } } }, @@ -21791,7 +20195,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21801,7 +20205,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21811,7 +20215,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21821,7 +20225,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21831,7 +20235,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21877,7 +20281,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pagePermissionsResponse" + "$ref": "#/components/schemas/handlers.pagePermissionsResponse" } } }, @@ -21887,7 +20291,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21897,7 +20301,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21907,7 +20311,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21917,7 +20321,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21960,7 +20364,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.pageGrantPermissionRequest" + "$ref": "#/components/schemas/handlers.pageGrantPermissionRequest" } } }, @@ -21983,7 +20387,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -21993,7 +20397,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22003,7 +20407,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22013,7 +20417,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22023,7 +20427,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22080,7 +20484,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22090,7 +20494,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22100,7 +20504,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22110,7 +20514,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22148,7 +20552,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse" + "$ref": "#/components/schemas/handlers.PriorityResponse" }, "type": "array" } @@ -22160,7 +20564,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22170,7 +20574,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22180,7 +20584,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22190,7 +20594,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22200,7 +20604,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22238,7 +20642,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary" + "$ref": "#/components/schemas/dto.StatusSummary" }, "type": "array" } @@ -22250,7 +20654,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22260,7 +20664,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22270,7 +20674,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22280,7 +20684,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22290,7 +20694,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22329,7 +20733,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary" + "$ref": "#/components/schemas/dto.StatusSummary" }, "type": "array" } @@ -22341,7 +20745,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22351,7 +20755,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22361,7 +20765,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22371,7 +20775,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22381,7 +20785,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22427,7 +20831,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.templateListResponse" + "$ref": "#/components/schemas/handlers.templateListResponse" } } }, @@ -22437,7 +20841,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22447,7 +20851,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22457,7 +20861,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22467,7 +20871,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22477,7 +20881,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22510,7 +20914,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.templateCreateRequest" + "$ref": "#/components/schemas/handlers.templateCreateRequest" } } }, @@ -22533,7 +20937,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22543,7 +20947,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22553,7 +20957,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22563,7 +20967,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22573,7 +20977,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22583,7 +20987,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22631,7 +21035,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22641,7 +21045,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22651,7 +21055,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22661,7 +21065,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22671,7 +21075,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22724,7 +21128,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22734,7 +21138,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22744,7 +21148,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22754,7 +21158,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22764,7 +21168,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22807,7 +21211,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.templateUpdateRequest" + "$ref": "#/components/schemas/handlers.templateUpdateRequest" } } }, @@ -22830,7 +21234,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22840,7 +21244,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22850,7 +21254,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22860,7 +21264,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22870,7 +21274,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22880,7 +21284,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22918,7 +21322,7 @@ "application/json": { "schema": { "items": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.WorkflowResponse" + "$ref": "#/components/schemas/handlers.WorkflowResponse" }, "type": "array" } @@ -22930,7 +21334,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22940,7 +21344,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22950,7 +21354,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22960,7 +21364,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -22970,7 +21374,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23037,7 +21441,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23047,7 +21451,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23057,7 +21461,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23067,7 +21471,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23077,7 +21481,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23133,7 +21537,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23143,7 +21547,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23153,7 +21557,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23163,7 +21567,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23173,7 +21577,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23222,7 +21626,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23232,7 +21636,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23242,7 +21646,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23252,7 +21656,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23305,7 +21709,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23315,7 +21719,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23325,7 +21729,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23335,7 +21739,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23345,7 +21749,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23393,7 +21797,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23403,7 +21807,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23413,7 +21817,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23423,7 +21827,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23433,7 +21837,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23486,7 +21890,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23496,7 +21900,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23506,7 +21910,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23516,7 +21920,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23526,7 +21930,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23591,7 +21995,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23601,7 +22005,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23611,7 +22015,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23621,7 +22025,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23631,7 +22035,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23687,7 +22091,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23697,7 +22101,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23707,7 +22111,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23717,7 +22121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23727,7 +22131,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23789,7 +22193,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23799,7 +22203,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23809,7 +22213,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23819,7 +22223,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23829,7 +22233,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23887,7 +22291,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23897,7 +22301,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23907,7 +22311,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23917,7 +22321,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23927,7 +22331,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23989,7 +22393,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -23999,7 +22403,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24009,7 +22413,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24019,7 +22423,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24029,7 +22433,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24086,7 +22490,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24096,7 +22500,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24106,7 +22510,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24116,7 +22520,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24126,7 +22530,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24184,7 +22588,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24194,7 +22598,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24204,7 +22608,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24214,7 +22618,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24224,7 +22628,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24289,7 +22693,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24299,7 +22703,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24309,7 +22713,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24319,7 +22723,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24329,7 +22733,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24396,7 +22800,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24406,7 +22810,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24416,7 +22820,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24426,7 +22830,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24436,7 +22840,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24493,7 +22897,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24503,7 +22907,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24513,7 +22917,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24523,7 +22927,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24533,7 +22937,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24607,7 +23011,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24617,7 +23021,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24627,7 +23031,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24637,7 +23041,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24647,7 +23051,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24696,7 +23100,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24706,7 +23110,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24716,7 +23120,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24726,7 +23130,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24736,7 +23140,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24792,7 +23196,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24802,7 +23206,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24812,7 +23216,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24822,7 +23226,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24832,7 +23236,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24890,7 +23294,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24900,7 +23304,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24910,7 +23314,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24920,7 +23324,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24930,7 +23334,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24979,7 +23383,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24989,7 +23393,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -24999,7 +23403,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25009,7 +23413,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25019,7 +23423,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25072,7 +23476,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25082,7 +23486,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25092,7 +23496,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25102,7 +23506,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25112,7 +23516,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25177,7 +23581,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25187,7 +23591,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25197,7 +23601,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25207,7 +23611,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25217,7 +23621,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25266,7 +23670,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25276,7 +23680,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25286,7 +23690,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25296,7 +23700,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25306,7 +23710,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25362,7 +23766,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25372,7 +23776,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25382,7 +23786,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25392,7 +23796,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25402,7 +23806,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25450,7 +23854,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25460,7 +23864,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25470,7 +23874,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25480,7 +23884,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25490,7 +23894,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25555,7 +23959,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25565,7 +23969,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25575,7 +23979,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25585,7 +23989,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25595,7 +23999,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25645,7 +24049,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25655,7 +24059,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25665,7 +24069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25675,7 +24079,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25685,7 +24089,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25742,7 +24146,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25752,7 +24156,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25762,7 +24166,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25772,7 +24176,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25782,7 +24186,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25830,7 +24234,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25840,7 +24244,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25850,7 +24254,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25860,7 +24264,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25870,7 +24274,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25923,7 +24327,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25933,7 +24337,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25943,7 +24347,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25953,7 +24357,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -25963,7 +24367,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26028,7 +24432,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26038,7 +24442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26048,7 +24452,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26058,7 +24462,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26068,7 +24472,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26126,7 +24530,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26136,7 +24540,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26146,7 +24550,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26156,7 +24560,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26166,7 +24570,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26224,7 +24628,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26234,7 +24638,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26244,7 +24648,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26254,7 +24658,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26264,7 +24668,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26326,7 +24730,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26336,7 +24740,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26346,7 +24750,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26356,7 +24760,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26366,7 +24770,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26423,7 +24827,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26433,7 +24837,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26443,7 +24847,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26453,7 +24857,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26463,7 +24867,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26527,7 +24931,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26537,7 +24941,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26547,7 +24951,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26557,7 +24961,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26567,7 +24971,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26625,7 +25029,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26635,7 +25039,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26645,7 +25049,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26655,7 +25059,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26665,7 +25069,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26727,7 +25131,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26737,7 +25141,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26747,7 +25151,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26757,7 +25161,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26767,7 +25171,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26824,7 +25228,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26834,7 +25238,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26844,7 +25248,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26854,7 +25258,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26864,7 +25268,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26913,7 +25317,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26923,7 +25327,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26933,7 +25337,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26943,7 +25347,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -26953,7 +25357,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27009,7 +25413,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27019,7 +25423,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27029,7 +25433,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27039,7 +25443,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27049,7 +25453,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27097,7 +25501,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27107,7 +25511,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27117,7 +25521,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27127,7 +25531,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27137,7 +25541,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27190,7 +25594,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27200,7 +25604,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27210,7 +25614,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27220,7 +25624,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27230,7 +25634,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27295,7 +25699,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27305,7 +25709,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27315,7 +25719,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27325,7 +25729,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27335,7 +25739,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27391,7 +25795,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27401,7 +25805,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27411,7 +25815,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27421,7 +25825,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27431,7 +25835,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27489,7 +25893,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27499,7 +25903,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27509,7 +25913,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27519,7 +25923,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27529,7 +25933,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27587,7 +25991,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27597,7 +26001,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27607,7 +26011,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27617,7 +26021,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27627,7 +26031,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27661,7 +26065,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.testRunCreateRequest" + "$ref": "#/components/schemas/handlers.testRunCreateRequest" } } }, @@ -27684,7 +26088,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27694,7 +26098,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27704,7 +26108,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27714,7 +26118,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27724,7 +26128,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27772,7 +26176,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27782,7 +26186,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27792,7 +26196,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27802,7 +26206,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27812,7 +26216,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27865,7 +26269,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27875,7 +26279,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27885,7 +26289,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27895,7 +26299,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27905,7 +26309,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27964,7 +26368,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27974,7 +26378,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27984,7 +26388,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -27994,7 +26398,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28004,7 +26408,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28059,7 +26463,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28069,7 +26473,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28079,7 +26483,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28089,7 +26493,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28137,7 +26541,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28147,7 +26551,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28157,7 +26561,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28167,7 +26571,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28177,7 +26581,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28235,7 +26639,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28245,7 +26649,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28255,7 +26659,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28265,7 +26669,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28275,7 +26679,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28329,7 +26733,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.testResultUpdateRequest" + "$ref": "#/components/schemas/handlers.testResultUpdateRequest" } } }, @@ -28345,7 +26749,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28355,7 +26759,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28365,7 +26769,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28375,7 +26779,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28385,7 +26789,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28442,7 +26846,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28452,7 +26856,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28462,7 +26866,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28472,7 +26876,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28482,7 +26886,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28553,7 +26957,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28563,7 +26967,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28573,7 +26977,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28583,7 +26987,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28593,7 +26997,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28652,7 +27056,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28662,7 +27066,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28672,7 +27076,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28682,7 +27086,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28692,7 +27096,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28741,7 +27145,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28751,7 +27155,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28761,7 +27165,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28771,7 +27175,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28781,7 +27185,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28837,7 +27241,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28847,7 +27251,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28857,7 +27261,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28867,7 +27271,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28877,7 +27281,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28925,7 +27329,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28935,7 +27339,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28945,7 +27349,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28955,7 +27359,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -28965,7 +27369,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29018,7 +27422,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29028,7 +27432,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29038,7 +27442,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29048,7 +27452,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29058,7 +27462,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29123,7 +27527,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29133,7 +27537,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29143,7 +27547,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29153,7 +27557,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29163,7 +27567,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29221,7 +27625,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29231,7 +27635,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29241,7 +27645,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29251,7 +27655,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29261,7 +27665,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29319,7 +27723,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29329,7 +27733,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29339,7 +27743,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29349,7 +27753,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29359,7 +27763,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29421,7 +27825,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29431,7 +27835,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29441,7 +27845,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29451,7 +27855,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29461,7 +27865,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29518,7 +27922,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29528,7 +27932,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29538,7 +27942,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29548,7 +27952,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29558,7 +27962,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29612,7 +28016,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse" + "$ref": "#/components/schemas/dto.ItemResponse" } } }, @@ -29622,7 +28026,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29632,7 +28036,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29642,7 +28046,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29652,7 +28056,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, @@ -29662,7 +28066,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/internal_restapi_v1_handlers.ErrorResponse" + "$ref": "#/components/schemas/handlers.ErrorResponse" } } }, diff --git a/api/openapi.yaml b/api/openapi.yaml index 976e976d2..450f9d5f0 100644 --- a/api/openapi.yaml +++ b/api/openapi.yaml @@ -9,4458 +9,3404 @@ components: path: type: string type: object - health.livenessResponse: + dto.AssetCategoryResponse: properties: - status: + asset_count: + type: integer + children_count: + type: integer + created_at: + type: string + descendants_count: + type: integer + description: + type: string + has_children: + type: boolean + id: + type: integer + name: + type: string + parent_id: + type: integer + path: + type: string + set_id: + type: integer + updated_at: type: string type: object - health.readinessResponse: + dto.AssetCategorySummary: properties: - database: + id: + type: integer + name: type: string - status: + path: type: string type: object - internal_restapi_v1_handlers.AdminGroupCreateRequest: + dto.AssetCreateRequest: properties: + asset_tag: + type: string + asset_type_id: + type: integer + category_id: + type: integer + custom_field_values: + additionalProperties: {} + type: object description: type: string - name: + status_id: + type: integer + title: type: string type: object - internal_restapi_v1_handlers.AdminGroupResponse: + dto.AssetImportJobResponse: properties: + asset_type_id: + type: integer + completed_at: + type: string created_at: type: string - description: + created_rows: + type: integer + error_message: type: string + error_rows: + type: integer id: type: integer - member_count: + processed_rows: type: integer - name: + set_id: + type: integer + started_at: type: string - warnings: - items: - type: string - type: array + status: + type: string + total_rows: + type: integer type: object - internal_restapi_v1_handlers.AdminGroupUpdateRequest: + dto.AssetLinks: properties: - description: + self: type: string - name: + set: type: string type: object - internal_restapi_v1_handlers.AdminUserResponse: + dto.AssetResponse: properties: - avatar_url: + _links: + $ref: '#/components/schemas/dto.AssetLinks' + asset_tag: type: string + asset_type: + $ref: '#/components/schemas/dto.AssetTypeSummary' + asset_type_id: + type: integer + category: + $ref: '#/components/schemas/dto.AssetCategorySummary' + category_id: + type: integer created_at: type: string - email: - type: string - first_name: - type: string - full_name: + created_by: + type: integer + creator: + $ref: '#/components/schemas/dto.UserSummary' + custom_field_values: + additionalProperties: {} + type: object + description: type: string - group_ids: - items: - type: integer - type: array id: type: integer - is_active: - type: boolean - language: - type: string - last_name: - type: string - timezone: + linked_item_count: + description: |- + LinkedItemCount is the number of item↔asset links for this asset + (0 when the underlying query didn't ask for the rollup). + type: integer + set: + allOf: + - $ref: '#/components/schemas/dto.AssetSetSummary' + description: |- + Nested summaries — populated from the row's joined columns when the + underlying query asks for them, otherwise omitted. + set_id: + type: integer + status: + $ref: '#/components/schemas/dto.AssetStatusSummary' + status_id: + type: integer + title: type: string - username: + updated_at: type: string warnings: + description: |- + Warnings carries non-fatal anomalies surfaced by the query layer + (e.g. corrupt custom_field_values JSON). Always serialized as an + array (never null) so CLI consumers don't need to null-check. items: type: string type: array type: object - internal_restapi_v1_handlers.AdminUserUpdateRequest: + dto.AssetSetLinks: properties: - email: + assets: type: string - first_name: + categories: type: string - is_active: - type: boolean - last_name: + self: type: string - type: object - internal_restapi_v1_handlers.AgentRunResponse: - properties: - ended_at: + statuses: type: string - error: + types: type: string - id: + type: object + dto.AssetSetResponse: + properties: + _links: + $ref: '#/components/schemas/dto.AssetSetLinks' + asset_count: type: integer - item_id: + asset_type_count: type: integer - job_kind: - type: string - queued_at: - type: string - started_at: - type: string - status: + created_at: type: string - workspace_id: + created_by: type: integer - type: object - internal_restapi_v1_handlers.AuditLogEntryResponse: - properties: - action_type: - type: string - details: - additionalProperties: {} - type: object - error_message: + description: type: string id: type: integer - ip_address: - type: string - resource_id: - type: integer - resource_name: - type: string - resource_type: - type: string - success: + is_default: type: boolean - timestamp: + name: type: string - user_agent: + updated_at: type: string - user_id: - type: integer - username: + user_permission: type: string type: object - internal_restapi_v1_handlers.AuditLogStreamResponse: - properties: - entries: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AuditLogEntryResponse' - type: array - has_more: - type: boolean - next_after_id: - type: integer - type: object - internal_restapi_v1_handlers.CollectionListResponse: + dto.AssetSetSummary: properties: - items: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.CollectionResponse' - type: array - total: + id: type: integer + name: + type: string type: object - internal_restapi_v1_handlers.CollectionResponse: + dto.AssetStatusResponse: properties: + color: + type: string created_at: type: string description: type: string + display_order: + type: integer id: type: integer + is_default: + type: boolean name: type: string - slug: - type: string + set_id: + type: integer updated_at: type: string - workspace_id: - type: integer type: object - internal_restapi_v1_handlers.CustomFieldResponse: + dto.AssetStatusSummary: properties: - description: - type: string - display_order: - type: integer - field_type: + color: type: string id: type: integer name: type: string - options: - description: JSON string - type: string - required: - type: boolean type: object - internal_restapi_v1_handlers.ErrorResponse: + dto.AssetTypeFieldResponse: properties: - code: - description: Machine-readable error code + custom_field_id: + type: integer + display_order: + type: integer + field_description: type: string - details: - description: Additional error details - error: - description: Human-readable message + field_name: type: string - request_id: - description: Request correlation ID + field_type: + type: string + id: + type: integer + is_required: + type: boolean + options: type: string type: object - internal_restapi_v1_handlers.ItemTypeResponse: + dto.AssetTypeResponse: properties: + asset_count: + type: integer color: type: string + created_at: + type: string description: type: string - hierarchy_level: + display_order: type: integer + fields: + items: + $ref: '#/components/schemas/dto.AssetTypeFieldResponse' + type: array icon: type: string id: type: integer - is_default: + is_active: type: boolean name: type: string - sort_order: + set_id: type: integer + updated_at: + type: string type: object - internal_restapi_v1_handlers.IterationCreateRequest: + dto.AssetTypeSummary: properties: - description: + color: type: string - end_date: + icon: type: string - is_global: - type: boolean + id: + type: integer name: type: string - start_date: - type: string - status: + type: object + dto.AssetUpdateRequest: + properties: + asset_tag: type: string - type_id: + asset_type_id: type: integer - workspace_id: + category_id: type: integer - required: - - end_date - - name - - start_date + custom_field_values: + additionalProperties: {} + type: object + description: + type: string + status_id: + type: integer + title: + type: string type: object - internal_restapi_v1_handlers.IterationResponse: + dto.AttachmentResponse: properties: created_at: type: string - description: + download_url: type: string - end_date: + file_size: + type: integer + filename: type: string + has_thumbnail: + type: boolean id: type: integer - is_global: - type: boolean - name: + item_id: + type: integer + mime_type: type: string - start_date: + original_filename: type: string - status: + thumbnail_url: type: string - type_color: + uploader: + $ref: '#/components/schemas/dto.UserSummary' + type: object + dto.CommentCreateRequest: + properties: + content: type: string - type_id: - type: integer - type_name: + required: + - content + type: object + dto.CommentResponse: + properties: + author: + $ref: '#/components/schemas/dto.UserSummary' + content: + type: string + content_html: type: string + created_at: + type: string + id: + type: integer + item_id: + type: integer updated_at: type: string warnings: items: type: string type: array - workspace_id: - type: integer type: object - internal_restapi_v1_handlers.IterationUpdateRequest: + dto.CommentUpdateRequest: properties: - description: - type: string - end_date: - type: string - name: - type: string - start_date: - type: string - status: + content: type: string - type_id: - nullable: true - type: integer + required: + - content type: object - internal_restapi_v1_handlers.MilestoneCreateRequest: + dto.EnforcedTemplateSummary: properties: - category_id: - type: integer - description: - type: string + applied: + type: boolean name: type: string - status: - type: string - target_date: - type: string - required: - - name + template_id: + type: integer type: object - internal_restapi_v1_handlers.MilestoneProgressItemResponse: + dto.HistoryResponse: properties: - assignee_avatar: + changed_at: type: string - assignee_name: + field_name: type: string id: type: integer - item_number: + item_id: type: integer - priority_color: - type: string - priority_name: - type: string - status_color: + new_value: type: string - status_name: + old_value: type: string - title: + resolved_new_value: type: string - workspace_id: - type: integer - workspace_key: + resolved_old_value: type: string + user: + $ref: '#/components/schemas/dto.UserSummary' type: object - internal_restapi_v1_handlers.MilestoneProgressResponse: + dto.ItemCreateRequest: properties: - category_color: - type: string - completed_items: + assignee_id: type: integer + custom_fields: + additionalProperties: {} + type: object description: type: string - items_by_category: - additionalProperties: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressItemResponse' - type: array - type: object - milestone_id: - type: integer - milestone_name: + due_date: type: string - percent_complete: - type: number - status: + end_date: type: string - status_breakdown: + is_task: + type: boolean + item_type_id: + type: integer + iteration_id: + type: integer + milestone_ids: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse' + type: integer type: array - target_date: - type: string - total_items: + parent_id: type: integer - type: object - internal_restapi_v1_handlers.MilestoneResponse: - properties: - category_color: - type: string - category_id: + priority_id: type: integer - category_name: - type: string - created_at: - type: string - description: - type: string - id: + project_id: type: integer - is_global: - type: boolean - name: + start_date: type: string - position: + status_id: + description: |- + Optional create-time placement. If omitted, the item uses the workflow initial status. + If provided, it must be the initial status or directly reachable from the initial status + without workflow conditions, validators, or approval gates. type: integer - status: - type: string - target_date: - type: string - updated_at: + title: + maxLength: 255 type: string - warnings: - items: - type: string - type: array workspace_id: type: integer + required: + - title + - workspace_id type: object - internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse: + dto.ItemLinks: properties: - category_color: + attachments: type: string - category_name: + children: type: string - is_completed: - type: boolean - item_count: - type: integer - type: object - internal_restapi_v1_handlers.MilestoneUpdateRequest: - properties: - category_id: - nullable: true - type: integer - description: + comments: type: string - name: + history: type: string - status: + parent: type: string - target_date: - nullable: true + self: + type: string + transitions: + type: string + workspace: type: string type: object - internal_restapi_v1_handlers.PaginatedResponse: - properties: - data: {} - pagination: - $ref: '#/components/schemas/windshift_internal_restapi.PaginationMeta' - type: object - internal_restapi_v1_handlers.PriorityResponse: + dto.ItemResponse: properties: - color: + _links: + allOf: + - $ref: '#/components/schemas/dto.ItemLinks' + description: HATEOAS links + assignee: + $ref: '#/components/schemas/dto.UserSummary' + attachments: + items: + $ref: '#/components/schemas/dto.AttachmentResponse' + type: array + children: + items: + $ref: '#/components/schemas/dto.ItemResponse' + type: array + comments: + description: Expanded collections (populated based on ?expand= parameter) + items: + $ref: '#/components/schemas/dto.CommentResponse' + type: array + completed_at: + type: string + created_at: + description: Timestamps type: string + creator: + $ref: '#/components/schemas/dto.UserSummary' + custom_fields: + additionalProperties: {} + type: object description: type: string - icon: + description_html: type: string - id: - type: integer - is_default: - type: boolean - name: - type: string - sort_order: - type: integer - type: object - internal_restapi_v1_handlers.StatusCategoryResponse: - properties: - color: + due_date: type: string - description: + end_date: type: string + enforced_template: + allOf: + - $ref: '#/components/schemas/dto.EnforcedTemplateSummary' + description: |- + EnforcedTemplate echoes the mandatory work item template the item's type + enforces (WI-438), populated only on the create response so non-UI callers + learn the expected structure even when they supplied their own + description. Omitted when the type enforces no mandatory template. + history: + items: + $ref: '#/components/schemas/dto.HistoryResponse' + type: array id: type: integer - is_completed: - type: boolean - is_default: + is_task: type: boolean - name: - type: string - type: object - internal_restapi_v1_handlers.StatusResponse: - properties: - category_color: + item_type: + $ref: '#/components/schemas/dto.ItemTypeSummary' + iteration: + $ref: '#/components/schemas/dto.IterationSummary' + key: + description: e.g., "PROJ-123" type: string - category_id: + milestones: + items: + $ref: '#/components/schemas/dto.MilestoneSummary' + type: array + parent_id: + description: |- + Hierarchy. ParentID is the raw DB id. ParentKey is the parent's + ready-to-display key (e.g. "WI-120"), computed server-side from the + parent's own workspace — clients must render this rather than building a + key from ParentID, which is a DB id in a different namespace and may even + point into another workspace. ParentKey and ParentTitle are populated + only on permission-checked single-item reads, and only when the caller + may view the parent (see ItemHandler.setParentSummary); they are omitted + from list responses and withheld across a workspace boundary the caller + cannot see. type: integer - category_name: + parent_key: type: string - description: + parent_title: type: string - id: + priority: + $ref: '#/components/schemas/dto.PrioritySummary' + project: + $ref: '#/components/schemas/dto.ProjectSummary' + start_date: + type: string + status: + allOf: + - $ref: '#/components/schemas/dto.StatusSummary' + description: Related entities (populated based on ?expand= parameter) + title: + type: string + transitions: + items: + $ref: '#/components/schemas/dto.TransitionResponse' + type: array + updated_at: + type: string + workspace: + $ref: '#/components/schemas/dto.WorkspaceSummary' + workspace_id: type: integer - is_completed: - type: boolean - is_default: - type: boolean - name: + workspace_item_number: + type: integer + workspace_key: type: string type: object - internal_restapi_v1_handlers.TUIPreferencesResponse: + dto.ItemTypeChangeRequest: properties: - last_workspace_id: + target_item_type_id: type: integer - split_ratio: - type: number - theme: - type: string + target_status_id: + type: integer + required: + - target_item_type_id type: object - internal_restapi_v1_handlers.UserResponse: + dto.ItemTypeSummary: properties: - avatar_url: - type: string - created_at: - type: string - email: + builtin_key: type: string - first_name: + color: type: string - full_name: + hierarchy_level: + type: integer + icon: type: string id: type: integer - is_active: - type: boolean - is_agent: - type: boolean - language: + name: type: string - last_name: + type: object + dto.ItemUpdateRequest: + properties: + assignee_id: + type: integer + custom_fields: + additionalProperties: {} + type: object + description: type: string - timezone: + due_date: type: string - username: + end_date: type: string - warnings: + is_task: + type: boolean + item_type_id: + type: integer + iteration_id: + type: integer + milestone_ids: items: - type: string + type: integer type: array + parent_id: + type: integer + priority_id: + type: integer + project_id: + type: integer + start_date: + type: string + title: + maxLength: 255 + type: string type: object - internal_restapi_v1_handlers.WorkflowResponse: + dto.IterationSummary: properties: - created_at: - type: string - description: + end_date: type: string id: type: integer - is_default: - type: boolean name: type: string - transitions: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse' - type: array - updated_at: + start_date: + type: string + status: type: string type: object - internal_restapi_v1_handlers.WorkspaceCreateRequest: + dto.MilestoneSummary: properties: - color: + id: + type: integer + name: type: string - description: + status: type: string - icon: + target_date: type: string - key: - maxLength: 10 - minLength: 2 + type: object + dto.PageLinks: + properties: + history: type: string - name: - maxLength: 100 + permissions: + type: string + self: + type: string + workspace: type: string - template_workspace_id: - type: integer - required: - - key - - name type: object - internal_restapi_v1_handlers.WorkspaceResponse: + dto.PageResponse: properties: - active: - type: boolean - color: + _links: + $ref: '#/components/schemas/dto.PageLinks' + archived_at: type: string - created_at: + archived_by: + type: integer + content: type: string - description: + content_hash: type: string - icon: + created_at: + type: string + created_by: + type: integer + depth: + type: integer + excerpt: type: string id: type: integer - internal_comments_enabled: - type: boolean - is_personal: + inherit_permissions: type: boolean - is_template: + is_home: type: boolean - key: + labels: + description: |- + Labels carries the workspace page-labels currently attached to the + page. Populated by the service layer when the page-label repository + is wired; always serialized as an array (never null) so CLI/JSON + consumers don't need to null-check. + items: + $ref: '#/components/schemas/models.PageLabel' + type: array + metadata: + additionalProperties: {} + type: object + parent_id: + type: integer + path: type: string - name: + slug: + type: string + title: type: string updated_at: type: string - warnings: - items: - type: string - type: array + updated_by: + type: integer + workspace_id: + type: integer type: object - internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse: + dto.PageRevisionResponse: properties: - color: + change_summary: type: string - configuration_set_name: + change_type: type: string - description: + content: type: string - icon: + created_at: + type: string + created_by: + type: integer + depth: + type: integer + excerpt: type: string id: type: integer - item_count: + page_id: type: integer - name: + parent_id: + type: integer + path: type: string - template_count: + revision_number: type: integer + slug: + type: string + title: + type: string type: object - internal_restapi_v1_handlers.WorkspaceUpdateRequest: + dto.PrioritySummary: properties: - active: - type: boolean - color: + builtin_key: type: string - description: + color: type: string icon: type: string - is_template: - type: boolean + id: + type: integer name: type: string type: object - internal_restapi_v1_handlers.actionDefinitionRequest: + dto.ProjectSummary: properties: - description: - type: string - edges: - items: - $ref: '#/components/schemas/models.ActionEdge' - type: array + id: + type: integer name: type: string - nodes: - items: - $ref: '#/components/schemas/models.ActionNode' - type: array - trigger_config: - type: string - trigger_type: - $ref: '#/components/schemas/models.ActionTriggerType' type: object - internal_restapi_v1_handlers.agentSkillListResponse: + dto.StatusSummary: properties: - items: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.agentSkillSummary' - type: array - type: object - internal_restapi_v1_handlers.agentSkillSummary: - properties: - description: + builtin_key: + type: string + category_builtin_key: + type: string + category_color: + type: string + category_id: + type: integer + category_name: type: string - enabled: - type: boolean id: type: integer + is_completed: + type: boolean name: type: string type: object - internal_restapi_v1_handlers.batchItemLinksResponse: + dto.TransitionRequest: properties: - has_more_links: - type: boolean - incoming: - items: - $ref: '#/components/schemas/models.ItemLink' - type: array - item_id: - type: integer - next_after_link_id: + to_status_id: type: integer - outgoing: - items: - $ref: '#/components/schemas/models.ItemLink' - type: array + required: + - to_status_id type: object - internal_restapi_v1_handlers.capabilityDTO: + dto.TransitionResponse: properties: - capability_type: - $ref: '#/components/schemas/models.CapabilityType' + from_all_statuses: + type: boolean + from_status: + $ref: '#/components/schemas/dto.StatusSummary' + from_status_id: + type: integer id: type: integer - name: - type: string + to_status: + $ref: '#/components/schemas/dto.StatusSummary' + to_status_id: + type: integer type: object - internal_restapi_v1_handlers.catalogResponse: + dto.TransitionResultResponse: properties: - capabilities: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.capabilityDTO' - type: array - nodes: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.nodeTypeDTO' - type: array - scope: - type: string - triggers: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.triggerTypeDTO' - type: array + item: + $ref: '#/components/schemas/dto.ItemResponse' + new_status_id: + type: integer + no_op: + type: boolean + old_status_id: + type: integer type: object - internal_restapi_v1_handlers.createWorklogRequest: + dto.UserSummary: properties: - date: - type: string - description: + avatar_url: type: string - duration: + email: type: string - duration_minutes: - type: integer - end_time: + first_name: type: string - item_id: - type: integer - item_key: + full_name: type: string - project_id: + id: type: integer - start_time: + last_name: type: string - timezone: + username: type: string type: object - internal_restapi_v1_handlers.diagramListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.ItemDiagram' - type: array - type: object - internal_restapi_v1_handlers.diagramWriteRequest: + dto.WorkspaceSummary: properties: - diagram_data: + id: + type: integer + key: type: string name: type: string type: object - internal_restapi_v1_handlers.itemChangeResponse: + handlers.AdminGroupCreateRequest: properties: - change_type: + description: + type: string + name: type: string - item_id: - type: integer type: object - internal_restapi_v1_handlers.itemChangesResponse: + handlers.AdminGroupResponse: properties: - changes: - items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.itemChangeResponse' - type: array - has_more: - type: boolean - next_cursor: + created_at: type: string - reset_required: - type: boolean - watermark: + description: type: string - type: object - internal_restapi_v1_handlers.itemLabelAddRequest: - properties: - label_id: + id: + type: integer + member_count: type: integer - type: object - internal_restapi_v1_handlers.itemLabelSetRequest: - properties: - label_ids: - items: - type: integer - type: array - type: object - internal_restapi_v1_handlers.labelCreateRequest: - properties: - color: - type: string name: type: string - type: object - internal_restapi_v1_handlers.labelListResponse: - properties: - items: + warnings: items: - $ref: '#/components/schemas/models.Label' + type: string type: array type: object - internal_restapi_v1_handlers.labelUpdateRequest: + handlers.AdminGroupUpdateRequest: properties: - color: + description: type: string name: type: string type: object - internal_restapi_v1_handlers.linkCreateRequest: + handlers.AdminUserResponse: properties: - link_type_id: - type: integer - source_id: - type: integer - source_type: + avatar_url: type: string - target_id: - type: integer - target_type: + created_at: type: string - type: object - internal_restapi_v1_handlers.milestoneReorderRequest: - properties: - category_id: - type: integer - ordered_ids: + email: + type: string + first_name: + type: string + full_name: + type: string + group_ids: items: type: integer type: array - type: object - internal_restapi_v1_handlers.nodeTypeDTO: - properties: - category: + id: + type: integer + is_active: + type: boolean + language: type: string - config_schema: - type: object - description: + last_name: type: string - is_iterator: - type: boolean - label: + timezone: type: string - outputs: + username: + type: string + warnings: items: type: string type: array - type: - $ref: '#/components/schemas/models.ActionNodeType' type: object - internal_restapi_v1_handlers.pageCreateRequest: + handlers.AdminUserUpdateRequest: properties: - content: + email: type: string - is_home: + first_name: + type: string + is_active: type: boolean - metadata: - additionalProperties: {} - type: object - parent_id: - type: integer - title: + last_name: type: string type: object - internal_restapi_v1_handlers.pageDiagramCreateRequest: + handlers.AgentRunResponse: properties: - excalidraw: - type: object - expected_content_hash: - type: string - mermaid: + ended_at: type: string - name: + error: type: string - placement: + id: + type: integer + item_id: + type: integer + job_kind: type: string - type: object - internal_restapi_v1_handlers.pageDiagramListResponse: - properties: - items: - items: - $ref: '#/components/schemas/services.PageDiagram' - type: array - type: object - internal_restapi_v1_handlers.pageDiagramUpdateRequest: - properties: - excalidraw: - type: object - expected_content_hash: + queued_at: type: string - mermaid: + started_at: type: string - name: + status: type: string + workspace_id: + type: integer type: object - internal_restapi_v1_handlers.pageGrantPermissionRequest: + handlers.AuditLogEntryResponse: properties: - permission_level: + action_type: type: string - principal_id: - type: integer - principal_type: + details: + additionalProperties: {} + type: object + error_message: type: string - type: object - internal_restapi_v1_handlers.pageHistoryListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse' - type: array - type: object - internal_restapi_v1_handlers.pageLabelAddRequest: - properties: - label_id: + id: type: integer - type: object - internal_restapi_v1_handlers.pageLabelCreateRequest: - properties: - color: + ip_address: type: string - name: + resource_id: + type: integer + resource_name: type: string - type: object - internal_restapi_v1_handlers.pageLabelListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.PageLabel' - type: array - type: object - internal_restapi_v1_handlers.pageLabelSetRequest: - properties: - label_ids: - items: - type: integer - type: array - type: object - internal_restapi_v1_handlers.pageLabelUpdateRequest: - properties: - color: + resource_type: type: string - name: + success: + type: boolean + timestamp: + type: string + user_agent: + type: string + user_id: + type: integer + username: type: string type: object - internal_restapi_v1_handlers.pageListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' - type: array - type: object - internal_restapi_v1_handlers.pageListWithLabelsResponse: + handlers.CollectionListResponse: properties: items: items: - $ref: '#/components/schemas/models.PageLabel' + $ref: '#/components/schemas/handlers.CollectionResponse' type: array + total: + type: integer type: object - internal_restapi_v1_handlers.pageMoveRequest: + handlers.CollectionResponse: properties: - destination_workspace_id: - type: integer - next_sibling_id: - type: integer - parent_id: + created_at: + type: string + description: + type: string + id: type: integer - prev_sibling_id: + name: + type: string + slug: + type: string + updated_at: + type: string + workspace_id: type: integer type: object - internal_restapi_v1_handlers.pagePermissionsResponse: + handlers.CustomFieldResponse: properties: - acl: - items: - $ref: '#/components/schemas/models.PagePermission' - type: array - effective_level: + description: type: string - inherit_permissions: - type: boolean - page_id: + display_order: type: integer - type: object - internal_restapi_v1_handlers.pageSetInheritanceRequest: - properties: - inherit_permissions: + field_type: + type: string + id: + type: integer + name: + type: string + options: + description: JSON string + type: string + required: type: boolean type: object - internal_restapi_v1_handlers.pageUpdateRequest: + handlers.ErrorResponse: properties: - content: + code: + description: Machine-readable error code type: string - expected_content_hash: + details: + description: Additional error details + error: + description: Human-readable message type: string - metadata: - additionalProperties: {} - type: object - title: + request_id: + description: Request correlation ID type: string type: object - internal_restapi_v1_handlers.recurrenceForceGenerateResponse: - properties: - instances_generated: - type: integer - type: object - internal_restapi_v1_handlers.recurrenceInstanceListResponse: - properties: - instances: - items: - $ref: '#/components/schemas/models.RecurrenceInstance' - type: array - pagination: - $ref: '#/components/schemas/windshift_internal_restapi.PaginationMeta' - type: object - internal_restapi_v1_handlers.rrulePreviewResponse: + handlers.ItemTypeResponse: properties: - dtstart: + builtin_key: type: string - occurrences: - items: - type: string - type: array - rrule: + color: type: string - type: object - internal_restapi_v1_handlers.startTimerRequest: - properties: description: type: string - item_id: - type: integer - project_id: - type: integer - workspace_id: + hierarchy_level: type: integer - type: object - internal_restapi_v1_handlers.templateCreateRequest: - properties: - description_body: + icon: type: string - is_active: + id: + type: integer + is_default: type: boolean - item_type_ids: - items: - type: integer - type: array - mode: - type: string name: type: string - type: object - internal_restapi_v1_handlers.templateListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.ItemTemplate' - type: array - mandatory_template_id: - description: |- - MandatoryTemplateID is set when the request filtered by item_type_id and - that type has an active mandatory template, so callers (create modal, CLI) - can flag it without re-deriving the invariant. + sort_order: type: integer type: object - internal_restapi_v1_handlers.templateUpdateRequest: + handlers.IterationCreateRequest: properties: - description_body: + description: type: string - is_active: - type: boolean - item_type_ids: - items: - type: integer - type: array - mode: + end_date: type: string + is_global: + type: boolean name: type: string - type: object - internal_restapi_v1_handlers.testResultUpdateRequest: - properties: - actual_result: - type: string - notes: + start_date: type: string status: type: string - type: object - internal_restapi_v1_handlers.testRunCreateRequest: - properties: - assignee_id: - type: integer - name: - type: string - set_id: + type_id: type: integer - template_id: + workspace_id: type: integer + required: + - end_date + - name + - start_date type: object - internal_restapi_v1_handlers.timeProjectResponse: + handlers.IterationResponse: properties: - category_color: - type: string - category_id: - type: integer - category_name: - type: string - color: - type: string - customer_id: - type: integer - customer_name: + created_at: type: string description: type: string - hourly_rate: - type: number + end_date: + type: string id: type: integer + is_global: + type: boolean name: type: string - settings: - additionalProperties: {} - type: object + start_date: + type: string status: type: string - total_hours: - type: number + type_color: + type: string + type_id: + type: integer + type_name: + type: string + updated_at: + type: string + warnings: + items: + type: string + type: array + workspace_id: + type: integer type: object - internal_restapi_v1_handlers.triggerTypeDTO: + handlers.IterationUpdateRequest: properties: - config_schema: - type: object description: type: string - label: + end_date: type: string - type: - $ref: '#/components/schemas/models.ActionTriggerType' + name: + type: string + start_date: + type: string + status: + type: string + type_id: + nullable: true + type: integer type: object - internal_restapi_v1_handlers.updateWorklogRequest: + handlers.MilestoneCreateRequest: properties: + category_id: + type: integer description: type: string + name: + type: string + status: + type: string + target_date: + type: string + required: + - name type: object - internal_restapi_v1_handlers.validateActionResponse: + handlers.MilestoneProgressItemResponse: properties: - errors: - items: - $ref: '#/components/schemas/actioncatalog.ValidationError' - type: array - type: object - internal_restapi_v1_handlers.worklogResponse: - properties: - created_at: + assignee_avatar: + type: string + assignee_name: + type: string + id: type: integer - customer_id: + item_number: type: integer - customer_name: + priority_builtin_key: type: string - date: + priority_color: + type: string + priority_name: + type: string + status_builtin_key: + type: string + status_color: + type: string + status_name: + type: string + title: + type: string + workspace_id: type: integer - description: + workspace_key: type: string - duration_minutes: + type: object + handlers.MilestoneProgressResponse: + properties: + category_color: + type: string + completed_items: type: integer - end_time: + description: + type: string + items_by_category: + additionalProperties: + items: + $ref: '#/components/schemas/handlers.MilestoneProgressItemResponse' + type: array + type: object + milestone_id: type: integer - id: + milestone_name: + type: string + percent_complete: + type: number + status: + type: string + status_breakdown: + items: + $ref: '#/components/schemas/handlers.MilestoneStatusBreakdownResponse' + type: array + target_date: + type: string + total_items: type: integer - item_id: + type: object + handlers.MilestoneResponse: + properties: + category_color: + type: string + category_id: type: integer - item_title: + category_name: type: string - project_id: + created_at: + type: string + description: + type: string + id: type: integer - project_max_hours: - type: number - project_name: + is_global: + type: boolean + name: type: string - project_total_hours: - type: number - start_time: + position: type: integer + status: + type: string + target_date: + type: string updated_at: - type: integer + type: string + warnings: + items: + type: string + type: array workspace_id: type: integer - workspace_item_number: + type: object + handlers.MilestoneStatusBreakdownResponse: + properties: + category_builtin_key: + type: string + category_color: + type: string + category_name: + type: string + is_completed: + type: boolean + item_count: type: integer - workspace_key: + type: object + handlers.MilestoneUpdateRequest: + properties: + category_id: + nullable: true + type: integer + description: + type: string + name: + type: string + status: + type: string + target_date: + nullable: true type: string type: object - models.APIToken: + handlers.PaginatedResponse: properties: - created_at: + data: {} + pagination: + $ref: '#/components/schemas/restapi.PaginationMeta' + type: object + handlers.PriorityResponse: + properties: + builtin_key: type: string - expires_at: + color: + type: string + description: + type: string + icon: type: string id: type: integer - is_temporary: - description: True for SSH session tokens + is_default: type: boolean - last_used_at: - type: string name: - description: Human-readable name for the token type: string - permissions: - description: JSON array of permissions - type: string - token_prefix: - description: First few characters for identification + sort_order: + type: integer + type: object + handlers.StatusCategoryResponse: + properties: + builtin_key: type: string - updated_at: + color: type: string - user_email: - description: Joined fields + description: type: string - user_id: + id: type: integer - user_name: + is_completed: + type: boolean + is_default: + type: boolean + name: type: string type: object - models.Action: + handlers.StatusResponse: properties: - actor_name: + builtin_key: type: string - actor_user_id: - description: |- - ActorUserID overrides the execution actor. NULL means the action runs under - the triggering user's permissions. Setting this field requires the global - action.set_actor permission because it grants cross-workspace impersonation. + category_builtin_key: + type: string + category_color: + type: string + category_id: type: integer - allowed_role_ids: - description: |- - AllowedRoleIDs restricts a manual action to members of these workspace - roles. An empty list means every workspace editor may trigger it. - items: - type: integer - type: array - created_at: + category_name: type: string - created_by: + description: + type: string + id: type: integer - creator_name: - description: Joined fields for API responses + is_completed: + type: boolean + is_default: + type: boolean + name: + type: string + type: object + handlers.TUIPreferencesResponse: + properties: + last_workspace_id: + type: integer + split_ratio: + type: number + theme: + type: string + type: object + handlers.WorkflowResponse: + properties: + builtin_key: + type: string + created_at: type: string description: type: string - edges: - items: - $ref: '#/components/schemas/models.ActionEdge' - type: array id: type: integer - is_enabled: + is_default: type: boolean name: type: string - nodes: + transitions: items: - $ref: '#/components/schemas/models.ActionNode' + $ref: '#/components/schemas/dto.TransitionResponse' type: array - trigger_config: - description: JSON with trigger-specific conditions - type: string - trigger_type: - $ref: '#/components/schemas/models.ActionTriggerType' updated_at: type: string - workspace_id: - type: integer type: object - models.ActionEdge: + handlers.WorkspaceCreateRequest: properties: - action_id: - type: integer - created_at: + color: type: string - edge_type: - description: default, true, false (for conditions) + description: type: string - id: - type: integer - source_handle: + icon: type: string - source_node_id: - type: integer - target_handle: + key: + maxLength: 10 + minLength: 2 type: string - target_node_id: + name: + maxLength: 100 + type: string + template_workspace_id: type: integer + required: + - key + - name type: object - models.ActionNode: + handlers.WorkspaceResponse: properties: - action_id: - type: integer + active: + type: boolean + color: + type: string created_at: type: string + description: + type: string + icon: + type: string id: type: integer - node_config: - description: JSON configuration for the node - type: string - node_type: - $ref: '#/components/schemas/models.ActionNodeType' - position_x: - type: number - position_y: - type: number - updated_at: - type: string - type: object - models.ActionNodeType: - enum: - - trigger - - set_field - - set_status - - add_comment - - notify_user - - condition - - update_asset - - create_asset - - round_robin_assign - - ai_extract - - ai_agent - - container_run - - http_request - - transition_item - - related_items - - create_milestone - type: string - x-enum-varnames: - - ActionNodeTrigger - - ActionNodeSetField - - ActionNodeSetStatus - - ActionNodeAddComment - - ActionNodeNotifyUser - - ActionNodeCondition - - ActionNodeUpdateAsset - - ActionNodeCreateAsset - - ActionNodeRoundRobinAssign - - ActionNodeAIExtract - - ActionNodeAIAgent - - ActionNodeContainerRun - - ActionNodeHTTPRequest - - ActionNodeTransitionItem - - ActionNodeRelatedItems - - ActionNodeCreateMilestone - models.ActionTriggerType: - enum: - - status_transition - - item_created - - item_updated - - item_linked - - manual - - scm_tag_created - - scm_release_branch_created - - scm_pr_linked - - scm_pr_merged - type: string - x-enum-varnames: - - ActionTriggerStatusTransition - - ActionTriggerItemCreated - - ActionTriggerItemUpdated - - ActionTriggerItemLinked - - ActionTriggerManual - - ActionTriggerSCMTagCreated - - ActionTriggerSCMReleaseBranchCreated - - ActionTriggerSCMPRLinked - - ActionTriggerSCMPRMerged - models.ActiveTimer: - properties: - created_at: - description: Unix timestamp - type: integer - customer_name: - type: string - description: - type: string - id: - type: integer - item_id: - description: Optional link to work item - type: integer - item_title: - type: string - project_id: - type: integer - project_name: - type: string - start_time_utc: - description: Unix timestamp in UTC - type: integer - user_id: - type: integer - workspace_id: - type: integer - workspace_item_number: - type: integer - workspace_key: - type: string - workspace_name: - type: string - type: object - models.Attachment: - properties: - created_at: - type: string - file_size: - type: integer - filename: - description: Stored filename (UUID-based) - type: string - has_thumbnail: - description: Whether thumbnail was generated - type: boolean - id: - type: integer - item_id: - type: integer - mime_type: - type: string - original_filename: - description: Original user filename - type: string - uploaded_by: - type: integer - uploader_email: - type: string - uploader_name: - description: Joined fields for API responses - type: string - type: object - models.AttachmentUploadResponse: - properties: - attachment: - $ref: '#/components/schemas/models.Attachment' - message: - type: string - success: - type: boolean - type: object - models.CalendarScheduleEntry: - properties: - created_at: - type: string - duration_minutes: - description: Duration in minutes, optional - type: integer - notes: - type: string - scheduled_date: - description: YYYY-MM-DD format - type: string - scheduled_time: - description: HH:MM format, optional - type: string - user_id: - type: integer - workspace_id: - description: User's personal workspace ID - type: integer - type: object - models.CapabilityType: - enum: - - docker_environment - - http_client - - llm_connection - - runner_pool - type: string - x-enum-varnames: - - CapabilityDockerEnvironment - - CapabilityHTTPClient - - CapabilityLLMConnection - - CapabilityRunnerPool - models.CreateRecurrenceRequest: - properties: - copy_assignee: - type: boolean - copy_custom_fields: - type: boolean - copy_description: - type: boolean - copy_priority: - type: boolean - dtend: - type: string - dtstart: - description: ISO 8601 format - type: string - lead_time_days: - type: integer - rrule: - type: string - status_on_create: - type: integer - template_item_id: - type: integer - timezone: - type: string - type: object - models.Item: - properties: - assignee_avatar: - description: Avatar URL of assigned user - type: string - assignee_email: - description: Email of assigned user - type: string - assignee_id: - description: User assignment fields - type: integer - assignee_name: - description: User information for API responses - type: string - calendar_data: - items: - $ref: '#/components/schemas/models.CalendarScheduleEntry' - type: array - channel_id: - description: Portal submission tracking fields (immutable once set) - type: integer - channel_name: - description: Portal submission tracking joined fields - type: string - children: - description: For tree representations - items: - $ref: '#/components/schemas/models.Item' - type: array - completed_at: - type: string - created_at: - type: string - creator_email: - description: Email of creator (internal user or portal customer) - type: string - creator_id: - description: Internal user who created this item - type: integer - creator_name: - description: Full name of creator (internal user or portal customer) - type: string - creator_portal_customer_email: - description: Email of portal customer creator - type: string - creator_portal_customer_id: - description: Portal customer who created this item (for portal submissions) - type: integer - creator_portal_customer_name: - description: Name of portal customer creator - type: string - custom_field_values: - additionalProperties: {} - type: object - description: - type: string - due_date: - description: Due date for item completion - type: string - effective_project_id: - description: |- - EffectiveProjectID is the resolved project after walking InheritProject - up the parent chain. Consumers that need "which time-tracking project - applies to this item" should read this, not ProjectID directly. - type: integer - effective_project_name: - type: string - end_date: - description: End date for item - type: string - estimate_minutes: - description: Time estimate in minutes (compared against logged worklog time) - type: integer - frac_index: - description: Manual sorting field - type: string - id: - type: integer - inherit_project: - description: If true, ProjectID is ignored and the parent item's effective - project is used - type: boolean - is_task: - description: Flag to mark this item as a task (checklist item) - type: boolean - item_type_id: - description: Optional, defaults to workspace's default item type - type: integer - item_type_name: - type: string - iteration_end_date: - type: string - iteration_id: - description: Optional iteration assignment - type: integer - iteration_name: - type: string - labels: - description: Global item labels - items: - $ref: '#/components/schemas/models.Label' - type: array - last_active_at: - description: |- - Recency for the board "Bubble Mode" sort. Bumped on activity (comments, - edits, transitions) but not on manual frac_index reorder. - type: string - milestones: - items: - $ref: '#/components/schemas/models.Milestone' - type: array - parent_id: - description: Hierarchy fields - type: integer - parent_title: - type: string - parent_workspace_item_number: - description: Parent's workspace-scoped number, for rendering the parent - key - type: integer - personal_labels: - items: - $ref: '#/components/schemas/models.PersonalLabel' - type: array - priority_color: - type: string - priority_icon: - type: string - priority_id: - description: Foreign key to priorities table - type: integer - priority_name: - type: string - project_id: - description: |- - Time-tracking project membership. "Project" in Windshift always refers - to a row in time_projects; both ProjectID and TimeProjectID below are - FKs to that table, serving different roles: - ProjectID - the project this item belongs to (the bucket - worklogs default to). Can be inherited from the - parent item; see InheritProject. - TimeProjectID - overrides the project used when logging time on - this specific item (independent of the bucket the - item belongs to). - EffectiveProjectID (below) is the resolved value after applying - inheritance, and is what consumers should read. - type: integer - project_inheritance_mode: - description: '"none" | "inherit" | "direct"' - type: string - project_name: - description: Name of the time-tracking project this item belongs to (joined - from time_projects via ProjectID) - type: string - related_work_item_id: - description: Personal task relationship (for linking personal workspace - tasks to work items) - type: integer - related_work_item_number: - type: integer - related_work_item_title: - description: Related work item joined fields (for personal tasks) - type: string - related_work_item_workspace_id: - type: integer - related_work_item_workspace_key: - type: string - reporter_avatar: - description: Avatar URL of reporter - type: string - reporter_email: - description: Email of reporter - type: string - reporter_id: - description: User who reported this item (from Jira import) - type: integer - reporter_name: - description: Full name of reporter - type: string - request_type_id: - description: Request type used for submission - type: integer - request_type_name: - description: Name of the request type - type: string - start_date: - description: Start date for item - type: string - status_color: - description: Color from the status category (joined field) - type: string - status_id: - description: Foreign key to statuses table - type: integer - status_name: - description: Name from statuses table (joined field) - type: string - status_since: - description: |- - StatusSince is when the item last entered its current status, derived from - item_history (falls back to created_at when there is no recorded change). - type: string - story_points: - description: Estimation - type: number - time_project_id: - type: integer - time_project_name: - description: Name of the time-tracking project overriding worklog defaults - (joined from time_projects via TimeProjectID) - type: string - title: - type: string - updated_at: - type: string - virtual_field_data: - additionalProperties: {} - type: object - workspace_id: - type: integer - workspace_item_number: - description: Workspace-specific sequential number for display keys - type: integer - workspace_key: - type: string - workspace_name: - description: Joined fields for API responses - type: string - type: object - models.ItemDiagram: - properties: - created_at: - type: string - created_by: - type: integer - creator_email: - type: string - creator_name: - description: Joined fields for API responses - type: string - diagram_data: - description: JSON with elements, appState, files - type: string - id: - type: integer - item_id: - type: integer - name: - type: string - updated_at: - type: string - updated_by: - type: integer - updated_by_email: - type: string - updated_by_name: - type: string - type: object - models.ItemLink: - properties: - created_at: - type: string - created_by: - type: integer - created_by_name: - type: string - custom_field_id: - type: integer - custom_field_name: - description: Custom field link metadata - type: string - id: - type: integer - link_type_color: - type: string - link_type_forward_label: - type: string - link_type_id: - type: integer - link_type_name: - description: Joined fields for API responses - type: string - link_type_reverse_label: - type: string - source_id: - type: integer - source_item_number: - description: |- - SourceItemNumber is the workspace-scoped item number (the "74" in - "WI-74"). Display the user-facing key as - SourceWorkspaceKey + "-" + SourceItemNumber, never SourceID — that - field is the global DB id and looks wrong (e.g. "WI-149") in UI. - type: integer - source_item_type_color: - type: string - source_item_type_icon: - type: string - source_item_type_id: - type: integer - source_item_type_name: - type: string - source_status_color: - type: string - source_status_id: - description: Source item details - type: integer - source_status_name: - type: string - source_title: - type: string - source_type: - description: '"item" or "test_case"' - type: string - source_workspace_id: - type: integer - source_workspace_key: - type: string - target_id: - type: integer - target_item_number: - description: 'TargetItemNumber: see SourceItemNumber.' - type: integer - target_item_type_color: - type: string - target_item_type_icon: - type: string - target_item_type_id: - type: integer - target_item_type_name: - type: string - target_status_color: - type: string - target_status_id: - description: Target item details - type: integer - target_status_name: - type: string - target_title: - type: string - target_type: - description: '"item" or "test_case"' - type: string - target_workspace_id: - type: integer - target_workspace_key: - type: string - type: object - models.ItemTemplate: - properties: - created_at: - type: string - created_by: - type: integer - description_body: - type: string - id: - type: integer - is_active: - type: boolean - item_type_ids: - items: - type: integer - type: array - mode: - type: string - name: - type: string - updated_at: - type: string - updated_by: - type: integer - workspace_id: - type: integer - type: object - models.Label: - properties: - color: - type: string - created_at: - type: string - id: - type: integer - name: - type: string - updated_at: - type: string - type: object - models.LinkType: - properties: - active: - type: boolean - allowed_entity_types: - description: nil = all types allowed; e.g. ["item","test_case"] - items: - type: string - type: array - color: - type: string - created_at: - type: string - description: - type: string - forward_label: - type: string - id: - type: integer - is_system: - type: boolean - name: - type: string - reverse_label: - type: string - updated_at: - type: string - type: object - models.Milestone: - properties: - category_color: - type: string - category_id: - type: integer - category_name: - description: Joined fields for API responses - type: string - created_at: - type: string - description: - type: string - external_key: - description: Stable upsert key set by automation (e.g. tag short-name); - unique per workspace when set - type: string - id: - type: integer - is_global: - description: false=local to workspace, true=global (shared) - type: boolean - latest_release: - $ref: '#/components/schemas/models.MilestoneRelease' - name: - type: string - position: - description: Manual sort order (drag-and-drop), scoped per (is_global, workspace_id, - category_id) - type: integer - releases: - items: - $ref: '#/components/schemas/models.MilestoneRelease' - type: array - status: - description: planning, in-progress, completed, cancelled - type: string - target_date: - description: Date in YYYY-MM-DD format, nullable - type: string - updated_at: - type: string - workspace_id: - description: NULL if global, set if local to workspace - type: integer - workspace_name: - type: string - type: object - models.MilestoneRelease: - properties: - body: - type: string - created_at: - type: string - created_by: - type: integer - id: - type: integer - is_draft: - type: boolean - is_prerelease: - type: boolean - milestone_id: - type: integer - name: - type: string - scm_connection_id: - description: Visible only to users with connection workspace access - type: integer - scm_release_id: - type: string - scm_release_url: - type: string - scm_repository: - description: '"owner/repo"; same visibility as SCMConnectionID' - type: string - tag_name: - type: string - target_commitish: - type: string - type: object - models.PageLabel: - properties: - color: - type: string - created_at: - type: string - id: - type: integer - name: - type: string - updated_at: - type: string - workspace_id: - type: integer - type: object - models.PagePermission: - properties: - granted_at: - type: string - granted_by: - type: integer - id: - type: integer - page_id: - type: integer - permission_level: - type: string - principal_id: - type: integer - principal_type: - type: string - type: object - models.PersonalLabel: - properties: - color: - type: string - created_at: - type: string - id: - type: integer - name: - type: string - updated_at: - type: string - user_id: - description: NULL for global labels, user_id for user-specific labels - type: integer - type: object - models.RRulePreviewRequest: - properties: - count: - description: Number of occurrences to preview (default 10) - type: integer - dtstart: - type: string - rrule: - type: string - type: object - models.RecurrenceInstance: - properties: - created_at: - type: string - id: - type: integer - instance_item_id: - type: integer - item_status: - type: string - item_title: - type: string - recurrence_rule_id: - type: integer - scheduled_date: - type: string - sequence_number: - type: integer - type: object - models.RecurrenceRule: - properties: - copy_assignee: - type: boolean - copy_custom_fields: - type: boolean - copy_description: - type: boolean - copy_priority: - type: boolean - created_at: - type: string - created_by: - type: integer - creator_name: - type: string - dtend: - type: string - dtstart: - description: Recurrence start date - type: string - id: - type: integer - instance_count: - type: integer - is_active: - type: boolean - last_generated_until: - type: string - lead_time_days: - type: integer - next_generation_check: - type: string - next_occurrence: - type: string - rrule: - description: e.g., "FREQ=WEEKLY;BYDAY=MO,WE,FR" - type: string - status_on_create: - type: integer - template_item_id: - type: integer - template_title: - type: string - timezone: - description: IANA timezone - type: string - updated_at: - type: string - workspace_id: - type: integer - workspace_key: - type: string - workspace_name: - type: string - type: object - models.SkillPageReference: - properties: - id: - type: integer - title: - type: string - type: object - models.TestCase: - properties: - created_at: - type: string - estimated_duration: - description: in seconds - type: integer - folder_id: - type: integer - folder_name: - type: string - id: - type: integer - labels: - items: - $ref: '#/components/schemas/models.TestLabel' - type: array - name: - type: string - preconditions: - type: string - priority: - description: low, medium, high, critical - type: string - sort_order: - type: integer - status: - description: active, inactive, draft - type: string - test_steps: - items: - $ref: '#/components/schemas/models.TestStep' - type: array - title: - type: string - updated_at: - type: string - workspace_id: - type: integer - type: object - models.TestFolder: - properties: - created_at: - type: string - description: - type: string - id: - type: integer - name: - type: string - parent_id: - type: integer - sort_order: - type: integer - test_case_count: - type: integer - updated_at: - type: string - workspace_id: - type: integer - type: object - models.TestLabel: - properties: - color: - type: string - created_at: - type: string - description: - type: string - id: - type: integer - name: - type: string - updated_at: - type: string - workspace_id: - type: integer - type: object - models.TestRun: - properties: - assignee_avatar: - type: string - assignee_email: - type: string - assignee_id: - description: User assigned to execute this run - type: integer - assignee_name: - type: string - created_at: - type: string - ended_at: - type: string - id: - type: integer - name: - type: string - set_id: - type: integer - started_at: - type: string - template_id: - description: Optional reference to template - type: integer - workspace_id: - type: integer - type: object - models.TestRunTemplate: - properties: - created_at: - type: string - description: - type: string - id: - type: integer - name: - type: string - set_id: - type: integer - set_name: - type: string - updated_at: - type: string - workspace_id: - type: integer - type: object - models.TestSet: - properties: - created_at: - type: string - description: - type: string - failed_runs: - type: integer - id: - type: integer - last_run_date: - type: string - last_run_status: - type: string - milestone_id: - type: integer - milestone_name: - type: string - name: - type: string - successful_runs: - type: integer - test_case_count: - type: integer - total_runs: - type: integer - updated_at: - type: string - workspace_id: - type: integer - type: object - models.TestStep: - properties: - action: - type: string - created_at: - type: string - data: - type: string - expected: - type: string - id: - type: integer - step_number: - type: integer - test_case_id: - type: integer - updated_at: - type: string - type: object - models.UpdateRecurrenceRequest: - properties: - copy_assignee: - type: boolean - copy_custom_fields: - type: boolean - copy_description: - type: boolean - copy_priority: - type: boolean - dtend: - type: string - dtstart: - type: string - is_active: - type: boolean - lead_time_days: - type: integer - rrule: - type: string - status_on_create: - type: integer - timezone: - type: string - type: object - models.WorkspaceAgentSkill: - properties: - body: - type: string - created_at: - type: string - created_by_user_id: - description: CreatedByUserID is a soft audit ref; nil when the creator was - deleted. - type: integer - description: - type: string - enabled: - type: boolean - id: - type: integer - name: - type: string - pages: - description: |- - Pages are the workspace pages referenced by this skill (WI-517). On the - admin surface they round-trip so the editor can render the current - selection; on the agent-facing `ws skill get` surface their markdown is - inlined into Body instead. nil/omitted when the skill references none. - items: - $ref: '#/components/schemas/models.SkillPageReference' - type: array - updated_at: - type: string - workspace_id: - type: integer - type: object - services.PageDiagram: - properties: - attachment_id: - type: integer - content_hash: - type: string - created_at: - type: string - kind: - type: string - name: - type: string - page_id: - type: integer - payload: - type: object - revision_number: - type: integer - type: object - services.TestRunDetail: - properties: - results: - items: - $ref: '#/components/schemas/services.TestRunResultWithCaseTitle' - type: array - run: - $ref: '#/components/schemas/models.TestRun' - step_results: - additionalProperties: - $ref: '#/components/schemas/services.TestRunStepResult' - type: object - test_cases: - items: - $ref: '#/components/schemas/models.TestCase' - type: array - type: object - services.TestRunResultWithCaseTitle: - properties: - actual_result: - type: string - created_at: - type: string - executed_at: - type: string - id: - type: integer - notes: - type: string - run_id: - type: integer - status: - description: '"passed", "failed", "blocked", "skipped", "not_run"' - type: string - test_case_id: - type: integer - test_case_title: - type: string - updated_at: - type: string - type: object - services.TestRunStepResult: - properties: - actual_result: - type: string - executed_at: - type: string - item_id: - type: integer - notes: - type: string - status: - type: string - step_id: - type: integer - test_case_id: - type: integer - type: object - windshift_internal_restapi.ErrorResponse: - properties: - code: - description: Machine-readable error code - type: string - details: - description: Additional error details - error: - description: Human-readable message - type: string - request_id: - description: Request correlation ID - type: string - type: object - windshift_internal_restapi.PaginatedResponse: - properties: - data: {} - pagination: - $ref: '#/components/schemas/windshift_internal_restapi.PaginationMeta' - type: object - windshift_internal_restapi.PaginationMeta: - properties: - has_more: + internal_comments_enabled: type: boolean - limit: - type: integer - page: - type: integer - total: - type: integer - total_pages: - type: integer - type: object - windshift_internal_restapi_v1_dto.AssetCategoryResponse: - properties: - asset_count: - type: integer - children_count: - type: integer - created_at: - type: string - descendants_count: - type: integer - description: - type: string - has_children: + is_personal: type: boolean - id: - type: integer - name: + is_template: + type: boolean + key: type: string - parent_id: - type: integer - path: + name: type: string - set_id: - type: integer updated_at: type: string + warnings: + items: + type: string + type: array type: object - windshift_internal_restapi_v1_dto.AssetCategorySummary: + handlers.WorkspaceTemplateSummaryResponse: properties: - id: - type: integer - name: - type: string - path: + color: type: string - type: object - windshift_internal_restapi_v1_dto.AssetCreateRequest: - properties: - asset_tag: + configuration_set_name: type: string - asset_type_id: - type: integer - category_id: - type: integer - custom_field_values: - additionalProperties: {} - type: object description: type: string - status_id: - type: integer - title: - type: string - type: object - windshift_internal_restapi_v1_dto.AssetImportJobResponse: - properties: - asset_type_id: - type: integer - completed_at: - type: string - created_at: - type: string - created_rows: - type: integer - error_message: + icon: type: string - error_rows: - type: integer id: type: integer - processed_rows: - type: integer - set_id: + item_count: type: integer - started_at: - type: string - status: + name: type: string - total_rows: + template_count: type: integer type: object - windshift_internal_restapi_v1_dto.AssetLinks: + handlers.WorkspaceUpdateRequest: properties: - self: + active: + type: boolean + color: type: string - set: + description: type: string - type: object - windshift_internal_restapi_v1_dto.AssetResponse: - properties: - _links: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetLinks' - asset_tag: + icon: type: string - asset_type: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeSummary' - asset_type_id: - type: integer - category: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategorySummary' - category_id: - type: integer - created_at: + is_template: + type: boolean + name: type: string - created_by: - type: integer - creator: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' - custom_field_values: - additionalProperties: {} - type: object + type: object + handlers.actionDefinitionRequest: + properties: description: type: string - id: - type: integer - linked_item_count: - description: |- - LinkedItemCount is the number of item↔asset links for this asset - (0 when the underlying query didn't ask for the rollup). - type: integer - set: - allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetSummary' - description: |- - Nested summaries — populated from the row's joined columns when the - underlying query asks for them, otherwise omitted. - set_id: - type: integer - status: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusSummary' - status_id: - type: integer - title: - type: string - updated_at: + edges: + items: + $ref: '#/components/schemas/models.ActionEdge' + type: array + name: type: string - warnings: - description: |- - Warnings carries non-fatal anomalies surfaced by the query layer - (e.g. corrupt custom_field_values JSON). Always serialized as an - array (never null) so CLI consumers don't need to null-check. + nodes: items: - type: string + $ref: '#/components/schemas/models.ActionNode' type: array + trigger_config: + type: string + trigger_type: + $ref: '#/components/schemas/models.ActionTriggerType' type: object - windshift_internal_restapi_v1_dto.AssetSetLinks: + handlers.agentSkillListResponse: properties: - assets: - type: string - categories: - type: string - self: - type: string - statuses: - type: string - types: - type: string + items: + items: + $ref: '#/components/schemas/handlers.agentSkillSummary' + type: array type: object - windshift_internal_restapi_v1_dto.AssetSetResponse: + handlers.agentSkillSummary: properties: - _links: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetLinks' - asset_count: - type: integer - asset_type_count: - type: integer - created_at: - type: string - created_by: - type: integer description: type: string + enabled: + type: boolean id: type: integer - is_default: - type: boolean name: type: string - updated_at: - type: string - user_permission: - type: string type: object - windshift_internal_restapi_v1_dto.AssetSetSummary: + handlers.batchItemLinksResponse: + properties: + has_more_links: + type: boolean + incoming: + items: + $ref: '#/components/schemas/models.ItemLink' + type: array + item_id: + type: integer + next_after_link_id: + type: integer + outgoing: + items: + $ref: '#/components/schemas/models.ItemLink' + type: array + type: object + handlers.capabilityDTO: properties: + capability_type: + $ref: '#/components/schemas/models.CapabilityType' id: type: integer name: type: string type: object - windshift_internal_restapi_v1_dto.AssetStatusResponse: + handlers.catalogResponse: properties: - color: + capabilities: + items: + $ref: '#/components/schemas/handlers.capabilityDTO' + type: array + nodes: + items: + $ref: '#/components/schemas/handlers.nodeTypeDTO' + type: array + scope: type: string - created_at: + triggers: + items: + $ref: '#/components/schemas/handlers.triggerTypeDTO' + type: array + type: object + handlers.createWorklogRequest: + properties: + date: type: string description: type: string - display_order: + duration: + type: string + duration_minutes: type: integer - id: + end_time: + type: string + item_id: type: integer - is_default: - type: boolean - name: + item_key: type: string - set_id: + project_id: type: integer - updated_at: + start_time: + type: string + timezone: type: string type: object - windshift_internal_restapi_v1_dto.AssetStatusSummary: + handlers.diagramListResponse: + properties: + items: + items: + $ref: '#/components/schemas/models.ItemDiagram' + type: array + type: object + handlers.diagramWriteRequest: properties: - color: + diagram_data: type: string - id: - type: integer name: type: string type: object - windshift_internal_restapi_v1_dto.AssetTypeFieldResponse: + handlers.itemChangeResponse: properties: - custom_field_id: - type: integer - display_order: - type: integer - field_description: - type: string - field_name: - type: string - field_type: + change_type: type: string - id: + item_id: type: integer - is_required: - type: boolean - options: - type: string type: object - windshift_internal_restapi_v1_dto.AssetTypeResponse: + handlers.itemLabelAddRequest: properties: - asset_count: - type: integer - color: - type: string - created_at: - type: string - description: - type: string - display_order: + label_id: type: integer - fields: + type: object + handlers.itemLabelSetRequest: + properties: + label_ids: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeFieldResponse' + type: integer type: array - icon: + type: object + handlers.labelCreateRequest: + properties: + color: type: string - id: - type: integer - is_active: - type: boolean name: type: string - set_id: - type: integer - updated_at: - type: string type: object - windshift_internal_restapi_v1_dto.AssetTypeSummary: + handlers.labelListResponse: + properties: + items: + items: + $ref: '#/components/schemas/models.Label' + type: array + type: object + handlers.labelUpdateRequest: properties: color: type: string - icon: - type: string - id: - type: integer name: type: string type: object - windshift_internal_restapi_v1_dto.AssetUpdateRequest: + handlers.linkCreateRequest: properties: - asset_tag: + link_type_id: + type: integer + source_id: + type: integer + source_type: type: string - asset_type_id: + target_id: type: integer + target_type: + type: string + type: object + handlers.milestoneReorderRequest: + properties: category_id: type: integer - custom_field_values: - additionalProperties: {} + ordered_ids: + items: + type: integer + type: array + type: object + handlers.nodeTypeDTO: + properties: + category: + type: string + config_schema: type: object description: type: string - status_id: - type: integer - title: + is_iterator: + type: boolean + label: type: string + outputs: + items: + type: string + type: array + type: + $ref: '#/components/schemas/models.ActionNodeType' type: object - windshift_internal_restapi_v1_dto.AttachmentResponse: + handlers.pageCreateRequest: properties: - created_at: - type: string - download_url: - type: string - file_size: - type: integer - filename: + content: type: string - has_thumbnail: + is_home: type: boolean - id: - type: integer - item_id: + metadata: + additionalProperties: {} + type: object + parent_id: type: integer - mime_type: - type: string - original_filename: - type: string - thumbnail_url: + title: type: string - uploader: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' type: object - windshift_internal_restapi_v1_dto.CommentCreateRequest: + handlers.pageDiagramListResponse: properties: - content: - type: string - required: - - content + items: + items: + $ref: '#/components/schemas/services.PageDiagram' + type: array type: object - windshift_internal_restapi_v1_dto.CommentResponse: + handlers.pageGrantPermissionRequest: properties: - author: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' - content: - type: string - created_at: + permission_level: type: string - id: - type: integer - item_id: + principal_id: type: integer - updated_at: + principal_type: type: string - warnings: + type: object + handlers.pageHistoryListResponse: + properties: + items: items: - type: string + $ref: '#/components/schemas/dto.PageRevisionResponse' type: array type: object - windshift_internal_restapi_v1_dto.CommentUpdateRequest: + handlers.pageLabelAddRequest: properties: - content: - type: string - required: - - content + label_id: + type: integer type: object - windshift_internal_restapi_v1_dto.EnforcedTemplateSummary: + handlers.pageLabelCreateRequest: properties: - applied: - type: boolean + color: + type: string name: type: string - template_id: - type: integer type: object - windshift_internal_restapi_v1_dto.HistoryResponse: + handlers.pageLabelListResponse: properties: - changed_at: - type: string - field_name: - type: string - id: - type: integer - item_id: - type: integer - new_value: - type: string - old_value: - type: string - resolved_new_value: - type: string - resolved_old_value: - type: string - user: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' + items: + items: + $ref: '#/components/schemas/models.PageLabel' + type: array type: object - windshift_internal_restapi_v1_dto.ItemCreateRequest: + handlers.pageLabelSetRequest: properties: - assignee_id: - type: integer - custom_fields: - additionalProperties: {} - type: object - description: - type: string - due_date: + label_ids: + items: + type: integer + type: array + type: object + handlers.pageLabelUpdateRequest: + properties: + color: type: string - end_date: + name: type: string - is_task: - type: boolean - item_type_id: - type: integer - iteration_id: - type: integer - milestone_ids: + type: object + handlers.pageListResponse: + properties: + items: items: - type: integer + $ref: '#/components/schemas/dto.PageResponse' type: array - parent_id: + type: object + handlers.pageListWithLabelsResponse: + properties: + items: + items: + $ref: '#/components/schemas/models.PageLabel' + type: array + type: object + handlers.pageMoveRequest: + properties: + destination_workspace_id: type: integer - priority_id: + next_sibling_id: type: integer - project_id: + parent_id: type: integer - start_date: - type: string - status_id: - description: |- - Optional create-time placement. If omitted, the item uses the workflow initial status. - If provided, it must be the initial status or directly reachable from the initial status - without workflow conditions, validators, or approval gates. + prev_sibling_id: type: integer - title: - maxLength: 255 + type: object + handlers.pagePermissionsResponse: + properties: + acl: + items: + $ref: '#/components/schemas/models.PagePermission' + type: array + effective_level: type: string - workspace_id: + inherit_permissions: + type: boolean + page_id: type: integer - required: - - title - - workspace_id type: object - windshift_internal_restapi_v1_dto.ItemLinks: + handlers.pageSetInheritanceRequest: properties: - attachments: - type: string - children: - type: string - comments: - type: string - history: - type: string - parent: - type: string - self: + inherit_permissions: + type: boolean + type: object + handlers.pageUpdateRequest: + properties: + content: type: string - transitions: + expected_content_hash: type: string - workspace: + metadata: + additionalProperties: {} + type: object + title: type: string type: object - windshift_internal_restapi_v1_dto.ItemResponse: + handlers.recurrenceForceGenerateResponse: properties: - _links: - allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemLinks' - description: HATEOAS links - assignee: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' - attachments: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AttachmentResponse' - type: array - children: + instances_generated: + type: integer + type: object + handlers.recurrenceInstanceListResponse: + properties: + instances: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/models.RecurrenceInstance' type: array - comments: - description: Expanded collections (populated based on ?expand= parameter) + pagination: + $ref: '#/components/schemas/restapi.PaginationMeta' + type: object + handlers.rrulePreviewResponse: + properties: + dtstart: + type: string + occurrences: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse' + type: string type: array - completed_at: - type: string - created_at: - description: Timestamps + rrule: type: string - creator: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.UserSummary' - custom_fields: - additionalProperties: {} - type: object + type: object + handlers.startTimerRequest: + properties: description: type: string - due_date: - type: string - end_date: + item_id: + type: integer + project_id: + type: integer + workspace_id: + type: integer + type: object + handlers.templateCreateRequest: + properties: + description_body: type: string - enforced_template: - allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.EnforcedTemplateSummary' - description: |- - EnforcedTemplate echoes the mandatory work item template the item's type - enforces (WI-438), populated only on the create response so non-UI callers - learn the expected structure even when they supplied their own - description. Omitted when the type enforces no mandatory template. - history: + is_active: + type: boolean + item_type_ids: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.HistoryResponse' + type: integer type: array - id: - type: integer - is_task: - type: boolean - item_type: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemTypeSummary' - iteration: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.IterationSummary' - key: - description: e.g., "PROJ-123" + mode: type: string - milestones: + name: + type: string + type: object + handlers.templateListResponse: + properties: + items: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.MilestoneSummary' + $ref: '#/components/schemas/models.ItemTemplate' type: array - parent_id: + mandatory_template_id: description: |- - Hierarchy. ParentID is the raw DB id. ParentKey is the parent's - ready-to-display key (e.g. "WI-120"), computed server-side from the - parent's own workspace — clients must render this rather than building a - key from ParentID, which is a DB id in a different namespace and may even - point into another workspace. ParentKey and ParentTitle are populated - only on permission-checked single-item reads, and only when the caller - may view the parent (see ItemHandler.setParentSummary); they are omitted - from list responses and withheld across a workspace boundary the caller - cannot see. + MandatoryTemplateID is set when the request filtered by item_type_id and + that type has an active mandatory template, so callers (create modal, CLI) + can flag it without re-deriving the invariant. type: integer - parent_key: + type: object + handlers.templateUpdateRequest: + properties: + description_body: type: string - parent_title: + is_active: + type: boolean + item_type_ids: + items: + type: integer + type: array + mode: type: string - priority: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PrioritySummary' - project: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ProjectSummary' - start_date: + name: type: string - status: - allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary' - description: Related entities (populated based on ?expand= parameter) - title: + type: object + handlers.testResultUpdateRequest: + properties: + actual_result: type: string - transitions: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse' - type: array - updated_at: + notes: type: string - workspace: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.WorkspaceSummary' - workspace_id: - type: integer - workspace_item_number: - type: integer - workspace_key: + status: type: string type: object - windshift_internal_restapi_v1_dto.ItemTypeChangeRequest: + handlers.testRunCreateRequest: properties: - target_item_type_id: + assignee_id: type: integer - target_status_id: + name: + type: string + set_id: + type: integer + template_id: type: integer - required: - - target_item_type_id type: object - windshift_internal_restapi_v1_dto.ItemTypeSummary: + handlers.timeProjectResponse: properties: + category_color: + type: string + category_id: + type: integer + category_name: + type: string color: type: string - hierarchy_level: + customer_id: type: integer - icon: + customer_name: + type: string + description: type: string + hourly_rate: + type: number id: type: integer name: type: string + settings: + additionalProperties: {} + type: object + status: + type: string + total_hours: + type: number type: object - windshift_internal_restapi_v1_dto.ItemUpdateRequest: + handlers.triggerTypeDTO: properties: - assignee_id: - type: integer - custom_fields: - additionalProperties: {} + config_schema: type: object description: type: string - due_date: + label: type: string - end_date: + type: + $ref: '#/components/schemas/models.ActionTriggerType' + type: object + handlers.updateWorklogRequest: + properties: + description: type: string - is_task: - type: boolean - item_type_id: - type: integer - iteration_id: - type: integer - milestone_ids: + type: object + handlers.validateActionResponse: + properties: + errors: items: - type: integer + $ref: '#/components/schemas/actioncatalog.ValidationError' type: array - parent_id: - type: integer - priority_id: + type: object + handlers.worklogResponse: + properties: + created_at: type: integer - project_id: + customer_id: type: integer - start_date: - type: string - title: - maxLength: 255 + customer_name: type: string - type: object - windshift_internal_restapi_v1_dto.IterationSummary: - properties: - end_date: + date: + type: integer + description: type: string + duration_minutes: + type: integer + end_time: + type: integer id: type: integer - name: + item_id: + type: integer + item_title: type: string - start_date: + project_id: + type: integer + project_max_hours: + type: number + project_name: + type: string + project_total_hours: + type: number + start_time: + type: integer + updated_at: + type: integer + workspace_id: + type: integer + workspace_item_number: + type: integer + workspace_key: type: string + type: object + health.livenessResponse: + properties: status: type: string type: object - windshift_internal_restapi_v1_dto.MilestoneSummary: + health.readinessResponse: properties: - id: - type: integer - name: + database: type: string status: type: string - target_date: - type: string type: object - windshift_internal_restapi_v1_dto.PageLinks: + models.APIToken: properties: - history: + created_at: + type: string + expires_at: + type: string + id: + type: integer + is_temporary: + description: True for SSH session tokens + type: boolean + last_used_at: + type: string + name: + description: Human-readable name for the token type: string permissions: + description: JSON array of permissions type: string - self: + token_prefix: + description: First few characters for identification type: string - workspace: + updated_at: type: string - type: object - windshift_internal_restapi_v1_dto.PageResponse: - properties: - _links: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageLinks' - archived_at: + user_email: + description: Joined fields type: string - archived_by: + user_id: type: integer - content: + user_name: type: string - content_hash: + type: object + models.Action: + properties: + actor_name: type: string + actor_user_id: + description: |- + ActorUserID overrides the execution actor. NULL means the action runs under + the triggering user's permissions. Setting this field requires the global + action.set_actor permission because it grants cross-workspace impersonation. + type: integer + allowed_role_ids: + description: |- + AllowedRoleIDs restricts a manual action to members of these workspace + roles. An empty list means every workspace editor may trigger it. + items: + type: integer + type: array created_at: type: string created_by: type: integer - depth: - type: integer - excerpt: + creator_name: + description: Joined fields for API responses + type: string + description: type: string + edges: + items: + $ref: '#/components/schemas/models.ActionEdge' + type: array id: type: integer - inherit_permissions: - type: boolean - is_home: + is_enabled: type: boolean - labels: - description: |- - Labels carries the workspace page-labels currently attached to the - page. Populated by the service layer when the page-label repository - is wired; always serialized as an array (never null) so CLI/JSON - consumers don't need to null-check. + name: + type: string + nodes: items: - $ref: '#/components/schemas/models.PageLabel' + $ref: '#/components/schemas/models.ActionNode' type: array - metadata: - additionalProperties: {} - type: object - parent_id: - type: integer - path: - type: string - slug: - type: string - title: + trigger_config: + description: JSON with trigger-specific conditions type: string + trigger_type: + $ref: '#/components/schemas/models.ActionTriggerType' updated_at: type: string - updated_by: - type: integer workspace_id: type: integer type: object - windshift_internal_restapi_v1_dto.PageRevisionResponse: + models.ActionEdge: properties: - change_summary: - type: string - change_type: - type: string - content: - type: string + action_id: + type: integer created_at: type: string - created_by: - type: integer - depth: - type: integer - excerpt: + edge_type: + description: default, true, false (for conditions) type: string id: type: integer - page_id: - type: integer - parent_id: - type: integer - path: + source_handle: type: string - revision_number: + source_node_id: type: integer - slug: - type: string - title: + target_handle: type: string + target_node_id: + type: integer type: object - windshift_internal_restapi_v1_dto.PrioritySummary: + models.ActionNode: properties: - color: - type: string - icon: + action_id: + type: integer + created_at: type: string id: type: integer - name: + node_config: + description: JSON configuration for the node + type: string + node_type: + $ref: '#/components/schemas/models.ActionNodeType' + position_x: + type: number + position_y: + type: number + updated_at: type: string type: object - windshift_internal_restapi_v1_dto.ProjectSummary: + models.ActionNodeType: + enum: + - trigger + - set_field + - set_status + - add_comment + - notify_user + - condition + - update_asset + - create_asset + - round_robin_assign + - ai_extract + - ai_agent + - container_run + - http_request + - transition_item + - related_items + - create_milestone + type: string + x-enum-varnames: + - ActionNodeTrigger + - ActionNodeSetField + - ActionNodeSetStatus + - ActionNodeAddComment + - ActionNodeNotifyUser + - ActionNodeCondition + - ActionNodeUpdateAsset + - ActionNodeCreateAsset + - ActionNodeRoundRobinAssign + - ActionNodeAIExtract + - ActionNodeAIAgent + - ActionNodeContainerRun + - ActionNodeHTTPRequest + - ActionNodeTransitionItem + - ActionNodeRelatedItems + - ActionNodeCreateMilestone + models.ActionTriggerType: + enum: + - status_transition + - item_created + - item_updated + - item_linked + - manual + - scm_tag_created + - scm_release_branch_created + - scm_pr_linked + - scm_pr_merged + type: string + x-enum-varnames: + - ActionTriggerStatusTransition + - ActionTriggerItemCreated + - ActionTriggerItemUpdated + - ActionTriggerItemLinked + - ActionTriggerManual + - ActionTriggerSCMTagCreated + - ActionTriggerSCMReleaseBranchCreated + - ActionTriggerSCMPRLinked + - ActionTriggerSCMPRMerged + models.ActiveTimer: properties: - id: + created_at: + description: Unix timestamp type: integer - name: + customer_name: type: string - type: object - windshift_internal_restapi_v1_dto.StatusSummary: - properties: - category_color: + description: type: string - category_id: + id: type: integer - category_name: + item_id: + description: Optional link to work item + type: integer + item_title: type: string - id: + project_id: type: integer - is_completed: - type: boolean - name: + project_name: type: string - type: object - windshift_internal_restapi_v1_dto.TransitionRequest: - properties: - to_status_id: + start_time_utc: + description: Unix timestamp in UTC type: integer - required: - - to_status_id + user_id: + type: integer + workspace_id: + type: integer + workspace_item_number: + type: integer + workspace_key: + type: string + workspace_name: + type: string type: object - windshift_internal_restapi_v1_dto.TransitionResponse: + models.Attachment: properties: - from_status: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary' - from_status_id: + created_at: + type: string + file_size: type: integer + filename: + description: Stored filename (UUID-based) + type: string + has_thumbnail: + description: Whether thumbnail was generated + type: boolean id: type: integer - to_status: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary' - to_status_id: + item_id: + type: integer + mime_type: + type: string + original_filename: + description: Original user filename + type: string + uploaded_by: type: integer + uploader_email: + type: string + uploader_name: + description: Joined fields for API responses + type: string type: object - windshift_internal_restapi_v1_dto.TransitionResultResponse: + models.AttachmentUploadResponse: properties: - item: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' - new_status_id: - type: integer - no_op: + attachment: + $ref: '#/components/schemas/models.Attachment' + message: + type: string + success: type: boolean - old_status_id: - type: integer type: object - windshift_internal_restapi_v1_dto.UserSummary: + models.CalendarScheduleEntry: properties: - avatar_url: + created_at: type: string - email: + duration_minutes: + description: Duration in minutes, optional + type: integer + notes: type: string - first_name: + scheduled_date: + description: YYYY-MM-DD format type: string - full_name: + scheduled_time: + description: HH:MM format, optional type: string - id: + user_id: + type: integer + workspace_id: + description: User's personal workspace ID type: integer - last_name: - type: string - username: - type: string type: object - windshift_internal_restapi_v1_dto.WorkspaceSummary: + models.CapabilityType: + enum: + - docker_environment + - http_client + - llm_connection + - runner_pool + type: string + x-enum-varnames: + - CapabilityDockerEnvironment + - CapabilityHTTPClient + - CapabilityLLMConnection + - CapabilityRunnerPool + models.CreateRecurrenceRequest: properties: - id: - type: integer - key: + copy_assignee: + type: boolean + copy_custom_fields: + type: boolean + copy_description: + type: boolean + copy_priority: + type: boolean + dtend: type: string - name: + dtstart: + description: ISO 8601 format type: string - type: object - windshift_internal_restapi_v1_handlers.AdminGroupCreateRequest: - properties: - description: + lead_time_days: + type: integer + rrule: type: string - name: + status_on_create: + type: integer + template_item_id: + type: integer + timezone: type: string type: object - windshift_internal_restapi_v1_handlers.AdminGroupResponse: + models.Item: properties: - created_at: + assignee_avatar: + description: Avatar URL of assigned user type: string - description: + assignee_email: + description: Email of assigned user type: string - id: + assignee_id: + description: User assignment fields type: integer - member_count: + assignee_name: + description: User information for API responses + type: string + calendar_data: + items: + $ref: '#/components/schemas/models.CalendarScheduleEntry' + type: array + channel_id: + description: Portal submission tracking fields (immutable once set) type: integer - name: + channel_name: + description: Portal submission tracking joined fields type: string - warnings: + children: + description: For tree representations items: - type: string + $ref: '#/components/schemas/models.Item' type: array - type: object - windshift_internal_restapi_v1_handlers.AdminGroupUpdateRequest: - properties: - description: + completed_at: type: string - name: + created_at: type: string - type: object - windshift_internal_restapi_v1_handlers.AdminUserResponse: - properties: - avatar_url: + creator_email: + description: Email of creator (internal user or portal customer) type: string - created_at: + creator_id: + description: Internal user who created this item + type: integer + creator_name: + description: Full name of creator (internal user or portal customer) type: string - email: + creator_portal_customer_email: + description: Email of portal customer creator type: string - first_name: + creator_portal_customer_id: + description: Portal customer who created this item (for portal submissions) + type: integer + creator_portal_customer_name: + description: Name of portal customer creator type: string - full_name: + custom_field_values: + additionalProperties: {} + type: object + description: + type: string + description_html: + type: string + due_date: + description: Due date for item completion + type: string + effective_project_id: + description: |- + EffectiveProjectID is the resolved project after walking InheritProject + up the parent chain. Consumers that need "which time-tracking project + applies to this item" should read this, not ProjectID directly. + type: integer + effective_project_name: + type: string + end_date: + description: End date for item + type: string + estimate_minutes: + description: Time estimate in minutes (compared against logged worklog time) + type: integer + frac_index: + description: Manual sorting field type: string - group_ids: - items: - type: integer - type: array id: type: integer - is_active: + inherit_project: + description: If true, ProjectID is ignored and the parent item's effective + project is used type: boolean - language: + is_task: + description: Flag to mark this item as a task (checklist item) + type: boolean + item_type_builtin_key: type: string - last_name: + item_type_id: + description: Optional, defaults to workspace's default item type + type: integer + item_type_name: type: string - timezone: + iteration_end_date: type: string - username: + iteration_id: + description: Optional iteration assignment + type: integer + iteration_name: type: string - warnings: + labels: + description: Global item labels items: - type: string + $ref: '#/components/schemas/models.Label' type: array - type: object - windshift_internal_restapi_v1_handlers.AdminUserUpdateRequest: - properties: - email: + last_active_at: + description: |- + Recency for the board "Bubble Mode" sort. Bumped on activity (comments, + edits, transitions) but not on manual frac_index reorder. type: string - first_name: + milestones: + items: + $ref: '#/components/schemas/models.Milestone' + type: array + parent_id: + description: Hierarchy fields + type: integer + parent_title: type: string - is_active: - type: boolean - last_name: + parent_workspace_item_number: + description: Parent's workspace-scoped number, for rendering the parent + key + type: integer + personal_labels: + items: + $ref: '#/components/schemas/models.PersonalLabel' + type: array + priority_builtin_key: type: string - type: object - windshift_internal_restapi_v1_handlers.AgentRunResponse: - properties: - ended_at: + priority_color: type: string - error: + priority_icon: type: string - id: - type: integer - item_id: + priority_id: + description: Foreign key to priorities table type: integer - job_kind: - type: string - queued_at: + priority_name: type: string - started_at: + project_id: + description: |- + Time-tracking project membership. "Project" in Windshift always refers + to a row in time_projects; both ProjectID and TimeProjectID below are + FKs to that table, serving different roles: + ProjectID - the project this item belongs to (the bucket + worklogs default to). Can be inherited from the + parent item; see InheritProject. + TimeProjectID - overrides the project used when logging time on + this specific item (independent of the bucket the + item belongs to). + EffectiveProjectID (below) is the resolved value after applying + inheritance, and is what consumers should read. + type: integer + project_inheritance_mode: + description: '"none" | "inherit" | "direct"' type: string - status: + project_name: + description: Name of the time-tracking project this item belongs to (joined + from time_projects via ProjectID) type: string - workspace_id: + related_work_item_id: + description: Personal task relationship (for linking personal workspace + tasks to work items) type: integer - type: object - windshift_internal_restapi_v1_handlers.AuditLogEntryResponse: - properties: - action_type: - type: string - details: - additionalProperties: {} - type: object - error_message: + related_work_item_number: + type: integer + related_work_item_title: + description: Related work item joined fields (for personal tasks) type: string - id: + related_work_item_workspace_id: type: integer - ip_address: + related_work_item_workspace_key: type: string - resource_id: + reporter_avatar: + description: Avatar URL of reporter + type: string + reporter_email: + description: Email of reporter + type: string + reporter_id: + description: User who reported this item (from Jira import) type: integer - resource_name: + reporter_name: + description: Full name of reporter type: string - resource_type: + request_type_id: + description: Request type used for submission + type: integer + request_type_name: + description: Name of the request type type: string - success: - type: boolean - timestamp: + start_date: + description: Start date for item type: string - user_agent: + status_builtin_key: + description: Stable key for translating built-in statuses type: string - user_id: - type: integer - username: + status_color: + description: Color from the status category (joined field) type: string - type: object - windshift_internal_restapi_v1_handlers.AuditLogStreamResponse: - properties: - entries: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.AuditLogEntryResponse' - type: array - has_more: - type: boolean - next_after_id: - type: integer - type: object - windshift_internal_restapi_v1_handlers.CollectionListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionResponse' - type: array - total: + status_id: + description: Foreign key to statuses table type: integer - type: object - windshift_internal_restapi_v1_handlers.CollectionResponse: - properties: - created_at: + status_name: + description: Name from statuses table (joined field) type: string - description: + status_since: + description: |- + StatusSince is when the item last entered its current status, derived from + item_history (falls back to created_at when there is no recorded change). type: string - id: + story_points: + description: Estimation + type: number + time_project_id: type: integer - name: + time_project_name: + description: Name of the time-tracking project overriding worklog defaults + (joined from time_projects via TimeProjectID) type: string - slug: + title: type: string updated_at: type: string + virtual_field_data: + additionalProperties: {} + type: object workspace_id: type: integer + workspace_item_number: + description: Workspace-specific sequential number for display keys + type: integer + workspace_key: + type: string + workspace_name: + description: Joined fields for API responses + type: string type: object - windshift_internal_restapi_v1_handlers.CustomFieldResponse: + models.ItemDiagram: properties: - description: + created_at: type: string - display_order: + created_by: type: integer - field_type: + creator_email: + type: string + creator_name: + description: Joined fields for API responses + type: string + diagram_data: + description: JSON with elements, appState, files type: string id: type: integer + item_id: + type: integer name: type: string - options: - description: JSON string - type: string - required: - type: boolean - type: object - windshift_internal_restapi_v1_handlers.ErrorResponse: - properties: - code: - description: Machine-readable error code + updated_at: type: string - details: - description: Additional error details - error: - description: Human-readable message + updated_by: + type: integer + updated_by_email: type: string - request_id: - description: Request correlation ID + updated_by_name: type: string type: object - windshift_internal_restapi_v1_handlers.ItemTypeResponse: + models.ItemLink: properties: - color: - type: string - description: + created_at: type: string - hierarchy_level: + created_by: type: integer - icon: + created_by_name: type: string - id: + custom_field_id: type: integer - is_default: - type: boolean - name: + custom_field_name: + description: Custom field link metadata type: string - sort_order: + id: type: integer - type: object - windshift_internal_restapi_v1_handlers.IterationCreateRequest: - properties: - description: - type: string - end_date: + link_type_color: type: string - is_global: - type: boolean - name: + link_type_forward_label: type: string - start_date: + link_type_id: + type: integer + link_type_name: + description: Joined fields for API responses type: string - status: + link_type_reverse_label: type: string - type_id: + source_id: type: integer - workspace_id: + source_item_number: + description: |- + SourceItemNumber is the workspace-scoped item number (the "74" in + "WI-74"). Display the user-facing key as + SourceWorkspaceKey + "-" + SourceItemNumber, never SourceID — that + field is the global DB id and looks wrong (e.g. "WI-149") in UI. type: integer - required: - - end_date - - name - - start_date - type: object - windshift_internal_restapi_v1_handlers.IterationResponse: - properties: - created_at: + source_item_type_color: type: string - description: + source_item_type_icon: type: string - end_date: + source_item_type_id: + type: integer + source_item_type_name: type: string - id: + source_status_color: + type: string + source_status_id: + description: Source item details type: integer - is_global: - type: boolean - name: + source_status_name: type: string - start_date: + source_title: type: string - status: + source_type: + description: '"item" or "test_case"' type: string - type_color: + source_workspace_id: + type: integer + source_workspace_key: type: string - type_id: + target_id: type: integer - type_name: + target_item_number: + description: 'TargetItemNumber: see SourceItemNumber.' + type: integer + target_item_type_color: type: string - updated_at: + target_item_type_icon: type: string - warnings: - items: - type: string - type: array - workspace_id: + target_item_type_id: type: integer - type: object - windshift_internal_restapi_v1_handlers.IterationUpdateRequest: - properties: - description: + target_item_type_name: type: string - end_date: + target_status_color: type: string - name: + target_status_id: + description: Target item details + type: integer + target_status_name: type: string - start_date: + target_title: type: string - status: + target_type: + description: '"item" or "test_case"' type: string - type_id: - nullable: true + target_workspace_id: type: integer + target_workspace_key: + type: string type: object - windshift_internal_restapi_v1_handlers.MilestoneCreateRequest: + models.ItemTemplate: properties: - category_id: + created_at: + type: string + created_by: type: integer - description: + description_body: type: string - name: + id: + type: integer + is_active: + type: boolean + item_type_ids: + items: + type: integer + type: array + mode: type: string - status: + name: type: string - target_date: + updated_at: type: string - required: - - name + updated_by: + type: integer + workspace_id: + type: integer type: object - windshift_internal_restapi_v1_handlers.MilestoneProgressItemResponse: + models.Label: properties: - assignee_avatar: + color: type: string - assignee_name: + created_at: type: string id: type: integer - item_number: - type: integer - priority_color: - type: string - priority_name: - type: string - status_color: - type: string - status_name: - type: string - title: + name: type: string - workspace_id: - type: integer - workspace_key: + updated_at: type: string type: object - windshift_internal_restapi_v1_handlers.MilestoneProgressResponse: + models.LinkType: properties: - category_color: + active: + type: boolean + allowed_entity_types: + description: nil = all types allowed; e.g. ["item","test_case"] + items: + type: string + type: array + builtin_key: + type: string + color: + type: string + created_at: type: string - completed_items: - type: integer description: type: string - items_by_category: - additionalProperties: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.MilestoneProgressItemResponse' - type: array - type: object - milestone_id: + forward_label: + type: string + id: type: integer - milestone_name: + is_system: + type: boolean + name: type: string - percent_complete: - type: number - status: + reverse_label: type: string - status_breakdown: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse' - type: array - target_date: + updated_at: type: string - total_items: - type: integer type: object - windshift_internal_restapi_v1_handlers.MilestoneResponse: + models.Milestone: properties: category_color: type: string category_id: type: integer category_name: + description: Joined fields for API responses type: string created_at: type: string description: type: string + external_key: + description: Stable upsert key set by automation (e.g. tag short-name); + unique per workspace when set + type: string id: type: integer is_global: + description: false=local to workspace, true=global (shared) type: boolean + latest_release: + $ref: '#/components/schemas/models.MilestoneRelease' name: type: string position: + description: Manual sort order (drag-and-drop), scoped per (is_global, workspace_id, + category_id) type: integer + releases: + items: + $ref: '#/components/schemas/models.MilestoneRelease' + type: array status: + description: planning, in-progress, completed, cancelled type: string target_date: + description: Date in YYYY-MM-DD format, nullable type: string updated_at: type: string - warnings: - items: - type: string - type: array workspace_id: + description: NULL if global, set if local to workspace type: integer + workspace_name: + type: string type: object - windshift_internal_restapi_v1_handlers.MilestoneStatusBreakdownResponse: + models.MilestoneRelease: properties: - category_color: + assets: + items: + $ref: '#/components/schemas/models.SCMReleaseAsset' + type: array + body: type: string - category_name: + created_at: type: string - is_completed: - type: boolean - item_count: + created_by: type: integer - type: object - windshift_internal_restapi_v1_handlers.MilestoneUpdateRequest: - properties: - category_id: - nullable: true + id: type: integer - description: + is_draft: + type: boolean + is_prerelease: + type: boolean + last_synced_at: type: string + milestone_id: + type: integer name: type: string - status: + release_status: type: string - target_date: - nullable: true + released_at: type: string - type: object - windshift_internal_restapi_v1_handlers.PaginatedResponse: - properties: - data: {} - pagination: - $ref: '#/components/schemas/windshift_internal_restapi.PaginationMeta' - type: object - windshift_internal_restapi_v1_handlers.PriorityResponse: - properties: - color: + scm_connection_id: + description: Visible only to users with connection workspace access + type: integer + scm_release_id: type: string - description: + scm_release_url: type: string - icon: + scm_repository: + description: '"owner/repo"; same visibility as SCMConnectionID' type: string - id: - type: integer - is_default: - type: boolean - name: + tag_name: type: string - sort_order: + tag_url: + type: string + target_commitish: + type: string + workspace_repository_id: type: integer type: object - windshift_internal_restapi_v1_handlers.StatusCategoryResponse: + models.PageLabel: properties: color: type: string - description: + created_at: type: string id: type: integer - is_completed: - type: boolean - is_default: - type: boolean name: type: string + updated_at: + type: string + workspace_id: + type: integer type: object - windshift_internal_restapi_v1_handlers.StatusResponse: + models.PagePermission: properties: - category_color: + granted_at: type: string - category_id: + granted_by: type: integer - category_name: - type: string - description: - type: string id: type: integer - is_completed: - type: boolean - is_default: - type: boolean - name: + page_id: + type: integer + permission_level: type: string - type: object - windshift_internal_restapi_v1_handlers.TUIPreferencesResponse: - properties: - last_workspace_id: + principal_id: type: integer - split_ratio: - type: number - theme: + principal_type: type: string type: object - windshift_internal_restapi_v1_handlers.UserResponse: + models.PersonalLabel: properties: - avatar_url: + color: type: string created_at: type: string - email: - type: string - first_name: - type: string - full_name: - type: string id: type: integer - is_active: - type: boolean - is_agent: - type: boolean - language: - type: string - last_name: - type: string - timezone: + name: type: string - username: + updated_at: type: string - warnings: - items: - type: string - type: array + user_id: + description: NULL for global labels, user_id for user-specific labels + type: integer type: object - windshift_internal_restapi_v1_handlers.WorkflowResponse: + models.RRulePreviewRequest: properties: - created_at: - type: string - description: - type: string - id: + count: + description: Number of occurrences to preview (default 10) type: integer - is_default: - type: boolean - name: + dtstart: type: string - transitions: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse' - type: array - updated_at: + rrule: type: string type: object - windshift_internal_restapi_v1_handlers.WorkspaceCreateRequest: + models.RecurrenceInstance: properties: - color: - type: string - description: + created_at: type: string - icon: + id: + type: integer + instance_item_id: + type: integer + item_status: type: string - key: - maxLength: 10 - minLength: 2 + item_title: type: string - name: - maxLength: 100 + recurrence_rule_id: + type: integer + scheduled_date: type: string - template_workspace_id: + sequence_number: type: integer - required: - - key - - name type: object - windshift_internal_restapi_v1_handlers.WorkspaceResponse: + models.RecurrenceRule: properties: - active: + copy_assignee: + type: boolean + copy_custom_fields: + type: boolean + copy_description: + type: boolean + copy_priority: type: boolean - color: - type: string created_at: type: string - description: + created_by: + type: integer + creator_name: type: string - icon: + dtend: + type: string + dtstart: + description: Recurrence start date type: string id: type: integer - internal_comments_enabled: - type: boolean - is_personal: - type: boolean - is_template: + instance_count: + type: integer + is_active: type: boolean - key: + last_generated_until: type: string - name: + lead_time_days: + type: integer + next_generation_check: type: string - updated_at: + next_occurrence: type: string - warnings: - items: - type: string - type: array - type: object - windshift_internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse: - properties: - color: + rrule: + description: e.g., "FREQ=WEEKLY;BYDAY=MO,WE,FR" type: string - configuration_set_name: + status_on_create: + type: integer + template_item_id: + type: integer + template_title: type: string - description: + timezone: + description: IANA timezone type: string - icon: + updated_at: type: string - id: - type: integer - item_count: + workspace_id: type: integer - name: + workspace_key: + type: string + workspace_name: type: string - template_count: - type: integer type: object - windshift_internal_restapi_v1_handlers.WorkspaceUpdateRequest: + models.SCMReleaseAsset: properties: - active: - type: boolean - color: - type: string - description: + direct_url: type: string - icon: + format: type: string - is_template: - type: boolean - name: + kind: type: string - type: object - windshift_internal_restapi_v1_handlers.actionDefinitionRequest: - properties: - description: + link_type: type: string - edges: - items: - $ref: '#/components/schemas/models.ActionEdge' - type: array name: type: string - nodes: - items: - $ref: '#/components/schemas/models.ActionNode' - type: array - trigger_config: + url: type: string - trigger_type: - $ref: '#/components/schemas/models.ActionTriggerType' - type: object - windshift_internal_restapi_v1_handlers.agentSkillListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.agentSkillSummary' - type: array type: object - windshift_internal_restapi_v1_handlers.agentSkillSummary: + models.SkillActivationUsage: properties: - description: - type: string - enabled: - type: boolean - id: + bytes: + type: integer + estimated_tokens: + type: integer + max_bytes: + type: integer + max_tokens: + type: integer + page_prefix_bytes: + type: integer + page_prefix_runes: type: integer - name: - type: string type: object - windshift_internal_restapi_v1_handlers.capabilityDTO: + models.SkillPageReference: properties: - capability_type: - $ref: '#/components/schemas/models.CapabilityType' + activation_bytes: + type: integer + activation_runes: + type: integer id: type: integer - name: + page_updated_at: type: string - type: object - windshift_internal_restapi_v1_handlers.catalogResponse: - properties: - capabilities: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.capabilityDTO' - type: array - nodes: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.nodeTypeDTO' - type: array - scope: + snapshot_at: type: string - triggers: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.triggerTypeDTO' - type: array - type: object - windshift_internal_restapi_v1_handlers.createWorklogRequest: - properties: - date: + snapshot_title: type: string - description: + stale: + type: boolean + title: type: string - duration: + type: object + models.TestCase: + properties: + created_at: type: string - duration_minutes: + estimated_duration: + description: in seconds type: integer - end_time: - type: string - item_id: + folder_id: type: integer - item_key: + folder_name: type: string - project_id: + id: type: integer - start_time: - type: string - timezone: - type: string - type: object - windshift_internal_restapi_v1_handlers.diagramListResponse: - properties: - items: + labels: items: - $ref: '#/components/schemas/models.ItemDiagram' + $ref: '#/components/schemas/models.TestLabel' type: array - type: object - windshift_internal_restapi_v1_handlers.diagramWriteRequest: - properties: - diagram_data: - type: string name: type: string - type: object - windshift_internal_restapi_v1_handlers.itemChangeResponse: - properties: - change_type: + preconditions: type: string - item_id: + priority: + description: low, medium, high, critical + type: string + sort_order: type: integer - type: object - windshift_internal_restapi_v1_handlers.itemChangesResponse: - properties: - changes: + status: + description: active, inactive, draft + type: string + test_steps: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.itemChangeResponse' + $ref: '#/components/schemas/models.TestStep' type: array - has_more: - type: boolean - next_cursor: + title: type: string - reset_required: - type: boolean - watermark: + updated_at: type: string - type: object - windshift_internal_restapi_v1_handlers.itemLabelAddRequest: - properties: - label_id: + workspace_id: type: integer type: object - windshift_internal_restapi_v1_handlers.itemLabelSetRequest: - properties: - label_ids: - items: - type: integer - type: array - type: object - windshift_internal_restapi_v1_handlers.labelCreateRequest: + models.TestFolder: properties: - color: - type: string - name: + created_at: type: string - type: object - windshift_internal_restapi_v1_handlers.labelListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.Label' - type: array - type: object - windshift_internal_restapi_v1_handlers.labelUpdateRequest: - properties: - color: + description: type: string + id: + type: integer name: type: string - type: object - windshift_internal_restapi_v1_handlers.linkCreateRequest: - properties: - link_type_id: + parent_id: type: integer - source_id: + sort_order: type: integer - source_type: - type: string - target_id: + test_case_count: type: integer - target_type: + updated_at: type: string - type: object - windshift_internal_restapi_v1_handlers.milestoneReorderRequest: - properties: - category_id: + workspace_id: type: integer - ordered_ids: - items: - type: integer - type: array type: object - windshift_internal_restapi_v1_handlers.nodeTypeDTO: + models.TestLabel: properties: - category: + color: + type: string + created_at: type: string - config_schema: - type: object description: type: string - is_iterator: - type: boolean - label: + id: + type: integer + name: type: string - outputs: - items: - type: string - type: array - type: - $ref: '#/components/schemas/models.ActionNodeType' + updated_at: + type: string + workspace_id: + type: integer type: object - windshift_internal_restapi_v1_handlers.pageCreateRequest: + models.TestRun: properties: - content: - type: string - is_home: - type: boolean - metadata: - additionalProperties: {} - type: object - parent_id: + assignee_avatar: + type: string + assignee_email: + type: string + assignee_id: + description: User assigned to execute this run type: integer - title: + assignee_name: type: string - type: object - windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest: - properties: - excalidraw: - type: object - expected_content_hash: + created_at: type: string - mermaid: + ended_at: type: string + id: + type: integer name: type: string - placement: + set_id: + type: integer + started_at: type: string + template_id: + description: Optional reference to template + type: integer + workspace_id: + type: integer type: object - windshift_internal_restapi_v1_handlers.pageDiagramListResponse: - properties: - items: - items: - $ref: '#/components/schemas/services.PageDiagram' - type: array - type: object - windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest: + models.TestRunTemplate: properties: - excalidraw: - type: object - expected_content_hash: + created_at: type: string - mermaid: + description: type: string + id: + type: integer name: type: string - type: object - windshift_internal_restapi_v1_handlers.pageGrantPermissionRequest: - properties: - permission_level: - type: string - principal_id: + set_id: type: integer - principal_type: + set_name: type: string - type: object - windshift_internal_restapi_v1_handlers.pageHistoryListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse' - type: array - type: object - windshift_internal_restapi_v1_handlers.pageLabelAddRequest: - properties: - label_id: + updated_at: + type: string + workspace_id: type: integer type: object - windshift_internal_restapi_v1_handlers.pageLabelCreateRequest: + models.TestSet: properties: - color: + created_at: type: string - name: + description: type: string - type: object - windshift_internal_restapi_v1_handlers.pageLabelListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.PageLabel' - type: array - type: object - windshift_internal_restapi_v1_handlers.pageLabelSetRequest: - properties: - label_ids: - items: - type: integer - type: array - type: object - windshift_internal_restapi_v1_handlers.pageLabelUpdateRequest: - properties: - color: + failed_runs: + type: integer + id: + type: integer + last_run_date: + type: string + last_run_status: + type: string + milestone_id: + type: integer + milestone_name: type: string name: type: string - type: object - windshift_internal_restapi_v1_handlers.pageListResponse: - properties: - items: - items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' - type: array - type: object - windshift_internal_restapi_v1_handlers.pageListWithLabelsResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.PageLabel' - type: array - type: object - windshift_internal_restapi_v1_handlers.pageMoveRequest: - properties: - destination_workspace_id: + successful_runs: type: integer - next_sibling_id: + test_case_count: type: integer - parent_id: + total_runs: type: integer - prev_sibling_id: + updated_at: + type: string + workspace_id: type: integer type: object - windshift_internal_restapi_v1_handlers.pagePermissionsResponse: + models.TestStep: properties: - acl: - items: - $ref: '#/components/schemas/models.PagePermission' - type: array - effective_level: + action: type: string - inherit_permissions: - type: boolean - page_id: + created_at: + type: string + data: + type: string + expected: + type: string + id: + type: integer + step_number: + type: integer + test_case_id: type: integer + updated_at: + type: string type: object - windshift_internal_restapi_v1_handlers.pageSetInheritanceRequest: + models.UpdateRecurrenceRequest: properties: - inherit_permissions: + copy_assignee: type: boolean - type: object - windshift_internal_restapi_v1_handlers.pageUpdateRequest: - properties: - content: + copy_custom_fields: + type: boolean + copy_description: + type: boolean + copy_priority: + type: boolean + dtend: type: string - expected_content_hash: + dtstart: type: string - metadata: - additionalProperties: {} - type: object - title: + is_active: + type: boolean + lead_time_days: + type: integer + rrule: type: string - type: object - windshift_internal_restapi_v1_handlers.recurrenceForceGenerateResponse: - properties: - instances_generated: + status_on_create: type: integer + timezone: + type: string type: object - windshift_internal_restapi_v1_handlers.recurrenceInstanceListResponse: + models.WorkspaceAgentSkill: properties: - instances: + body: + type: string + created_at: + type: string + created_by_user_id: + description: CreatedByUserID is a soft audit ref; nil when the creator was + deleted. + type: integer + description: + type: string + enabled: + type: boolean + id: + type: integer + name: + type: string + pages: + description: |- + Pages are the workspace pages referenced by this skill (WI-517). On the + admin surface they round-trip with snapshot review state; the exact saved + content is rendered into a run grant. nil/omitted when there are none. items: - $ref: '#/components/schemas/models.RecurrenceInstance' + $ref: '#/components/schemas/models.SkillPageReference' type: array - pagination: - $ref: '#/components/schemas/windshift_internal_restapi.PaginationMeta' + updated_at: + type: string + usage: + $ref: '#/components/schemas/models.SkillActivationUsage' + workspace_id: + type: integer type: object - windshift_internal_restapi_v1_handlers.rrulePreviewResponse: + restapi.ErrorResponse: properties: - dtstart: + code: + description: Machine-readable error code type: string - occurrences: - items: - type: string - type: array - rrule: + details: + description: Additional error details + error: + description: Human-readable message + type: string + request_id: + description: Request correlation ID type: string type: object - windshift_internal_restapi_v1_handlers.startTimerRequest: + restapi.PaginatedResponse: properties: - description: - type: string - item_id: + data: {} + pagination: + $ref: '#/components/schemas/restapi.PaginationMeta' + type: object + restapi.PaginationMeta: + properties: + has_more: + type: boolean + limit: type: integer - project_id: + page: type: integer - workspace_id: + total: + type: integer + total_pages: type: integer type: object - windshift_internal_restapi_v1_handlers.templateCreateRequest: + services.PageDiagram: properties: - description_body: + attachment_id: + type: integer + content_hash: type: string - is_active: - type: boolean - item_type_ids: - items: - type: integer - type: array - mode: + created_at: + type: string + kind: type: string name: type: string - type: object - windshift_internal_restapi_v1_handlers.templateListResponse: - properties: - items: - items: - $ref: '#/components/schemas/models.ItemTemplate' - type: array - mandatory_template_id: - description: |- - MandatoryTemplateID is set when the request filtered by item_type_id and - that type has an active mandatory template, so callers (create modal, CLI) - can flag it without re-deriving the invariant. + page_id: + type: integer + payload: + type: object + revision_number: type: integer type: object - windshift_internal_restapi_v1_handlers.templateUpdateRequest: + services.TestRunDetail: properties: - description_body: - type: string - is_active: - type: boolean - item_type_ids: + results: items: - type: integer + $ref: '#/components/schemas/services.TestRunResultWithCaseTitle' + type: array + run: + $ref: '#/components/schemas/models.TestRun' + step_results: + additionalProperties: + $ref: '#/components/schemas/services.TestRunStepResult' + type: object + test_cases: + items: + $ref: '#/components/schemas/models.TestCase' type: array - mode: - type: string - name: - type: string type: object - windshift_internal_restapi_v1_handlers.testResultUpdateRequest: + services.TestRunResultWithCaseTitle: properties: actual_result: type: string + created_at: + type: string + executed_at: + type: string + id: + type: integer notes: type: string + run_id: + type: integer status: + description: '"passed", "failed", "blocked", "skipped", "not_run"' + type: string + test_case_id: + type: integer + test_case_title: + type: string + updated_at: type: string type: object - windshift_internal_restapi_v1_handlers.testRunCreateRequest: + services.TestRunStepResult: properties: - assignee_id: + actual_result: + type: string + executed_at: + type: string + item_id: type: integer - name: + notes: type: string - set_id: + status: + type: string + step_id: type: integer - template_id: + test_case_id: type: integer type: object - windshift_internal_restapi_v1_handlers.timeProjectResponse: + windshift_internal_restapi_v1_handlers.AuditLogStreamResponse: properties: - category_color: - type: string - category_id: + entries: + items: + $ref: '#/components/schemas/handlers.AuditLogEntryResponse' + type: array + has_more: + type: boolean + next_after_id: type: integer - category_name: + type: object + windshift_internal_restapi_v1_handlers.UserResponse: + properties: + agent_presence: type: string - color: + avatar_url: type: string - customer_id: - type: integer - customer_name: + created_at: type: string - description: + email: + type: string + first_name: + type: string + full_name: type: string - hourly_rate: - type: number id: type: integer - name: - type: string - settings: - additionalProperties: {} - type: object - status: + is_active: + type: boolean + is_agent: + type: boolean + language: type: string - total_hours: - type: number - type: object - windshift_internal_restapi_v1_handlers.triggerTypeDTO: - properties: - config_schema: - type: object - description: + last_name: type: string - label: + timezone: type: string - type: - $ref: '#/components/schemas/models.ActionTriggerType' - type: object - windshift_internal_restapi_v1_handlers.updateWorklogRequest: - properties: - description: + username: type: string + warnings: + items: + type: string + type: array type: object - windshift_internal_restapi_v1_handlers.validateActionResponse: + windshift_internal_restapi_v1_handlers.itemChangesResponse: properties: - errors: + changes: items: - $ref: '#/components/schemas/actioncatalog.ValidationError' + $ref: '#/components/schemas/handlers.itemChangeResponse' type: array + has_more: + type: boolean + next_cursor: + type: string + reset_required: + type: boolean + watermark: + type: string type: object - windshift_internal_restapi_v1_handlers.worklogResponse: + windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest: properties: - created_at: - type: integer - customer_id: - type: integer - customer_name: + excalidraw: + type: object + expected_content_hash: type: string - date: - type: integer - description: + mermaid: type: string - duration_minutes: - type: integer - end_time: - type: integer - id: - type: integer - item_id: - type: integer - item_title: + name: type: string - project_id: - type: integer - project_max_hours: - type: number - project_name: + placement: type: string - project_total_hours: - type: number - start_time: - type: integer - updated_at: - type: integer - workspace_id: - type: integer - workspace_item_number: - type: integer - workspace_key: + type: object + windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest: + properties: + excalidraw: + type: object + expected_content_hash: + type: string + mermaid: + type: string + name: type: string type: object securitySchemes: @@ -4504,7 +3450,7 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: @@ -4516,26 +3462,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid user_id "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:api-tokens:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4559,26 +3505,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid token ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:api-tokens:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token not found security: - BearerAuth: [] @@ -4631,11 +3577,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AuditLogEntryResponse' + $ref: '#/components/schemas/handlers.AuditLogEntryResponse' type: array type: object description: OK @@ -4643,26 +3589,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid filter parameter "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:audit-logs:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4692,32 +3638,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AuditLogStreamResponse' + $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.AuditLogStreamResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid after_id or limit "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:audit-logs:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4744,11 +3690,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AdminGroupResponse' + $ref: '#/components/schemas/handlers.AdminGroupResponse' type: array type: object description: OK @@ -4756,20 +3702,20 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:groups:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4782,7 +3728,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AdminGroupCreateRequest' + $ref: '#/components/schemas/handlers.AdminGroupCreateRequest' description: Group to create required: true x-originalParamName: body @@ -4791,32 +3737,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AdminGroupResponse' + $ref: '#/components/schemas/handlers.AdminGroupResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing name "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:groups:write scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4840,32 +3786,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid group ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:groups:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Group not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4885,7 +3831,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.AdminGroupUpdateRequest' + $ref: '#/components/schemas/handlers.AdminGroupUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -4896,32 +3842,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid group ID, request body, or no fields to update "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:groups:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Group not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4949,11 +3895,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.AdminUserResponse' + $ref: '#/components/schemas/handlers.AdminUserResponse' type: array type: object description: OK @@ -4961,20 +3907,20 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:users:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -4995,7 +3941,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.AdminUserUpdateRequest' + $ref: '#/components/schemas/handlers.AdminUserUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -5010,32 +3956,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid user ID, request body, or no fields to update "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Caller is not a system admin or token lacks the admin:users:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: User not found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5056,13 +4002,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategoryResponse' + $ref: '#/components/schemas/dto.AssetCategoryResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset category not found security: - BearerAuth: [] @@ -5077,14 +4023,14 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetResponse' + $ref: '#/components/schemas/dto.AssetSetResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized security: - BearerAuth: [] @@ -5105,13 +4051,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetSetResponse' + $ref: '#/components/schemas/dto.AssetSetResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5164,19 +4110,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.PaginatedResponse' + $ref: '#/components/schemas/restapi.PaginatedResponse' description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5195,7 +4141,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetCreateRequest' + $ref: '#/components/schemas/dto.AssetCreateRequest' description: Create payload required: true x-originalParamName: body @@ -5204,19 +4150,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse' + $ref: '#/components/schemas/dto.AssetResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5265,19 +4211,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetImportJobResponse' + $ref: '#/components/schemas/dto.AssetImportJobResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5299,14 +4245,14 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetCategoryResponse' + $ref: '#/components/schemas/dto.AssetCategoryResponse' type: array description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5328,14 +4274,14 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusResponse' + $ref: '#/components/schemas/dto.AssetStatusResponse' type: array description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5357,14 +4303,14 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeResponse' + $ref: '#/components/schemas/dto.AssetTypeResponse' type: array description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset set not found security: - BearerAuth: [] @@ -5385,13 +4331,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetStatusResponse' + $ref: '#/components/schemas/dto.AssetStatusResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset status not found security: - BearerAuth: [] @@ -5412,13 +4358,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetTypeResponse' + $ref: '#/components/schemas/dto.AssetTypeResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset type not found security: - BearerAuth: [] @@ -5441,7 +4387,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset not found security: - BearerAuth: [] @@ -5461,13 +4407,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse' + $ref: '#/components/schemas/dto.AssetResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset not found security: - BearerAuth: [] @@ -5486,7 +4432,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetUpdateRequest' + $ref: '#/components/schemas/dto.AssetUpdateRequest' description: Partial-update payload required: true x-originalParamName: body @@ -5495,13 +4441,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AssetResponse' + $ref: '#/components/schemas/dto.AssetResponse' description: OK "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Asset not found security: - BearerAuth: [] @@ -5529,7 +4475,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: attachment not found or you lack item.edit security: - BearerAuth: [] @@ -5557,25 +4503,25 @@ paths: content: application/octet-stream: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/octet-stream: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/octet-stream: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Attachment not found or not visible to caller "500": content: application/octet-stream: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5603,26 +4549,26 @@ paths: content: image/jpeg: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: image/jpeg: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: image/jpeg: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Attachment not found, has no thumbnail, or is not visible to caller "500": content: image/jpeg: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5649,25 +4595,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionListResponse' + $ref: '#/components/schemas/handlers.CollectionListResponse' description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the collections:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5690,37 +4636,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.CollectionResponse' + $ref: '#/components/schemas/handlers.CollectionResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid collection key "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the collections:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Collection not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5769,11 +4715,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -5781,31 +4727,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid QL query stored on the collection "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks collections:read or items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Collection not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5830,31 +4776,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid comment ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:delete scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Comment not found or caller cannot delete it "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5876,37 +4822,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse' + $ref: '#/components/schemas/dto.CommentResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid comment ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Comment not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5927,7 +4873,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentUpdateRequest' + $ref: '#/components/schemas/dto.CommentUpdateRequest' description: Updated content required: true x-originalParamName: body @@ -5936,37 +4882,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse' + $ref: '#/components/schemas/dto.CommentResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid comment ID, request body, or empty content "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Comment not found or caller cannot edit it "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -5981,26 +4927,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.CustomFieldResponse' + $ref: '#/components/schemas/handlers.CustomFieldResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the custom-fields:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6021,37 +4967,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.CustomFieldResponse' + $ref: '#/components/schemas/handlers.CustomFieldResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid custom field ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the custom-fields:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Custom field not found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6074,31 +5020,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid diagram ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Diagram not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6126,31 +5072,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid diagram ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Diagram not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6171,7 +5117,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.diagramWriteRequest' + $ref: '#/components/schemas/handlers.diagramWriteRequest' description: Replacement diagram contents required: true x-originalParamName: body @@ -6186,31 +5132,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Diagram not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6241,26 +5187,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse' + $ref: '#/components/schemas/handlers.ItemTypeResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-types:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6281,37 +5227,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse' + $ref: '#/components/schemas/handlers.ItemTypeResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item type ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-types:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item type not found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6391,11 +5337,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -6403,25 +5349,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid query parameter "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6439,7 +5385,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemCreateRequest' + $ref: '#/components/schemas/dto.ItemCreateRequest' description: Item to create required: true x-originalParamName: body @@ -6448,33 +5394,33 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body, missing required field, or invalid create-time status_id "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope or caller cannot edit the target workspace "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6499,31 +5445,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:delete scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6552,37 +5498,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6604,7 +5550,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemUpdateRequest' + $ref: '#/components/schemas/dto.ItemUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -6613,37 +5559,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or attempted to update status_id "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6679,32 +5625,32 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.AgentRunResponse' + $ref: '#/components/schemas/handlers.AgentRunResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not accessible "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6726,38 +5672,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.AttachmentResponse' + $ref: '#/components/schemas/dto.AttachmentResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6803,13 +5749,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: item not found or you lack item.edit security: - BearerAuth: [] @@ -6832,7 +5778,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemTypeChangeRequest' + $ref: '#/components/schemas/dto.ItemTypeChangeRequest' description: Target item type and optional target status required: true x-originalParamName: body @@ -6841,44 +5787,44 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid body or missing target_item_type_id "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Target status required because the current status is not in the target type's workflow "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6900,38 +5846,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -6968,11 +5914,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse' + $ref: '#/components/schemas/dto.CommentResponse' type: array type: object description: OK @@ -6980,31 +5926,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7024,7 +5970,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentCreateRequest' + $ref: '#/components/schemas/dto.CommentCreateRequest' description: Comment to create required: true x-originalParamName: body @@ -7033,37 +5979,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.CommentResponse' + $ref: '#/components/schemas/dto.CommentResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7087,37 +6033,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.diagramListResponse' + $ref: '#/components/schemas/handlers.diagramListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7138,7 +6084,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.diagramWriteRequest' + $ref: '#/components/schemas/handlers.diagramWriteRequest' description: Diagram to create required: true x-originalParamName: body @@ -7153,31 +6099,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7219,38 +6165,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.HistoryResponse' + $ref: '#/components/schemas/dto.HistoryResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7271,37 +6217,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelListResponse' + $ref: '#/components/schemas/handlers.labelListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7320,7 +6266,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.itemLabelAddRequest' + $ref: '#/components/schemas/handlers.itemLabelAddRequest' description: Label to attach required: true x-originalParamName: body @@ -7329,43 +6275,43 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelListResponse' + $ref: '#/components/schemas/handlers.labelListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found, not editable, or label not found "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Label is already attached to this item "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7386,7 +6332,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.itemLabelSetRequest' + $ref: '#/components/schemas/handlers.itemLabelSetRequest' description: Replacement label set required: true x-originalParamName: body @@ -7395,37 +6341,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelListResponse' + $ref: '#/components/schemas/handlers.labelListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found, not editable, or label not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7454,31 +6400,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not editable by caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7510,25 +6456,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid entity ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Entity not found or not accessible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7551,31 +6497,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7601,31 +6547,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7659,37 +6605,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Conflict "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7723,31 +6669,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7768,37 +6714,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.recurrenceForceGenerateResponse' + $ref: '#/components/schemas/handlers.recurrenceForceGenerateResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7829,37 +6775,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.recurrenceInstanceListResponse' + $ref: '#/components/schemas/handlers.recurrenceInstanceListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7881,7 +6827,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionRequest' + $ref: '#/components/schemas/dto.TransitionRequest' description: Target status and optional approval payload required: true x-originalParamName: body @@ -7890,45 +6836,45 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResultResponse' + $ref: '#/components/schemas/dto.TransitionResultResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body, missing to_status_id, or transition rejected by a validator "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Transition blocked by approval state (pending, rejected, or must-decide) "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -7950,38 +6896,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse' + $ref: '#/components/schemas/dto.TransitionResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid item ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8006,32 +6952,32 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Too many ids "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8076,31 +7022,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8138,11 +7084,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' type: array type: object description: OK @@ -8150,19 +7096,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the iterations:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8178,7 +7124,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationCreateRequest' + $ref: '#/components/schemas/handlers.IterationCreateRequest' description: Iteration to create required: true x-originalParamName: body @@ -8187,32 +7133,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks iterations:write or caller lacks the required scope permission "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8235,32 +7181,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid iteration ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the iterations:delete scope or caller cannot delete this iteration "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Iteration not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8282,37 +7228,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid iteration ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the iterations:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Iteration not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8334,7 +7280,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationUpdateRequest' + $ref: '#/components/schemas/handlers.IterationUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -8343,38 +7289,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid iteration ID or request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the iterations:write scope or caller cannot edit this iteration "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Iteration not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8398,13 +7344,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8420,7 +7366,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.linkCreateRequest' + $ref: '#/components/schemas/handlers.linkCreateRequest' description: Link to create required: true x-originalParamName: body @@ -8435,38 +7381,79 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body, missing required field, or entity types not allowed for the link type "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Source or target entity not found / not accessible to caller "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: A link between these entities already exists "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] summary: Create a cross-entity link tags: - links + /links/{id}: + delete: + parameters: + - description: Link ID + in: path + name: id + required: true + schema: + type: integer + responses: + "204": + description: Link deleted + "400": + content: + application/json: + schema: + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Invalid link ID + "401": + content: + application/json: + schema: + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Unauthorized + "404": + content: + application/json: + schema: + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Link not found or caller lacks edit on the source entity + "500": + content: + application/json: + schema: + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Internal Server Error + security: + - BearerAuth: [] + summary: Delete a link by ID + tags: + - links /links/batch: get: description: Selects up to 100 visible anchor items by CQL or explicit ids and @@ -8520,11 +7507,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.batchItemLinksResponse' + $ref: '#/components/schemas/handlers.batchItemLinksResponse' type: array type: object description: OK @@ -8532,72 +7519,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] summary: List direct links for a batch of items tags: - links - /links/{id}: - delete: - parameters: - - description: Link ID - in: path - name: id - required: true - schema: - type: integer - responses: - "204": - description: Link deleted - "400": - content: - application/json: - schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Invalid link ID - "401": - content: - application/json: - schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Unauthorized - "404": - content: - application/json: - schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Link not found or caller lacks edit on the source entity - "500": - content: - application/json: - schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Internal Server Error - security: - - BearerAuth: [] - summary: Delete a link by ID - tags: - - links /metrics: get: description: Returns Go runtime, process, database, HTTP, agent, webhook, and @@ -8649,11 +7595,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' type: array type: object description: OK @@ -8661,19 +7607,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8688,7 +7634,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneCreateRequest' + $ref: '#/components/schemas/handlers.MilestoneCreateRequest' description: Milestone to create required: true x-originalParamName: body @@ -8697,31 +7643,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks milestones:write or caller lacks milestone.create "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8744,32 +7690,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:delete scope or caller cannot delete this milestone "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Milestone not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8791,37 +7737,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Milestone not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8844,7 +7790,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneUpdateRequest' + $ref: '#/components/schemas/handlers.MilestoneUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -8853,38 +7799,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid milestone ID or request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:write scope or caller cannot edit this milestone "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Milestone not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8929,11 +7875,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -8941,31 +7887,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Milestone not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -8989,37 +7935,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressResponse' + $ref: '#/components/schemas/handlers.MilestoneProgressResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the milestones:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Milestone not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9035,7 +7981,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.milestoneReorderRequest' + $ref: '#/components/schemas/handlers.milestoneReorderRequest' description: Ordered milestone IDs required: true x-originalParamName: body @@ -9052,25 +7998,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks milestones:write or caller lacks milestone.create "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9130,25 +8076,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid entity ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Entity not found or not accessible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9163,26 +8109,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse' + $ref: '#/components/schemas/handlers.PriorityResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the priorities:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9203,37 +8149,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse' + $ref: '#/components/schemas/handlers.PriorityResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid priority ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the priorities:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Priority not found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9277,31 +8223,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.rrulePreviewResponse' + $ref: '#/components/schemas/handlers.rrulePreviewResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9356,11 +8302,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -9368,25 +8314,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Missing q/ql, or invalid CQL query "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9404,26 +8350,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.StatusCategoryResponse' + $ref: '#/components/schemas/handlers.StatusCategoryResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the statuses:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9444,37 +8390,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.StatusCategoryResponse' + $ref: '#/components/schemas/handlers.StatusCategoryResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid category ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the statuses:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Status category not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9491,26 +8437,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.StatusResponse' + $ref: '#/components/schemas/handlers.StatusResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Missing or invalid bearer token "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the statuses:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9531,37 +8477,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.StatusResponse' + $ref: '#/components/schemas/handlers.StatusResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid status ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the statuses:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Status not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9593,25 +8539,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid entity ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Entity not found or not accessible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9634,20 +8580,20 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.timeProjectResponse' + $ref: '#/components/schemas/handlers.timeProjectResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -9670,25 +8616,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.timeProjectResponse' + $ref: '#/components/schemas/handlers.timeProjectResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -9731,11 +8677,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.worklogResponse' + $ref: '#/components/schemas/handlers.worklogResponse' type: array type: object description: OK @@ -9743,13 +8689,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized security: - BearerAuth: [] @@ -9764,7 +8710,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.createWorklogRequest' + $ref: '#/components/schemas/handlers.createWorklogRequest' description: Worklog to create required: true x-originalParamName: body @@ -9780,19 +8726,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: No permission to book time on this project security: - BearerAuth: [] @@ -9817,25 +8763,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Caller does not own the worklog "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -9856,7 +8802,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.updateWorklogRequest' + $ref: '#/components/schemas/handlers.updateWorklogRequest' description: New description required: true x-originalParamName: body @@ -9872,25 +8818,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Caller does not own the worklog "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -9912,7 +8858,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized security: - BearerAuth: [] @@ -9927,7 +8873,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.startTimerRequest' + $ref: '#/components/schemas/handlers.startTimerRequest' description: Timer to start required: true x-originalParamName: body @@ -9943,25 +8889,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Forbidden "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: A timer is already running security: - BearerAuth: [] @@ -9984,13 +8930,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi.ErrorResponse' + $ref: '#/components/schemas/restapi.ErrorResponse' description: No timer is running security: - BearerAuth: [] @@ -10029,7 +8975,7 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: @@ -10041,19 +8987,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks users:read or caller lacks user.list "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10082,31 +9028,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid user ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the users:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: User not found "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10127,19 +9073,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the users:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10155,25 +9101,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse' + $ref: '#/components/schemas/handlers.TUIPreferencesResponse' description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the user-preferences:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10189,7 +9135,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse' + $ref: '#/components/schemas/handlers.TUIPreferencesResponse' description: TUI preferences required: true x-originalParamName: preferences @@ -10198,31 +9144,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.TUIPreferencesResponse' + $ref: '#/components/schemas/handlers.TUIPreferencesResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Malformed body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the user-preferences:write scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10237,26 +9183,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.WorkflowResponse' + $ref: '#/components/schemas/handlers.WorkflowResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workflows:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10284,37 +9230,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.WorkflowResponse' + $ref: '#/components/schemas/handlers.WorkflowResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workflow ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workflows:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workflow not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10336,38 +9282,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.TransitionResponse' + $ref: '#/components/schemas/dto.TransitionResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workflow ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workflows:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workflow not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10384,26 +9330,26 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceTemplateSummaryResponse' + $ref: '#/components/schemas/handlers.WorkspaceTemplateSummaryResponse' type: array description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10439,11 +9385,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse' + $ref: '#/components/schemas/handlers.WorkspaceResponse' type: array type: object description: OK @@ -10451,19 +9397,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10479,7 +9425,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceCreateRequest' + $ref: '#/components/schemas/handlers.WorkspaceCreateRequest' description: Workspace to create required: true x-originalParamName: body @@ -10488,50 +9434,50 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse' + $ref: '#/components/schemas/handlers.WorkspaceResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks workspaces:write or caller lacks workspace.create "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: 'TEMPLATE_WORKSPACE_NOT_FOUND: template workspace missing or not visible' "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: A workspace with this key already exists "422": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: INVALID_WORKSPACE_TEMPLATE or WORKSPACE_TEMPLATE_TOO_LARGE "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10554,31 +9500,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:delete scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller cannot delete it "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10600,37 +9546,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse' + $ref: '#/components/schemas/handlers.WorkspaceResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10649,7 +9595,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceUpdateRequest' + $ref: '#/components/schemas/handlers.WorkspaceUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -10658,37 +9604,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkspaceResponse' + $ref: '#/components/schemas/handlers.WorkspaceResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID or request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller cannot edit it "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -10713,31 +9659,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.catalogResponse' + $ref: '#/components/schemas/handlers.catalogResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the actions:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or no action.manage permission security: - BearerAuth: [] @@ -10766,19 +9712,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Forbidden "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -10801,7 +9747,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest' + $ref: '#/components/schemas/handlers.actionDefinitionRequest' description: Action definition required: true x-originalParamName: body @@ -10816,25 +9762,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Validation failed — see details.errors "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks actions:write "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -10867,7 +9813,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -10895,7 +9841,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest' + $ref: '#/components/schemas/handlers.actionDefinitionRequest' description: Updated definition required: true x-originalParamName: body @@ -10910,13 +9856,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Not Found security: - BearerAuth: [] @@ -10939,7 +9885,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.actionDefinitionRequest' + $ref: '#/components/schemas/handlers.actionDefinitionRequest' description: Definition to validate required: true x-originalParamName: body @@ -10948,7 +9894,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.validateActionResponse' + $ref: '#/components/schemas/handlers.validateActionResponse' description: Validation result — errors is empty when the definition would persist security: @@ -10970,31 +9916,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.agentSkillListResponse' + $ref: '#/components/schemas/handlers.agentSkillListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Workspace not found or caller lacks item.view + $ref: '#/components/schemas/handlers.ErrorResponse' + description: No active run snapshot for this token and workspace "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11027,25 +9973,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or skill ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' - description: Skill not found in this workspace or caller lacks item.view + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Skill not present in this run snapshot + "422": + content: + application/json: + schema: + $ref: '#/components/schemas/handlers.ErrorResponse' + description: Saved activation exceeds the supported budget "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11054,10 +10006,10 @@ paths: - agents /workspaces/{id}/assignable-users: get: - description: Returns active users with limited fields for assignment pickers. - Unlike /users this needs no global user.list permission — view access to the - workspace is enough. Sensitive fields (email, timezone, language) are always - stripped. Mirrors the session surface's assignable-users endpoint. + description: Returns active users who can view the workspace, plus only agents + with a ready workspace binding. Unlike /users this needs no global user.list + permission. Sensitive fields (email, timezone, language) are always stripped. + Shared by assignment and mention pickers. parameters: - description: Workspace ID in: path @@ -11078,25 +10030,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the users:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not accessible "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11118,38 +10070,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ItemTypeResponse' + $ref: '#/components/schemas/handlers.ItemTypeResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11184,11 +10136,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -11196,31 +10148,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11265,11 +10217,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' type: array type: object description: OK @@ -11277,31 +10229,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11323,7 +10275,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationCreateRequest' + $ref: '#/components/schemas/handlers.IterationCreateRequest' description: Iteration to create required: true x-originalParamName: body @@ -11332,37 +10284,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID, request body, or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11392,32 +10344,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or iteration ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:delete scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, iteration not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11447,38 +10399,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or iteration ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, iteration not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11506,7 +10458,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationUpdateRequest' + $ref: '#/components/schemas/handlers.IterationUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -11515,38 +10467,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.IterationResponse' + $ref: '#/components/schemas/handlers.IterationResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID, iteration ID, or request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, iteration not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11570,37 +10522,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelListResponse' + $ref: '#/components/schemas/handlers.labelListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11621,7 +10573,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelCreateRequest' + $ref: '#/components/schemas/handlers.labelCreateRequest' description: Label to create required: true x-originalParamName: body @@ -11636,37 +10588,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not editable by caller "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: A global label with this name already exists "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11696,31 +10648,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not editable or label not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11752,31 +10704,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not visible or label not found "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11803,7 +10755,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.labelUpdateRequest' + $ref: '#/components/schemas/handlers.labelUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -11818,37 +10770,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or invalid field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not editable or label not found "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Another global label already has the new name "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11892,11 +10844,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' type: array type: object description: OK @@ -11904,31 +10856,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -11950,7 +10902,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneCreateRequest' + $ref: '#/components/schemas/handlers.MilestoneCreateRequest' description: Milestone to create required: true x-originalParamName: body @@ -11959,37 +10911,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID, request body, or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12019,32 +10971,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:delete scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, milestone not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12074,38 +11026,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, milestone not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12135,7 +11087,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneUpdateRequest' + $ref: '#/components/schemas/handlers.MilestoneUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -12144,38 +11096,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneResponse' + $ref: '#/components/schemas/handlers.MilestoneResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID, milestone ID, or request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, milestone not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12226,11 +11178,11 @@ paths: application/json: schema: allOf: - - $ref: '#/components/schemas/internal_restapi_v1_handlers.PaginatedResponse' + - $ref: '#/components/schemas/handlers.PaginatedResponse' - properties: data: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' type: array type: object description: OK @@ -12238,32 +11190,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, milestone not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12293,38 +11245,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.MilestoneProgressResponse' + $ref: '#/components/schemas/handlers.MilestoneProgressResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or milestone ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found, milestone not found, or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12348,7 +11300,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.milestoneReorderRequest' + $ref: '#/components/schemas/handlers.milestoneReorderRequest' description: Ordered milestone IDs required: true x-originalParamName: body @@ -12365,31 +11317,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks items:write "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12411,31 +11363,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageLabelListResponse' + $ref: '#/components/schemas/handlers.pageLabelListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks page.view "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12457,7 +11409,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageLabelCreateRequest' + $ref: '#/components/schemas/handlers.pageLabelCreateRequest' description: Label to create required: true x-originalParamName: body @@ -12472,31 +11424,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks page.edit "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: A page label with this name already exists in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12527,25 +11479,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Label not found in this workspace or caller lacks page.edit "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12578,25 +11530,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Label not found in this workspace or caller lacks page.view "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12624,7 +11576,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageLabelUpdateRequest' + $ref: '#/components/schemas/handlers.pageLabelUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -12639,31 +11591,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or invalid field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Label not found in this workspace or caller lacks page.edit "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Another page label in this workspace already has the new name "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12687,31 +11639,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageListResponse' + $ref: '#/components/schemas/handlers.pageListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12732,7 +11684,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageCreateRequest' + $ref: '#/components/schemas/handlers.pageCreateRequest' description: Page to create required: true x-originalParamName: body @@ -12741,39 +11693,39 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: Created "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace or parent page not visible to caller, or caller lacks page.create "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page-tree depth exceeded or a uniqueness rule rejected the write "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12804,25 +11756,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or page ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.admin / page.delete "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12848,31 +11800,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or page ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12898,7 +11850,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageUpdateRequest' + $ref: '#/components/schemas/handlers.pageUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -12907,31 +11859,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.edit "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -12984,13 +11936,13 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: page not found or you lack page.edit security: - BearerAuth: [] @@ -13017,25 +11969,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageDiagramListResponse' + $ref: '#/components/schemas/handlers.pageDiagramListResponse' description: OK "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks pages:read "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or page.view denied security: - BearerAuth: [] @@ -13060,7 +12012,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageDiagramCreateRequest' + $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageDiagramCreateRequest' description: Diagram payload and placement required: true x-originalParamName: body @@ -13075,31 +12027,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid scene, name, or placement "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks pages:write "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or page.edit denied "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Stale content hash security: - BearerAuth: [] @@ -13138,19 +12090,19 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks pages:read "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Diagram not found, wrong Page, or page.view denied security: - BearerAuth: [] @@ -13184,7 +12136,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageDiagramUpdateRequest' + $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageDiagramUpdateRequest' description: Replacement payload required: true x-originalParamName: body @@ -13199,31 +12151,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid scene "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks pages:write "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Diagram not found, wrong Page, or page.edit denied "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Stale content hash or ambiguous reference security: - BearerAuth: [] @@ -13262,31 +12214,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageHistoryListResponse' + $ref: '#/components/schemas/handlers.pageHistoryListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or page ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13321,31 +12273,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageRevisionResponse' + $ref: '#/components/schemas/dto.PageRevisionResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, page, or revision ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page or revision not found or you lack page.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13380,32 +12332,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, page, or revision ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page or revision not found or you lack page.edit / restore permission "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13433,7 +12385,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageSetInheritanceRequest' + $ref: '#/components/schemas/handlers.pageSetInheritanceRequest' description: Inheritance flag required: true x-originalParamName: body @@ -13442,31 +12394,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.admin "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13493,31 +12445,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse' + $ref: '#/components/schemas/handlers.pageListWithLabelsResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or page ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.view "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13543,7 +12495,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageLabelAddRequest' + $ref: '#/components/schemas/handlers.pageLabelAddRequest' description: Label to attach required: true x-originalParamName: body @@ -13552,38 +12504,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse' + $ref: '#/components/schemas/handlers.pageListWithLabelsResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or missing required field "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found, you lack page.edit, or label doesn't belong to the workspace "409": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Label is already attached to this page "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13611,7 +12563,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageLabelSetRequest' + $ref: '#/components/schemas/handlers.pageLabelSetRequest' description: Replacement label set required: true x-originalParamName: body @@ -13620,32 +12572,32 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.pageListWithLabelsResponse' + $ref: '#/components/schemas/handlers.pageListWithLabelsResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found, you lack page.edit, or a label doesn't belong to the workspace "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13681,25 +12633,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, page, or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.edit "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13728,7 +12680,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageMoveRequest' + $ref: '#/components/schemas/handlers.pageMoveRequest' description: Move destination required: true x-originalParamName: body @@ -13737,37 +12689,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.PageResponse' + $ref: '#/components/schemas/dto.PageResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page or destination parent not found or you lack page.edit "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Move would create a cycle or exceed depth limits "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13796,31 +12748,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pagePermissionsResponse' + $ref: '#/components/schemas/handlers.pagePermissionsResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or page ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13847,7 +12799,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageGrantPermissionRequest' + $ref: '#/components/schemas/handlers.pageGrantPermissionRequest' description: ACL row to grant required: true x-originalParamName: body @@ -13862,31 +12814,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body, missing required field, or invalid principal/level "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page not found or you lack page.admin "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Permission already granted for this principal "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13921,25 +12873,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, page, or permission ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Page or permission not found or you lack page.admin "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -13973,31 +12925,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.pageListResponse' + $ref: '#/components/schemas/handlers.pageListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14022,38 +12974,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.PriorityResponse' + $ref: '#/components/schemas/handlers.PriorityResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14076,38 +13028,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary' + $ref: '#/components/schemas/dto.StatusSummary' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14132,38 +13084,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.StatusSummary' + $ref: '#/components/schemas/dto.StatusSummary' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14193,37 +13145,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.templateListResponse' + $ref: '#/components/schemas/handlers.templateListResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or item_type_id "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-templates:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14242,7 +13194,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.templateCreateRequest' + $ref: '#/components/schemas/handlers.templateCreateRequest' description: Template to create required: true x-originalParamName: body @@ -14257,38 +13209,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid body, mode, or item type "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-templates:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not editable by caller "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Name taken, or a mandatory template already exists for the type "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14317,31 +13269,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-templates:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Template not found in this workspace or not editable by caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14373,31 +13325,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-templates:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Template not found in this workspace or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14423,7 +13375,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.templateUpdateRequest' + $ref: '#/components/schemas/handlers.templateUpdateRequest' description: Fields to update required: true x-originalParamName: body @@ -14438,38 +13390,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Bad Request "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the item-templates:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Template not found in this workspace or not editable by caller "409": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Name taken, or a mandatory template already exists for the type "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14493,38 +13445,38 @@ paths: application/json: schema: items: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.WorkflowResponse' + $ref: '#/components/schemas/handlers.WorkflowResponse' type: array description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the workspaces:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14566,31 +13518,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or folder ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14624,31 +13576,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14677,31 +13629,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14733,31 +13685,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14797,31 +13749,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14855,31 +13807,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14919,31 +13871,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -14978,31 +13930,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15041,31 +13993,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case or label not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15100,31 +14052,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, case, or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15159,31 +14111,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or test case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15223,31 +14175,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15282,31 +14234,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, case, or step ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test step not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15352,31 +14304,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test step not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15418,31 +14370,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15471,25 +14423,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15523,31 +14475,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15576,31 +14528,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15634,31 +14586,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15688,31 +14640,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or folder ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test folder not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15744,31 +14696,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or folder ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test folder not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15808,31 +14760,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test folder not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15868,31 +14820,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15921,31 +14873,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -15979,31 +14931,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16032,31 +14984,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or label ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test label not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16096,31 +15048,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test label not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16151,31 +15103,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16211,31 +15163,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16264,31 +15216,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or plan ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16320,31 +15272,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or plan ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16384,31 +15336,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16443,31 +15395,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or plan ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16502,31 +15454,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or plan ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16565,31 +15517,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan or case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16624,31 +15576,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, plan, or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test plan not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16689,31 +15641,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid query parameters "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16748,31 +15700,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or result ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test result not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16812,31 +15764,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test result or item not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16871,31 +15823,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, result, or item ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test result not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16924,31 +15876,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -16982,31 +15934,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17035,31 +15987,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or template ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run template not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17091,31 +16043,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or template ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run template not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17155,31 +16107,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run template not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17214,31 +16166,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or template ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Template not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17273,31 +16225,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or template ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run template not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17333,31 +16285,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17379,7 +16331,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.testRunCreateRequest' + $ref: '#/components/schemas/handlers.testRunCreateRequest' description: Test run to create required: true x-originalParamName: body @@ -17394,31 +16346,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.execute "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17447,31 +16399,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17503,31 +16455,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17564,31 +16516,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17621,25 +16573,25 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17668,31 +16620,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17727,31 +16679,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17787,7 +16739,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.testResultUpdateRequest' + $ref: '#/components/schemas/handlers.testResultUpdateRequest' description: Result update required: true x-originalParamName: body @@ -17798,31 +16750,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run or result not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17858,31 +16810,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17930,31 +16882,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run, step, or item not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -17992,31 +16944,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or run ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test run not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18045,31 +16997,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.view "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18103,31 +17055,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Workspace not found or caller lacks test.manage "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18156,31 +17108,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or set ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18212,31 +17164,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or set ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18276,31 +17228,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body or validation error "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18335,31 +17287,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or set ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18394,31 +17346,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace or set ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18457,31 +17409,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid request body "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set or case not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18516,31 +17468,31 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace, set, or case ID "401": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the tests:write scope "404": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Test set not found in this workspace "500": content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] @@ -18577,37 +17529,37 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/windshift_internal_restapi_v1_dto.ItemResponse' + $ref: '#/components/schemas/dto.ItemResponse' description: OK "400": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Invalid workspace key or item number "401": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Unauthorized "403": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Token lacks the items:read scope "404": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Item not found or not visible to caller "500": content: application/json: schema: - $ref: '#/components/schemas/internal_restapi_v1_handlers.ErrorResponse' + $ref: '#/components/schemas/handlers.ErrorResponse' description: Internal Server Error security: - BearerAuth: [] diff --git a/docs/gitlab-scm.md b/docs/gitlab-scm.md new file mode 100644 index 000000000..e37110938 --- /dev/null +++ b/docs/gitlab-scm.md @@ -0,0 +1,50 @@ +# GitLab SCM integration + +Windshift supports GitLab.com and self-managed GitLab as an SCM provider. The +integration uses GitLab REST API v4 and supports nested namespaces such as +`group/subgroup/project`. + +## Provider setup + +Create an SCM provider in **Admin → Source Control** and choose **GitLab**. + +- For GitLab.com, leave Base URL empty or use `https://gitlab.com`. +- For self-managed GitLab, enter the instance root URL, for example + `https://gitlab.example.com`. A trailing `/api/v4` is accepted and normalized. +- OAuth applications should grant the `api` scope. Register the callback URL + shown by Windshift in the GitLab application. +- PAT providers require a token with API access and sufficient project role for + the operations users will perform. + +After an administrator creates the provider, a workspace administrator can +connect it, authorize with OAuth or PAT, and link one or more projects. + +## Supported project data + +The provider supports project discovery, branches, commits, merge requests, +MR notes and review discussions, tags, compare ranges, and GitLab Releases. +Windshift uses GitLab merge-request terminology in provider data while keeping +the provider-neutral `pull_request` value in its internal SCM link model. + +Repository polling remains the recovery mechanism. A workspace administrator +can also open a linked GitLab project's webhook settings in Windshift, generate +a callback URL and one-time secret, then configure that webhook in GitLab for: + +- push and tag push; +- merge request; +- note; +- release. + +Webhook requests are token-validated, project-validated, rate-limited, and +deduplicated before they trigger a repository sync. + +## Milestone releases + +When releasing a milestone, users can either create a new SCM release or attach +an existing Git tag/GitLab Release. Stored release data includes the project, +tag and release URLs, release status and date, downloadable assets, and the last +successful synchronization time. + +Normal repository sync refreshes attached release metadata. If a remote release +is removed but its tag remains, the record becomes `tag_only`; if both disappear, +it becomes `missing` rather than silently deleting the milestone history. diff --git a/frontend/src/lib/api/scm.js b/frontend/src/lib/api/scm.js index 3e1e6a9ff..4ff8b0146 100644 --- a/frontend/src/lib/api/scm.js +++ b/frontend/src/lib/api/scm.js @@ -104,6 +104,17 @@ export const workspaceSCM = { method: 'POST', }), + getReleaseCandidates: (repoId) => + fetchAPI(`/workspace-repositories/${repoId}/release-candidates`), + + getWebhookConfig: (repoId) => fetchAPI(`/workspace-repositories/${repoId}/webhook`), + + rotateWebhookSecret: (repoId) => + fetchAPI(`/workspace-repositories/${repoId}/webhook/rotate-secret`, { method: 'POST' }), + + deleteWebhookConfig: (repoId) => + fetchAPI(`/workspace-repositories/${repoId}/webhook`, { method: 'DELETE' }), + startOAuth: (workspaceId, connId) => fetchAPI(`/workspaces/${workspaceId}/scm-connections/${connId}/auth/start`, { method: 'POST', diff --git a/frontend/src/lib/dialogs/CreatePRFromBranchModal.svelte b/frontend/src/lib/dialogs/CreatePRFromBranchModal.svelte index 15667bde3..f664fac2d 100644 --- a/frontend/src/lib/dialogs/CreatePRFromBranchModal.svelte +++ b/frontend/src/lib/dialogs/CreatePRFromBranchModal.svelte @@ -21,6 +21,7 @@ // svelte-ignore state_referenced_locally let prBody = $state(itemKey ? `Linked to ${itemKey}` : ''); let baseBranch = $state(''); + const isGitLab = $derived(branchLink?.provider_type === 'gitlab'); async function submit() { if (!branchLink?.id) { @@ -39,7 +40,7 @@ }; const result = await api.itemSCMLinks.createPRFromBranch(branchLink.id, data); - successToast(t('scm.prCreatedSuccess', { prNumber: result.pr_number })); + successToast(t(isGitLab ? 'scm.mrCreatedSuccess' : 'scm.prCreatedSuccess', { prNumber: result.pr_number })); oncreated?.(result); } catch (err) { console.error('Failed to create PR:', err); @@ -55,9 +56,15 @@ } - + @@ -110,8 +117,9 @@ diff --git a/frontend/src/lib/features/items/ItemSCMLinks.svelte b/frontend/src/lib/features/items/ItemSCMLinks.svelte index 080869dbe..ec04e29f5 100644 --- a/frontend/src/lib/features/items/ItemSCMLinks.svelte +++ b/frontend/src/lib/features/items/ItemSCMLinks.svelte @@ -25,6 +25,7 @@ // Segmented buckets for the dev panel const pullRequests = $derived(links.filter(l => l.link_type === 'pull_request')); + const hasGitLabPullRequests = $derived(pullRequests.some(link => link.provider_type === 'gitlab')); const branchLinks = $derived(links.filter(l => l.link_type === 'branch')); const commitLinks = $derived(links.filter(l => l.link_type === 'commit')); // PR rollup follows Jira semantics: OPEN > MERGED > DECLINED @@ -293,7 +294,7 @@ {#if pullRequests.length > 0}
- {t('scm.pullRequests')} + {t(hasGitLabPullRequests ? 'scm.mergeRequests' : 'scm.pullRequests')} {pullRequests.length} @@ -413,7 +414,7 @@ class="p-1 rounded hover:bg-opacity-50" style="color: var(--ds-text-subtle);" onclick={() => openCreatePRModal(link)} - title={t('scm.createPullRequest')} + title={t(link.provider_type === 'gitlab' ? 'scm.createMergeRequest' : 'scm.createPullRequest')} > diff --git a/frontend/src/lib/features/milestones/MilestoneDetail.svelte b/frontend/src/lib/features/milestones/MilestoneDetail.svelte index b29c9d036..a9e1c365b 100644 --- a/frontend/src/lib/features/milestones/MilestoneDetail.svelte +++ b/frontend/src/lib/features/milestones/MilestoneDetail.svelte @@ -277,7 +277,7 @@ {/if} {#if milestone?.releases?.length > 0}
- {#each milestone.releases as release} + {#each milestone.releases as release (release.id)}
{release.tag_name} @@ -291,9 +291,14 @@ {#if release.is_prerelease} Pre-release {/if} - {#if release.scm_release_url} + {#if release.release_status && release.release_status !== 'released'} + + {release.release_status.replaceAll('_', ' ')} + + {/if} + {#if release.scm_release_url || release.tag_url} {/if} - {formatDateShort(release.created_at)} + {#if release.assets?.length} + {release.assets.length} assets + {/if} + {formatDateShort(release.released_at || release.created_at)}
{/each}
@@ -390,7 +398,7 @@

{t('milestones.byStatusCategory')}

{#if progress.status_breakdown && progress.status_breakdown.length > 0} - {#each progress.status_breakdown as breakdown} + {#each progress.status_breakdown as breakdown (breakdown.category_id ?? breakdown.category_name)}
connection.id === selectedConnectionId)?.provider_type); // Release form fields (snapshot of milestone at open; user-edited thereafter) // svelte-ignore state_referenced_locally @@ -64,6 +68,7 @@ if (connections.length === 1) { selectedConnectionId = connections[0].id; + await loadRepositories(selectedConnectionId); } } catch (err) { console.error('Failed to load SCM connections:', err); @@ -92,6 +97,7 @@ repositories = repos; if (repos.length === 1) { selectedRepository = repos[0].repository_name ?? ''; + await loadReleaseCandidates(selectedRepository); } else { selectedRepository = ''; } @@ -103,9 +109,34 @@ } } - $effect(() => { - loadRepositories(selectedConnectionId); - }); + async function loadReleaseCandidates(repositoryName) { + releaseCandidates = []; + if (releaseMode !== 'attach' || !repositoryName) return; + const repository = repositories.find(repo => repo.repository_name === repositoryName); + if (!repository?.id) return; + loadingCandidates = true; + try { + releaseCandidates = await api.workspaceSCM.getReleaseCandidates(repository.id) || []; + if (releaseCandidates.length === 1) tagName = releaseCandidates[0].tag_name; + } catch (err) { + console.error('Failed to load release candidates:', err); + error = err.message || 'Failed to load existing tags and releases.'; + } finally { + loadingCandidates = false; + } + } + + async function handleReleaseModeChange(mode) { + if (mode === 'attach') { + await loadReleaseCandidates(selectedRepository); + } else { + releaseCandidates = []; + } + } + + async function handleConnectionChange(connection) { + await loadRepositories(connection?.id ?? null); + } function getConnectionLabel(conn) { const base = conn.name ?? conn.provider_name ?? `Connection ${conn.id}`; @@ -115,7 +146,8 @@ const canSubmit = $derived( !submitting && tagName.trim().length > 0 && - (!selectedConnectionId || selectedRepository.length > 0) + (!selectedConnectionId || selectedRepository.length > 0) && + (releaseMode !== 'attach' || releaseCandidates.some(candidate => candidate.tag_name === tagName)) ); async function generateNotes() { @@ -141,11 +173,12 @@ try { const payload = { + mode: releaseMode, tag_name: tagName.trim(), name: releaseName.trim(), body: releaseBody.trim(), - is_draft: isDraft, - is_prerelease: isPrerelease, + is_draft: selectedProviderType === 'gitlab' ? false : isDraft, + is_prerelease: selectedProviderType === 'gitlab' ? false : isPrerelease, target_commitish: targetCommitish.trim() }; @@ -158,7 +191,9 @@ idempotencyKey ??= crypto.randomUUID(); const updatedMilestone = await api.milestones.release(milestone.id, payload, idempotencyKey); successToast( - updatedMilestone.latest_release?.scm_release_url + releaseMode === 'attach' + ? `Attached ${tagName.trim()} to the milestone.` + : updatedMilestone.latest_release?.scm_release_url ? `Release created at ${updatedMilestone.latest_release.scm_release_url}` : 'Milestone marked as completed.', 'Released' @@ -209,6 +244,7 @@ allowClear={true} getValue={(c) => c.id} getLabel={getConnectionLabel} + onSelect={handleConnectionChange} />
@@ -230,10 +266,27 @@ placeholder="Select a repository" getValue={(r) => r.repository_name ?? ''} getLabel={(r) => r.repository_name ?? ''} + onSelect={(repository) => loadReleaseCandidates(repository.repository_name)} /> {/if}
{/if} + + {#if selectedConnectionId && selectedRepository} +
+ + item.value} + getLabel={(item) => item.label} + onSelect={(item) => handleReleaseModeChange(item.value)} + /> +
+ {/if} {:else}

No SCM connections available. The milestone will be marked as completed without creating a release. @@ -242,16 +295,36 @@

- - + + {#if releaseMode === 'attach'} + {#if loadingCandidates} +
+ + Loading tags and releases… +
+ {:else if releaseCandidates.length === 0} +

No tags or releases were found in this repository.

+ {:else} + candidate.tag_name} + getLabel={(candidate) => `${candidate.tag_name} · ${candidate.release ? 'release' : 'tag'}`} + /> + {/if} + {:else} + + {/if}
+ {#if releaseMode === 'create'}
-
- - -
+ {#if selectedProviderType === 'gitlab'} +

GitLab Releases are published directly and do not expose draft or pre-release states.

+ {:else} +
+ + +
+ {/if} + {/if} {/if}
diff --git a/frontend/src/lib/locales/en/adminOperations.js b/frontend/src/lib/locales/en/adminOperations.js index 1bdc6ee84..b7ed69eca 100644 --- a/frontend/src/lib/locales/en/adminOperations.js +++ b/frontend/src/lib/locales/en/adminOperations.js @@ -387,6 +387,14 @@ export default { unlinkMessage: 'Unlink {name}?', unlinkedRepository: 'Unlinked {name}', unlinkFailed: 'Failed to unlink repository', + gitlabWebhook: 'GitLab webhook', + webhookHelp: 'Add the callback URL and secret to the GitLab project webhook. Push, tag, merge request, note, and release events are accepted.', + configureWebhook: 'Generate webhook details', + rotateWebhookSecret: 'Rotate secret', + webhookSecretOnce: 'Copy this secret now. It will not be shown again.', + webhookSecretRotated: 'GitLab webhook secret generated', + webhookLoadFailed: 'Failed to load GitLab webhook settings', + webhookRotateFailed: 'Failed to generate GitLab webhook secret', }, workspaceTemplates: { title: 'Work item templates', diff --git a/frontend/src/lib/locales/en/misc.js b/frontend/src/lib/locales/en/misc.js index 53013c781..feff90758 100644 --- a/frontend/src/lib/locales/en/misc.js +++ b/frontend/src/lib/locales/en/misc.js @@ -813,6 +813,7 @@ export default { // CreatePRFromBranchModal createPullRequest: 'Create Pull Request', + createMergeRequest: 'Create Merge Request', createPRFrom: 'Create PR from branch: {branch}', prTitle: 'PR Title', description: 'Description', @@ -820,6 +821,7 @@ export default { baseBranchPRHelp: "Leave empty to use the repository's default branch.", createPR: 'Create PR', prCreatedSuccess: 'Pull request #{prNumber} created successfully', + mrCreatedSuccess: 'Merge request !{prNumber} created successfully', failedToCreatePR: 'Failed to create pull request', noBranchLink: 'No branch link provided', @@ -849,6 +851,7 @@ export default { connect: 'Connect {provider}', noLinksYet: 'No development links yet', pullRequests: 'Pull requests', + mergeRequests: 'Merge requests', branches: 'Branches', commits: 'Commits', smartCommitsTitle: 'Process smart commits', diff --git a/frontend/src/lib/locales/ru/adminOperations.js b/frontend/src/lib/locales/ru/adminOperations.js index bea9eb614..31e9528df 100644 --- a/frontend/src/lib/locales/ru/adminOperations.js +++ b/frontend/src/lib/locales/ru/adminOperations.js @@ -397,6 +397,14 @@ export default { unlinkMessage: 'Удалить связь с репозиторием {name}?', unlinkedRepository: 'Связь с {name} удалена', unlinkFailed: 'Не удалось удалить связь с репозиторием', + gitlabWebhook: 'Webhook GitLab', + webhookHelp: 'Добавьте URL и секрет в webhook проекта GitLab. Принимаются события push, tag, merge request, note и release.', + configureWebhook: 'Создать параметры webhook', + rotateWebhookSecret: 'Сменить секрет', + webhookSecretOnce: 'Скопируйте секрет сейчас — повторно он показан не будет.', + webhookSecretRotated: 'Секрет webhook GitLab создан', + webhookLoadFailed: 'Не удалось загрузить настройки webhook GitLab', + webhookRotateFailed: 'Не удалось создать секрет webhook GitLab', }, workspaceTemplates: { title: 'Шаблоны рабочих элементов', diff --git a/frontend/src/lib/locales/ru/misc.js b/frontend/src/lib/locales/ru/misc.js index 6c5e5fa4d..6728e9f43 100644 --- a/frontend/src/lib/locales/ru/misc.js +++ b/frontend/src/lib/locales/ru/misc.js @@ -150,9 +150,9 @@ export default { scm: { createBranch: 'Создать ветку', createBranchFor: 'Создать ветку для {itemKey}', repository: 'Репозиторий', selectRepository: 'Выберите репозиторий…', branchName: 'Название ветки', baseBranch: 'Базовая ветка', baseBranchHelp: 'Ветка, от которой создаётся новая. По умолчанию используется основная ветка репозитория.', creating: 'Создание…', branchCreatedSuccess: 'Ветка создана', noReposLinked: 'С этим рабочим пространством не связаны репозитории', linkReposHelp: 'Свяжите репозитории в разделе «Настройки рабочего пространства → Управление кодом»', fillAllRequired: 'Заполните все обязательные поля', failedToLoadRepos: 'Не удалось загрузить репозитории', failedToCreateBranch: 'Не удалось создать ветку', - createPullRequest: 'Создать запрос на слияние', createPRFrom: 'Создать PR из ветки {branch}', prTitle: 'Название PR', description: 'Описание', baseBranchPR: 'Базовая ветка', baseBranchPRHelp: 'Оставьте пустым, чтобы использовать основную ветку репозитория.', createPR: 'Создать PR', prCreatedSuccess: 'Запрос на слияние №{prNumber} создан', failedToCreatePR: 'Не удалось создать запрос на слияние', noBranchLink: 'Ссылка на ветку не указана', + createPullRequest: 'Создать запрос на слияние', createMergeRequest: 'Создать Merge Request', createPRFrom: 'Создать PR из ветки {branch}', prTitle: 'Название PR', description: 'Описание', baseBranchPR: 'Базовая ветка', baseBranchPRHelp: 'Оставьте пустым, чтобы использовать основную ветку репозитория.', createPR: 'Создать PR', prCreatedSuccess: 'Запрос на слияние №{prNumber} создан', mrCreatedSuccess: 'Merge Request !{prNumber} создан', failedToCreatePR: 'Не удалось создать запрос на слияние', noBranchLink: 'Ссылка на ветку не указана', linkDevResource: 'Связать с разработкой', linkDevResourceDesc: 'Добавьте связь с PR, веткой или коммитом', type: 'Тип', pr: 'PR', branch: 'Ветка', commit: 'Коммит', prNumber: 'Номер PR', commitSha: 'SHA коммита', titleOptional: 'Название (необязательно)', linkResource: 'Добавить связь', linking: 'Создание связи…', failedToCreateLink: 'Не удалось создать связь', - development: 'Разработка', linkExisting: 'Добавить существующую связь', failedToStartConnection: 'Не удалось начать подключение', failedToLoadLinks: 'Не удалось загрузить связи', confirmRemoveLink: 'Удалить эту связь?', noRepositoriesLinked: 'С этим рабочим пространством не связаны репозитории', connectYourAccount: 'Подключите учётную запись {provider}', connectToCreate: 'Подключитесь, чтобы создавать ветки и запросы на слияние из рабочих элементов.', connect: 'Подключить {provider}', noLinksYet: 'PR, ветки и коммиты пока не связаны', pullRequests: 'Запросы на слияние', branches: 'Ветки', commits: 'Коммиты', smartCommitsTitle: 'Выполнять команды из коммитов', smartCommitsDescription: 'При слиянии выполнять команды «#comment …» и «#» из описания PR и сообщений коммитов.', smartCommitsWarningTitle: 'Адрес автора коммита невозможно проверить', smartCommitsWarningBody: 'Команды из коммита выполняются от имени пользователя, чей адрес совпадает с адресом автора в Git. Git не подтверждает этот адрес: автор коммита может указать любое значение. Включайте функцию только для репозиториев, участникам которых вы доверяете.', smartCommitsUpdateFailed: 'Не удалось обновить настройку команд из коммитов', + development: 'Разработка', linkExisting: 'Добавить существующую связь', failedToStartConnection: 'Не удалось начать подключение', failedToLoadLinks: 'Не удалось загрузить связи', confirmRemoveLink: 'Удалить эту связь?', noRepositoriesLinked: 'С этим рабочим пространством не связаны репозитории', connectYourAccount: 'Подключите учётную запись {provider}', connectToCreate: 'Подключитесь, чтобы создавать ветки и запросы на слияние из рабочих элементов.', connect: 'Подключить {provider}', noLinksYet: 'PR, ветки и коммиты пока не связаны', pullRequests: 'Запросы на слияние', mergeRequests: 'Merge Requests', branches: 'Ветки', commits: 'Коммиты', smartCommitsTitle: 'Выполнять команды из коммитов', smartCommitsDescription: 'При слиянии выполнять команды «#comment …» и «#» из описания PR и сообщений коммитов.', smartCommitsWarningTitle: 'Адрес автора коммита невозможно проверить', smartCommitsWarningBody: 'Команды из коммита выполняются от имени пользователя, чей адрес совпадает с адресом автора в Git. Git не подтверждает этот адрес: автор коммита может указать любое значение. Включайте функцию только для репозиториев, участникам которых вы доверяете.', smartCommitsUpdateFailed: 'Не удалось обновить настройку команд из коммитов', }, organization: { diff --git a/frontend/src/lib/settings/SCMProviderManager.svelte b/frontend/src/lib/settings/SCMProviderManager.svelte index 4a539abee..895e2ddac 100644 --- a/frontend/src/lib/settings/SCMProviderManager.svelte +++ b/frontend/src/lib/settings/SCMProviderManager.svelte @@ -49,9 +49,10 @@ // Workspace restriction state let allowedWorkspaceIds = $state([]); - // Provider types (only GitHub and Gitea supported) + // Provider types const providerTypes = [ { value: 'github', label: 'GitHub', icon: Github }, + { value: 'gitlab', label: 'GitLab', icon: GitBranch }, { value: 'gitea', label: 'Gitea / Forgejo', icon: GitBranch }, ]; @@ -67,16 +68,10 @@ m.value !== 'github_app' || formData.provider_type === 'github' )); - // Reset auth method if it becomes invalid for the selected provider - $effect(() => { - if (formData.auth_method === 'github_app' && formData.provider_type !== 'github') { - formData.auth_method = 'oauth'; - } - }); - // Default OAuth scopes per provider type const defaultScopes = { github: 'repo read:user user:email', + gitlab: 'api', gitea: 'read:user read:repository write:repository', }; @@ -108,15 +103,14 @@ let discoveringInstallations = $state(false); let discoveryError = $state(null); - // Update scopes when provider type changes (only if scopes is a default value) - $effect(() => { - if (formData.provider_type) { - const currentIsDefault = Object.values(defaultScopes).includes(formData.scopes); - if (currentIsDefault) { - formData.scopes = defaultScopes[formData.provider_type] || defaultScopes.github; - } + function handleProviderTypeChange(providerType) { + if (formData.auth_method === 'github_app' && providerType !== 'github') { + formData.auth_method = 'oauth'; } - }); + if (Object.values(defaultScopes).includes(formData.scopes)) { + formData.scopes = defaultScopes[providerType] || defaultScopes.github; + } + } onMount(async () => { await loadProviders(); @@ -182,7 +176,7 @@ github_app_private_key: '', github_app_installation_id: provider.github_app_installation_id || '', github_org_id: provider.github_org_id || null, - scopes: provider.scopes || 'repo', + scopes: provider.scopes || defaultScopes[provider.provider_type] || defaultScopes.github, workspace_restriction_mode: provider.workspace_restriction_mode || 'unrestricted', }; formErrors = {}; @@ -430,7 +424,7 @@ {:else} - {#each providers as provider} + {#each providers as provider (provider.id)} {@const ProviderIcon = getProviderIcon(provider.provider_type)}
@@ -532,6 +526,7 @@ placeholder="Select provider type" getValue={(item) => item.value} getLabel={(item) => item.label} + onSelect={(item) => handleProviderTypeChange(item.value)} />
@@ -546,12 +541,12 @@
- - {#if formData.provider_type === 'gitea'} + + {#if formData.provider_type === 'gitea' || formData.provider_type === 'gitlab'} {/if} @@ -578,7 +573,7 @@

{t('settings.scmProviders.enterSlugForCallback')}

{/if} - {t('settings.scmProviders.useThisUrl')} {formData.provider_type === 'github' ? 'GitHub' : 'Gitea'} + {t('settings.scmProviders.useThisUrl')} {getProviderLabel(formData.provider_type)}
{/snippet} @@ -655,7 +650,7 @@

Select an organization:

- {#each discoveredInstallations as installation} + {#each discoveredInstallations as installation (installation.id)} + {/if} {repo.repository_name} {repo.default_branch} @@ -475,6 +524,33 @@
{/if} + {#if conn.provider_type === 'gitlab' && webhookConfigs[repo.id]} + {@const webhookConfig = webhookConfigs[repo.id]} +
+
+

{t('scmSettings.gitlabWebhook')}

+

{t('scmSettings.webhookHelp')}

+
+ {#if webhookConfig.configured} +
+
+ {webhookConfig.callback_url} + +
+ {#if webhookConfig.secret} +
+ {webhookConfig.secret} + +
+

{t('scmSettings.webhookSecretOnce')}

+ {/if} +
+ {/if} + +
+ {/if}
{/each}
diff --git a/internal/database/gitlab_schema_test.go b/internal/database/gitlab_schema_test.go new file mode 100644 index 000000000..3a7fadc6d --- /dev/null +++ b/internal/database/gitlab_schema_test.go @@ -0,0 +1,36 @@ +package database + +import ( + "path/filepath" + "testing" +) + +func TestFreshSQLiteSchemaIncludesGitLabReleaseAndWebhookTables(t *testing.T) { + db, err := NewSQLiteDBWithPoolSizes(filepath.Join(t.TempDir(), "windshift.db"), 1, 1) + if err != nil { + t.Fatal(err) + } + defer func() { _ = db.Close() }() + if err := db.Initialize(); err != nil { + t.Fatal(err) + } + + for _, column := range []string{"workspace_repository_id", "tag_url", "release_status", "released_at", "assets_json", "last_synced_at"} { + var count int + if err := db.QueryRow(`SELECT COUNT(*) FROM pragma_table_info('milestone_releases') WHERE name = ?`, column).Scan(&count); err != nil { + t.Fatal(err) + } + if count != 1 { + t.Fatalf("milestone_releases column %q is missing", column) + } + } + for _, table := range []string{"scm_webhooks", "scm_webhook_deliveries"} { + var count int + if err := db.QueryRow(`SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = ?`, table).Scan(&count); err != nil { + t.Fatal(err) + } + if count != 1 { + t.Fatalf("table %q is missing", table) + } + } +} diff --git a/internal/database/migrations.go b/internal/database/migrations.go index 4da63bf29..666b7b892 100644 --- a/internal/database/migrations.go +++ b/internal/database/migrations.go @@ -478,6 +478,96 @@ var Catalog = []Migration{ CREATE UNIQUE INDEX uq_themes_builtin_key ON themes(builtin_key) WHERE builtin_key IS NOT NULL; `, }, + { + Version: "20260831_gitlab_release_metadata", + Name: "Add repository-scoped SCM release metadata", + CheckSQLite: sqliteColumnCheck("milestone_releases", "release_status"), + CheckPostgres: pgColumnCheck("milestone_releases", "release_status"), + SQLite: ` + ALTER TABLE milestone_releases ADD COLUMN workspace_repository_id INTEGER; + ALTER TABLE milestone_releases ADD COLUMN tag_url TEXT; + ALTER TABLE milestone_releases ADD COLUMN release_status TEXT NOT NULL DEFAULT 'tag_only'; + ALTER TABLE milestone_releases ADD COLUMN released_at DATETIME; + ALTER TABLE milestone_releases ADD COLUMN assets_json TEXT NOT NULL DEFAULT '[]'; + ALTER TABLE milestone_releases ADD COLUMN last_synced_at DATETIME; + CREATE UNIQUE INDEX uq_milestone_releases_repository_tag + ON milestone_releases(workspace_repository_id, tag_name) + WHERE workspace_repository_id IS NOT NULL; + `, + Postgres: ` + ALTER TABLE milestone_releases ADD COLUMN workspace_repository_id INTEGER; + ALTER TABLE milestone_releases ADD COLUMN tag_url TEXT; + ALTER TABLE milestone_releases ADD COLUMN release_status TEXT NOT NULL DEFAULT 'tag_only'; + ALTER TABLE milestone_releases ADD COLUMN released_at TIMESTAMPTZ; + ALTER TABLE milestone_releases ADD COLUMN assets_json JSONB NOT NULL DEFAULT '[]'::jsonb; + ALTER TABLE milestone_releases ADD COLUMN last_synced_at TIMESTAMPTZ; + CREATE UNIQUE INDEX uq_milestone_releases_repository_tag + ON milestone_releases(workspace_repository_id, tag_name) + WHERE workspace_repository_id IS NOT NULL; + `, + }, + { + Version: "20260831_scm_webhook_ingress", + Name: "Add manual SCM webhook ingress", + CheckSQLite: "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='scm_webhooks'", + CheckPostgres: "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=current_schema() AND table_name='scm_webhooks'", + SQLite: ` + CREATE TABLE scm_webhooks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + workspace_repository_id INTEGER NOT NULL UNIQUE REFERENCES workspace_repositories(id) ON DELETE CASCADE, + webhook_key TEXT NOT NULL UNIQUE, + webhook_external_id TEXT, + webhook_secret_encrypted TEXT NOT NULL, + events TEXT NOT NULL DEFAULT '["push","tag_push","merge_request","note","release"]', + is_active BOOLEAN NOT NULL DEFAULT true, + last_delivery_at DATETIME, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP + ); + CREATE TABLE scm_webhook_deliveries ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + scm_webhook_id INTEGER NOT NULL REFERENCES scm_webhooks(id) ON DELETE CASCADE, + delivery_id TEXT NOT NULL, + event_type TEXT NOT NULL, + payload_summary TEXT, + status TEXT NOT NULL DEFAULT 'pending', + error_message TEXT, + processing_time_ms INTEGER, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE(scm_webhook_id, delivery_id) + ); + CREATE INDEX idx_scm_webhook_deliveries_status ON scm_webhook_deliveries(status, created_at); + `, + Postgres: ` + CREATE TABLE scm_webhooks ( + id SERIAL PRIMARY KEY, + workspace_repository_id INTEGER NOT NULL UNIQUE REFERENCES workspace_repositories(id) ON DELETE CASCADE, + webhook_key TEXT NOT NULL UNIQUE, + webhook_external_id TEXT, + webhook_secret_encrypted TEXT NOT NULL, + events JSONB NOT NULL DEFAULT '["push","tag_push","merge_request","note","release"]'::jsonb, + is_active BOOLEAN NOT NULL DEFAULT true, + last_delivery_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP + ); + CREATE TABLE scm_webhook_deliveries ( + id SERIAL PRIMARY KEY, + scm_webhook_id INTEGER NOT NULL REFERENCES scm_webhooks(id) ON DELETE CASCADE, + delivery_id TEXT NOT NULL, + event_type TEXT NOT NULL, + payload_summary JSONB, + status TEXT NOT NULL DEFAULT 'pending', + error_message TEXT, + processing_time_ms INTEGER, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE(scm_webhook_id, delivery_id) + ); + CREATE INDEX idx_scm_webhook_deliveries_status ON scm_webhook_deliveries(status, created_at); + `, + }, } func (m Migration) checksum(driver string) string { diff --git a/internal/database/schema/milestones.sql b/internal/database/schema/milestones.sql index 5195f7e18..1350f0725 100644 --- a/internal/database/schema/milestones.sql +++ b/internal/database/schema/milestones.sql @@ -44,6 +44,12 @@ CREATE TABLE IF NOT EXISTS milestone_releases ( is_draft INTEGER NOT NULL DEFAULT 0, is_prerelease INTEGER NOT NULL DEFAULT 0, target_commitish TEXT, + workspace_repository_id INTEGER, + tag_url TEXT, + release_status TEXT NOT NULL DEFAULT 'tag_only', + released_at DATETIME, + assets_json TEXT NOT NULL DEFAULT '[]', + last_synced_at DATETIME, scm_connection_id INTEGER REFERENCES workspace_scm_connections(id) ON DELETE SET NULL, scm_repository TEXT, scm_release_id TEXT, @@ -74,6 +80,9 @@ CREATE INDEX IF NOT EXISTS idx_milestone_releases_milestone_id ON milestone_rele CREATE UNIQUE INDEX IF NOT EXISTS uq_milestone_releases_idempotency ON milestone_releases(milestone_id, idempotency_key) WHERE idempotency_key IS NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS uq_milestone_releases_repository_tag + ON milestone_releases(workspace_repository_id, tag_name) + WHERE workspace_repository_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_item_milestones_item_id ON item_milestones(item_id); CREATE INDEX IF NOT EXISTS idx_item_milestones_milestone_id ON item_milestones(milestone_id); -- Partial unique index: one external_key per workspace, but NULLs are unconstrained. diff --git a/internal/database/schema/milestones_existing.sql b/internal/database/schema/milestones_existing.sql index 946a3a7e1..8b158c8da 100644 --- a/internal/database/schema/milestones_existing.sql +++ b/internal/database/schema/milestones_existing.sql @@ -43,6 +43,12 @@ CREATE TABLE IF NOT EXISTS milestone_releases ( is_draft INTEGER NOT NULL DEFAULT 0, is_prerelease INTEGER NOT NULL DEFAULT 0, target_commitish TEXT, + workspace_repository_id INTEGER, + tag_url TEXT, + release_status TEXT NOT NULL DEFAULT 'tag_only', + released_at DATETIME, + assets_json TEXT NOT NULL DEFAULT '[]', + last_synced_at DATETIME, scm_connection_id INTEGER REFERENCES workspace_scm_connections(id) ON DELETE SET NULL, scm_repository TEXT, scm_release_id TEXT, diff --git a/internal/database/schema/milestones_existing_postgres.sql b/internal/database/schema/milestones_existing_postgres.sql index 659c4861e..b75a3882f 100644 --- a/internal/database/schema/milestones_existing_postgres.sql +++ b/internal/database/schema/milestones_existing_postgres.sql @@ -44,6 +44,12 @@ CREATE TABLE IF NOT EXISTS milestone_releases ( is_draft BOOLEAN NOT NULL DEFAULT false, is_prerelease BOOLEAN NOT NULL DEFAULT false, target_commitish TEXT, + workspace_repository_id INTEGER, + tag_url TEXT, + release_status TEXT NOT NULL DEFAULT 'tag_only', + released_at TIMESTAMPTZ, + assets_json JSONB NOT NULL DEFAULT '[]'::jsonb, + last_synced_at TIMESTAMPTZ, scm_connection_id INTEGER, scm_repository TEXT, scm_release_id TEXT, diff --git a/internal/database/schema/milestones_postgres.sql b/internal/database/schema/milestones_postgres.sql index c7e126759..d32edf1e6 100644 --- a/internal/database/schema/milestones_postgres.sql +++ b/internal/database/schema/milestones_postgres.sql @@ -43,6 +43,12 @@ CREATE TABLE IF NOT EXISTS milestone_releases ( is_draft BOOLEAN NOT NULL DEFAULT false, is_prerelease BOOLEAN NOT NULL DEFAULT false, target_commitish TEXT, + workspace_repository_id INTEGER, + tag_url TEXT, + release_status TEXT NOT NULL DEFAULT 'tag_only', + released_at TIMESTAMPTZ, + assets_json JSONB NOT NULL DEFAULT '[]'::jsonb, + last_synced_at TIMESTAMPTZ, scm_connection_id INTEGER, -- FK added in scm_postgres.sql (circular dep: items→milestones→scm→items) scm_repository TEXT, scm_release_id TEXT, @@ -73,6 +79,9 @@ CREATE INDEX IF NOT EXISTS idx_milestone_releases_milestone_id ON milestone_rele CREATE UNIQUE INDEX IF NOT EXISTS uq_milestone_releases_idempotency ON milestone_releases(milestone_id, idempotency_key) WHERE idempotency_key IS NOT NULL; +CREATE UNIQUE INDEX IF NOT EXISTS uq_milestone_releases_repository_tag + ON milestone_releases(workspace_repository_id, tag_name) + WHERE workspace_repository_id IS NOT NULL; CREATE INDEX IF NOT EXISTS idx_item_milestones_item_id ON item_milestones(item_id); CREATE INDEX IF NOT EXISTS idx_item_milestones_milestone_id ON item_milestones(milestone_id); -- Partial unique index: one external_key per workspace, but NULLs are unconstrained. diff --git a/internal/database/schema/scm.sql b/internal/database/schema/scm.sql index 42ecb6cd6..e333224ae 100644 --- a/internal/database/schema/scm.sql +++ b/internal/database/schema/scm.sql @@ -1,5 +1,5 @@ -- SCM (Source Control Management) provider integration tables --- Supports GitHub and Gitea/Forgejo +-- Supports GitHub, GitLab, and Gitea/Forgejo -- SCM Providers (system-level configuration) -- Similar pattern to sso_providers table @@ -121,6 +121,35 @@ CREATE INDEX IF NOT EXISTS idx_workspace_repos_connection ON workspace_repositor CREATE INDEX IF NOT EXISTS idx_workspace_repos_name ON workspace_repositories(repository_name); CREATE INDEX IF NOT EXISTS idx_workspace_repos_active ON workspace_repositories(is_active); +CREATE TABLE IF NOT EXISTS scm_webhooks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + workspace_repository_id INTEGER NOT NULL UNIQUE REFERENCES workspace_repositories(id) ON DELETE CASCADE, + webhook_key TEXT NOT NULL UNIQUE, + webhook_external_id TEXT, + webhook_secret_encrypted TEXT NOT NULL, + events TEXT NOT NULL DEFAULT '["push","tag_push","merge_request","note","release"]', + is_active BOOLEAN NOT NULL DEFAULT true, + last_delivery_at DATETIME, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS scm_webhook_deliveries ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + scm_webhook_id INTEGER NOT NULL REFERENCES scm_webhooks(id) ON DELETE CASCADE, + delivery_id TEXT NOT NULL, + event_type TEXT NOT NULL, + payload_summary TEXT, + status TEXT NOT NULL DEFAULT 'pending', + error_message TEXT, + processing_time_ms INTEGER, + created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE(scm_webhook_id, delivery_id) +); + +CREATE INDEX IF NOT EXISTS idx_scm_webhook_deliveries_status ON scm_webhook_deliveries(status, created_at); + -- Durable health snapshots for scheduled SCM operations. One row per -- connection and operation keeps diagnostics useful without retaining an -- unbounded failure history. diff --git a/internal/database/schema/scm_postgres.sql b/internal/database/schema/scm_postgres.sql index 1b51ceb37..47f66a268 100644 --- a/internal/database/schema/scm_postgres.sql +++ b/internal/database/schema/scm_postgres.sql @@ -1,5 +1,5 @@ -- SCM (Source Control Management) provider integration tables (PostgreSQL) --- Supports GitHub and Gitea/Forgejo +-- Supports GitHub, GitLab, and Gitea/Forgejo -- SCM Providers (system-level configuration) -- Similar pattern to sso_providers table @@ -121,6 +121,35 @@ CREATE INDEX IF NOT EXISTS idx_workspace_repos_connection ON workspace_repositor CREATE INDEX IF NOT EXISTS idx_workspace_repos_name ON workspace_repositories(repository_name); CREATE INDEX IF NOT EXISTS idx_workspace_repos_active ON workspace_repositories(is_active); +CREATE TABLE IF NOT EXISTS scm_webhooks ( + id SERIAL PRIMARY KEY, + workspace_repository_id INTEGER NOT NULL UNIQUE REFERENCES workspace_repositories(id) ON DELETE CASCADE, + webhook_key TEXT NOT NULL UNIQUE, + webhook_external_id TEXT, + webhook_secret_encrypted TEXT NOT NULL, + events JSONB NOT NULL DEFAULT '["push","tag_push","merge_request","note","release"]'::jsonb, + is_active BOOLEAN NOT NULL DEFAULT true, + last_delivery_at TIMESTAMPTZ, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +CREATE TABLE IF NOT EXISTS scm_webhook_deliveries ( + id SERIAL PRIMARY KEY, + scm_webhook_id INTEGER NOT NULL REFERENCES scm_webhooks(id) ON DELETE CASCADE, + delivery_id TEXT NOT NULL, + event_type TEXT NOT NULL, + payload_summary JSONB, + status TEXT NOT NULL DEFAULT 'pending', + error_message TEXT, + processing_time_ms INTEGER, + created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, + UNIQUE(scm_webhook_id, delivery_id) +); + +CREATE INDEX IF NOT EXISTS idx_scm_webhook_deliveries_status ON scm_webhook_deliveries(status, created_at); + -- Durable health snapshots for scheduled SCM operations. One row per -- connection and operation keeps diagnostics useful without retaining an -- unbounded failure history. diff --git a/internal/handlers/milestones.go b/internal/handlers/milestones.go index e02fa7465..3f7634fb4 100644 --- a/internal/handlers/milestones.go +++ b/internal/handlers/milestones.go @@ -9,6 +9,7 @@ import ( "net/http" "strconv" "strings" + "time" "windshift/internal/logger" "windshift/internal/models" @@ -16,6 +17,7 @@ import ( "windshift/internal/sanitize" "windshift/internal/scm" "windshift/internal/services" + "windshift/internal/utils" ) type MilestoneHandler struct { @@ -28,6 +30,7 @@ type MilestoneHandler struct { type milestoneReleaseProvider interface { CreateRelease(context.Context, string, string, scm.CreateReleaseOptions) (*scm.Release, error) ListReleases(context.Context, string, string) ([]scm.Release, error) + ListTags(context.Context, string, string, time.Time) ([]scm.Tag, error) } func NewMilestoneHandler(planningService *services.PlanningService, permissionService *services.PermissionService, credentialResolver *scm.CredentialResolver, auditor *logger.Auditor) *MilestoneHandler { @@ -42,7 +45,7 @@ func NewMilestoneHandler(planningService *services.PlanningService, permissionSe if err != nil { return nil, err } - releaseProvider, ok := provider.(scm.ReleaseProvider) + releaseProvider, ok := provider.(milestoneReleaseProvider) if !ok { return nil, errors.New("SCM provider does not support releases") } @@ -157,18 +160,24 @@ func (h *MilestoneHandler) Get(w http.ResponseWriter, r *http.Request) { releases := make([]models.MilestoneRelease, 0, len(releaseResults)) for _, rr := range releaseResults { rel := models.MilestoneRelease{ - ID: rr.ID, - MilestoneID: rr.MilestoneID, - TagName: rr.TagName, - Name: rr.Name, - Body: rr.Body, - IsDraft: rr.IsDraft, - IsPrerelease: rr.IsPrerelease, - TargetCommitish: rr.TargetCommitish, - SCMReleaseID: rr.SCMReleaseID, - SCMReleaseURL: rr.SCMReleaseURL, - CreatedBy: rr.CreatedBy, - CreatedAt: rr.CreatedAt, + ID: rr.ID, + MilestoneID: rr.MilestoneID, + WorkspaceRepositoryID: rr.WorkspaceRepositoryID, + TagName: rr.TagName, + TagURL: rr.TagURL, + ReleaseStatus: rr.ReleaseStatus, + ReleasedAt: rr.ReleasedAt, + Assets: rr.Assets, + LastSyncedAt: rr.LastSyncedAt, + Name: rr.Name, + Body: rr.Body, + IsDraft: rr.IsDraft, + IsPrerelease: rr.IsPrerelease, + TargetCommitish: rr.TargetCommitish, + SCMReleaseID: rr.SCMReleaseID, + SCMReleaseURL: rr.SCMReleaseURL, + CreatedBy: rr.CreatedBy, + CreatedAt: rr.CreatedAt, } // Apply same SCM field visibility rules as milestoneResultToModel if rr.SCMConnectionID != nil { @@ -638,18 +647,24 @@ func (h *MilestoneHandler) milestoneResultToModel(r *services.MilestoneResult, u if r.LatestRelease != nil { rel := &models.MilestoneRelease{ - ID: r.LatestRelease.ID, - MilestoneID: r.LatestRelease.MilestoneID, - TagName: r.LatestRelease.TagName, - Name: r.LatestRelease.Name, - Body: r.LatestRelease.Body, - IsDraft: r.LatestRelease.IsDraft, - IsPrerelease: r.LatestRelease.IsPrerelease, - TargetCommitish: r.LatestRelease.TargetCommitish, - SCMReleaseID: r.LatestRelease.SCMReleaseID, - SCMReleaseURL: r.LatestRelease.SCMReleaseURL, - CreatedBy: r.LatestRelease.CreatedBy, - CreatedAt: r.LatestRelease.CreatedAt, + ID: r.LatestRelease.ID, + MilestoneID: r.LatestRelease.MilestoneID, + WorkspaceRepositoryID: r.LatestRelease.WorkspaceRepositoryID, + TagName: r.LatestRelease.TagName, + TagURL: r.LatestRelease.TagURL, + ReleaseStatus: r.LatestRelease.ReleaseStatus, + ReleasedAt: r.LatestRelease.ReleasedAt, + Assets: r.LatestRelease.Assets, + LastSyncedAt: r.LatestRelease.LastSyncedAt, + Name: r.LatestRelease.Name, + Body: r.LatestRelease.Body, + IsDraft: r.LatestRelease.IsDraft, + IsPrerelease: r.LatestRelease.IsPrerelease, + TargetCommitish: r.LatestRelease.TargetCommitish, + SCMReleaseID: r.LatestRelease.SCMReleaseID, + SCMReleaseURL: r.LatestRelease.SCMReleaseURL, + CreatedBy: r.LatestRelease.CreatedBy, + CreatedAt: r.LatestRelease.CreatedAt, } // Expose scm_connection_id and scm_repository only if user has access to the connection's workspace if r.LatestRelease.SCMConnectionID != nil { @@ -670,6 +685,7 @@ func (h *MilestoneHandler) milestoneResultToModel(r *services.MilestoneResult, u // releaseRequest is the request body for the Release endpoint. type releaseRequest struct { + Mode string `json:"mode"` // create (default) or attach ConnectionID int `json:"connection_id"` RepositoryID int `json:"repository_id"` Repository string `json:"repository"` // "owner/repo" @@ -697,10 +713,19 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { respondValidationError(w, r, "tag_name is required") return } + req.Mode = strings.ToLower(strings.TrimSpace(req.Mode)) + if req.Mode == "" { + req.Mode = "create" + } + if req.Mode != "create" && req.Mode != "attach" { + respondValidationError(w, r, "mode must be 'create' or 'attach'") + return + } // Resolve every local dependency before persisting the attempt. No provider // side effect may occur until the durable idempotency row exists. var scmConnectionID *int + var workspaceRepositoryID *int var scmRepository *string var releaseProvider milestoneReleaseProvider var owner, repository string @@ -724,12 +749,14 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { return } repositoryName := linkedRepository.RepositoryName - parts := strings.SplitN(repositoryName, "/", 2) - if len(parts) != 2 { - respondValidationError(w, r, "repository must be in 'owner/repo' format") + repositoryID := linkedRepository.ID + workspaceRepositoryID = &repositoryID + var pathOK bool + owner, repository, pathOK = utils.SplitRepositoryPath(repositoryName) + if !pathOK { + respondValidationError(w, r, "repository must be in 'namespace/project' format") return } - owner, repository = parts[0], parts[1] cid := req.ConnectionID scmConnectionID = &cid scmRepository = &repositoryName @@ -745,6 +772,41 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { } createdBy := user.ID + var existingRelease *scm.Release + if req.Mode == "attach" { + if releaseProvider == nil { + respondValidationError(w, r, "attach mode requires an SCM connection and linked repository") + return + } + releases, listErr := releaseProvider.ListReleases(r.Context(), owner, repository) + if listErr != nil { + respondBadRequest(w, r, "Failed to load SCM releases: "+listErr.Error()) + return + } + for i := range releases { + if releases[i].TagName == req.TagName { + existingRelease = &releases[i] + break + } + } + if existingRelease == nil { + tags, listErr := releaseProvider.ListTags(r.Context(), owner, repository, time.Time{}) + if listErr != nil { + respondBadRequest(w, r, "Failed to load SCM tags: "+listErr.Error()) + return + } + for _, tag := range tags { + if tag.Name == req.TagName { + existingRelease = &scm.Release{TagName: tag.Name, TagURL: tag.URL, Status: "tag_only"} + break + } + } + } + if existingRelease == nil { + respondValidationError(w, r, "the selected tag or release no longer exists in the SCM repository") + return + } + } idempotencyKey := strings.TrimSpace(r.Header.Get("Idempotency-Key")) if len(idempotencyKey) > 200 { respondValidationError(w, r, "Idempotency-Key must be at most 200 characters") @@ -755,17 +817,18 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { } params := services.ReleaseMilestoneParams{ - ID: id, - IdempotencyKey: idempotencyKey, - TagName: req.TagName, - Name: req.Name, - Body: req.Body, - IsDraft: req.IsDraft, - IsPrerelease: req.IsPrerelease, - TargetCommitish: req.TargetCommitish, - SCMConnectionID: scmConnectionID, - SCMRepository: scmRepository, - CreatedBy: &createdBy, + ID: id, + IdempotencyKey: idempotencyKey, + TagName: req.TagName, + Name: req.Name, + Body: req.Body, + IsDraft: req.IsDraft, + IsPrerelease: req.IsPrerelease, + TargetCommitish: req.TargetCommitish, + SCMConnectionID: scmConnectionID, + WorkspaceRepositoryID: workspaceRepositoryID, + SCMRepository: scmRepository, + CreatedBy: &createdBy, } attempt, err := h.planningService.BeginMilestoneRelease(r.Context(), params) if err != nil { @@ -791,7 +854,7 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { } if releaseProvider != nil { - var release *scm.Release + release := existingRelease if attempt.NeedsReconcile { releases, listErr := releaseProvider.ListReleases(r.Context(), owner, repository) if listErr != nil { @@ -806,7 +869,7 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { } } } - if release == nil { + if release == nil && req.Mode == "create" { release, err = releaseProvider.CreateRelease(r.Context(), owner, repository, scm.CreateReleaseOptions{ TagName: req.TagName, TargetCommitish: req.TargetCommitish, @@ -821,8 +884,25 @@ func (h *MilestoneHandler) Release(w http.ResponseWriter, r *http.Request) { return } } - params.SCMReleaseID = &release.ID - params.SCMReleaseURL = &release.URL + if release.ID != "" { + params.SCMReleaseID = &release.ID + } + if release.URL != "" { + params.SCMReleaseURL = &release.URL + } + params.Name = release.Name + params.Body = release.Body + params.IsDraft = release.IsDraft + params.IsPrerelease = release.IsPrerelease + if release.TagURL != "" { + params.TagURL = &release.TagURL + } + params.ReleaseStatus = release.Status + params.Assets = release.Assets + if release.ReleasedAt != nil { + releasedAt := release.ReleasedAt.UTC().Format(time.RFC3339) + params.ReleasedAt = &releasedAt + } } result, err := h.planningService.CompleteMilestoneRelease(r.Context(), attempt.ID, attempt.LeaseToken, params) @@ -843,8 +923,8 @@ func milestoneReleaseFallbackKey(milestoneID, userID int, req releaseRequest, re repositoryName = *repository } canonical := fmt.Sprintf( - "%d\n%d\n%d\n%s\n%s\n%s\n%s\n%t\n%t\n%s", - milestoneID, userID, req.ConnectionID, repositoryName, req.TagName, + "%d\n%d\n%s\n%d\n%s\n%s\n%s\n%s\n%t\n%t\n%s", + milestoneID, userID, req.Mode, req.ConnectionID, repositoryName, req.TagName, req.Name, req.Body, req.IsDraft, req.IsPrerelease, req.TargetCommitish, ) sum := sha256.Sum256([]byte(canonical)) diff --git a/internal/handlers/scm_gitlab_webhooks.go b/internal/handlers/scm_gitlab_webhooks.go new file mode 100644 index 000000000..f895c5ff2 --- /dev/null +++ b/internal/handlers/scm_gitlab_webhooks.go @@ -0,0 +1,309 @@ +package handlers + +import ( + "context" + "crypto/rand" + "crypto/sha256" + "crypto/subtle" + "database/sql" + "encoding/base64" + "encoding/hex" + "encoding/json" + "errors" + "io" + "log/slog" + "net/http" + "strconv" + "strings" + "time" + + "windshift/internal/models" +) + +var gitLabWebhookEvents = []string{"push", "tag_push", "merge_request", "note", "release"} + +type gitLabWebhookConfigResponse struct { + Configured bool `json:"configured"` + CallbackURL string `json:"callback_url,omitempty"` + Secret string `json:"secret,omitempty"` + Events []string `json:"events"` + Active bool `json:"active"` + LastDeliveryAt *time.Time `json:"last_delivery_at,omitempty"` +} + +func (h *SCMItemLinksHandler) webhookRepoAdmin(w http.ResponseWriter, r *http.Request, repoID int) (string, bool) { + user, ok := RequireAuth(w, r) + if !ok { + return "", false + } + var workspaceID int + var providerType string + err := h.db.QueryRowContext(r.Context(), ` + SELECT wsc.workspace_id, sp.provider_type + FROM workspace_repositories wr + JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id + JOIN scm_providers sp ON sp.id = wsc.scm_provider_id + WHERE wr.id = ? + `, repoID).Scan(&workspaceID, &providerType) + if errors.Is(err, sql.ErrNoRows) { + respondNotFound(w, r, "workspace_repository") + return "", false + } + if err != nil { + respondInternalError(w, r, err) + return "", false + } + if !RequireWorkspacePermission(w, r, user.ID, workspaceID, models.PermissionWorkspaceAdmin, h.permissionService) { + return "", false + } + return providerType, true +} + +func (h *SCMItemLinksHandler) webhookCallbackURL(r *http.Request, key string) string { + base := h.baseURL + if base == "" { + scheme := "https" + if r.TLS == nil { + if forwarded := r.Header.Get("X-Forwarded-Proto"); forwarded != "" { + scheme = forwarded + } else { + scheme = "http" + } + } + host := r.Host + if forwarded := r.Header.Get("X-Forwarded-Host"); forwarded != "" { + host = forwarded + } + base = scheme + "://" + host + } + return strings.TrimRight(base, "/") + "/api/scm/webhooks/gitlab/" + key +} + +// GetGitLabWebhookConfig returns manual setup information without exposing the secret. +func (h *SCMItemLinksHandler) GetGitLabWebhookConfig(w http.ResponseWriter, r *http.Request) { + repoID, ok := requireIDParam(w, r, "repoId") + if !ok { + return + } + providerType, ok := h.webhookRepoAdmin(w, r, repoID) + if !ok { + return + } + if providerType != string(models.SCMProviderTypeGitLab) { + respondBadRequest(w, r, "Webhooks on this endpoint are only available for GitLab repositories") + return + } + var key string + var active bool + var lastDelivery sql.NullTime + err := h.db.QueryRowContext(r.Context(), `SELECT webhook_key, is_active, last_delivery_at FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID).Scan(&key, &active, &lastDelivery) + if errors.Is(err, sql.ErrNoRows) { + respondJSONOK(w, gitLabWebhookConfigResponse{Configured: false, Events: gitLabWebhookEvents}) + return + } + if err != nil { + respondInternalError(w, r, err) + return + } + response := gitLabWebhookConfigResponse{Configured: true, CallbackURL: h.webhookCallbackURL(r, key), Events: gitLabWebhookEvents, Active: active} + if lastDelivery.Valid { + response.LastDeliveryAt = &lastDelivery.Time + } + respondJSONOK(w, response) +} + +func randomWebhookValue(bytesCount int) (string, error) { + raw := make([]byte, bytesCount) + if _, err := rand.Read(raw); err != nil { + return "", err + } + return base64.RawURLEncoding.EncodeToString(raw), nil +} + +// RotateGitLabWebhookSecret creates or rotates the one-time manual setup secret. +func (h *SCMItemLinksHandler) RotateGitLabWebhookSecret(w http.ResponseWriter, r *http.Request) { + repoID, ok := requireIDParam(w, r, "repoId") + if !ok { + return + } + providerType, ok := h.webhookRepoAdmin(w, r, repoID) + if !ok { + return + } + if providerType != string(models.SCMProviderTypeGitLab) { + respondBadRequest(w, r, "Webhooks on this endpoint are only available for GitLab repositories") + return + } + secret, err := randomWebhookValue(32) + if err != nil { + respondInternalError(w, r, err) + return + } + encrypted, err := h.encryption.Encrypt(secret) + if err != nil { + respondInternalError(w, r, err) + return + } + var key string + err = h.db.QueryRowContext(r.Context(), `SELECT webhook_key FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID).Scan(&key) + if errors.Is(err, sql.ErrNoRows) { + key, err = randomWebhookValue(18) + if err == nil { + _, err = h.db.ExecWriteContext(r.Context(), ` + INSERT INTO scm_webhooks(workspace_repository_id, webhook_key, webhook_secret_encrypted, events, is_active) + VALUES (?, ?, ?, ?, true) + `, repoID, key, encrypted, `["push","tag_push","merge_request","note","release"]`) + } + } else if err == nil { + _, err = h.db.ExecWriteContext(r.Context(), `UPDATE scm_webhooks SET webhook_secret_encrypted=?, is_active=true, updated_at=CURRENT_TIMESTAMP WHERE workspace_repository_id=?`, encrypted, repoID) + } + if err != nil { + respondInternalError(w, r, err) + return + } + respondJSONOK(w, gitLabWebhookConfigResponse{Configured: true, CallbackURL: h.webhookCallbackURL(r, key), Secret: secret, Events: gitLabWebhookEvents, Active: true}) +} + +func (h *SCMItemLinksHandler) DeleteGitLabWebhookConfig(w http.ResponseWriter, r *http.Request) { + repoID, ok := requireIDParam(w, r, "repoId") + if !ok { + return + } + if _, ok := h.webhookRepoAdmin(w, r, repoID); !ok { + return + } + if _, err := h.db.ExecWriteContext(r.Context(), `DELETE FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID); err != nil { + respondInternalError(w, r, err) + return + } + respondJSONOK(w, map[string]bool{"deleted": true}) +} + +type gitLabWebhookPayload struct { + ObjectKind string `json:"object_kind"` + EventName string `json:"event_name"` + ProjectID int64 `json:"project_id"` + Ref string `json:"ref"` + Project struct { + ID int64 `json:"id"` + PathWithNamespace string `json:"path_with_namespace"` + } `json:"project"` + ObjectAttributes struct { + IID int `json:"iid"` + Action string `json:"action"` + Tag string `json:"tag"` + } `json:"object_attributes"` +} + +func normalizeGitLabWebhookKind(payload gitLabWebhookPayload) string { + kind := strings.ToLower(strings.TrimSpace(payload.ObjectKind)) + switch kind { + case "push", "tag_push", "merge_request", "note", "release": + return kind + default: + return "" + } +} + +// ReceiveGitLabWebhook validates and deduplicates a GitLab delivery, then +// schedules a targeted repository sync. Polling remains the recovery path. +func (h *SCMItemLinksHandler) ReceiveGitLabWebhook(w http.ResponseWriter, r *http.Request) { + key := r.PathValue("webhookKey") + var hookID, repoID int + var encryptedSecret, externalProjectID, providerType string + err := h.db.QueryRowContext(r.Context(), ` + SELECT sw.id, sw.workspace_repository_id, sw.webhook_secret_encrypted, + wr.repository_external_id, sp.provider_type + FROM scm_webhooks sw + JOIN workspace_repositories wr ON wr.id = sw.workspace_repository_id + JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id + JOIN scm_providers sp ON sp.id = wsc.scm_provider_id + WHERE sw.webhook_key = ? AND sw.is_active = true AND wr.is_active = true + `, key).Scan(&hookID, &repoID, &encryptedSecret, &externalProjectID, &providerType) + if errors.Is(err, sql.ErrNoRows) { + respondNotFound(w, r, "scm_webhook") + return + } + if err != nil { + respondInternalError(w, r, err) + return + } + if providerType != string(models.SCMProviderTypeGitLab) { + respondBadRequest(w, r, "Invalid webhook provider") + return + } + secret, err := h.encryption.Decrypt(encryptedSecret) + if err != nil { + respondInternalError(w, r, err) + return + } + provided := r.Header.Get("X-Gitlab-Token") + if len(secret) != len(provided) || subtle.ConstantTimeCompare([]byte(secret), []byte(provided)) != 1 { + respondJSON(w, http.StatusUnauthorized, map[string]string{"error": "invalid webhook token"}) + return + } + + r.Body = http.MaxBytesReader(w, r.Body, 2<<20) + body, err := io.ReadAll(r.Body) + if err != nil { + respondBadRequest(w, r, "Webhook payload is too large or unreadable") + return + } + var payload gitLabWebhookPayload + if err := json.Unmarshal(body, &payload); err != nil { + respondBadRequest(w, r, "Invalid GitLab webhook JSON") + return + } + eventType := normalizeGitLabWebhookKind(payload) + if eventType == "" { + respondJSON(w, http.StatusAccepted, map[string]bool{"ignored": true}) + return + } + projectID := payload.Project.ID + if projectID == 0 { + projectID = payload.ProjectID + } + if strconv.FormatInt(projectID, 10) != externalProjectID { + respondJSON(w, http.StatusForbidden, map[string]string{"error": "project mismatch"}) + return + } + deliveryID := strings.TrimSpace(r.Header.Get("X-Gitlab-Event-UUID")) + if deliveryID == "" { + digest := sha256.Sum256(body) + deliveryID = hex.EncodeToString(digest[:]) + } + summary, _ := json.Marshal(map[string]any{"object_kind": eventType, "project_id": projectID, "path": payload.Project.PathWithNamespace, "iid": payload.ObjectAttributes.IID, "action": payload.ObjectAttributes.Action, "ref": payload.Ref, "tag": payload.ObjectAttributes.Tag}) + result, err := h.db.ExecWriteContext(r.Context(), ` + INSERT INTO scm_webhook_deliveries(scm_webhook_id, delivery_id, event_type, payload_summary, status) + VALUES (?, ?, ?, ?, 'pending') ON CONFLICT DO NOTHING + `, hookID, deliveryID, eventType, string(summary)) + if err != nil { + respondInternalError(w, r, err) + return + } + inserted, _ := result.RowsAffected() + _, _ = h.db.ExecWriteContext(r.Context(), `UPDATE scm_webhooks SET last_delivery_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP WHERE id=?`, hookID) + respondJSON(w, http.StatusAccepted, map[string]bool{"accepted": true}) + if inserted == 0 { + return + } + + go func() { + started := time.Now() + ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second) + defer cancel() + syncErr := h.syncService.SyncRepository(ctx, repoID) + status, errorMessage := "processed", "" + if syncErr != nil { + status, errorMessage = "failed", syncErr.Error() + slog.Warn("GitLab webhook sync failed", slog.Int("repository_id", repoID), slog.Any("error", syncErr)) + } + _, updateErr := h.db.ExecWriteContext(ctx, ` + UPDATE scm_webhook_deliveries SET status=?, error_message=?, processing_time_ms=?, updated_at=CURRENT_TIMESTAMP + WHERE scm_webhook_id=? AND delivery_id=? + `, status, errorMessage, time.Since(started).Milliseconds(), hookID, deliveryID) + if updateErr != nil { + slog.Warn("GitLab webhook delivery update failed", slog.Any("error", updateErr), slog.String("delivery_id", deliveryID)) + } + }() +} diff --git a/internal/handlers/scm_item_links.go b/internal/handlers/scm_item_links.go index a4ab1ebf6..34a096a62 100644 --- a/internal/handlers/scm_item_links.go +++ b/internal/handlers/scm_item_links.go @@ -8,6 +8,7 @@ import ( "log/slog" "net/http" "strconv" + "strings" "time" "windshift/internal/database" @@ -26,6 +27,7 @@ type SCMItemLinksHandler struct { encryption *sso.SecretEncryption syncService *scm.SyncService permissionService *services.PermissionService + baseURL string } // getItemURL constructs the URL to an item based on the request context @@ -98,12 +100,13 @@ type CreateBranchForItemResponse struct { } // NewSCMItemLinksHandler creates a new item SCM links handler -func NewSCMItemLinksHandler(db database.Database, encryption *sso.SecretEncryption, permissionService *services.PermissionService) *SCMItemLinksHandler { +func NewSCMItemLinksHandler(db database.Database, encryption *sso.SecretEncryption, permissionService *services.PermissionService, baseURL string) *SCMItemLinksHandler { return &SCMItemLinksHandler{ db: db, encryption: encryption, syncService: scm.NewSyncService(db, encryption), permissionService: permissionService, + baseURL: strings.TrimRight(baseURL, "/"), } } @@ -492,6 +495,41 @@ func (h *SCMItemLinksHandler) SyncWorkspaceRepository(w http.ResponseWriter, r * }) } +// ListReleaseCandidates returns tags/releases that can be attached to a milestone. +func (h *SCMItemLinksHandler) ListReleaseCandidates(w http.ResponseWriter, r *http.Request) { + repoID, ok := requireIDParam(w, r, "repoId") + if !ok { + return + } + user, ok := RequireAuth(w, r) + if !ok { + return + } + var workspaceID int + err := h.db.QueryRow(` + SELECT wsc.workspace_id FROM workspace_repositories wr + JOIN workspace_scm_connections wsc ON wr.workspace_scm_connection_id = wsc.id + WHERE wr.id = ? + `, repoID).Scan(&workspaceID) + if errors.Is(err, sql.ErrNoRows) { + respondNotFound(w, r, "repository") + return + } + if err != nil { + respondInternalError(w, r, err) + return + } + if !RequireWorkspacePermission(w, r, user.ID, workspaceID, models.PermissionItemView, h.permissionService) { + return + } + candidates, err := h.syncService.ListReleaseCandidates(r.Context(), repoID, user.ID) + if err != nil { + respondBadRequest(w, r, "Failed to load tags and releases: "+err.Error()) + return + } + respondJSONOK(w, candidates) +} + // GetWorkspaceRepositoriesForItem returns repositories available for linking to an item func (h *SCMItemLinksHandler) GetWorkspaceRepositoriesForItem(w http.ResponseWriter, r *http.Request) { itemID, ok := requireIDParam(w, r, "id") diff --git a/internal/handlers/scm_providers.go b/internal/handlers/scm_providers.go index 8a95d0811..6885a419a 100644 --- a/internal/handlers/scm_providers.go +++ b/internal/handlers/scm_providers.go @@ -132,10 +132,11 @@ func (h *SCMProviderHandler) CreateProvider(w http.ResponseWriter, r *http.Reque validTypes := map[models.SCMProviderType]bool{ models.SCMProviderTypeGitHub: true, + models.SCMProviderTypeGitLab: true, models.SCMProviderTypeGitea: true, } if !validTypes[req.ProviderType] { - respondBadRequest(w, r, "Invalid provider type. Supported: github, gitea") + respondBadRequest(w, r, "Invalid provider type. Supported: github, gitlab, gitea") return } @@ -264,10 +265,11 @@ func (h *SCMProviderHandler) UpdateProvider(w http.ResponseWriter, r *http.Reque validTypes := map[models.SCMProviderType]bool{ models.SCMProviderTypeGitHub: true, + models.SCMProviderTypeGitLab: true, models.SCMProviderTypeGitea: true, } if req.ProviderType != "" && !validTypes[req.ProviderType] { - respondBadRequest(w, r, "Invalid provider type. Supported: github, gitea") + respondBadRequest(w, r, "Invalid provider type. Supported: github, gitlab, gitea") return } diff --git a/internal/handlers/scm_providers_oauth.go b/internal/handlers/scm_providers_oauth.go index 548cbf6aa..94ac79694 100644 --- a/internal/handlers/scm_providers_oauth.go +++ b/internal/handlers/scm_providers_oauth.go @@ -145,6 +145,23 @@ func (h *SCMProviderHandler) StartOAuth(w http.ResponseWriter, r *http.Request) url.QueryEscape(scopes), state, ) + case models.SCMProviderTypeGitLab: + gitlabBaseURL := "https://gitlab.com" + if baseURL.Valid && strings.TrimSpace(baseURL.String) != "" { + gitlabBaseURL = strings.TrimSuffix(strings.TrimSuffix(baseURL.String, "/"), "/api/v4") + } + scopes := oauthScopes.String + if scopes == "" { + scopes = "api" + } + authURL = fmt.Sprintf( + "%s/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s", + gitlabBaseURL, + clientID.String, + url.QueryEscape(redirectURI), + url.QueryEscape(scopes), + state, + ) default: respondBadRequest(w, r, "OAuth not supported for this provider type") return @@ -360,6 +377,24 @@ func (h *SCMProviderHandler) exchangeOAuthCode(ctx context.Context, params oauth expiresAt: tokens.ExpiresAt, }, nil + case models.SCMProviderTypeGitLab: + cfg := scm.ProviderConfig{ + ProviderType: params.providerType, + AuthMethod: models.SCMAuthMethodOAuth, + BaseURL: params.baseURL, + OAuthClientID: params.clientID, + OAuthClientSecret: params.clientSecret, + } + gitlabProvider, err := scm.NewGitLabProvider(cfg) + if err != nil { + return nil, fmt.Errorf("failed to create GitLab provider: %w", err) + } + tokens, err := gitlabProvider.ExchangeCode(ctx, params.code, params.redirectURI) + if err != nil { + return nil, fmt.Errorf("failed to exchange code: %w", err) + } + return &oauthTokenResult{accessToken: tokens.AccessToken, refreshToken: tokens.RefreshToken, expiresAt: tokens.ExpiresAt}, nil + default: return nil, fmt.Errorf("OAuth not supported for provider type: %s", params.providerType) } @@ -445,6 +480,22 @@ func (h *SCMProviderHandler) fetchSCMUserInfo(ctx context.Context, providerType info.username = scmUser.Username info.userID = scmUser.ID info.avatarURL = scmUser.AvatarURL + + case models.SCMProviderTypeGitLab: + cfg := scm.ProviderConfig{ProviderType: providerType, AuthMethod: models.SCMAuthMethodOAuth, BaseURL: baseURL, OAuthAccessToken: accessToken} + gitlabProvider, err := scm.NewGitLabProvider(cfg) + if err != nil { + slog.Warn("failed to create GitLab provider for user info", slog.String("component", "scm"), slog.Any("error", err)) + return info + } + scmUser, err := gitlabProvider.GetCurrentUser(ctx) + if err != nil { + slog.Warn("failed to get GitLab user info", slog.String("component", "scm"), slog.Any("error", err)) + return info + } + info.username = scmUser.Username + info.userID = scmUser.ID + info.avatarURL = scmUser.AvatarURL } if info.username != "" { diff --git a/internal/handlers/scm_workspace.go b/internal/handlers/scm_workspace.go index 212c7e977..6aa287167 100644 --- a/internal/handlers/scm_workspace.go +++ b/internal/handlers/scm_workspace.go @@ -813,6 +813,23 @@ func (h *SCMWorkspaceHandler) StartWorkspaceOAuth(w http.ResponseWriter, r *http url.QueryEscape(scopes), state, ) + case models.SCMProviderTypeGitLab: + gitlabBaseURL := "https://gitlab.com" + if strings.TrimSpace(oauthCfg.BaseURL) != "" { + gitlabBaseURL = strings.TrimSuffix(strings.TrimSuffix(oauthCfg.BaseURL, "/"), "/api/v4") + } + scopes := "api" + if oauthCfg.Scopes != "" { + scopes = oauthCfg.Scopes + } + authURL = fmt.Sprintf( + "%s/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s", + gitlabBaseURL, + oauthCfg.ClientID, + url.QueryEscape(redirectURI), + url.QueryEscape(scopes), + state, + ) default: respondBadRequest(w, r, "OAuth not supported for this provider type") return diff --git a/internal/models/integration.go b/internal/models/integration.go index 5de6c3734..cea0f5cf9 100644 --- a/internal/models/integration.go +++ b/internal/models/integration.go @@ -11,6 +11,7 @@ type SCMProviderType string const ( SCMProviderTypeGitHub SCMProviderType = "github" + SCMProviderTypeGitLab SCMProviderType = "gitlab" SCMProviderTypeGitea SCMProviderType = "gitea" ) @@ -201,6 +202,7 @@ type ItemSCMLinkRequest struct { type SCMWebhook struct { ID int `json:"id"` WorkspaceRepositoryID int `json:"workspace_repository_id"` + WebhookKey string `json:"webhook_key,omitempty"` WebhookExternalID string `json:"webhook_external_id,omitempty"` WebhookSecretEncrypted string `json:"-"` // Never expose Events string `json:"events"` // JSON array @@ -223,6 +225,17 @@ type SCMWebhookDelivery struct { CreatedAt time.Time `json:"created_at"` } +// SCMReleaseAsset is a downloadable source archive or an explicit external +// link associated with an SCM release. +type SCMReleaseAsset struct { + Kind string `json:"kind"` + Name string `json:"name"` + URL string `json:"url"` + DirectURL string `json:"direct_url,omitempty"` + Format string `json:"format,omitempty"` + LinkType string `json:"link_type,omitempty"` +} + // IssueSyncLabelMode represents the label sync mode type IssueSyncLabelMode string diff --git a/internal/models/workspace.go b/internal/models/workspace.go index 1865bcd80..2d98f63ef 100644 --- a/internal/models/workspace.go +++ b/internal/models/workspace.go @@ -128,20 +128,26 @@ type MilestoneCategory struct { // MilestoneRelease represents a release record for a milestone type MilestoneRelease struct { - ID int `json:"id"` - MilestoneID int `json:"milestone_id"` - TagName string `json:"tag_name"` - Name string `json:"name,omitempty"` - Body string `json:"body,omitempty"` - IsDraft bool `json:"is_draft"` - IsPrerelease bool `json:"is_prerelease"` - TargetCommitish string `json:"target_commitish,omitempty"` - SCMConnectionID *int `json:"scm_connection_id,omitempty"` // Visible only to users with connection workspace access - SCMRepository *string `json:"scm_repository,omitempty"` // "owner/repo"; same visibility as SCMConnectionID - SCMReleaseID *string `json:"scm_release_id,omitempty"` - SCMReleaseURL *string `json:"scm_release_url,omitempty"` - CreatedBy *int `json:"created_by,omitempty"` - CreatedAt string `json:"created_at"` + ID int `json:"id"` + MilestoneID int `json:"milestone_id"` + WorkspaceRepositoryID *int `json:"workspace_repository_id,omitempty"` + TagName string `json:"tag_name"` + TagURL *string `json:"tag_url,omitempty"` + ReleaseStatus string `json:"release_status,omitempty"` + ReleasedAt *string `json:"released_at,omitempty"` + Assets []SCMReleaseAsset `json:"assets,omitempty"` + LastSyncedAt *string `json:"last_synced_at,omitempty"` + Name string `json:"name,omitempty"` + Body string `json:"body,omitempty"` + IsDraft bool `json:"is_draft"` + IsPrerelease bool `json:"is_prerelease"` + TargetCommitish string `json:"target_commitish,omitempty"` + SCMConnectionID *int `json:"scm_connection_id,omitempty"` // Visible only to users with connection workspace access + SCMRepository *string `json:"scm_repository,omitempty"` // "owner/repo"; same visibility as SCMConnectionID + SCMReleaseID *string `json:"scm_release_id,omitempty"` + SCMReleaseURL *string `json:"scm_release_url,omitempty"` + CreatedBy *int `json:"created_by,omitempty"` + CreatedAt string `json:"created_at"` } // Milestone represents a project milestone diff --git a/internal/routes/scm.go b/internal/routes/scm.go index 9074543a5..a3cb085a0 100644 --- a/internal/routes/scm.go +++ b/internal/routes/scm.go @@ -67,6 +67,11 @@ func RegisterSCMRoutes(deps *Deps) { api.HandleH("DELETE /workspaces/{id}/scm-connections/{connId}/auth", auth(wsAdmin(http.HandlerFunc(deps.SCM.Workspace.ClearWorkspaceCredentials)))) api.HandleH("GET /workspaces/{id}/scm-connections/{connId}/auth/status", auth(wsView(http.HandlerFunc(deps.SCM.Workspace.GetWorkspaceConnectionAuthStatus)))) api.HandleH("POST /workspace-repositories/{repoId}/sync", auth(http.HandlerFunc(deps.SCM.ItemLinks.SyncWorkspaceRepository))) + api.HandleH("GET /workspace-repositories/{repoId}/release-candidates", auth(http.HandlerFunc(deps.SCM.ItemLinks.ListReleaseCandidates))) + api.HandleH("GET /workspace-repositories/{repoId}/webhook", auth(http.HandlerFunc(deps.SCM.ItemLinks.GetGitLabWebhookConfig))) + api.HandleH("POST /workspace-repositories/{repoId}/webhook/rotate-secret", auth(http.HandlerFunc(deps.SCM.ItemLinks.RotateGitLabWebhookSecret))) + api.HandleH("DELETE /workspace-repositories/{repoId}/webhook", auth(http.HandlerFunc(deps.SCM.ItemLinks.DeleteGitLabWebhookConfig))) + api.HandleH("POST /scm/webhooks/gitlab/{webhookKey}", deps.WebhookLimiter.Limit(http.HandlerFunc(deps.SCM.ItemLinks.ReceiveGitLabWebhook))) // Item SCM Links endpoints api.HandleH("GET /items/{id}/scm-links", auth(http.HandlerFunc(deps.SCM.ItemLinks.GetItemSCMLinks))) diff --git a/internal/scm/credentials.go b/internal/scm/credentials.go index 641f1a9f9..48f1edd82 100644 --- a/internal/scm/credentials.go +++ b/internal/scm/credentials.go @@ -506,6 +506,19 @@ func (r *CredentialResolver) RefreshOAuthTokenIfNeeded(ctx context.Context, conn var err error switch creds.ProviderType { + case models.SCMProviderTypeGitLab: + var gitlabProvider *GitLabProvider + gitlabProvider, err = NewGitLabProvider(cfg) + if err != nil { + return "", fmt.Errorf("failed to create provider for refresh: %w", err) + } + newTokens, err = gitlabProvider.RefreshToken(ctx, creds.OAuthRefreshToken) + if err != nil { + if errors.Is(err, ErrRefreshTokenInvalid) { + r.invalidateStoredCredentials(ctx, creds, connectionID) + } + return "", fmt.Errorf("failed to refresh token: %w", err) + } case models.SCMProviderTypeGitea: var giteaProvider *GiteaProvider giteaProvider, err = NewGiteaProvider(cfg) diff --git a/internal/scm/gitea.go b/internal/scm/gitea.go index fc62c61f7..96acf0e98 100644 --- a/internal/scm/gitea.go +++ b/internal/scm/gitea.go @@ -454,7 +454,7 @@ func (g *GiteaProvider) ListPullRequestReviewEvents(ctx context.Context, owner, return nil, err } for _, c := range comments { - events = append(events, IssueComment{ID: c.ID, Kind: "review_comment", Body: c.Body, User: c.User.toUser(), Path: c.Path, Line: c.NewPosition, ThreadID: review.ID, CreatedAt: c.CreatedAt, UpdatedAt: c.UpdatedAt}) + events = append(events, IssueComment{ID: c.ID, Kind: "review_comment", Body: c.Body, User: c.User.toUser(), Path: c.Path, Line: c.NewPosition, ThreadID: fmt.Sprintf("%d", review.ID), CreatedAt: c.CreatedAt, UpdatedAt: c.UpdatedAt}) } } if len(reviews) < perPage { @@ -501,7 +501,7 @@ func (g *GiteaProvider) CreateIssueComment(ctx context.Context, owner, repo stri } // UpdateIssueComment edits an existing issue/PR comment by its id. -func (g *GiteaProvider) UpdateIssueComment(ctx context.Context, owner, repo string, commentID int64, commentBody string) error { +func (g *GiteaProvider) UpdateIssueComment(ctx context.Context, owner, repo string, _ int, commentID int64, commentBody string) error { reqURL := g.apiURL(fmt.Sprintf("/repos/%s/%s/issues/comments/%d", url.PathEscape(owner), url.PathEscape(repo), commentID)) @@ -869,16 +869,24 @@ type giteaRelease struct { } func (r giteaRelease) toRelease() Release { + status := "released" + if r.Draft { + status = "draft" + } else if r.Prerelease { + status = "prerelease" + } return Release{ ID: fmt.Sprintf("%d", r.ID), TagName: r.TagName, Name: r.Name, Body: r.Body, URL: r.HTMLURL, + Status: status, IsDraft: r.Draft, IsPrerelease: r.Prerelease, CreatedAt: r.CreatedAt, PublishedAt: r.PublishedAt, + ReleasedAt: r.PublishedAt, } } diff --git a/internal/scm/github.go b/internal/scm/github.go index 33ae70267..8905c1a3a 100644 --- a/internal/scm/github.go +++ b/internal/scm/github.go @@ -1048,7 +1048,7 @@ func (g *GitHubProvider) ListPullRequestReviewEvents(ctx context.Context, owner, events = append(events, IssueComment{ ID: c.ID, Kind: "review_comment", Body: c.Body, User: c.User.toUser(), AuthorAssociation: c.AuthorAssociation, Path: c.Path, Line: line, Side: c.Side, - ThreadID: c.InReplyToID, CreatedAt: c.CreatedAt, UpdatedAt: c.UpdatedAt, + ThreadID: strconv.FormatInt(c.InReplyToID, 10), CreatedAt: c.CreatedAt, UpdatedAt: c.UpdatedAt, }) } if len(comments) < 100 { @@ -1082,7 +1082,7 @@ func (g *GitHubProvider) CanUserWriteRepository(ctx context.Context, owner, repo } // UpdateIssueComment updates an existing comment on an issue -func (g *GitHubProvider) UpdateIssueComment(ctx context.Context, owner, repo string, commentID int64, commentBody string) error { +func (g *GitHubProvider) UpdateIssueComment(ctx context.Context, owner, repo string, _ int, commentID int64, commentBody string) error { if err := g.ensureInstallationToken(ctx); err != nil { return err } @@ -1430,16 +1430,24 @@ type githubRelease struct { } func (r githubRelease) toRelease() Release { + status := "released" + if r.Draft { + status = "draft" + } else if r.Prerelease { + status = "prerelease" + } return Release{ ID: strconv.Itoa(r.ID), TagName: r.TagName, Name: r.Name, Body: r.Body, URL: r.HTMLURL, + Status: status, IsDraft: r.Draft, IsPrerelease: r.Prerelease, CreatedAt: r.CreatedAt, PublishedAt: r.PublishedAt, + ReleasedAt: r.PublishedAt, } } diff --git a/internal/scm/gitlab.go b/internal/scm/gitlab.go new file mode 100644 index 000000000..300c24470 --- /dev/null +++ b/internal/scm/gitlab.go @@ -0,0 +1,808 @@ +package scm + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "strconv" + "strings" + "time" + + "windshift/internal/models" +) + +const gitLabDefaultURL = "https://gitlab.com" + +var ( + _ Provider = (*GitLabProvider)(nil) + _ OAuthProvider = (*GitLabProvider)(nil) + _ TokenRevoker = (*GitLabProvider)(nil) + _ ReleaseProvider = (*GitLabProvider)(nil) + _ CommitProvider = (*GitLabProvider)(nil) + _ RefProvider = (*GitLabProvider)(nil) + _ IssueCommentProvider = (*GitLabProvider)(nil) + _ PullRequestReviewProvider = (*GitLabProvider)(nil) + _ RepositoryPermissionProvider = (*GitLabProvider)(nil) +) + +// GitLabProvider implements GitLab REST API v4 for GitLab.com and +// self-managed installations. +type GitLabProvider struct { + baseProvider + baseURL string + apiBaseURL string + authMethod models.SCMAuthMethod + accessToken string + clientID string + clientSecret string +} + +func NewGitLabProvider(cfg ProviderConfig) (*GitLabProvider, error) { + baseURL := strings.TrimSpace(cfg.BaseURL) + if baseURL == "" { + baseURL = gitLabDefaultURL + } + baseURL = strings.TrimRight(baseURL, "/") + baseURL = strings.TrimSuffix(baseURL, "/api/v4") + if _, err := url.ParseRequestURI(baseURL); err != nil { + return nil, fmt.Errorf("invalid GitLab base URL: %w", err) + } + + accessToken := cfg.PersonalAccessToken + if cfg.AuthMethod == models.SCMAuthMethodOAuth { + accessToken = cfg.OAuthAccessToken + } + p := &GitLabProvider{ + baseURL: baseURL, + apiBaseURL: baseURL + "/api/v4", + authMethod: cfg.AuthMethod, + accessToken: accessToken, + clientID: cfg.OAuthClientID, + clientSecret: cfg.OAuthClientSecret, + } + p.baseProvider = baseProvider{ + httpClient: newSCMHTTPClient(30 * time.Second), + setAuthHeader: p.setAuthHeader, + handleErrorResponse: p.handleErrorResponse, + } + return p, nil +} + +func (g *GitLabProvider) GetType() models.SCMProviderType { return models.SCMProviderTypeGitLab } + +func (g *GitLabProvider) apiURL(path string) string { return g.apiBaseURL + path } + +func (g *GitLabProvider) projectPath(owner, repo string) string { + return url.PathEscape(strings.Trim(owner, "/") + "/" + strings.Trim(repo, "/")) +} + +func (g *GitLabProvider) projectWebURL(owner, repo string) string { + return g.baseURL + "/" + strings.Trim(owner, "/") + "/" + strings.Trim(repo, "/") +} + +func (g *GitLabProvider) projectAPIURL(owner, repo, suffix string) string { + return g.apiURL("/projects/" + g.projectPath(owner, repo) + suffix) +} + +func (g *GitLabProvider) setAuthHeader(req *http.Request) { + if g.accessToken == "" { + return + } + if g.authMethod == models.SCMAuthMethodPAT { + req.Header.Set("PRIVATE-TOKEN", g.accessToken) + } else { + req.Header.Set("Authorization", "Bearer "+g.accessToken) + } + req.Header.Set("Accept", "application/json") +} + +func (g *GitLabProvider) handleErrorResponse(resp *http.Response) error { + body, readErr := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if readErr != nil { + return fmt.Errorf("%w: read GitLab response: %v", ErrProviderError, readErr) + } + message := strings.TrimSpace(string(body)) + switch resp.StatusCode { + case http.StatusUnauthorized: + return ErrInvalidCredentials + case http.StatusForbidden: + return fmt.Errorf("%w: %s", ErrForbidden, message) + case http.StatusNotFound: + return ErrNotFound + case http.StatusTooManyRequests: + return ErrRateLimited + case http.StatusConflict: + return ErrAlreadyExists + case http.StatusBadRequest, http.StatusUnprocessableEntity: + if strings.Contains(strings.ToLower(message), "already exists") || strings.Contains(strings.ToLower(message), "another open merge request") { + return ErrAlreadyExists + } + } + return fmt.Errorf("%w: GitLab status %d: %s", ErrProviderError, resp.StatusCode, message) +} + +func (g *GitLabProvider) TestConnection(ctx context.Context) error { + return g.doJSON(ctx, http.MethodGet, g.apiURL("/user"), http.NoBody, http.StatusOK, nil) +} + +func (g *GitLabProvider) ListRepositories(ctx context.Context, opts ListRepositoriesOptions) ([]Repository, error) { + page, perPage := opts.Page, opts.PerPage + if page <= 0 { + page = 1 + } + if perPage <= 0 { + perPage = 50 + } + q := url.Values{ + "membership": {"true"}, "simple": {"true"}, "page": {strconv.Itoa(page)}, + "per_page": {strconv.Itoa(perPage)}, "order_by": {"last_activity_at"}, "sort": {"desc"}, + } + if opts.Visibility != "" && opts.Visibility != "all" { + q.Set("visibility", opts.Visibility) + } + var raw []gitLabProject + if err := g.doJSON(ctx, http.MethodGet, g.apiURL("/projects?"+q.Encode()), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + out := make([]Repository, 0, len(raw)) + for _, project := range raw { + out = append(out, project.toRepository()) + } + return out, nil +} + +func (g *GitLabProvider) GetRepository(ctx context.Context, owner, repo string) (*Repository, error) { + var raw gitLabProject + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, ""), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + result := raw.toRepository() + return &result, nil +} + +func (g *GitLabProvider) ListBranches(ctx context.Context, owner, repo string) ([]Branch, error) { + const perPage, maxBranches = 100, 1000 + var out []Branch + for page := 1; len(out) < maxBranches; page++ { + var raw []gitLabBranch + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/repository/branches?page=%d&per_page=%d", page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, branch := range raw { + out = append(out, branch.toBranch()) + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) ListPullRequests(ctx context.Context, owner, repo string, opts ListPROptions) ([]PullRequest, error) { + page, perPage := opts.Page, opts.PerPage + if page <= 0 { + page = 1 + } + if perPage <= 0 { + perPage = 50 + } + state := opts.State + if state == "" || state == "open" { + state = "opened" + } + q := url.Values{"scope": {"all"}, "state": {state}, "page": {strconv.Itoa(page)}, "per_page": {strconv.Itoa(perPage)}} + if opts.Sort != "" { + orderBy := opts.Sort + if orderBy == "updated" || orderBy == "created" { + orderBy += "_at" + } + q.Set("order_by", orderBy) + } + if opts.Direction != "" { + q.Set("sort", opts.Direction) + } + var raw []gitLabMergeRequest + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, "/merge_requests?"+q.Encode()), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + out := make([]PullRequest, 0, len(raw)) + for _, mr := range raw { + out = append(out, mr.toPullRequest(owner+"/"+repo)) + } + return out, nil +} + +func (g *GitLabProvider) GetPullRequest(ctx context.Context, owner, repo string, number int) (*PullRequest, error) { + var raw gitLabMergeRequest + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, fmt.Sprintf("/merge_requests/%d", number)), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + result := raw.toPullRequest(owner + "/" + repo) + return &result, nil +} + +func (g *GitLabProvider) ListPullRequestCommits(ctx context.Context, owner, repo string, number int) ([]Commit, error) { + const perPage, maxCommits = 100, 500 + var out []Commit + for page := 1; len(out) < maxCommits; page++ { + var raw []gitLabCommit + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/merge_requests/%d/commits?page=%d&per_page=%d", number, page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, commit := range raw { + out = append(out, commit.toCommit()) + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) CreateBranch(ctx context.Context, owner, repo, branchName, baseBranch string) error { + body, err := json.Marshal(map[string]string{"branch": branchName, "ref": baseBranch}) + if err != nil { + return err + } + return g.doJSON(ctx, http.MethodPost, g.projectAPIURL(owner, repo, "/repository/branches"), bytes.NewReader(body), http.StatusCreated, nil) +} + +func (g *GitLabProvider) CreatePullRequest(ctx context.Context, owner, repo string, opts CreatePROptions) (*PullRequest, error) { + title := opts.Title + if opts.Draft && !strings.HasPrefix(strings.ToLower(strings.TrimSpace(title)), "draft:") { + title = "Draft: " + title + } + body, err := json.Marshal(map[string]any{ + "title": title, "description": opts.Body, "source_branch": opts.HeadBranch, + "target_branch": opts.BaseBranch, + }) + if err != nil { + return nil, err + } + var raw gitLabMergeRequest + if err := g.doJSON(ctx, http.MethodPost, g.projectAPIURL(owner, repo, "/merge_requests"), bytes.NewReader(body), http.StatusCreated, &raw); err != nil { + return nil, err + } + result := raw.toPullRequest(owner + "/" + repo) + return &result, nil +} + +func (g *GitLabProvider) GetCommit(ctx context.Context, owner, repo, sha string) (*Commit, error) { + var raw gitLabCommit + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, "/repository/commits/"+url.PathEscape(sha)), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + result := raw.toCommit() + return &result, nil +} + +func (g *GitLabProvider) ListCommits(ctx context.Context, owner, repo string, opts ListCommitsOptions) ([]Commit, error) { + page, perPage := opts.Page, opts.PerPage + if page <= 0 { + page = 1 + } + if perPage <= 0 { + perPage = 50 + } + q := url.Values{"page": {strconv.Itoa(page)}, "per_page": {strconv.Itoa(perPage)}} + if opts.Sha != "" { + q.Set("ref_name", opts.Sha) + } + if opts.Since != nil && !opts.Since.IsZero() { + q.Set("since", opts.Since.Format(time.RFC3339)) + } + var raw []gitLabCommit + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, "/repository/commits?"+q.Encode()), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + out := make([]Commit, 0, len(raw)) + for _, commit := range raw { + out = append(out, commit.toCommit()) + } + return out, nil +} + +func (g *GitLabProvider) ListTags(ctx context.Context, owner, repo string, since time.Time) ([]Tag, error) { + const perPage, maxTags = 100, 500 + var out []Tag + webURL := g.projectWebURL(owner, repo) + for page := 1; len(out) < maxTags; page++ { + var raw []gitLabTag + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/repository/tags?page=%d&per_page=%d", page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, tag := range raw { + created := tag.Commit.CommittedDate + if !since.IsZero() && created.Before(since) { + continue + } + out = append(out, Tag{Name: tag.Name, SHA: tag.Target, URL: webURL + "/-/tags/" + url.PathEscape(tag.Name), CreatedAt: created}) + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) CompareCommits(ctx context.Context, owner, repo, base, head string) ([]Commit, error) { + q := url.Values{"from": {base}, "to": {head}, "straight": {"true"}} + var raw struct { + Commits []gitLabCommit `json:"commits"` + } + if err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, "/repository/compare?"+q.Encode()), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + out := make([]Commit, 0, len(raw.Commits)) + for i, commit := range raw.Commits { + if i >= 500 { + break + } + out = append(out, commit.toCommit()) + } + return out, nil +} + +func (g *GitLabProvider) CreateRelease(ctx context.Context, owner, repo string, opts CreateReleaseOptions) (*Release, error) { + bodyMap := map[string]any{"tag_name": opts.TagName, "name": opts.Name, "description": opts.Body} + if opts.TargetCommitish != "" { + bodyMap["ref"] = opts.TargetCommitish + } + body, err := json.Marshal(bodyMap) + if err != nil { + return nil, err + } + var raw gitLabRelease + if err := g.doJSON(ctx, http.MethodPost, g.projectAPIURL(owner, repo, "/releases"), bytes.NewReader(body), http.StatusCreated, &raw); err != nil { + return nil, err + } + result := raw.toRelease(g.projectWebURL(owner, repo)) + return &result, nil +} + +func (g *GitLabProvider) ListReleases(ctx context.Context, owner, repo string) ([]Release, error) { + const perPage = 100 + var out []Release + webURL := g.projectWebURL(owner, repo) + for page := 1; ; page++ { + var raw []gitLabRelease + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/releases?page=%d&per_page=%d", page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, release := range raw { + out = append(out, release.toRelease(webURL)) + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) ListIssueComments(ctx context.Context, owner, repo string, number int) ([]IssueComment, error) { + const perPage = 100 + var out []IssueComment + for page := 1; ; page++ { + var raw []gitLabNote + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/merge_requests/%d/notes?sort=asc&page=%d&per_page=%d", number, page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, note := range raw { + if note.System || note.Type != "" { + continue + } + out = append(out, note.toIssueComment("issue_comment", "")) + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) ListPullRequestReviewEvents(ctx context.Context, owner, repo string, number int) ([]IssueComment, error) { + const perPage = 100 + var out []IssueComment + for page := 1; ; page++ { + var raw []gitLabDiscussion + reqURL := g.projectAPIURL(owner, repo, fmt.Sprintf("/merge_requests/%d/discussions?page=%d&per_page=%d", number, page, perPage)) + if err := g.doJSON(ctx, http.MethodGet, reqURL, http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + for _, discussion := range raw { + if discussion.IndividualNote { + continue + } + for _, note := range discussion.Notes { + if note.System { + continue + } + kind := "review" + if note.Position.NewPath != "" { + kind = "review_comment" + } + out = append(out, note.toIssueComment(kind, discussion.ID)) + } + } + if len(raw) < perPage { + break + } + } + return out, nil +} + +func (g *GitLabProvider) CreateIssueComment(ctx context.Context, owner, repo string, number int, commentBody string) (int64, error) { + body, err := json.Marshal(map[string]string{"body": commentBody}) + if err != nil { + return 0, err + } + var raw gitLabNote + if err := g.doJSON(ctx, http.MethodPost, g.projectAPIURL(owner, repo, fmt.Sprintf("/merge_requests/%d/notes", number)), bytes.NewReader(body), http.StatusCreated, &raw); err != nil { + return 0, err + } + return raw.ID, nil +} + +func (g *GitLabProvider) UpdateIssueComment(ctx context.Context, owner, repo string, number int, commentID int64, commentBody string) error { + body, err := json.Marshal(map[string]string{"body": commentBody}) + if err != nil { + return err + } + path := fmt.Sprintf("/merge_requests/%d/notes/%d", number, commentID) + return g.doJSON(ctx, http.MethodPut, g.projectAPIURL(owner, repo, path), bytes.NewReader(body), http.StatusOK, nil) +} + +func (g *GitLabProvider) CanUserWriteRepository(ctx context.Context, owner, repo, username string) (bool, error) { + q := url.Values{"username": {username}} + var users []gitLabUser + if err := g.doJSON(ctx, http.MethodGet, g.apiURL("/users?"+q.Encode()), http.NoBody, http.StatusOK, &users); err != nil { + return false, err + } + var userID int64 + for _, user := range users { + if strings.EqualFold(user.Username, username) { + userID = user.ID + break + } + } + if userID == 0 { + return false, nil + } + var member struct { + AccessLevel int `json:"access_level"` + } + err := g.doJSON(ctx, http.MethodGet, g.projectAPIURL(owner, repo, "/members/all/"+strconv.FormatInt(userID, 10)), http.NoBody, http.StatusOK, &member) + if errors.Is(err, ErrNotFound) { + return false, nil + } + if err != nil { + return false, err + } + return member.AccessLevel >= 30, nil +} + +func (g *GitLabProvider) RegisterWebhook(ctx context.Context, owner, repo string, opts WebhookOptions) (*WebhookRegistration, error) { + events := map[string]bool{} + if len(opts.Events) == 0 { + events["push_events"] = true + events["merge_requests_events"] = true + } + for _, event := range opts.Events { + switch event { + case "push": + events["push_events"] = true + case "tag_push": + events["tag_push_events"] = true + case "pull_request", "merge_request": + events["merge_requests_events"] = true + case "note": + events["note_events"] = true + case "release": + events["releases_events"] = true + } + } + bodyMap := map[string]any{"url": opts.URL, "token": opts.Secret, "enable_ssl_verification": true} + for key, enabled := range events { + bodyMap[key] = enabled + } + body, err := json.Marshal(bodyMap) + if err != nil { + return nil, err + } + var raw gitLabHook + if err := g.doJSON(ctx, http.MethodPost, g.projectAPIURL(owner, repo, "/hooks"), bytes.NewReader(body), http.StatusCreated, &raw); err != nil { + return nil, err + } + return &WebhookRegistration{ID: strconv.FormatInt(raw.ID, 10), URL: raw.URL, Events: opts.Events, IsActive: true, CreatedAt: raw.CreatedAt}, nil +} + +func (g *GitLabProvider) DeleteWebhook(ctx context.Context, owner, repo, webhookID string) error { + return g.doJSON(ctx, http.MethodDelete, g.projectAPIURL(owner, repo, "/hooks/"+url.PathEscape(webhookID)), http.NoBody, http.StatusNoContent, nil) +} + +func (g *GitLabProvider) GetOAuthURL(state, redirectURI string) string { + q := url.Values{"client_id": {g.clientID}, "redirect_uri": {redirectURI}, "response_type": {"code"}, "state": {state}, "scope": {"api"}} + return g.baseURL + "/oauth/authorize?" + q.Encode() +} + +func (g *GitLabProvider) performTokenRequest(ctx context.Context, params url.Values) (*OAuthTokens, error) { + req, err := http.NewRequestWithContext(ctx, http.MethodPost, g.baseURL+"/oauth/token", strings.NewReader(params.Encode())) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Accept", "application/json") + resp, err := g.httpClient.Do(req) + if err != nil { + return nil, err + } + defer func() { _ = resp.Body.Close() }() + body, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20)) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + if resp.StatusCode == http.StatusBadRequest && bytes.Contains(body, []byte("invalid_grant")) { + return nil, fmt.Errorf("%w: %s", ErrRefreshTokenInvalid, body) + } + return nil, fmt.Errorf("%w: %s", ErrProviderError, body) + } + var raw struct { + AccessToken string `json:"access_token"` + TokenType string `json:"token_type"` + RefreshToken string `json:"refresh_token"` + ExpiresIn int `json:"expires_in"` + CreatedAt int64 `json:"created_at"` + Scope string `json:"scope"` + } + if err := json.Unmarshal(body, &raw); err != nil { + return nil, err + } + result := &OAuthTokens{AccessToken: raw.AccessToken, TokenType: raw.TokenType, RefreshToken: raw.RefreshToken, Scope: raw.Scope} + if raw.ExpiresIn > 0 { + base := time.Now() + if raw.CreatedAt > 0 { + base = time.Unix(raw.CreatedAt, 0) + } + expires := base.Add(time.Duration(raw.ExpiresIn) * time.Second) + result.ExpiresAt = &expires + } + return result, nil +} + +func (g *GitLabProvider) ExchangeCode(ctx context.Context, code, redirectURI string) (*OAuthTokens, error) { + return g.performTokenRequest(ctx, url.Values{"client_id": {g.clientID}, "client_secret": {g.clientSecret}, "code": {code}, "grant_type": {"authorization_code"}, "redirect_uri": {redirectURI}}) +} + +func (g *GitLabProvider) RefreshToken(ctx context.Context, refreshToken string) (*OAuthTokens, error) { + return g.performTokenRequest(ctx, url.Values{"client_id": {g.clientID}, "client_secret": {g.clientSecret}, "refresh_token": {refreshToken}, "grant_type": {"refresh_token"}}) +} + +func (g *GitLabProvider) RevokeToken(ctx context.Context, accessToken string) error { + params := url.Values{"client_id": {g.clientID}, "client_secret": {g.clientSecret}, "token": {accessToken}} + req, err := http.NewRequestWithContext(ctx, http.MethodPost, g.baseURL+"/oauth/revoke", strings.NewReader(params.Encode())) + if err != nil { + return err + } + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + resp, err := g.httpClient.Do(req) + if err != nil { + return err + } + defer func() { _ = resp.Body.Close() }() + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent { + return g.handleErrorResponse(resp) + } + return nil +} + +func (g *GitLabProvider) GetCurrentUser(ctx context.Context) (*User, error) { + var raw gitLabUser + if err := g.doJSON(ctx, http.MethodGet, g.apiURL("/user"), http.NoBody, http.StatusOK, &raw); err != nil { + return nil, err + } + result := raw.toUser() + return &result, nil +} + +type gitLabProject struct { + ID int64 `json:"id"` + Name string `json:"name"` + PathWithNamespace string `json:"path_with_namespace"` + Description string `json:"description"` + WebURL string `json:"web_url"` + HTTPURL string `json:"http_url_to_repo"` + SSHURL string `json:"ssh_url_to_repo"` + DefaultBranch string `json:"default_branch"` + Visibility string `json:"visibility"` + Archived bool `json:"archived"` + CreatedAt time.Time `json:"created_at"` + LastActivityAt time.Time `json:"last_activity_at"` + Namespace struct { + FullPath string `json:"full_path"` + } `json:"namespace"` +} + +func (p gitLabProject) toRepository() Repository { + return Repository{ID: strconv.FormatInt(p.ID, 10), Name: p.Name, FullName: p.PathWithNamespace, Description: p.Description, + URL: p.WebURL, CloneURL: p.HTTPURL, SSHURL: p.SSHURL, DefaultBranch: p.DefaultBranch, IsPrivate: p.Visibility == "private", + IsArchived: p.Archived, Owner: p.Namespace.FullPath, CreatedAt: p.CreatedAt, UpdatedAt: p.LastActivityAt} +} + +type gitLabUser struct { + ID int64 `json:"id"` + Username string `json:"username"` + Name string `json:"name"` + PublicEmail string `json:"public_email"` + Email string `json:"email"` + AvatarURL string `json:"avatar_url"` +} + +func (u gitLabUser) toUser() User { + email := u.Email + if email == "" { + email = u.PublicEmail + } + return User{ID: strconv.FormatInt(u.ID, 10), Username: u.Username, Name: u.Name, Email: email, AvatarURL: u.AvatarURL} +} + +type gitLabCommit struct { + ID string `json:"id"` + Message string `json:"message"` + WebURL string `json:"web_url"` + AuthorName string `json:"author_name"` + AuthorEmail string `json:"author_email"` + AuthoredDate time.Time `json:"authored_date"` + CommitterName string `json:"committer_name"` + CommitterEmail string `json:"committer_email"` + CommittedDate time.Time `json:"committed_date"` +} + +func (c gitLabCommit) toCommit() Commit { + created := c.AuthoredDate + if created.IsZero() { + created = c.CommittedDate + } + return Commit{SHA: c.ID, Message: c.Message, URL: c.WebURL, Author: User{Name: c.AuthorName, Email: c.AuthorEmail}, Committer: User{Name: c.CommitterName, Email: c.CommitterEmail}, CreatedAt: created} +} + +type gitLabBranch struct { + Name string `json:"name"` + Protected bool `json:"protected"` + Default bool `json:"default"` + Commit gitLabCommit `json:"commit"` +} + +func (b gitLabBranch) toBranch() Branch { + return Branch{Name: b.Name, SHA: b.Commit.ID, Protected: b.Protected, IsDefault: b.Default} +} + +type gitLabMergeRequest struct { + ID int64 `json:"id"` + IID int `json:"iid"` + Title string `json:"title"` + Description string `json:"description"` + State string `json:"state"` + WebURL string `json:"web_url"` + SourceBranch string `json:"source_branch"` + TargetBranch string `json:"target_branch"` + SHA string `json:"sha"` + Draft bool `json:"draft"` + WorkInProgress bool `json:"work_in_progress"` + Author gitLabUser `json:"author"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + MergedAt *time.Time `json:"merged_at"` + ClosedAt *time.Time `json:"closed_at"` +} + +func (mr gitLabMergeRequest) toPullRequest(repo string) PullRequest { + state := mr.State + if state == "opened" { + state = "open" + } + merged := state == "merged" || mr.MergedAt != nil + if merged { + state = "merged" + } + return PullRequest{ID: int(mr.ID), Number: mr.IID, Title: mr.Title, Body: mr.Description, State: state, URL: mr.WebURL, HeadBranch: mr.SourceBranch, HeadRepo: repo, HeadSHA: mr.SHA, BaseBranch: mr.TargetBranch, IsMerged: merged, IsDraft: mr.Draft || mr.WorkInProgress, Author: mr.Author.toUser(), CreatedAt: mr.CreatedAt, UpdatedAt: mr.UpdatedAt, MergedAt: mr.MergedAt, ClosedAt: mr.ClosedAt} +} + +type gitLabTag struct { + Name string `json:"name"` + Target string `json:"target"` + Commit gitLabCommit `json:"commit"` +} + +type gitLabRelease struct { + TagName string `json:"tag_name"` + Name string `json:"name"` + Description string `json:"description"` + CreatedAt time.Time `json:"created_at"` + ReleasedAt time.Time `json:"released_at"` + Upcoming bool `json:"upcoming_release"` + Historical bool `json:"historical_release"` + Links struct { + Self string `json:"self"` + } `json:"_links"` + Assets struct { + Sources []struct { + Format string `json:"format"` + URL string `json:"url"` + } `json:"sources"` + Links []struct { + Name string `json:"name"` + URL string `json:"url"` + DirectURL string `json:"direct_asset_url"` + LinkType string `json:"link_type"` + } `json:"links"` + } `json:"assets"` +} + +func (r gitLabRelease) toRelease(projectURL string) Release { + status := "released" + if r.Upcoming { + status = "upcoming" + } else if r.Historical { + status = "historical" + } + assets := make([]models.SCMReleaseAsset, 0, len(r.Assets.Sources)+len(r.Assets.Links)) + for _, source := range r.Assets.Sources { + assets = append(assets, models.SCMReleaseAsset{Kind: "source", Name: source.Format, URL: source.URL, Format: source.Format}) + } + for _, link := range r.Assets.Links { + assets = append(assets, models.SCMReleaseAsset{Kind: "link", Name: link.Name, URL: link.URL, DirectURL: link.DirectURL, LinkType: link.LinkType}) + } + var released *time.Time + if !r.ReleasedAt.IsZero() { + releasedAt := r.ReleasedAt + released = &releasedAt + } + return Release{ID: r.TagName, TagName: r.TagName, TagURL: projectURL + "/-/tags/" + url.PathEscape(r.TagName), Name: r.Name, Body: r.Description, URL: r.Links.Self, Status: status, Assets: assets, CreatedAt: r.CreatedAt, PublishedAt: released, ReleasedAt: released} +} + +type gitLabNote struct { + ID int64 `json:"id"` + Type string `json:"type"` + Body string `json:"body"` + Author gitLabUser `json:"author"` + System bool `json:"system"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Position struct { + NewPath string `json:"new_path"` + NewLine int `json:"new_line"` + OldPath string `json:"old_path"` + OldLine int `json:"old_line"` + PositionType string `json:"position_type"` + } `json:"position"` +} + +func (n gitLabNote) toIssueComment(kind, threadID string) IssueComment { + path, line, side := n.Position.NewPath, n.Position.NewLine, "RIGHT" + if path == "" { + path, line, side = n.Position.OldPath, n.Position.OldLine, "LEFT" + } + return IssueComment{ID: n.ID, Kind: kind, Body: n.Body, User: n.Author.toUser(), Path: path, Line: line, Side: side, ThreadID: threadID, CreatedAt: n.CreatedAt, UpdatedAt: n.UpdatedAt} +} + +type gitLabDiscussion struct { + ID string `json:"id"` + IndividualNote bool `json:"individual_note"` + Notes []gitLabNote `json:"notes"` +} +type gitLabHook struct { + ID int64 `json:"id"` + URL string `json:"url"` + CreatedAt time.Time `json:"created_at"` +} diff --git a/internal/scm/gitlab_test.go b/internal/scm/gitlab_test.go new file mode 100644 index 000000000..e012a9bb2 --- /dev/null +++ b/internal/scm/gitlab_test.go @@ -0,0 +1,120 @@ +package scm + +import ( + "context" + "io" + "net/http" + "strings" + "testing" + "time" + + "windshift/internal/models" +) + +type roundTripFunc func(*http.Request) (*http.Response, error) + +func (f roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) { return f(request) } + +func jsonResponse(status int, body string) *http.Response { + return &http.Response{StatusCode: status, Header: make(http.Header), Body: io.NopCloser(strings.NewReader(body))} +} + +func TestGitLabProviderNestedProjectAndPAT(t *testing.T) { + t.Parallel() + provider, err := NewGitLabProvider(ProviderConfig{BaseURL: "https://git.example/api/v4", AuthMethod: models.SCMAuthMethodPAT, PersonalAccessToken: "pat-token"}) + if err != nil { + t.Fatal(err) + } + provider.httpClient = &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) { + if request.URL.EscapedPath() != "/api/v4/projects/group%2Fsubgroup%2Fproject" { + t.Fatalf("unexpected path: %s", request.URL.EscapedPath()) + } + if got := request.Header.Get("PRIVATE-TOKEN"); got != "pat-token" { + t.Fatalf("unexpected PAT header: %q", got) + } + return jsonResponse(http.StatusOK, `{ + "id":42,"name":"project","path_with_namespace":"group/subgroup/project", + "web_url":"https://git.example/group/subgroup/project", + "http_url_to_repo":"https://git.example/group/subgroup/project.git", + "ssh_url_to_repo":"git@git.example:group/subgroup/project.git", + "default_branch":"main","visibility":"private", + "namespace":{"full_path":"group/subgroup"} + }`), nil + })} + + repository, err := provider.GetRepository(context.Background(), "group/subgroup", "project") + if err != nil { + t.Fatal(err) + } + if repository.FullName != "group/subgroup/project" || repository.Owner != "group/subgroup" || repository.ID != "42" { + t.Fatalf("unexpected repository mapping: %+v", repository) + } +} + +func TestGitLabProviderReleaseMetadata(t *testing.T) { + t.Parallel() + const releasedAt = "2026-08-30T12:00:00Z" + provider, err := NewGitLabProvider(ProviderConfig{BaseURL: "https://git.example", AuthMethod: models.SCMAuthMethodOAuth, OAuthAccessToken: "oauth-token"}) + if err != nil { + t.Fatal(err) + } + provider.httpClient = &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) { + if got := request.Header.Get("Authorization"); got != "Bearer oauth-token" { + t.Fatalf("unexpected OAuth header: %q", got) + } + return jsonResponse(http.StatusOK, `[{ + "tag_name":"v2.0.0","name":"Version 2","description":"Notes", + "created_at":"2026-08-30T12:00:00Z","released_at":"2026-08-30T12:00:00Z", + "_links":{"self":"https://git.example/group/project/-/releases/v2.0.0"}, + "assets":{ + "sources":[{"format":"zip","url":"https://git.example/source.zip"}], + "links":[{"name":"binary","url":"https://cdn.example/app","direct_asset_url":"/downloads/app","link_type":"package"}] + } + }]`), nil + })} + + releases, err := provider.ListReleases(context.Background(), "group", "project") + if err != nil { + t.Fatal(err) + } + if len(releases) != 1 || releases[0].Status != "released" || releases[0].TagURL != "https://git.example/group/project/-/tags/v2.0.0" { + t.Fatalf("unexpected release mapping: %+v", releases) + } + if len(releases[0].Assets) != 2 || releases[0].Assets[1].DirectURL != "/downloads/app" { + t.Fatalf("unexpected assets: %+v", releases[0].Assets) + } + want, _ := time.Parse(time.RFC3339, releasedAt) + if releases[0].ReleasedAt == nil || !releases[0].ReleasedAt.Equal(want) { + t.Fatalf("unexpected release date: %v", releases[0].ReleasedAt) + } +} + +func TestGitLabProviderRefreshToken(t *testing.T) { + t.Parallel() + provider, err := NewGitLabProvider(ProviderConfig{BaseURL: "https://git.example", AuthMethod: models.SCMAuthMethodOAuth, OAuthClientID: "client", OAuthClientSecret: "secret"}) + if err != nil { + t.Fatal(err) + } + provider.httpClient = &http.Client{Transport: roundTripFunc(func(request *http.Request) (*http.Response, error) { + if request.URL.Path != "/oauth/token" || request.Method != http.MethodPost { + t.Fatalf("unexpected request: %s %s", request.Method, request.URL.Path) + } + body, readErr := io.ReadAll(request.Body) + if readErr != nil { + t.Fatal(readErr) + } + values := string(body) + if !strings.Contains(values, "grant_type=refresh_token") || !strings.Contains(values, "refresh_token=refresh-me") { + t.Fatalf("unexpected form: %s", values) + } + return jsonResponse(http.StatusOK, `{"access_token":"new-token","refresh_token":"next-refresh","token_type":"Bearer","expires_in":7200,"scope":"api"}`), nil + })} + + tokens, err := provider.RefreshToken(context.Background(), "refresh-me") + if err != nil { + t.Fatal(err) + } + if tokens.AccessToken != "new-token" || tokens.RefreshToken != "next-refresh" || tokens.ExpiresAt == nil { + t.Fatalf("unexpected tokens: %+v", tokens) + } +} diff --git a/internal/scm/issue_sync.go b/internal/scm/issue_sync.go index 92e929318..a7eeef2ab 100644 --- a/internal/scm/issue_sync.go +++ b/internal/scm/issue_sync.go @@ -531,17 +531,18 @@ func (s *IssueSyncService) PushCommentToGitHub(ctx context.Context, itemID, comm // PushCommentUpdateToGitHub pushes a Windshift comment edit to the linked GitHub comment. func (s *IssueSyncService) PushCommentUpdateToGitHub(ctx context.Context, commentID, authorID int, newBody string) { var ghCommentID int64 + var issueNumber int var repoName string var connectionID int err := s.db.QueryRowContext(ctx, ` - SELECT isc2.github_comment_id, wr.repository_name, wr.workspace_scm_connection_id + SELECT isc2.github_comment_id, isi.github_issue_number, wr.repository_name, wr.workspace_scm_connection_id FROM issue_sync_comments isc2 JOIN issue_sync_items isi ON isi.id = isc2.issue_sync_item_id JOIN issue_sync_configs isc ON isc.id = isi.issue_sync_config_id JOIN workspace_repositories wr ON wr.id = isc.workspace_repository_id WHERE isc2.comment_id = ? AND isc.sync_enabled = ? AND isc.sync_comments = ? - `, commentID, true, true).Scan(&ghCommentID, &repoName, &connectionID) + `, commentID, true, true).Scan(&ghCommentID, &issueNumber, &repoName, &connectionID) if err != nil { if !errors.Is(err, sql.ErrNoRows) { slog.Error("lookup sync comment for update pushback", "comment_id", commentID, "error", err) @@ -578,7 +579,7 @@ func (s *IssueSyncService) PushCommentUpdateToGitHub(ctx context.Context, commen return } - if err := issueProvider.UpdateIssueComment(ctx, parts[0], parts[1], ghCommentID, newBody); err != nil { + if err := issueProvider.UpdateIssueComment(ctx, parts[0], parts[1], issueNumber, ghCommentID, newBody); err != nil { slog.Error("push comment update to GitHub", "github_comment_id", ghCommentID, "error", err) } } diff --git a/internal/scm/milestone_attach.go b/internal/scm/milestone_attach.go index 6223eb82d..061f2feab 100644 --- a/internal/scm/milestone_attach.go +++ b/internal/scm/milestone_attach.go @@ -6,10 +6,10 @@ import ( "errors" "fmt" "log/slog" - "strings" "windshift/internal/repository" "windshift/internal/services" + "windshift/internal/utils" ) // MilestoneAttacher implements services.MilestoneCommitAttacher by @@ -69,11 +69,10 @@ func (m *MilestoneAttacher) AttachCommitIssues(ctx context.Context, in services. return result, errors.New("provider does not implement RefProvider (CompareCommits)") } - parts := strings.SplitN(repoCtx.repositoryName, "/", 2) - if len(parts) != 2 { + owner, repo, ok := utils.SplitRepositoryPath(repoCtx.repositoryName) + if !ok { return result, fmt.Errorf("invalid repository_name %q", repoCtx.repositoryName) } - owner, repo := parts[0], parts[1] commits, err := rp.CompareCommits(ctx, owner, repo, in.BaseRef, in.HeadRef) if err != nil { diff --git a/internal/scm/pr_review_events.go b/internal/scm/pr_review_events.go index 1907a78c1..5480b0a09 100644 --- a/internal/scm/pr_review_events.go +++ b/internal/scm/pr_review_events.go @@ -226,7 +226,7 @@ func reviewInstruction(event prReviewEvent) string { Path string `json:"path"` Line int `json:"line"` Side string `json:"side"` - ThreadID int64 `json:"thread_id"` + ThreadID string `json:"thread_id"` } if json.Unmarshal([]byte(event.ContextJSON), &reviewContext) != nil { return event.Body @@ -235,7 +235,7 @@ func reviewInstruction(event prReviewEvent) string { if reviewContext.Line > 0 { location += fmt.Sprintf(":%d", reviewContext.Line) } - return fmt.Sprintf("PR %s request at %s (side=%s, thread=%d):\n\n%s", event.Kind, location, reviewContext.Side, reviewContext.ThreadID, event.Body) + return fmt.Sprintf("PR %s request at %s (side=%s, thread=%s):\n\n%s", event.Kind, location, reviewContext.Side, reviewContext.ThreadID, event.Body) } func eventMarker(eventID int64, phase string) string { diff --git a/internal/scm/sync.go b/internal/scm/sync.go index 7bd6efca1..ed06c7880 100644 --- a/internal/scm/sync.go +++ b/internal/scm/sync.go @@ -3,9 +3,11 @@ package scm import ( "context" "database/sql" + "encoding/json" "errors" "fmt" "log/slog" + "net/url" "regexp" "strconv" "strings" @@ -18,6 +20,7 @@ import ( "windshift/internal/repository" "windshift/internal/services" "windshift/internal/sso" + "windshift/internal/utils" ) // Sync pagination/budget constants applied to every per-repo sync. These @@ -472,11 +475,10 @@ func (s *SyncService) SyncRepository(ctx context.Context, repoID int) error { // syncRepository performs the actual sync for a single repository func (s *SyncService) syncRepository(ctx context.Context, provider Provider, repoID int, repositoryName, defaultBranch string, workspaceID int, workspaceKey, itemKeyPattern string, lastSyncedAt time.Time) error { - parts := strings.SplitN(repositoryName, "/", 2) - if len(parts) != 2 { + owner, repo, ok := utils.SplitRepositoryPath(repositoryName) + if !ok { return fmt.Errorf("invalid repository name format: %s", repositoryName) } - owner, repo := parts[0], parts[1] slog.Debug("Syncing repository", slog.String("component", "scm"), slog.String("repository", repositoryName), slog.String("workspace", workspaceKey)) @@ -503,6 +505,9 @@ func (s *SyncService) syncRepository(ctx context.Context, provider Provider, rep if err := s.syncTagsAndReleases(ctx, provider, owner, repo, repoID, workspaceID, baselineRefs); err != nil { syncErrs = append(syncErrs, fmt.Errorf("sync tags: %w", err)) } + if err := s.syncAttachedReleases(ctx, provider, owner, repo, repoID); err != nil { + syncErrs = append(syncErrs, fmt.Errorf("sync attached releases: %w", err)) + } if err := errors.Join(syncErrs...); err != nil { return fmt.Errorf("sync repository %q: %w", repositoryName, err) } @@ -518,6 +523,109 @@ func (s *SyncService) syncRepository(ctx context.Context, provider Provider, rep return nil } +// syncAttachedReleases refreshes milestone release records from current SCM +// truth. Tags and releases are intentionally distinct: deleting a release +// leaves a tag_only record, while deleting both marks the attachment missing. +func (s *SyncService) syncAttachedReleases(ctx context.Context, provider Provider, owner, repo string, repoID int) error { + var attached int + if err := s.db.QueryRowContext(ctx, `SELECT COUNT(*) FROM milestone_releases WHERE workspace_repository_id = ? AND state = 'created'`, repoID).Scan(&attached); err != nil || attached == 0 { + return err + } + releaseProvider, releasesOK := provider.(ReleaseProvider) + refProvider, refsOK := provider.(RefProvider) + if !releasesOK || !refsOK { + return nil + } + releases, err := releaseProvider.ListReleases(ctx, owner, repo) + if err != nil { + return err + } + tags, err := refProvider.ListTags(ctx, owner, repo, time.Time{}) + if err != nil { + return err + } + releaseByTag := make(map[string]Release, len(releases)) + for _, release := range releases { + releaseByTag[release.TagName] = release + } + tagByName := make(map[string]Tag, len(tags)) + for _, tag := range tags { + tagByName[tag.Name] = tag + } + + rows, err := s.db.QueryContext(ctx, `SELECT id, tag_name FROM milestone_releases WHERE workspace_repository_id = ? AND state = 'created'`, repoID) + if err != nil { + return err + } + defer func() { _ = rows.Close() }() + type attachedRelease struct { + id int + tag string + } + var attachedRows []attachedRelease + for rows.Next() { + var row attachedRelease + if err := rows.Scan(&row.id, &row.tag); err != nil { + return err + } + attachedRows = append(attachedRows, row) + } + if err := rows.Err(); err != nil { + return err + } + + for _, row := range attachedRows { + if release, ok := releaseByTag[row.tag]; ok { + assetsJSON, _ := json.Marshal(release.Assets) + releasedAt := release.ReleasedAt + if releasedAt == nil { + releasedAt = release.PublishedAt + } + status := release.Status + if status == "" { + if release.IsDraft { + status = "draft" + } else if release.IsPrerelease { + status = "prerelease" + } else { + status = "released" + } + } + _, err = s.db.ExecWriteContext(ctx, ` + UPDATE milestone_releases + SET name=?, body=?, is_draft=?, is_prerelease=?, tag_url=?, release_status=?, + released_at=?, assets_json=?, scm_release_id=?, scm_release_url=?, + last_synced_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP + WHERE id=? + `, release.Name, release.Body, release.IsDraft, release.IsPrerelease, release.TagURL, status, + releasedAt, string(assetsJSON), release.ID, release.URL, row.id) + if err != nil { + return err + } + continue + } + if tag, ok := tagByName[row.tag]; ok { + _, err = s.db.ExecWriteContext(ctx, ` + UPDATE milestone_releases + SET name=NULL, body=NULL, is_draft=false, is_prerelease=false, tag_url=?, + release_status='tag_only', released_at=NULL, assets_json='[]', + scm_release_id=NULL, scm_release_url=NULL, last_synced_at=CURRENT_TIMESTAMP, + updated_at=CURRENT_TIMESTAMP WHERE id=? + `, tag.URL, row.id) + } else { + _, err = s.db.ExecWriteContext(ctx, ` + UPDATE milestone_releases SET release_status='missing', tag_url=NULL, + released_at=NULL, assets_json='[]', scm_release_id=NULL, scm_release_url=NULL, + last_synced_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP WHERE id=? + `, row.id) + } + if err != nil { + return err + } + } + return nil +} + // syncPullRequests syncs pull requests from a repository. The paginated // fetch is delegated to iteratePullRequests so the loop can be unit-tested // in isolation; the callback below performs the per-PR work. @@ -951,8 +1059,7 @@ func (s *SyncService) syncBranches(ctx context.Context, provider Provider, owner continue // Item doesn't exist in this workspace } - // Construct branch URL (best effort - varies by provider) - branchURL := fmt.Sprintf("https://github.com/%s/%s/tree/%s", owner, repo, branch.Name) + branchURL := branchWebURL(provider, owner, repo, branch.Name) err = s.upsertItemSCMLink(ctx, itemID, repoID, models.SCMLinkTypeBranch, branch.Name, branchURL, branch.Name, "", "", "", string(key.Source)) @@ -965,6 +1072,18 @@ func (s *SyncService) syncBranches(ctx context.Context, provider Provider, owner return nil } +func branchWebURL(provider Provider, owner, repo, branch string) string { + escapedBranch := url.PathEscape(branch) + switch typed := provider.(type) { + case *GitLabProvider: + return typed.projectWebURL(owner, repo) + "/-/tree/" + escapedBranch + case *GiteaProvider: + return typed.baseURL + "/" + owner + "/" + repo + "/src/branch/" + escapedBranch + default: + return "https://github.com/" + owner + "/" + repo + "/tree/" + escapedBranch + } +} + // findItemByKey finds an item by its workspace key and number. Returns 0 // (without error) when no item matches. func (s *SyncService) findItemByKey(_ context.Context, workspaceID int, workspaceKey string, itemNumber int) (int, error) { @@ -1238,11 +1357,10 @@ func (s *SyncService) refreshItemSCMLink(ctx context.Context, linkID int, userID } } - parts := strings.SplitN(repositoryName, "/", 2) - if len(parts) != 2 { + owner, repo, ok := utils.SplitRepositoryPath(repositoryName) + if !ok { return fmt.Errorf("invalid repository name format: %s", repositoryName) } - owner, repo := parts[0], parts[1] return s.updateLinkFromProvider(ctx, provider, owner, repo, linkID, linkType, externalID, externalURL.String) } @@ -1369,11 +1487,10 @@ func (s *SyncService) resolveRepoAndProvider(ctx context.Context, workspaceRepoI } // Parse owner/repo from repository name - parts := strings.SplitN(repositoryName, "/", 2) - if len(parts) != 2 { + owner, repo, ok := utils.SplitRepositoryPath(repositoryName) + if !ok { return nil, fmt.Errorf("invalid repository name format: %s", repositoryName) } - owner, repo := parts[0], parts[1] // Resolve provider credentials credResolver := NewCredentialResolver(s.db, s.encryption) @@ -1409,6 +1526,8 @@ func (s *SyncService) resolveRepoAndProvider(ctx context.Context, workspaceRepoI switch providerType { case models.SCMProviderTypeGitHub: resolvedBaseURL = "https://github.com" + case models.SCMProviderTypeGitLab: + resolvedBaseURL = "https://gitlab.com" case models.SCMProviderTypeGitea: resolvedBaseURL = "https://gitea.com" } @@ -1425,6 +1544,67 @@ func (s *SyncService) resolveRepoAndProvider(ctx context.Context, workspaceRepoI }, nil } +// ListReleaseCandidates returns existing tags, enriched with first-class SCM +// release metadata when the provider exposes a release for the same tag. +func (s *SyncService) ListReleaseCandidates(ctx context.Context, workspaceRepoID, userID int) ([]ReleaseCandidate, error) { + rc, err := s.resolveRepoAndProvider(ctx, workspaceRepoID, userID) + if err != nil { + return nil, err + } + refProvider, ok := rc.Provider.(RefProvider) + if !ok { + return nil, errors.New("SCM provider does not support tags") + } + releaseProvider, ok := rc.Provider.(ReleaseProvider) + if !ok { + return nil, errors.New("SCM provider does not support releases") + } + + tags, err := refProvider.ListTags(ctx, rc.Owner, rc.Repo, time.Time{}) + if err != nil { + return nil, fmt.Errorf("list tags: %w", err) + } + releases, err := releaseProvider.ListReleases(ctx, rc.Owner, rc.Repo) + if err != nil { + return nil, fmt.Errorf("list releases: %w", err) + } + releasesByTag := make(map[string]Release, len(releases)) + for _, release := range releases { + releasesByTag[release.TagName] = release + } + + candidates := make([]ReleaseCandidate, 0, len(tags)+len(releases)) + seen := make(map[string]struct{}, len(tags)) + for _, tag := range tags { + candidate := ReleaseCandidate{TagName: tag.Name, TagURL: tag.URL, SHA: tag.SHA, Status: "tag_only"} + if release, exists := releasesByTag[tag.Name]; exists { + releaseCopy := release + candidate.Release = &releaseCopy + candidate.Status = release.Status + if candidate.Status == "" { + candidate.Status = "released" + } + if release.TagURL != "" { + candidate.TagURL = release.TagURL + } + } + candidates = append(candidates, candidate) + seen[tag.Name] = struct{}{} + } + for _, release := range releases { + if _, exists := seen[release.TagName]; exists { + continue + } + releaseCopy := release + status := release.Status + if status == "" { + status = "released" + } + candidates = append(candidates, ReleaseCandidate{TagName: release.TagName, TagURL: release.TagURL, Status: status, Release: &releaseCopy}) + } + return candidates, nil +} + // CreateBranchForRepository creates a branch in a workspace repository. // This method implements the plugins.SCMService interface. // If userID is provided (> 0), it uses the user's personal OAuth token for OAuth providers. @@ -1452,8 +1632,7 @@ func (s *SyncService) CreateBranchForRepository(ctx context.Context, workspaceRe return "", fmt.Errorf("failed to create branch: %w", err) } - // Both GitHub and Gitea use /tree/ for branch URLs - branchURL := fmt.Sprintf("%s/%s/tree/%s", rc.BaseURL, rc.RepositoryName, branchName) + branchURL := branchWebURL(rc.Provider, rc.Owner, rc.Repo, branchName) slog.Debug("Created branch", slog.String("component", "scm"), slog.String("branch", branchName), slog.String("repository", rc.RepositoryName)) return branchURL, nil @@ -1558,6 +1737,8 @@ func (s *SyncService) CreatePullRequestForRepository(ctx context.Context, worksp switch rc.ProviderType { case models.SCMProviderTypeGitea: prURL = fmt.Sprintf("%s/%s/pulls/%d", rc.BaseURL, rc.RepositoryName, pr.Number) + case models.SCMProviderTypeGitLab: + prURL = fmt.Sprintf("%s/%s/-/merge_requests/%d", rc.BaseURL, rc.RepositoryName, pr.Number) default: prURL = fmt.Sprintf("%s/%s/pull/%d", rc.BaseURL, rc.RepositoryName, pr.Number) } diff --git a/internal/scm/types.go b/internal/scm/types.go index b7895b865..4e8764c14 100644 --- a/internal/scm/types.go +++ b/internal/scm/types.go @@ -1,5 +1,5 @@ // Package scm provides SCM (Source Control Management) provider integration -// for GitHub and Gitea/Forgejo. +// for GitHub, GitLab, and Gitea/Forgejo. package scm import ( @@ -11,7 +11,7 @@ import ( // Provider defines the interface that all SCM providers must implement type Provider interface { - // GetType returns the provider type (github, gitea) + // GetType returns the provider type (github, gitlab, gitea) GetType() models.SCMProviderType // TestConnection tests if the provider connection is working @@ -188,6 +188,7 @@ type Branch struct { type Tag struct { Name string `json:"name"` SHA string `json:"sha"` // target commit SHA + URL string `json:"url,omitempty"` CreatedAt time.Time `json:"created_at"` } @@ -263,15 +264,29 @@ type GitHubAppInstallation struct { // Release represents a release from an SCM provider type Release struct { - ID string `json:"id"` - TagName string `json:"tag_name"` - Name string `json:"name"` - Body string `json:"body"` - URL string `json:"url"` - IsDraft bool `json:"is_draft"` - IsPrerelease bool `json:"is_prerelease"` - CreatedAt time.Time `json:"created_at"` - PublishedAt *time.Time `json:"published_at,omitempty"` + ID string `json:"id"` + TagName string `json:"tag_name"` + TagURL string `json:"tag_url,omitempty"` + Name string `json:"name"` + Body string `json:"body"` + URL string `json:"url"` + Status string `json:"status,omitempty"` + Assets []models.SCMReleaseAsset `json:"assets,omitempty"` + IsDraft bool `json:"is_draft"` + IsPrerelease bool `json:"is_prerelease"` + CreatedAt time.Time `json:"created_at"` + PublishedAt *time.Time `json:"published_at,omitempty"` + ReleasedAt *time.Time `json:"released_at,omitempty"` +} + +// ReleaseCandidate is an existing tag that can be attached to a milestone. +// Release is populated when the provider has a first-class release for it. +type ReleaseCandidate struct { + TagName string `json:"tag_name"` + TagURL string `json:"tag_url,omitempty"` + SHA string `json:"sha,omitempty"` + Status string `json:"status"` + Release *Release `json:"release,omitempty"` } // CreateReleaseOptions contains options for creating a release @@ -334,6 +349,8 @@ func NewProvider(cfg ProviderConfig) (Provider, error) { switch cfg.ProviderType { case models.SCMProviderTypeGitHub: return NewGitHubProvider(cfg) + case models.SCMProviderTypeGitLab: + return NewGitLabProvider(cfg) case models.SCMProviderTypeGitea: return NewGiteaProvider(cfg) default: @@ -351,7 +368,7 @@ type IssueComment struct { Path string `json:"path,omitempty"` Line int `json:"line,omitempty"` Side string `json:"side,omitempty"` - ThreadID int64 `json:"thread_id,omitempty"` + ThreadID string `json:"thread_id,omitempty"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } @@ -371,7 +388,7 @@ type IssueCommentProvider interface { ListIssueComments(ctx context.Context, owner, repo string, number int) ([]IssueComment, error) // UpdateIssueComment updates an existing comment on an issue/PR - UpdateIssueComment(ctx context.Context, owner, repo string, commentID int64, body string) error + UpdateIssueComment(ctx context.Context, owner, repo string, number int, commentID int64, body string) error } // PullRequestReviewProvider exposes the review surfaces that are distinct diff --git a/internal/server/server.go b/internal/server/server.go index 58497a44d..e647009c0 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -771,7 +771,7 @@ func (s *Server) initialize() error { scmProviderHandler := handlers.NewSCMProviderHandler(s.db, cfg.Auth.SessionSecret, baseURL) scmWorkspaceRepo := repository.NewSCMWorkspaceRepository(s.db) scmWorkspaceHandler := handlers.NewSCMWorkspaceHandler(scmWorkspaceRepo, scmProviderHandler.GetEncryption(), scmProviderHandler, scm.NewCredentialResolver(s.db, scmProviderHandler.GetEncryption()), permService, baseURL) - scmItemLinksHandler := handlers.NewSCMItemLinksHandler(s.db, scmProviderHandler.GetEncryption(), permService) + scmItemLinksHandler := handlers.NewSCMItemLinksHandler(s.db, scmProviderHandler.GetEncryption(), permService, baseURL) userSCMTokenHandler := handlers.NewUserSCMTokenHandler(repository.NewUserSCMTokenRepository(s.db), scmProviderHandler.GetEncryption()) milestonePlanningService := services.NewPlanningService(s.db) milestonePlanningService.SetSCMWorkspaceRepository(scmWorkspaceRepo) diff --git a/internal/services/action_create_milestone.go b/internal/services/action_create_milestone.go index 35543ef06..6c41804ab 100644 --- a/internal/services/action_create_milestone.go +++ b/internal/services/action_create_milestone.go @@ -313,6 +313,12 @@ func (e *CreateMilestoneExecutor) attachRelease(ctx *models.ExecutionContext, mi } sha, _ := ctx.Variables["new_ref.sha"].(string) repoFullName, _ := ctx.Variables["new_repo.full_name"].(string) + var workspaceRepositoryID *int + if rawID, exists := ctx.Variables["new_repo.workspace_repository_id"]; exists { + if id, ok := coerceInt(rawID); ok && id > 0 { + workspaceRepositoryID = &id + } + } var repoPtr *string if repoFullName != "" { @@ -321,9 +327,10 @@ func (e *CreateMilestoneExecutor) attachRelease(ctx *models.ExecutionContext, mi } return e.planning.AttachRelease(ReleaseMilestoneParams{ - ID: milestoneID, - TagName: tagName, - TargetCommitish: sha, - SCMRepository: repoPtr, + ID: milestoneID, + WorkspaceRepositoryID: workspaceRepositoryID, + TagName: tagName, + TargetCommitish: sha, + SCMRepository: repoPtr, }) } diff --git a/internal/services/agent_pr_service.go b/internal/services/agent_pr_service.go index 7d9e153c3..963ee7fe8 100644 --- a/internal/services/agent_pr_service.go +++ b/internal/services/agent_pr_service.go @@ -613,12 +613,8 @@ func boundPRNote(s string) string { return strings.TrimSpace(s[:cut]) + "\n\n…(truncated)" } -// splitRepoSlug splits "owner/repo" into its parts. Returns ok=false -// when the input doesn't have exactly one slash separator. +// splitRepoSlug splits "namespace/project" at the final slash so GitLab +// subgroup paths remain part of the namespace. func splitRepoSlug(slug string) (owner, repo string, ok bool) { - parts := strings.SplitN(slug, "/", 3) - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return "", "", false - } - return parts[0], parts[1], true + return splitRepositoryPath(slug) } diff --git a/internal/services/binding_service.go b/internal/services/binding_service.go index 11d4a8c09..e4a72f2b4 100644 --- a/internal/services/binding_service.go +++ b/internal/services/binding_service.go @@ -34,13 +34,31 @@ var ErrBindingRepoNeedsSCMConnection = errors.New("binding service: repo_slug re // ErrBindingInvalidRepoSlug is returned when a binding's RepoSlug is // not of the canonical owner/repo shape (no path traversal, no // schemes, no leading slashes). -var ErrBindingInvalidRepoSlug = errors.New("binding service: repo_slug must be owner/repo, alphanumerics + . _ - only") +var ErrBindingInvalidRepoSlug = errors.New("binding service: repo_slug must be namespace/project, alphanumerics + . _ - only") -// validRepoSlug is the canonical owner/repo shape. Two segments -// separated by a single /. No "..", no leading slashes, no schemes — -// the regex on its own rejects all of those because none of the -// allowed characters can produce them. -var validRepoSlug = regexp.MustCompile(`^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$`) +// validRepoSlug accepts a namespace with one or more segments followed by a +// project. No traversal segments, leading slashes, or schemes are allowed. +var validRepoSlug = regexp.MustCompile(`^[A-Za-z0-9._-]+(?:/[A-Za-z0-9._-]+)+$`) + +func isValidRepoSlug(slug string) bool { + if !validRepoSlug.MatchString(slug) { + return false + } + for _, segment := range strings.Split(slug, "/") { + if segment == "." || segment == ".." { + return false + } + } + return true +} + +func splitRepositoryPath(slug string) (namespace, project string, ok bool) { + if !isValidRepoSlug(slug) { + return "", "", false + } + separator := strings.LastIndex(slug, "/") + return slug[:separator], slug[separator+1:], true +} const codingAgentVisionPromptSuffix = ` @@ -517,7 +535,7 @@ func normalizeRepoInputs(inputs []RepoInput) ([]models.BindingRepo, error) { seen := make(map[string]bool, len(inputs)) primaries := 0 for i, in := range inputs { - if !validRepoSlug.MatchString(in.RepoSlug) { + if !isValidRepoSlug(in.RepoSlug) { return nil, ErrBindingInvalidRepoSlug } if in.SCMConnectionID == nil { @@ -1797,7 +1815,7 @@ func applyLLMModelEnv(env map[string]string, cfg *llm.ConnectionRuntimeConfig) { // deriveCloneURL builds a credential-free HTTPS remote from trusted SCM data. func deriveCloneURL(providerType, baseURL, slug string) (string, error) { - if !validRepoSlug.MatchString(slug) { + if !isValidRepoSlug(slug) { return "", ErrBindingInvalidRepoSlug } host := "" @@ -1820,6 +1838,18 @@ func deriveCloneURL(providerType, baseURL, slug string) (string, error) { return "", fmt.Errorf("gitea base url: %w", err) } host = h + case "gitlab": + if baseURL == "" { + baseURL = "https://gitlab.com" + } + u, err := url.Parse(strings.TrimSuffix(strings.TrimSuffix(baseURL, "/"), "/api/v4")) + if err != nil { + return "", fmt.Errorf("gitlab base url: %w", err) + } + if u.Host == "" { + return "", fmt.Errorf("gitlab base url %q has no host", baseURL) + } + return strings.TrimSuffix(u.String(), "/") + "/" + slug + ".git", nil default: return "", fmt.Errorf("unsupported scm provider type %q", providerType) } diff --git a/internal/services/planning_milestones.go b/internal/services/planning_milestones.go index b64d44d96..a53599e66 100644 --- a/internal/services/planning_milestones.go +++ b/internal/services/planning_milestones.go @@ -5,6 +5,7 @@ import ( "crypto/rand" "database/sql" "encoding/hex" + "encoding/json" "errors" "fmt" "log/slog" @@ -100,9 +101,10 @@ func scanMilestoneRow(sc milestoneScanner) (MilestoneResult, error) { var description, targetDate, categoryName, categoryColor, workspaceName, externalKey sql.NullString var categoryID, workspaceID sql.NullInt64 // Release columns - var mrID, mrCreatedBy, mrSCMConnectionID sql.NullInt64 - var mrTagName, mrName, mrBody, mrTargetCommitish sql.NullString + var mrID, mrCreatedBy, mrSCMConnectionID, mrWorkspaceRepositoryID sql.NullInt64 + var mrTagName, mrName, mrBody, mrTargetCommitish, mrTagURL sql.NullString var mrSCMRepository, mrSCMReleaseID, mrSCMReleaseURL sql.NullString + var mrReleaseStatus, mrReleasedAt, mrAssetsJSON, mrLastSyncedAt sql.NullString var mrIsDraft, mrIsPrerelease sql.NullBool var mrCreatedAt sql.NullString @@ -110,7 +112,8 @@ func scanMilestoneRow(sc milestoneScanner) (MilestoneResult, error) { &categoryName, &categoryColor, &m.IsGlobal, &workspaceID, &workspaceName, &externalKey, &m.Position, &mrID, &mrTagName, &mrName, &mrBody, &mrIsDraft, &mrIsPrerelease, - &mrTargetCommitish, &mrSCMConnectionID, &mrSCMRepository, + &mrTargetCommitish, &mrWorkspaceRepositoryID, &mrTagURL, &mrReleaseStatus, + &mrReleasedAt, &mrAssetsJSON, &mrLastSyncedAt, &mrSCMConnectionID, &mrSCMRepository, &mrSCMReleaseID, &mrSCMReleaseURL, &mrCreatedBy, &mrCreatedAt, &m.CreatedAt, &m.UpdatedAt) if err != nil { @@ -135,8 +138,9 @@ func scanMilestoneRow(sc milestoneScanner) (MilestoneResult, error) { m.WorkspaceID = &id } m.LatestRelease = hydrateMilestoneRelease(m.ID, - mrID, mrCreatedBy, mrSCMConnectionID, + mrID, mrCreatedBy, mrSCMConnectionID, mrWorkspaceRepositoryID, mrTagName, mrName, mrBody, mrTargetCommitish, + mrTagURL, mrReleaseStatus, mrReleasedAt, mrAssetsJSON, mrLastSyncedAt, mrSCMRepository, mrSCMReleaseID, mrSCMReleaseURL, mrIsDraft, mrIsPrerelease, mrCreatedAt, ) @@ -162,20 +166,26 @@ func scanMilestones(rows *sql.Rows) ([]MilestoneResult, error) { //nolint:unpara // MilestoneReleaseResult represents a release record for a milestone. type MilestoneReleaseResult struct { - ID int - MilestoneID int - TagName string - Name string - Body string - IsDraft bool - IsPrerelease bool - TargetCommitish string - SCMConnectionID *int - SCMRepository *string - SCMReleaseID *string - SCMReleaseURL *string - CreatedBy *int - CreatedAt string + ID int + MilestoneID int + WorkspaceRepositoryID *int + TagName string + TagURL *string + ReleaseStatus string + ReleasedAt *string + Assets []models.SCMReleaseAsset + LastSyncedAt *string + Name string + Body string + IsDraft bool + IsPrerelease bool + TargetCommitish string + SCMConnectionID *int + SCMRepository *string + SCMReleaseID *string + SCMReleaseURL *string + CreatedBy *int + CreatedAt string } var ErrSCMRepositoryNotLinked = errors.New("SCM repository is not linked to the selected connection") @@ -261,7 +271,9 @@ func (s *PlanningService) ListMilestones(params MilestoneListParams) ([]Mileston m.is_global, m.workspace_id, w.name as workspace_name, m.external_key, m.position, mr.id, mr.tag_name, mr.name, mr.body, mr.is_draft, mr.is_prerelease, - mr.target_commitish, mr.scm_connection_id, mr.scm_repository, + mr.target_commitish, mr.workspace_repository_id, mr.tag_url, mr.release_status, + CAST(mr.released_at AS TEXT), CAST(mr.assets_json AS TEXT), CAST(mr.last_synced_at AS TEXT), + mr.scm_connection_id, mr.scm_repository, mr.scm_release_id, mr.scm_release_url, mr.created_by, mr.created_at, m.created_at, m.updated_at FROM milestones m @@ -370,7 +382,9 @@ func (s *PlanningService) GetMilestone(id int) (*MilestoneResult, error) { m.is_global, m.workspace_id, w.name as workspace_name, m.external_key, m.position, mr.id, mr.tag_name, mr.name, mr.body, mr.is_draft, mr.is_prerelease, - mr.target_commitish, mr.scm_connection_id, mr.scm_repository, + mr.target_commitish, mr.workspace_repository_id, mr.tag_url, mr.release_status, + CAST(mr.released_at AS TEXT), CAST(mr.assets_json AS TEXT), CAST(mr.last_synced_at AS TEXT), + mr.scm_connection_id, mr.scm_repository, mr.scm_release_id, mr.scm_release_url, mr.created_by, mr.created_at, m.created_at, m.updated_at FROM milestones m @@ -400,8 +414,9 @@ func (s *PlanningService) GetMilestone(id int) (*MilestoneResult, error) { // Returns nil if mrID is not valid (no release row). func hydrateMilestoneRelease( milestoneID int, - mrID, mrCreatedBy, mrSCMConnectionID sql.NullInt64, + mrID, mrCreatedBy, mrSCMConnectionID, mrWorkspaceRepositoryID sql.NullInt64, mrTagName, mrName, mrBody, mrTargetCommitish sql.NullString, + mrTagURL, mrReleaseStatus, mrReleasedAt, mrAssetsJSON, mrLastSyncedAt sql.NullString, mrSCMRepository, mrSCMReleaseID, mrSCMReleaseURL sql.NullString, mrIsDraft, mrIsPrerelease sql.NullBool, mrCreatedAt sql.NullString, @@ -418,6 +433,23 @@ func hydrateMilestoneRelease( CreatedAt: mrCreatedAt.String, TargetCommitish: mrTargetCommitish.String, } + if mrWorkspaceRepositoryID.Valid { + id := int(mrWorkspaceRepositoryID.Int64) + rel.WorkspaceRepositoryID = &id + } + if mrTagURL.Valid { + rel.TagURL = &mrTagURL.String + } + rel.ReleaseStatus = mrReleaseStatus.String + if mrReleasedAt.Valid { + rel.ReleasedAt = &mrReleasedAt.String + } + if mrLastSyncedAt.Valid { + rel.LastSyncedAt = &mrLastSyncedAt.String + } + if mrAssetsJSON.Valid && mrAssetsJSON.String != "" { + _ = json.Unmarshal([]byte(mrAssetsJSON.String), &rel.Assets) + } if mrIsDraft.Valid { rel.IsDraft = mrIsDraft.Bool } @@ -622,14 +654,18 @@ func (s *PlanningService) SetMilestoneStatus(milestoneID, workspaceID int, statu // control (e.g. "tag promotes branch milestone to in-progress, not // completed"). func (s *PlanningService) AttachRelease(params ReleaseMilestoneParams) error { + assetsJSON := releaseAssetsJSON(params.Assets) _, err := s.db.ExecWrite(` INSERT INTO milestone_releases ( milestone_id, tag_name, name, body, is_draft, is_prerelease, - target_commitish, scm_connection_id, scm_repository, scm_release_id, + target_commitish, workspace_repository_id, tag_url, release_status, released_at, assets_json, + scm_connection_id, scm_repository, scm_release_id, scm_release_url, created_by - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT DO NOTHING `, params.ID, params.TagName, params.Name, params.Body, params.IsDraft, params.IsPrerelease, - params.TargetCommitish, params.SCMConnectionID, params.SCMRepository, params.SCMReleaseID, + params.TargetCommitish, params.WorkspaceRepositoryID, params.TagURL, releaseStatusOrDefault(params.ReleaseStatus), params.ReleasedAt, assetsJSON, + params.SCMConnectionID, params.SCMRepository, params.SCMReleaseID, params.SCMReleaseURL, params.CreatedBy) if err != nil { return fmt.Errorf("failed to insert milestone release: %w", err) @@ -710,7 +746,9 @@ func (s *PlanningService) UpdateMilestone(params UpdateMilestoneParams) (*Milest func (s *PlanningService) ListMilestoneReleases(milestoneID int) ([]MilestoneReleaseResult, error) { rows, err := s.db.Query(` SELECT id, milestone_id, tag_name, name, body, is_draft, is_prerelease, - target_commitish, scm_connection_id, scm_repository, + target_commitish, workspace_repository_id, tag_url, release_status, + CAST(released_at AS TEXT), CAST(assets_json AS TEXT), CAST(last_synced_at AS TEXT), + scm_connection_id, scm_repository, scm_release_id, scm_release_url, created_by, created_at FROM milestone_releases WHERE milestone_id = ? AND state = 'created' @@ -725,12 +763,14 @@ func (s *PlanningService) ListMilestoneReleases(milestoneID int) ([]MilestoneRel for rows.Next() { var r MilestoneReleaseResult var name, body, targetCommitish sql.NullString - var scmConnectionID, createdBy sql.NullInt64 - var scmRepository, scmReleaseID, scmReleaseURL sql.NullString + var scmConnectionID, createdBy, workspaceRepositoryID sql.NullInt64 + var scmRepository, scmReleaseID, scmReleaseURL, tagURL sql.NullString + var releaseStatus, releasedAt, assetsJSON, lastSyncedAt sql.NullString var isDraft, isPrerelease sql.NullBool if err := rows.Scan(&r.ID, &r.MilestoneID, &r.TagName, &name, &body, - &isDraft, &isPrerelease, &targetCommitish, &scmConnectionID, &scmRepository, + &isDraft, &isPrerelease, &targetCommitish, &workspaceRepositoryID, &tagURL, + &releaseStatus, &releasedAt, &assetsJSON, &lastSyncedAt, &scmConnectionID, &scmRepository, &scmReleaseID, &scmReleaseURL, &createdBy, &r.CreatedAt); err != nil { return nil, fmt.Errorf("failed to scan milestone release: %w", err) } @@ -738,6 +778,23 @@ func (s *PlanningService) ListMilestoneReleases(milestoneID int) ([]MilestoneRel r.Name = name.String r.Body = body.String r.TargetCommitish = targetCommitish.String + if workspaceRepositoryID.Valid { + id := int(workspaceRepositoryID.Int64) + r.WorkspaceRepositoryID = &id + } + if tagURL.Valid { + r.TagURL = &tagURL.String + } + r.ReleaseStatus = releaseStatus.String + if releasedAt.Valid { + r.ReleasedAt = &releasedAt.String + } + if lastSyncedAt.Valid { + r.LastSyncedAt = &lastSyncedAt.String + } + if assetsJSON.Valid && assetsJSON.String != "" { + _ = json.Unmarshal([]byte(assetsJSON.String), &r.Assets) + } if isDraft.Valid { r.IsDraft = isDraft.Bool } @@ -773,19 +830,24 @@ func (s *PlanningService) ListMilestoneReleases(milestoneID int) ([]MilestoneRel // ReleaseMilestoneParams contains parameters for releasing a milestone. type ReleaseMilestoneParams struct { - ID int - IdempotencyKey string - TagName string - Name string - Body string - IsDraft bool - IsPrerelease bool - TargetCommitish string - SCMConnectionID *int - SCMRepository *string - SCMReleaseID *string - SCMReleaseURL *string - CreatedBy *int + ID int + IdempotencyKey string + WorkspaceRepositoryID *int + TagName string + TagURL *string + ReleaseStatus string + ReleasedAt *string + Assets []models.SCMReleaseAsset + Name string + Body string + IsDraft bool + IsPrerelease bool + TargetCommitish string + SCMConnectionID *int + SCMRepository *string + SCMReleaseID *string + SCMReleaseURL *string + CreatedBy *int } // MilestoneReleaseAttempt is a durable claim for one idempotent release @@ -800,15 +862,16 @@ type MilestoneReleaseAttempt struct { } type storedMilestoneReleaseRequest struct { - TagName string - Name sql.NullString - Body sql.NullString - IsDraft bool - IsPrerelease bool - TargetCommitish sql.NullString - SCMConnectionID sql.NullInt64 - SCMRepository sql.NullString - CreatedBy sql.NullInt64 + TagName string + Name sql.NullString + Body sql.NullString + IsDraft bool + IsPrerelease bool + TargetCommitish sql.NullString + WorkspaceRepositoryID sql.NullInt64 + SCMConnectionID sql.NullInt64 + SCMRepository sql.NullString + CreatedBy sql.NullInt64 } func milestoneReleaseRequestMatches(params ReleaseMilestoneParams, stored storedMilestoneReleaseRequest) bool { @@ -819,6 +882,7 @@ func milestoneReleaseRequestMatches(params ReleaseMilestoneParams, stored stored params.IsPrerelease == stored.IsPrerelease && stored.TargetCommitish.Valid && params.TargetCommitish == stored.TargetCommitish.String && nullableIntMatches(params.SCMConnectionID, stored.SCMConnectionID) && + nullableIntMatches(params.WorkspaceRepositoryID, stored.WorkspaceRepositoryID) && nullableStringMatches(params.SCMRepository, stored.SCMRepository) && nullableIntMatches(params.CreatedBy, stored.CreatedBy) } @@ -859,16 +923,19 @@ func (s *PlanningService) BeginMilestoneRelease(ctx context.Context, params Rele leaseExpiresAt := time.Now().UTC().Add(5 * time.Minute) return database.WithTxResult(s.db, func(tx database.Tx) (*MilestoneReleaseAttempt, error) { + assetsJSON := releaseAssetsJSON(params.Assets) result, err := tx.ExecWriteContext(ctx, ` INSERT INTO milestone_releases ( milestone_id, idempotency_key, state, lease_token, lease_expires_at, tag_name, name, body, is_draft, is_prerelease, target_commitish, + workspace_repository_id, tag_url, release_status, released_at, assets_json, scm_connection_id, scm_repository, created_by - ) VALUES (?, ?, 'pending', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, 'pending', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT DO NOTHING `, params.ID, params.IdempotencyKey, leaseToken, leaseExpiresAt, params.TagName, params.Name, params.Body, params.IsDraft, params.IsPrerelease, - params.TargetCommitish, params.SCMConnectionID, params.SCMRepository, params.CreatedBy) + params.TargetCommitish, params.WorkspaceRepositoryID, params.TagURL, releaseStatusOrDefault(params.ReleaseStatus), params.ReleasedAt, assetsJSON, + params.SCMConnectionID, params.SCMRepository, params.CreatedBy) if err != nil { return nil, fmt.Errorf("failed to persist pending milestone release: %w", err) } @@ -882,7 +949,7 @@ func (s *PlanningService) BeginMilestoneRelease(ctx context.Context, params Rele var storedRequest storedMilestoneReleaseRequest if err := tx.QueryRowContext(ctx, ` SELECT id, state, tag_name, name, body, is_draft, is_prerelease, - target_commitish, scm_connection_id, scm_repository, created_by + target_commitish, workspace_repository_id, scm_connection_id, scm_repository, created_by FROM milestone_releases WHERE milestone_id = ? AND idempotency_key = ? `, params.ID, params.IdempotencyKey).Scan( @@ -894,6 +961,7 @@ func (s *PlanningService) BeginMilestoneRelease(ctx context.Context, params Rele &storedRequest.IsDraft, &storedRequest.IsPrerelease, &storedRequest.TargetCommitish, + &storedRequest.WorkspaceRepositoryID, &storedRequest.SCMConnectionID, &storedRequest.SCMRepository, &storedRequest.CreatedBy, @@ -959,14 +1027,18 @@ func (s *PlanningService) MarkMilestoneReleaseUncertain(ctx context.Context, att // CompleteMilestoneRelease atomically records the remote identity and marks // the milestone completed. Either both local effects commit or neither does. func (s *PlanningService) CompleteMilestoneRelease(ctx context.Context, attemptID int, leaseToken string, params ReleaseMilestoneParams) (*MilestoneResult, error) { + assetsJSON := releaseAssetsJSON(params.Assets) err := database.WithTx(s.db, func(tx database.Tx) error { result, err := tx.ExecWriteContext(ctx, ` UPDATE milestone_releases - SET state = 'created', scm_release_id = ?, scm_release_url = ?, + SET state = 'created', name = ?, body = ?, is_draft = ?, is_prerelease = ?, + scm_release_id = ?, scm_release_url = ?, tag_url = ?, + release_status = ?, released_at = ?, assets_json = ?, last_synced_at = CURRENT_TIMESTAMP, last_error = NULL, lease_token = NULL, lease_expires_at = NULL, updated_at = CURRENT_TIMESTAMP WHERE id = ? AND lease_token = ? AND state = 'pending' - `, params.SCMReleaseID, params.SCMReleaseURL, attemptID, leaseToken) + `, params.Name, params.Body, params.IsDraft, params.IsPrerelease, + params.SCMReleaseID, params.SCMReleaseURL, params.TagURL, releaseStatusOrDefault(params.ReleaseStatus), params.ReleasedAt, assetsJSON, attemptID, leaseToken) if err != nil { return fmt.Errorf("failed to finalize milestone release: %w", err) } @@ -1003,15 +1075,18 @@ func (s *PlanningService) CompleteMilestoneRelease(ctx context.Context, attemptI // release metadata. Its local insert and milestone status transition are // transactional. func (s *PlanningService) ReleaseMilestone(params ReleaseMilestoneParams) (*MilestoneResult, error) { + assetsJSON := releaseAssetsJSON(params.Assets) err := database.WithTx(s.db, func(tx database.Tx) error { _, err := tx.ExecWrite(` INSERT INTO milestone_releases ( milestone_id, idempotency_key, state, tag_name, name, body, - is_draft, is_prerelease, target_commitish, scm_connection_id, + is_draft, is_prerelease, target_commitish, workspace_repository_id, + tag_url, release_status, released_at, assets_json, scm_connection_id, scm_repository, scm_release_id, scm_release_url, created_by - ) VALUES (?, ?, 'created', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + ) VALUES (?, ?, 'created', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, params.ID, nullablePlanningString(params.IdempotencyKey), params.TagName, params.Name, params.Body, params.IsDraft, params.IsPrerelease, params.TargetCommitish, + params.WorkspaceRepositoryID, params.TagURL, releaseStatusOrDefault(params.ReleaseStatus), params.ReleasedAt, assetsJSON, params.SCMConnectionID, params.SCMRepository, params.SCMReleaseID, params.SCMReleaseURL, params.CreatedBy) if err != nil { @@ -1039,6 +1114,24 @@ func nullablePlanningString(value string) any { return value } +func releaseStatusOrDefault(status string) string { + if strings.TrimSpace(status) == "" { + return "tag_only" + } + return status +} + +func releaseAssetsJSON(assets []models.SCMReleaseAsset) string { + if len(assets) == 0 { + return "[]" + } + raw, err := json.Marshal(assets) + if err != nil { + return "[]" + } + return string(raw) +} + // DeleteMilestone deletes a milestone. HTTP adapters may supply an audit actor; // internal automation/import callers omit it and rely on their own execution // trail instead of manufacturing a user-driven audit event. diff --git a/internal/services/planning_milestones_release_test.go b/internal/services/planning_milestones_release_test.go new file mode 100644 index 000000000..676201100 --- /dev/null +++ b/internal/services/planning_milestones_release_test.go @@ -0,0 +1,78 @@ +package services + +import ( + "context" + "path/filepath" + "testing" + + "windshift/internal/database" + "windshift/internal/models" +) + +func newMilestoneReleaseTestService(t *testing.T) (*PlanningService, database.Database) { + t.Helper() + db, err := database.NewSQLiteDBWithPoolSizes(filepath.Join(t.TempDir(), "windshift.db"), 1, 1) + if err != nil { + t.Fatal(err) + } + if err := db.Initialize(); err != nil { + _ = db.Close() + t.Fatal(err) + } + return NewPlanningService(db), db +} + +func insertGlobalMilestone(t *testing.T, db database.Database, name string) int { + t.Helper() + var id int + if err := db.QueryRow(`INSERT INTO milestones(name, description, status, is_global) VALUES (?, '', 'planning', true) RETURNING id`, name).Scan(&id); err != nil { + t.Fatal(err) + } + return id +} + +func TestAttachReleaseStoresExtendedMetadata(t *testing.T) { + service, db := newMilestoneReleaseTestService(t) + defer func() { _ = db.Close() }() + milestoneID := insertGlobalMilestone(t, db, "Attached release") + tagURL := "https://git.example/group/project/-/tags/v1.0.0" + releasedAt := "2026-08-30T12:00:00Z" + + err := service.AttachRelease(ReleaseMilestoneParams{ + ID: milestoneID, TagName: "v1.0.0", TagURL: &tagURL, ReleaseStatus: "released", ReleasedAt: &releasedAt, + Assets: []models.SCMReleaseAsset{{Kind: "link", Name: "binary", URL: "https://cdn.example/app"}}, + }) + if err != nil { + t.Fatal(err) + } + releases, err := service.ListMilestoneReleases(milestoneID) + if err != nil { + t.Fatal(err) + } + if len(releases) != 1 || releases[0].ReleaseStatus != "released" || len(releases[0].Assets) != 1 || releases[0].TagURL == nil || *releases[0].TagURL != tagURL { + t.Fatalf("unexpected stored release: %+v", releases) + } +} + +func TestBeginAndCompleteMilestoneReleaseStoresProviderTruth(t *testing.T) { + service, db := newMilestoneReleaseTestService(t) + defer func() { _ = db.Close() }() + milestoneID := insertGlobalMilestone(t, db, "Created release") + + params := ReleaseMilestoneParams{ID: milestoneID, IdempotencyKey: "release-key", TagName: "v2.0.0", Name: "requested name", Body: "requested body"} + attempt, err := service.BeginMilestoneRelease(context.Background(), params) + if err != nil { + t.Fatal(err) + } + params.Name = "GitLab release" + params.Body = "GitLab notes" + params.ReleaseStatus = "released" + params.Assets = []models.SCMReleaseAsset{{Kind: "source", Name: "zip", URL: "https://git.example/source.zip"}} + result, err := service.CompleteMilestoneRelease(context.Background(), attempt.ID, attempt.LeaseToken, params) + if err != nil { + t.Fatal(err) + } + if result.Status != "completed" || result.LatestRelease == nil || result.LatestRelease.Name != "GitLab release" || len(result.LatestRelease.Assets) != 1 { + t.Fatalf("unexpected completed milestone: %+v", result) + } +} diff --git a/internal/utils/repository_path.go b/internal/utils/repository_path.go new file mode 100644 index 000000000..180de0092 --- /dev/null +++ b/internal/utils/repository_path.go @@ -0,0 +1,14 @@ +package utils + +import "strings" + +// SplitRepositoryPath splits namespace/project at the final slash so nested +// GitLab namespaces remain intact in the namespace portion. +func SplitRepositoryPath(fullName string) (namespace, project string, ok bool) { + fullName = strings.TrimSpace(fullName) + separator := strings.LastIndex(fullName, "/") + if separator <= 0 || separator == len(fullName)-1 { + return "", "", false + } + return fullName[:separator], fullName[separator+1:], true +} diff --git a/internal/utils/repository_path_test.go b/internal/utils/repository_path_test.go new file mode 100644 index 000000000..89e4d8092 --- /dev/null +++ b/internal/utils/repository_path_test.go @@ -0,0 +1,29 @@ +package utils + +import "testing" + +func TestSplitRepositoryPath(t *testing.T) { + t.Parallel() + tests := []struct { + path string + namespace string + project string + ok bool + }{ + {path: "owner/project", namespace: "owner", project: "project", ok: true}, + {path: "group/subgroup/project", namespace: "group/subgroup", project: "project", ok: true}, + {path: " group/subgroup/project ", namespace: "group/subgroup", project: "project", ok: true}, + {path: "project", ok: false}, + {path: "/project", ok: false}, + {path: "group/", ok: false}, + } + for _, test := range tests { + test := test + t.Run(test.path, func(t *testing.T) { + namespace, project, ok := SplitRepositoryPath(test.path) + if namespace != test.namespace || project != test.project || ok != test.ok { + t.Fatalf("SplitRepositoryPath(%q) = %q, %q, %v", test.path, namespace, project, ok) + } + }) + } +} From 64a94c906b415dfa6b8c81f45aa05a6c13b78f98 Mon Sep 17 00:00:00 2001 From: Kostenko Nikita <244571@niuitmo.ru> Date: Tue, 1 Sep 2026 01:47:44 +0300 Subject: [PATCH 2/4] docs(scm): clarify GitLab access token setup --- docs/gitlab-scm.md | 11 ++++++++--- frontend/src/lib/locales/ar/admin.js | 9 ++++++--- frontend/src/lib/locales/de/admin.js | 9 ++++++--- frontend/src/lib/locales/en/admin.js | 9 ++++++--- frontend/src/lib/locales/es/admin.js | 9 ++++++--- frontend/src/lib/locales/pt-BR/admin.js | 9 ++++++--- frontend/src/lib/locales/ru/admin.js | 9 ++++++--- frontend/src/lib/locales/zh-CN/admin.js | 9 ++++++--- .../src/lib/settings/SCMProviderManager.svelte | 16 ++++++++++++---- internal/handlers/scm_providers.go | 2 +- 10 files changed, 63 insertions(+), 29 deletions(-) diff --git a/docs/gitlab-scm.md b/docs/gitlab-scm.md index e37110938..88b2ccb76 100644 --- a/docs/gitlab-scm.md +++ b/docs/gitlab-scm.md @@ -13,11 +13,16 @@ Create an SCM provider in **Admin → Source Control** and choose **GitLab**. `https://gitlab.example.com`. A trailing `/api/v4` is accepted and normalized. - OAuth applications should grant the `api` scope. Register the callback URL shown by Windshift in the GitLab application. -- PAT providers require a token with API access and sufficient project role for - the operations users will perform. +- Access Token providers accept GitLab Personal, Project, and Group Access + Tokens through the same API authentication mechanism. The token needs API + access and a sufficient project role for the operations Windshift performs. + Prefer a Project or Group Access Token for bot and server-to-server + integrations because it limits access to a project or group hierarchy and + uses a dedicated GitLab bot identity. After an administrator creates the provider, a workspace administrator can -connect it, authorize with OAuth or PAT, and link one or more projects. +connect it, authorize with OAuth or an access token, and link one or more +projects. ## Supported project data diff --git a/frontend/src/lib/locales/ar/admin.js b/frontend/src/lib/locales/ar/admin.js index 91ad20995..d8de11fcf 100644 --- a/frontend/src/lib/locales/ar/admin.js +++ b/frontend/src/lib/locales/ar/admin.js @@ -456,8 +456,8 @@ export default { disabled: 'معطل', default: 'افتراضي', restricted: 'مقيد', - patConfigured: 'PAT مكوّن', - patNotConfigured: 'PAT غير مكوّن', + patConfigured: 'تم تكوين رمز الوصول', + patNotConfigured: 'لم يتم تكوين رمز الوصول', addSCMProvider: 'إضافة موفر إدارة الكود المصدري', editSCMProvider: 'تعديل موفر إدارة الكود المصدري', failedToLoad: 'فشل في تحميل موفري إدارة الكود المصدري', @@ -479,7 +479,10 @@ export default { oauthClientId: 'معرّف عميل OAuth', oauthClientSecret: 'سر عميل OAuth', leaveEmptyToKeep: 'اتركه فارغاً للاحتفاظ بالسر الحالي', - personalAccessToken: 'رمز الوصول الشخصي', + accessToken: 'رمز الوصول', + accessTokenHelp: 'استخدم رمز وصول بالأذونات المطلوبة لموفر الخدمة المحدد.', + gitlabAccessTokenHelp: + 'يقبل GitLab رموز الوصول الشخصية ورموز المشروع والمجموعة. يُفضّل استخدام رمز مشروع أو مجموعة لتكاملات الروبوت والخادم إلى الخادم.', githubAppId: 'معرّف تطبيق GitHub', privateKeyPem: 'المفتاح الخاص (PEM)', orgInstallation: 'تثبيت المؤسسة', diff --git a/frontend/src/lib/locales/de/admin.js b/frontend/src/lib/locales/de/admin.js index e7363fec2..186509340 100644 --- a/frontend/src/lib/locales/de/admin.js +++ b/frontend/src/lib/locales/de/admin.js @@ -460,8 +460,8 @@ export default { disabled: 'Deaktiviert', default: 'Standard', restricted: 'Eingeschränkt', - patConfigured: 'PAT konfiguriert', - patNotConfigured: 'PAT nicht konfiguriert', + patConfigured: 'Zugriffstoken konfiguriert', + patNotConfigured: 'Zugriffstoken nicht konfiguriert', addSCMProvider: 'SCM-Anbieter hinzufügen', editSCMProvider: 'SCM-Anbieter bearbeiten', failedToLoad: 'SCM-Anbieter konnten nicht geladen werden', @@ -483,7 +483,10 @@ export default { oauthClientId: 'OAuth-Client-ID', oauthClientSecret: 'OAuth-Client-Secret', leaveEmptyToKeep: 'Leer lassen, um bestehendes Secret zu behalten', - personalAccessToken: 'Persönliches Zugriffstoken', + accessToken: 'Zugriffstoken', + accessTokenHelp: 'Verwenden Sie ein Zugriffstoken mit den für den ausgewählten Anbieter erforderlichen Berechtigungen.', + gitlabAccessTokenHelp: + 'GitLab akzeptiert persönliche, projekt- und gruppenbezogene Zugriffstoken. Für Bot- und Server-zu-Server-Integrationen wird ein Projekt- oder Gruppentoken empfohlen.', githubAppId: 'GitHub-App-ID', privateKeyPem: 'Privater Schlüssel (PEM)', orgInstallation: 'Organisations-Installation', diff --git a/frontend/src/lib/locales/en/admin.js b/frontend/src/lib/locales/en/admin.js index 3cf108fdf..881cf29a0 100644 --- a/frontend/src/lib/locales/en/admin.js +++ b/frontend/src/lib/locales/en/admin.js @@ -445,8 +445,8 @@ export default { disabled: 'Disabled', default: 'Default', restricted: 'Restricted', - patConfigured: 'PAT Configured', - patNotConfigured: 'PAT Not Configured', + patConfigured: 'Access token configured', + patNotConfigured: 'Access token not configured', addSCMProvider: 'Add SCM Provider', editSCMProvider: 'Edit SCM Provider', failedToLoad: 'Failed to load SCM providers', @@ -468,7 +468,10 @@ export default { oauthClientId: 'OAuth Client ID', oauthClientSecret: 'OAuth Client Secret', leaveEmptyToKeep: 'Leave empty to keep existing secret', - personalAccessToken: 'Personal Access Token', + accessToken: 'Access Token', + accessTokenHelp: 'Use an access token with the permissions required for the selected provider.', + gitlabAccessTokenHelp: + 'GitLab accepts Personal, Project, and Group Access Tokens. Prefer a Project or Group token for bot and server-to-server integrations.', githubAppId: 'GitHub App ID', privateKeyPem: 'Private Key (PEM)', orgInstallation: 'Organization Installation', diff --git a/frontend/src/lib/locales/es/admin.js b/frontend/src/lib/locales/es/admin.js index a2aba8817..eb4dadd0f 100644 --- a/frontend/src/lib/locales/es/admin.js +++ b/frontend/src/lib/locales/es/admin.js @@ -455,8 +455,8 @@ export default { disabled: 'Deshabilitado', default: 'Predeterminado', restricted: 'Restringido', - patConfigured: 'PAT configurado', - patNotConfigured: 'PAT no configurado', + patConfigured: 'Token de acceso configurado', + patNotConfigured: 'Token de acceso no configurado', addSCMProvider: 'Agregar proveedor SCM', editSCMProvider: 'Editar proveedor SCM', failedToLoad: 'Error al cargar los proveedores SCM', @@ -478,7 +478,10 @@ export default { oauthClientId: 'ID de cliente OAuth', oauthClientSecret: 'Secreto de cliente OAuth', leaveEmptyToKeep: 'Deje vacío para mantener el secreto existente', - personalAccessToken: 'Token de acceso personal', + accessToken: 'Token de acceso', + accessTokenHelp: 'Utilice un token de acceso con los permisos requeridos por el proveedor seleccionado.', + gitlabAccessTokenHelp: + 'GitLab acepta tokens de acceso personales, de proyecto y de grupo. Se recomienda un token de proyecto o grupo para integraciones de bots y de servidor a servidor.', githubAppId: 'ID de aplicación GitHub', privateKeyPem: 'Clave privada (PEM)', orgInstallation: 'Instalación de organización', diff --git a/frontend/src/lib/locales/pt-BR/admin.js b/frontend/src/lib/locales/pt-BR/admin.js index c545503bb..ce060bb7d 100644 --- a/frontend/src/lib/locales/pt-BR/admin.js +++ b/frontend/src/lib/locales/pt-BR/admin.js @@ -455,8 +455,8 @@ export default { disabled: 'Desativado', default: 'Padrão', restricted: 'Restrito', - patConfigured: 'PAT Configurado', - patNotConfigured: 'PAT Não Configurado', + patConfigured: 'Token de acesso configurado', + patNotConfigured: 'Token de acesso não configurado', addSCMProvider: 'Adicionar Provedor SCM', editSCMProvider: 'Editar Provedor SCM', failedToLoad: 'Falha ao carregar provedores SCM', @@ -478,7 +478,10 @@ export default { oauthClientId: 'ID do Cliente OAuth', oauthClientSecret: 'Segredo do Cliente OAuth', leaveEmptyToKeep: 'Deixe vazio para manter o segredo existente', - personalAccessToken: 'Token de Acesso Pessoal', + accessToken: 'Token de acesso', + accessTokenHelp: 'Use um token de acesso com as permissões exigidas pelo provedor selecionado.', + gitlabAccessTokenHelp: + 'O GitLab aceita tokens de acesso pessoais, de projeto e de grupo. Prefira um token de projeto ou grupo para integrações de bots e entre servidores.', githubAppId: 'ID do GitHub App', privateKeyPem: 'Chave Privada (PEM)', orgInstallation: 'Instalação da Organização', diff --git a/frontend/src/lib/locales/ru/admin.js b/frontend/src/lib/locales/ru/admin.js index 72032e9d0..4396e96d6 100644 --- a/frontend/src/lib/locales/ru/admin.js +++ b/frontend/src/lib/locales/ru/admin.js @@ -491,8 +491,8 @@ export default { disabled: 'Отключён', default: 'По умолчанию', restricted: 'Ограничен', - patConfigured: 'PAT настроен', - patNotConfigured: 'PAT не настроен', + patConfigured: 'Токен доступа настроен', + patNotConfigured: 'Токен доступа не настроен', addSCMProvider: 'Добавить провайдера SCM', editSCMProvider: 'Изменить провайдера SCM', failedToLoad: 'Не удалось загрузить провайдеров SCM', @@ -515,7 +515,10 @@ export default { oauthClientId: 'ID клиента OAuth', oauthClientSecret: 'Секрет клиента OAuth', leaveEmptyToKeep: 'Оставьте пустым, чтобы сохранить текущий секрет', - personalAccessToken: 'Персональный токен доступа', + accessToken: 'Токен доступа', + accessTokenHelp: 'Используйте токен доступа с правами, необходимыми выбранному провайдеру.', + gitlabAccessTokenHelp: + 'GitLab принимает персональные, проектные и групповые токены доступа. Для ботов и межсерверных интеграций рекомендуется проектный или групповой токен.', githubAppId: 'ID приложения GitHub', privateKeyPem: 'Закрытый ключ (PEM)', orgInstallation: 'Установка в организации', diff --git a/frontend/src/lib/locales/zh-CN/admin.js b/frontend/src/lib/locales/zh-CN/admin.js index 70ce33780..897ed066a 100644 --- a/frontend/src/lib/locales/zh-CN/admin.js +++ b/frontend/src/lib/locales/zh-CN/admin.js @@ -356,8 +356,8 @@ export default { disabled: '已禁用', default: '默认', restricted: '受限', - patConfigured: 'PAT 已配置', - patNotConfigured: 'PAT 未配置', + patConfigured: '访问令牌已配置', + patNotConfigured: '访问令牌未配置', addSCMProvider: '添加 SCM 提供商', editSCMProvider: '编辑 SCM 提供商', failedToLoad: '加载 SCM 提供商失败', @@ -379,7 +379,10 @@ export default { oauthClientId: 'OAuth 客户端 ID', oauthClientSecret: 'OAuth 客户端密钥', leaveEmptyToKeep: '留空以保留现有密钥', - personalAccessToken: '个人访问令牌', + accessToken: '访问令牌', + accessTokenHelp: '使用具有所选提供商所需权限的访问令牌。', + gitlabAccessTokenHelp: + 'GitLab 支持个人、项目和群组访问令牌。对于机器人和服务器到服务器集成,建议使用项目或群组令牌。', githubAppId: 'GitHub 应用 ID', privateKeyPem: '私钥(PEM)', orgInstallation: '组织安装', diff --git a/frontend/src/lib/settings/SCMProviderManager.svelte b/frontend/src/lib/settings/SCMProviderManager.svelte index 895e2ddac..e67f86439 100644 --- a/frontend/src/lib/settings/SCMProviderManager.svelte +++ b/frontend/src/lib/settings/SCMProviderManager.svelte @@ -59,7 +59,7 @@ // Auth methods const authMethods = [ { value: 'oauth', label: 'OAuth App', description: 'Users authorize via OAuth flow' }, - { value: 'pat', label: 'Personal Access Token', description: 'Use a PAT for all operations' }, + { value: 'pat', label: 'Access Token', description: 'Use an access token for all operations' }, { value: 'github_app', label: 'GitHub App', description: 'Fine-grained permissions (GitHub only)' }, ]; @@ -220,7 +220,7 @@ } } else if (formData.auth_method === 'pat') { if (!editingProvider && !formData.personal_access_token) { - formErrors.personal_access_token = 'Personal Access Token is required'; + formErrors.personal_access_token = 'Access Token is required'; } } else if (formData.auth_method === 'github_app') { if (!formData.github_app_id) { @@ -375,6 +375,14 @@ return providerType?.label || type; } + function getAccessTokenHelp() { + const helpKey = formData.provider_type === 'gitlab' + ? 'settings.scmProviders.gitlabAccessTokenHelp' + : 'settings.scmProviders.accessTokenHelp'; + const help = t(helpKey); + return editingProvider ? `${help} ${t('settings.scmProviders.leaveEmptyToKeep')}` : help; + } + // Compute OAuth callback URL based on slug const oauthCallbackUrl = $derived(formData.slug ? `${publicBaseURL()}/api/scm/oauth/${formData.slug}/callback` @@ -592,9 +600,9 @@ {/if} - + {#if formData.auth_method === 'pat'} - + {/if} diff --git a/internal/handlers/scm_providers.go b/internal/handlers/scm_providers.go index 6885a419a..82a6f45ec 100644 --- a/internal/handlers/scm_providers.go +++ b/internal/handlers/scm_providers.go @@ -482,7 +482,7 @@ func (h *SCMProviderHandler) TestProvider(w http.ResponseWriter, r *http.Request } else { respondJSONOK(w, map[string]any{ "success": false, - "error": "Personal Access Token not configured", + "error": "Access token not configured", }) return } From 52285b39c7ad165c51ef03516bbcb89297d9e090 Mon Sep 17 00:00:00 2001 From: Kostenko Nikita <244571@niuitmo.ru> Date: Tue, 1 Sep 2026 15:30:49 +0300 Subject: [PATCH 3/4] chore(scm): remove ignored GitLab documentation --- docs/gitlab-scm.md | 55 ---------------------------------------------- 1 file changed, 55 deletions(-) delete mode 100644 docs/gitlab-scm.md diff --git a/docs/gitlab-scm.md b/docs/gitlab-scm.md deleted file mode 100644 index 88b2ccb76..000000000 --- a/docs/gitlab-scm.md +++ /dev/null @@ -1,55 +0,0 @@ -# GitLab SCM integration - -Windshift supports GitLab.com and self-managed GitLab as an SCM provider. The -integration uses GitLab REST API v4 and supports nested namespaces such as -`group/subgroup/project`. - -## Provider setup - -Create an SCM provider in **Admin → Source Control** and choose **GitLab**. - -- For GitLab.com, leave Base URL empty or use `https://gitlab.com`. -- For self-managed GitLab, enter the instance root URL, for example - `https://gitlab.example.com`. A trailing `/api/v4` is accepted and normalized. -- OAuth applications should grant the `api` scope. Register the callback URL - shown by Windshift in the GitLab application. -- Access Token providers accept GitLab Personal, Project, and Group Access - Tokens through the same API authentication mechanism. The token needs API - access and a sufficient project role for the operations Windshift performs. - Prefer a Project or Group Access Token for bot and server-to-server - integrations because it limits access to a project or group hierarchy and - uses a dedicated GitLab bot identity. - -After an administrator creates the provider, a workspace administrator can -connect it, authorize with OAuth or an access token, and link one or more -projects. - -## Supported project data - -The provider supports project discovery, branches, commits, merge requests, -MR notes and review discussions, tags, compare ranges, and GitLab Releases. -Windshift uses GitLab merge-request terminology in provider data while keeping -the provider-neutral `pull_request` value in its internal SCM link model. - -Repository polling remains the recovery mechanism. A workspace administrator -can also open a linked GitLab project's webhook settings in Windshift, generate -a callback URL and one-time secret, then configure that webhook in GitLab for: - -- push and tag push; -- merge request; -- note; -- release. - -Webhook requests are token-validated, project-validated, rate-limited, and -deduplicated before they trigger a repository sync. - -## Milestone releases - -When releasing a milestone, users can either create a new SCM release or attach -an existing Git tag/GitLab Release. Stored release data includes the project, -tag and release URLs, release status and date, downloadable assets, and the last -successful synchronization time. - -Normal repository sync refreshes attached release metadata. If a remote release -is removed but its tag remains, the record becomes `tag_only`; if both disappear, -it becomes `missing` rather than silently deleting the milestone history. From 3967e5d0e0f1aa04a7bc3bde4c5e4db7f557bd37 Mon Sep 17 00:00:00 2001 From: Kostenko Nikita <244571@niuitmo.ru> Date: Tue, 1 Sep 2026 16:51:31 +0300 Subject: [PATCH 4/4] fix(backend): satisfy GitLab SCM lint checks --- internal/handlers/scm_gitlab_webhooks.go | 100 ++++------ internal/handlers/scm_item_links.go | 2 + internal/repository/scm_webhook_repository.go | 182 ++++++++++++++++++ internal/scm/sync.go | 7 +- 4 files changed, 225 insertions(+), 66 deletions(-) create mode 100644 internal/repository/scm_webhook_repository.go diff --git a/internal/handlers/scm_gitlab_webhooks.go b/internal/handlers/scm_gitlab_webhooks.go index f895c5ff2..e1518e032 100644 --- a/internal/handlers/scm_gitlab_webhooks.go +++ b/internal/handlers/scm_gitlab_webhooks.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "crypto/sha256" "crypto/subtle" - "database/sql" "encoding/base64" "encoding/hex" "encoding/json" @@ -18,6 +17,7 @@ import ( "time" "windshift/internal/models" + "windshift/internal/repository" ) var gitLabWebhookEvents = []string{"push", "tag_push", "merge_request", "note", "release"} @@ -36,16 +36,8 @@ func (h *SCMItemLinksHandler) webhookRepoAdmin(w http.ResponseWriter, r *http.Re if !ok { return "", false } - var workspaceID int - var providerType string - err := h.db.QueryRowContext(r.Context(), ` - SELECT wsc.workspace_id, sp.provider_type - FROM workspace_repositories wr - JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id - JOIN scm_providers sp ON sp.id = wsc.scm_provider_id - WHERE wr.id = ? - `, repoID).Scan(&workspaceID, &providerType) - if errors.Is(err, sql.ErrNoRows) { + access, err := h.webhookRepo.GetRepositoryAccess(r.Context(), repoID) + if errors.Is(err, repository.ErrNotFound) { respondNotFound(w, r, "workspace_repository") return "", false } @@ -53,10 +45,10 @@ func (h *SCMItemLinksHandler) webhookRepoAdmin(w http.ResponseWriter, r *http.Re respondInternalError(w, r, err) return "", false } - if !RequireWorkspacePermission(w, r, user.ID, workspaceID, models.PermissionWorkspaceAdmin, h.permissionService) { + if !RequireWorkspacePermission(w, r, user.ID, access.WorkspaceID, models.PermissionWorkspaceAdmin, h.permissionService) { return "", false } - return providerType, true + return access.ProviderType, true } func (h *SCMItemLinksHandler) webhookCallbackURL(r *http.Request, key string) string { @@ -93,11 +85,8 @@ func (h *SCMItemLinksHandler) GetGitLabWebhookConfig(w http.ResponseWriter, r *h respondBadRequest(w, r, "Webhooks on this endpoint are only available for GitLab repositories") return } - var key string - var active bool - var lastDelivery sql.NullTime - err := h.db.QueryRowContext(r.Context(), `SELECT webhook_key, is_active, last_delivery_at FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID).Scan(&key, &active, &lastDelivery) - if errors.Is(err, sql.ErrNoRows) { + config, err := h.webhookRepo.GetConfig(r.Context(), repoID) + if errors.Is(err, repository.ErrNotFound) { respondJSONOK(w, gitLabWebhookConfigResponse{Configured: false, Events: gitLabWebhookEvents}) return } @@ -105,9 +94,12 @@ func (h *SCMItemLinksHandler) GetGitLabWebhookConfig(w http.ResponseWriter, r *h respondInternalError(w, r, err) return } - response := gitLabWebhookConfigResponse{Configured: true, CallbackURL: h.webhookCallbackURL(r, key), Events: gitLabWebhookEvents, Active: active} - if lastDelivery.Valid { - response.LastDeliveryAt = &lastDelivery.Time + response := gitLabWebhookConfigResponse{ + Configured: true, + CallbackURL: h.webhookCallbackURL(r, config.WebhookKey), + Events: gitLabWebhookEvents, + Active: config.Active, + LastDeliveryAt: config.LastDeliveryAt, } respondJSONOK(w, response) } @@ -144,19 +136,18 @@ func (h *SCMItemLinksHandler) RotateGitLabWebhookSecret(w http.ResponseWriter, r respondInternalError(w, r, err) return } - var key string - err = h.db.QueryRowContext(r.Context(), `SELECT webhook_key FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID).Scan(&key) - if errors.Is(err, sql.ErrNoRows) { - key, err = randomWebhookValue(18) - if err == nil { - _, err = h.db.ExecWriteContext(r.Context(), ` - INSERT INTO scm_webhooks(workspace_repository_id, webhook_key, webhook_secret_encrypted, events, is_active) - VALUES (?, ?, ?, ?, true) - `, repoID, key, encrypted, `["push","tag_push","merge_request","note","release"]`) - } - } else if err == nil { - _, err = h.db.ExecWriteContext(r.Context(), `UPDATE scm_webhooks SET webhook_secret_encrypted=?, is_active=true, updated_at=CURRENT_TIMESTAMP WHERE workspace_repository_id=?`, encrypted, repoID) + newKey, err := randomWebhookValue(18) + if err != nil { + respondInternalError(w, r, err) + return } + key, err := h.webhookRepo.RotateConfig( + r.Context(), + repoID, + newKey, + encrypted, + `["push","tag_push","merge_request","note","release"]`, + ) if err != nil { respondInternalError(w, r, err) return @@ -172,7 +163,7 @@ func (h *SCMItemLinksHandler) DeleteGitLabWebhookConfig(w http.ResponseWriter, r if _, ok := h.webhookRepoAdmin(w, r, repoID); !ok { return } - if _, err := h.db.ExecWriteContext(r.Context(), `DELETE FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID); err != nil { + if err := h.webhookRepo.DeleteConfig(r.Context(), repoID); err != nil { respondInternalError(w, r, err) return } @@ -209,18 +200,8 @@ func normalizeGitLabWebhookKind(payload gitLabWebhookPayload) string { // schedules a targeted repository sync. Polling remains the recovery path. func (h *SCMItemLinksHandler) ReceiveGitLabWebhook(w http.ResponseWriter, r *http.Request) { key := r.PathValue("webhookKey") - var hookID, repoID int - var encryptedSecret, externalProjectID, providerType string - err := h.db.QueryRowContext(r.Context(), ` - SELECT sw.id, sw.workspace_repository_id, sw.webhook_secret_encrypted, - wr.repository_external_id, sp.provider_type - FROM scm_webhooks sw - JOIN workspace_repositories wr ON wr.id = sw.workspace_repository_id - JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id - JOIN scm_providers sp ON sp.id = wsc.scm_provider_id - WHERE sw.webhook_key = ? AND sw.is_active = true AND wr.is_active = true - `, key).Scan(&hookID, &repoID, &encryptedSecret, &externalProjectID, &providerType) - if errors.Is(err, sql.ErrNoRows) { + target, err := h.webhookRepo.GetTargetByKey(r.Context(), key) + if errors.Is(err, repository.ErrNotFound) { respondNotFound(w, r, "scm_webhook") return } @@ -228,11 +209,11 @@ func (h *SCMItemLinksHandler) ReceiveGitLabWebhook(w http.ResponseWriter, r *htt respondInternalError(w, r, err) return } - if providerType != string(models.SCMProviderTypeGitLab) { + if target.ProviderType != string(models.SCMProviderTypeGitLab) { respondBadRequest(w, r, "Invalid webhook provider") return } - secret, err := h.encryption.Decrypt(encryptedSecret) + secret, err := h.encryption.Decrypt(target.EncryptedSecret) if err != nil { respondInternalError(w, r, err) return @@ -263,7 +244,7 @@ func (h *SCMItemLinksHandler) ReceiveGitLabWebhook(w http.ResponseWriter, r *htt if projectID == 0 { projectID = payload.ProjectID } - if strconv.FormatInt(projectID, 10) != externalProjectID { + if strconv.FormatInt(projectID, 10) != target.RepositoryExternalID { respondJSON(w, http.StatusForbidden, map[string]string{"error": "project mismatch"}) return } @@ -273,35 +254,28 @@ func (h *SCMItemLinksHandler) ReceiveGitLabWebhook(w http.ResponseWriter, r *htt deliveryID = hex.EncodeToString(digest[:]) } summary, _ := json.Marshal(map[string]any{"object_kind": eventType, "project_id": projectID, "path": payload.Project.PathWithNamespace, "iid": payload.ObjectAttributes.IID, "action": payload.ObjectAttributes.Action, "ref": payload.Ref, "tag": payload.ObjectAttributes.Tag}) - result, err := h.db.ExecWriteContext(r.Context(), ` - INSERT INTO scm_webhook_deliveries(scm_webhook_id, delivery_id, event_type, payload_summary, status) - VALUES (?, ?, ?, ?, 'pending') ON CONFLICT DO NOTHING - `, hookID, deliveryID, eventType, string(summary)) + inserted, err := h.webhookRepo.RecordPendingDelivery(r.Context(), target.ID, deliveryID, eventType, string(summary)) if err != nil { respondInternalError(w, r, err) return } - inserted, _ := result.RowsAffected() - _, _ = h.db.ExecWriteContext(r.Context(), `UPDATE scm_webhooks SET last_delivery_at=CURRENT_TIMESTAMP, updated_at=CURRENT_TIMESTAMP WHERE id=?`, hookID) respondJSON(w, http.StatusAccepted, map[string]bool{"accepted": true}) - if inserted == 0 { + if !inserted { return } + baseCtx := context.WithoutCancel(r.Context()) go func() { started := time.Now() - ctx, cancel := context.WithTimeout(context.Background(), 45*time.Second) + ctx, cancel := context.WithTimeout(baseCtx, 45*time.Second) defer cancel() - syncErr := h.syncService.SyncRepository(ctx, repoID) + syncErr := h.syncService.SyncRepository(ctx, target.WorkspaceRepositoryID) status, errorMessage := "processed", "" if syncErr != nil { status, errorMessage = "failed", syncErr.Error() - slog.Warn("GitLab webhook sync failed", slog.Int("repository_id", repoID), slog.Any("error", syncErr)) + slog.Warn("GitLab webhook sync failed", slog.Int("repository_id", target.WorkspaceRepositoryID), slog.Any("error", syncErr)) } - _, updateErr := h.db.ExecWriteContext(ctx, ` - UPDATE scm_webhook_deliveries SET status=?, error_message=?, processing_time_ms=?, updated_at=CURRENT_TIMESTAMP - WHERE scm_webhook_id=? AND delivery_id=? - `, status, errorMessage, time.Since(started).Milliseconds(), hookID, deliveryID) + updateErr := h.webhookRepo.CompleteDelivery(ctx, target.ID, deliveryID, status, errorMessage, time.Since(started)) if updateErr != nil { slog.Warn("GitLab webhook delivery update failed", slog.Any("error", updateErr), slog.String("delivery_id", deliveryID)) } diff --git a/internal/handlers/scm_item_links.go b/internal/handlers/scm_item_links.go index 34a096a62..4604a6e25 100644 --- a/internal/handlers/scm_item_links.go +++ b/internal/handlers/scm_item_links.go @@ -26,6 +26,7 @@ type SCMItemLinksHandler struct { db database.Database encryption *sso.SecretEncryption syncService *scm.SyncService + webhookRepo *repository.SCMWebhookRepository permissionService *services.PermissionService baseURL string } @@ -105,6 +106,7 @@ func NewSCMItemLinksHandler(db database.Database, encryption *sso.SecretEncrypti db: db, encryption: encryption, syncService: scm.NewSyncService(db, encryption), + webhookRepo: repository.NewSCMWebhookRepository(db), permissionService: permissionService, baseURL: strings.TrimRight(baseURL, "/"), } diff --git a/internal/repository/scm_webhook_repository.go b/internal/repository/scm_webhook_repository.go new file mode 100644 index 000000000..e26cf814e --- /dev/null +++ b/internal/repository/scm_webhook_repository.go @@ -0,0 +1,182 @@ +package repository + +import ( + "context" + "database/sql" + "errors" + "fmt" + "time" + + "windshift/internal/database" +) + +// SCMWebhookRepository persists GitLab webhook configuration and deliveries. +type SCMWebhookRepository struct { + db database.Database +} + +// SCMWebhookRepositoryAccess identifies the workspace and provider for a linked repository. +type SCMWebhookRepositoryAccess struct { + WorkspaceID int + ProviderType string +} + +// SCMWebhookConfig is the persisted configuration visible to workspace admins. +type SCMWebhookConfig struct { + WebhookKey string + Active bool + LastDeliveryAt *time.Time +} + +// SCMWebhookTarget contains the trusted data needed to validate an inbound webhook. +type SCMWebhookTarget struct { + ID int + WorkspaceRepositoryID int + EncryptedSecret string + RepositoryExternalID string + ProviderType string +} + +// NewSCMWebhookRepository constructs an SCM webhook repository. +func NewSCMWebhookRepository(db database.Database) *SCMWebhookRepository { + return &SCMWebhookRepository{db: db} +} + +// GetRepositoryAccess returns workspace and provider metadata for a linked repository. +func (r *SCMWebhookRepository) GetRepositoryAccess(ctx context.Context, repoID int) (SCMWebhookRepositoryAccess, error) { + var access SCMWebhookRepositoryAccess + err := r.db.QueryRowContext(ctx, ` + SELECT wsc.workspace_id, sp.provider_type + FROM workspace_repositories wr + JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id + JOIN scm_providers sp ON sp.id = wsc.scm_provider_id + WHERE wr.id = ? + `, repoID).Scan(&access.WorkspaceID, &access.ProviderType) + if errors.Is(err, sql.ErrNoRows) { + return SCMWebhookRepositoryAccess{}, ErrNotFound + } + if err != nil { + return SCMWebhookRepositoryAccess{}, fmt.Errorf("load SCM webhook repository access: %w", err) + } + return access, nil +} + +// GetConfig returns the webhook configuration for a linked repository. +func (r *SCMWebhookRepository) GetConfig(ctx context.Context, repoID int) (SCMWebhookConfig, error) { + var config SCMWebhookConfig + var lastDelivery sql.NullTime + err := r.db.QueryRowContext(ctx, ` + SELECT webhook_key, is_active, last_delivery_at + FROM scm_webhooks + WHERE workspace_repository_id = ? + `, repoID).Scan(&config.WebhookKey, &config.Active, &lastDelivery) + if errors.Is(err, sql.ErrNoRows) { + return SCMWebhookConfig{}, ErrNotFound + } + if err != nil { + return SCMWebhookConfig{}, fmt.Errorf("load SCM webhook config: %w", err) + } + if lastDelivery.Valid { + config.LastDeliveryAt = &lastDelivery.Time + } + return config, nil +} + +// RotateConfig creates or rotates a webhook secret while preserving an existing callback key. +func (r *SCMWebhookRepository) RotateConfig(ctx context.Context, repoID int, newKey, encryptedSecret, events string) (string, error) { + var key string + err := r.db.QueryRowContext(ctx, `SELECT webhook_key FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID).Scan(&key) + if errors.Is(err, sql.ErrNoRows) { + key = newKey + _, err = r.db.ExecWriteContext(ctx, ` + INSERT INTO scm_webhooks(workspace_repository_id, webhook_key, webhook_secret_encrypted, events, is_active) + VALUES (?, ?, ?, ?, true) + `, repoID, key, encryptedSecret, events) + } else if err == nil { + _, err = r.db.ExecWriteContext(ctx, ` + UPDATE scm_webhooks + SET webhook_secret_encrypted = ?, is_active = true, updated_at = CURRENT_TIMESTAMP + WHERE workspace_repository_id = ? + `, encryptedSecret, repoID) + } + if err != nil { + return "", fmt.Errorf("rotate SCM webhook config: %w", err) + } + return key, nil +} + +// DeleteConfig removes a linked repository's webhook configuration. +func (r *SCMWebhookRepository) DeleteConfig(ctx context.Context, repoID int) error { + if _, err := r.db.ExecWriteContext(ctx, `DELETE FROM scm_webhooks WHERE workspace_repository_id = ?`, repoID); err != nil { + return fmt.Errorf("delete SCM webhook config: %w", err) + } + return nil +} + +// GetTargetByKey returns an active webhook target and its validation metadata. +func (r *SCMWebhookRepository) GetTargetByKey(ctx context.Context, key string) (SCMWebhookTarget, error) { + var target SCMWebhookTarget + err := r.db.QueryRowContext(ctx, ` + SELECT sw.id, sw.workspace_repository_id, sw.webhook_secret_encrypted, + wr.repository_external_id, sp.provider_type + FROM scm_webhooks sw + JOIN workspace_repositories wr ON wr.id = sw.workspace_repository_id + JOIN workspace_scm_connections wsc ON wsc.id = wr.workspace_scm_connection_id + JOIN scm_providers sp ON sp.id = wsc.scm_provider_id + WHERE sw.webhook_key = ? AND sw.is_active = true AND wr.is_active = true + `, key).Scan( + &target.ID, + &target.WorkspaceRepositoryID, + &target.EncryptedSecret, + &target.RepositoryExternalID, + &target.ProviderType, + ) + if errors.Is(err, sql.ErrNoRows) { + return SCMWebhookTarget{}, ErrNotFound + } + if err != nil { + return SCMWebhookTarget{}, fmt.Errorf("load SCM webhook target: %w", err) + } + return target, nil +} + +// RecordPendingDelivery records a deduplicated delivery and updates webhook activity. +func (r *SCMWebhookRepository) RecordPendingDelivery(ctx context.Context, webhookID int, deliveryID, eventType, summary string) (bool, error) { + result, err := r.db.ExecWriteContext(ctx, ` + INSERT INTO scm_webhook_deliveries(scm_webhook_id, delivery_id, event_type, payload_summary, status) + VALUES (?, ?, ?, ?, 'pending') ON CONFLICT DO NOTHING + `, webhookID, deliveryID, eventType, summary) + if err != nil { + return false, fmt.Errorf("record pending SCM webhook delivery: %w", err) + } + inserted, err := result.RowsAffected() + if err != nil { + return false, fmt.Errorf("read pending SCM webhook delivery result: %w", err) + } + if _, err := r.db.ExecWriteContext(ctx, ` + UPDATE scm_webhooks + SET last_delivery_at = CURRENT_TIMESTAMP, updated_at = CURRENT_TIMESTAMP + WHERE id = ? + `, webhookID); err != nil { + return false, fmt.Errorf("update SCM webhook activity: %w", err) + } + return inserted > 0, nil +} + +// CompleteDelivery records the final delivery outcome. +func (r *SCMWebhookRepository) CompleteDelivery( + ctx context.Context, + webhookID int, + deliveryID, status, errorMessage string, + processingTime time.Duration, +) error { + _, err := r.db.ExecWriteContext(ctx, ` + UPDATE scm_webhook_deliveries + SET status = ?, error_message = ?, processing_time_ms = ?, updated_at = CURRENT_TIMESTAMP + WHERE scm_webhook_id = ? AND delivery_id = ? + `, status, errorMessage, processingTime.Milliseconds(), webhookID, deliveryID) + if err != nil { + return fmt.Errorf("complete SCM webhook delivery: %w", err) + } + return nil +} diff --git a/internal/scm/sync.go b/internal/scm/sync.go index ed06c7880..272cc9e60 100644 --- a/internal/scm/sync.go +++ b/internal/scm/sync.go @@ -583,11 +583,12 @@ func (s *SyncService) syncAttachedReleases(ctx context.Context, provider Provide } status := release.Status if status == "" { - if release.IsDraft { + switch { + case release.IsDraft: status = "draft" - } else if release.IsPrerelease { + case release.IsPrerelease: status = "prerelease" - } else { + default: status = "released" } }