{"openapi":"3.0.0","paths":{"/auth/me":{"get":{"operationId":"AuthController_getProfile","summary":"Get current user profile","description":"Returns user profile. Creates user and organization on first call.","parameters":[],"responses":{"200":{"description":"User profile","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfileDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Auth"],"security":[{"bearer":[]}]}},"/deployments":{"post":{"operationId":"DeploymentsController_deploy","summary":"Deploy application","description":"Deploys an application to AWS ECS using the provided configuration and image","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployRequestDto"}}}},"responses":{"201":{"description":"Deployment successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeployResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Deployments"]},"get":{"operationId":"DeploymentsController_listDeployments","summary":"List deployments","description":"Returns a paginated list of deployments for the specified organization","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (0-indexed)","schema":{"default":0,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort by","schema":{"type":"string"}},{"name":"sortDir","required":false,"in":"query","description":"Sort direction (asc or desc)","schema":{"enum":["asc","desc"],"type":"string"}},{"name":"search","required":false,"in":"query","description":"Search query to filter results","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID to filter deployments","schema":{"type":"string"}},{"name":"projectId","required":false,"in":"query","description":"Project ID to filter deployments","schema":{"type":"string"}},{"name":"serviceId","required":false,"in":"query","description":"Service ID to filter deployments","schema":{"type":"string"}},{"name":"environment","required":false,"in":"query","description":"Environment name to filter deployments","schema":{"type":"string"}},{"name":"includeArchived","required":false,"in":"query","description":"Include archived deployments","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Paginated list of deployments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Deployments"]}},"/deployments/active-teardowns":{"get":{"operationId":"DeploymentsController_getActiveTeardowns","summary":"List active teardowns","description":"Returns teardown deployments currently in progress","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"projectId","required":false,"in":"query","description":"Project ID to filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Active teardowns","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActiveTeardownListDto"}}}}},"tags":["Deployments"]}},"/deployments/rollback":{"post":{"operationId":"DeploymentsController_rollback","summary":"Rollback deployment","description":"Rolls back a deployment to a previous template version","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackRequestDto"}}}},"responses":{"201":{"description":"Rollback successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EcsDeployResultDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Deployments"]}},"/deployments/{id}/cancel":{"post":{"operationId":"DeploymentsController_cancelDeployment","summary":"Cancel deployment","description":"Marks a running deployment as failed and enqueues a teardown to clean up created resources","parameters":[{"name":"id","required":true,"in":"path","description":"Deployment ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Deployment cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelDeploymentResponseDto"}}}},"400":{"description":"Cannot cancel a teardown deployment"},"404":{"description":"Deployment not found"},"409":{"description":"Deployment already in terminal state"}},"tags":["Deployments"]}},"/deployments/{id}/progress":{"get":{"operationId":"DeploymentsController_getProgress","summary":"Get deployment progress","description":"Returns the current status and step progress for a deployment","parameters":[{"name":"id","required":true,"in":"path","description":"Deployment ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment progress","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeploymentProgressResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Deployment not found"}},"tags":["Deployments"]}},"/logs":{"get":{"operationId":"LogsController_listLogs","summary":"Query CloudWatch logs","description":"Retrieves CloudWatch logs for a deployed service","parameters":[{"name":"serviceName","required":true,"in":"query","description":"Service name","schema":{"type":"string"}},{"name":"projectId","required":false,"in":"query","description":"Project ID to resolve AWS connection","schema":{"type":"string"}},{"name":"environmentName","required":false,"in":"query","description":"Environment name","schema":{"type":"string"}},{"name":"logGroupName","required":false,"in":"query","description":"CloudWatch log group name","schema":{"type":"string"}},{"name":"logStreamPrefix","required":false,"in":"query","description":"Log stream prefix","schema":{"type":"string"}},{"name":"startTime","required":false,"in":"query","description":"Start time in Unix milliseconds","schema":{"type":"number"}},{"name":"endTime","required":false,"in":"query","description":"End time in Unix milliseconds","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Maximum number of events to return","schema":{"type":"number"}},{"name":"nextToken","required":false,"in":"query","description":"Pagination token","schema":{"type":"string"}},{"name":"region","required":false,"in":"query","description":"AWS region","schema":{"type":"string"}},{"name":"roleArn","required":false,"in":"query","description":"ARN of the IAM role to assume","schema":{"type":"string"}},{"name":"externalId","required":false,"in":"query","description":"External ID for assuming the role","schema":{"type":"string"}}],"responses":{"200":{"description":"Logs retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogQueryResultDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Logs"]}},"/health":{"get":{"operationId":"HealthController_status","summary":"Check service health","description":"Returns the health status of the API and database connection","parameters":[],"responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponseDto"}}}},"503":{"description":"Service is unhealthy"}},"tags":["Health"]}},"/discover":{"post":{"operationId":"DiscoveryController_discover","summary":"Discover AWS environment","description":"Discovers available AWS resources and configuration options for deployment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoveryRequestDto"}}}},"responses":{"200":{"description":"Discovery successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscoveryResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Discovery"]}},"/onboarding/infrastructure-defaults":{"get":{"operationId":"OnboardingController_getInfrastructureDefaults","summary":"Get default infrastructure settings for all resource types","parameters":[],"responses":{"200":{"description":"Infrastructure defaults","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InfrastructureDefaultsResponseDto"}}}}},"tags":["Onboarding"]}},"/onboarding/aws-setup":{"post":{"operationId":"OnboardingController_awsSetup","summary":"Validate AWS role and discover environment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsSetupRequestDto"}}}},"responses":{"200":{"description":"AWS setup validated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsSetupResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/smart-setup":{"post":{"operationId":"OnboardingController_smartSetup","summary":"Create onboarding defaults with smart setup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartSetupRequestDto"}}}},"responses":{"200":{"description":"Smart setup prepared","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartSetupResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/progress":{"post":{"operationId":"OnboardingController_saveProgress","summary":"Save onboarding progress","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProgressRequestDto"}}}},"responses":{"200":{"description":"Progress saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProgressResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/progress/{organizationId}":{"get":{"operationId":"OnboardingController_getProgress","summary":"Get onboarding progress","parameters":[{"name":"organizationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Progress fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProgressResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Not a member of the requested organization"},"404":{"description":"Progress not found"}},"tags":["Onboarding"]}},"/onboarding/github-installation":{"post":{"operationId":"OnboardingController_saveGitHubInstallation","summary":"Save GitHub installation for an organization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveGitHubInstallationRequestDto"}}}},"responses":{"200":{"description":"GitHub installation saved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallationResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"403":{"description":"Not a member of the requested organization"}},"tags":["Onboarding"]}},"/onboarding/github-installations":{"get":{"operationId":"OnboardingController_listGitHubInstallations","summary":"List GitHub installations for an organization","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub installations listed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallationsListResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Not a member of the requested organization"}},"tags":["Onboarding"]}},"/onboarding/github-installation/{organizationId}":{"get":{"operationId":"OnboardingController_getGitHubInstallation","summary":"Get GitHub installation for an organization","parameters":[{"name":"organizationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub installation fetched","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallationResponseDto"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Not a member of the requested organization"},"404":{"description":"GitHub installation not found"}},"tags":["Onboarding"]}},"/onboarding/analyze-repo":{"post":{"operationId":"OnboardingController_analyzeRepo","summary":"Analyze repository","description":"Analyzes an existing repository to detect framework, configuration, and missing files","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeRepoRequestDto"}}}},"responses":{"200":{"description":"Repository analyzed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeRepoResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/detect":{"post":{"operationId":"OnboardingController_detect","summary":"Detect project","description":"Scans a repository (and monorepo subdirectories) to infer all services, suggested managed resources, and reasoning","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectRequestDto"}}}},"responses":{"200":{"description":"Project detected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/generate-config":{"post":{"operationId":"OnboardingController_generateConfig","summary":"Generate configuration","description":"Generates strictops.yml, Dockerfile, and workflow files for a repository","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateConfigRequestDto"}}}},"responses":{"200":{"description":"Configuration generated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateConfigResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/onboarding/verify-setup":{"post":{"operationId":"OnboardingController_verifySetup","summary":"Verify setup","description":"Verifies that a repository is properly configured for StrictOps deployment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySetupRequestDto"}}}},"responses":{"200":{"description":"Setup verified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifySetupResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["Onboarding"]}},"/github/owners":{"get":{"operationId":"GitHubController_listOwners","summary":"List GitHub owners for an installation","description":"Returns the GitHub account (org or user) associated with a given installation ID","parameters":[{"name":"installationId","required":true,"in":"query","description":"GitHub App installation ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Owners retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubOwnersResponseDto"}}}},"400":{"description":"Invalid request"}},"tags":["GitHub"]}},"/github/repositories":{"get":{"operationId":"GitHubController_listRepositories","summary":"List repositories for an installation","description":"Returns repositories accessible to the given GitHub App installation","parameters":[{"name":"installationId","required":true,"in":"query","description":"GitHub App installation ID","schema":{"type":"number"}}],"responses":{"200":{"description":"Repositories retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubRepositoriesResponseDto"}}}},"400":{"description":"Invalid request"}},"tags":["GitHub"]}},"/github/branches":{"get":{"operationId":"GitHubController_listBranches","summary":"List branches for a repository","description":"Returns the branches of a repository accessible to the given GitHub App installation, default branch first","parameters":[{"name":"installationId","required":true,"in":"query","description":"GitHub App installation ID","schema":{"type":"number"}},{"name":"owner","required":true,"in":"query","description":"Repository owner login","schema":{"type":"string"}},{"name":"repo","required":true,"in":"query","description":"Repository name","schema":{"type":"string"}}],"responses":{"200":{"description":"Branches retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubBranchesResponseDto"}}}},"400":{"description":"Invalid request"}},"tags":["GitHub"]}},"/github/installations":{"get":{"operationId":"GitHubController_listInstallations","summary":"List existing GitHub App installations","description":"Returns all accounts that have installed the GitHub App. Useful for reconnecting after a DB reset.","parameters":[],"responses":{"200":{"description":"Installations retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallationsResponseDto"}}}}},"tags":["GitHub"]}},"/github/install-url":{"get":{"operationId":"GitHubController_getInstallUrl","summary":"Get GitHub App installation URL","description":"Returns the URL to install the GitHub App","parameters":[{"name":"state","required":false,"in":"query","description":"Optional state parameter for OAuth flow","schema":{"type":"string"}},{"name":"redirectUri","required":false,"in":"query","description":"Redirect URI after installation","schema":{"type":"string"}}],"responses":{"200":{"description":"Installation URL retrieved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallUrlResponseDto"}}}},"400":{"description":"Invalid request"}},"tags":["GitHub"]}},"/github/callback":{"get":{"operationId":"GitHubController_handleInstallCallback","summary":"Handle GitHub App installation callback","description":"Processes the callback after GitHub App installation","parameters":[{"name":"installation_id","required":false,"in":"query","description":"GitHub installation ID","schema":{"type":"string"}},{"name":"setup_action","required":false,"in":"query","description":"Setup action type","schema":{"type":"string"}},{"name":"state","required":false,"in":"query","description":"OAuth state parameter","schema":{"type":"string"}}],"responses":{"200":{"description":"Callback processed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubInstallCallbackResponseDto"}}}},"400":{"description":"Invalid request"}},"tags":["GitHub"]}},"/github/bootstrap":{"post":{"operationId":"GitHubController_bootstrapRepository","summary":"Bootstrap new repository","description":"Queues a job to create a new repository, set up GitHub Actions, and perform initial build and deployment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubBootstrapRequestDto"}}}},"responses":{"202":{"description":"Bootstrap job queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsyncGitHubBootstrapResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["GitHub"]}},"/github/bootstrap-project":{"post":{"operationId":"GitHubController_bootstrapProject","summary":"Bootstrap project from template","description":"Creates multiple repositories and services from a project template, sets up GitHub Actions, and deploys all services","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectBootstrapRequestDto"}}}},"responses":{"202":{"description":"Project bootstrap job queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectBootstrapResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["GitHub"]}},"/github/provision-project":{"post":{"operationId":"GitHubController_provisionProject","summary":"Provision a project from an onboarding state","description":"Creates a project, its services (pointing at an existing repository), managed resources and links, then enqueues one project deployment. Used by /onboarding/repo and /console/projects/new for the existing-repo source.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProvisionRequestDto"}}}},"responses":{"202":{"description":"Project provisioning queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProvisionResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["GitHub"]}},"/github/add-service":{"post":{"operationId":"GitHubController_addService","summary":"Add one service to an existing project","description":"Creates a single service in an existing project, optionally provisioning new resources and linking the service to existing/new project resources, then enqueues a deployment. Used by /console/services/new.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingProvisionRequestDto"}}}},"responses":{"202":{"description":"Add-service queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddServiceResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["GitHub"]}},"/github/webhook":{"post":{"operationId":"GitHubController_handleWebhook","summary":"Handle GitHub webhook","description":"Processes GitHub webhook events (push, installation, etc.). Authenticated via x-hub-signature-256 HMAC-SHA256.","parameters":[{"name":"x-hub-signature-256","in":"header","description":"HMAC-SHA256 of the raw body, prefixed sha256=","required":true,"schema":{"type":"string"}},{"name":"x-github-event","in":"header","description":"GitHub event type","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook processed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GitHubWebhookResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Missing or invalid webhook signature"}},"tags":["GitHub"]}},"/api-tokens":{"post":{"operationId":"ApiTokenController_createToken","summary":"Create API token","description":"Creates a new API token. The plaintext token is only returned once.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiTokenRequestDto"}}}},"responses":{"201":{"description":"Token created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiTokenResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"tags":["API Tokens"]},"get":{"operationId":"ApiTokenController_listTokens","summary":"List API tokens","description":"Returns a list of API tokens for the organization. Token secrets are not returned.","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID to filter tokens","schema":{"type":"string"}}],"responses":{"200":{"description":"List of tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["API Tokens"]}},"/api-tokens/{id}":{"delete":{"operationId":"ApiTokenController_revokeToken","summary":"Revoke API token","description":"Revokes an API token. The token will no longer be valid for authentication.","parameters":[{"name":"id","required":true,"in":"path","description":"Token ID","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Token revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeApiTokenResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Token not found"}},"tags":["API Tokens"]}},"/services/preview-yaml":{"post":{"operationId":"ServiceController_previewYaml","summary":"Preview YAML","description":"Returns generated strictops.yml for the project without deploying","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewYamlRequestDto"}}}},"responses":{"200":{"description":"Generated YAML","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreviewYamlResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}},"tags":["Services"]}},"/services":{"post":{"operationId":"ServiceController_createService","summary":"Create service","description":"Creates a new service for the project. Optionally triggers deployment.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceRequestDto"}}}},"responses":{"201":{"description":"Service created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceWithDeployResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"409":{"description":"Service with this name already exists"}},"tags":["Services"]},"get":{"operationId":"ServiceController_listServices","summary":"List services","description":"Returns a list of services for the project","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID to filter services","schema":{"type":"string"}}],"responses":{"200":{"description":"List of services","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Services"]}},"/services/{id}":{"get":{"operationId":"ServiceController_getService","summary":"Get service","description":"Returns a service by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Service details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Service not found"}},"tags":["Services"]}},"/projects":{"post":{"operationId":"ProjectController_createProject","summary":"Create project","description":"Creates a new project for the organization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectRequestDto"}}}},"responses":{"201":{"description":"Project created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"409":{"description":"Project with this slug already exists"}},"tags":["Projects"]},"get":{"operationId":"ProjectController_listProjects","summary":"List projects","description":"Returns a list of projects for the organization","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID to filter projects","schema":{"type":"string"}}],"responses":{"200":{"description":"List of projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Projects"]}},"/projects/{id}":{"get":{"operationId":"ProjectController_getProject","summary":"Get project","description":"Returns a project by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Project details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}},"tags":["Projects"]},"put":{"operationId":"ProjectController_updateProject","summary":"Update project","description":"Updates a project name and/or description","parameters":[{"name":"id","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProjectRequestDto"}}}},"responses":{"200":{"description":"Project updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"}},"tags":["Projects"]},"delete":{"operationId":"ProjectController_deleteProject","summary":"Delete project","description":"Deletes a project and cascades to its resources","parameters":[{"name":"id","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Project deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Project not found"},"409":{"description":"Retained resources must be deleted first"}},"tags":["Projects"]}},"/projects/{projectId}/domains":{"post":{"operationId":"ProjectDomainController_create","summary":"Bind a custom domain to a (service, environment)","parameters":[{"name":"projectId","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProjectDomainRequestDto"}}}},"responses":{"201":{"description":"Domain created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}},"400":{"description":"Invalid hostname or project missing AWS connection"},"404":{"description":"Project not found"},"409":{"description":"Hostname already bound"}},"tags":["Project Domains"]},"get":{"operationId":"ProjectDomainController_list","summary":"List custom domains for a project","parameters":[{"name":"projectId","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainListResponseDto"}}}}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/availability":{"get":{"operationId":"ProjectDomainController_availability","summary":"Check Route53 Domains availability + price for a hostname","description":"Calls AWS CheckDomainAvailability + ListPrices through the customer assumed role. Used by the registration wizard. No DB write, no cost — read-only.","parameters":[{"name":"projectId","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}},{"name":"hostname","required":true,"in":"query","description":"Apex domain to check (e.g. acme.com)","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainAvailabilityResponseDto"}}}},"400":{"description":"Invalid hostname or project missing AWS connection"}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/{id}":{"get":{"operationId":"ProjectDomainController_get","summary":"Get a custom domain","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}},"404":{"description":"Not found"}},"tags":["Project Domains"]},"delete":{"operationId":"ProjectDomainController_delete","summary":"Delete a custom domain binding","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"},"404":{"description":"Not found"}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/register":{"post":{"operationId":"ProjectDomainController_register","summary":"Register a new apex domain via AWS Route53 Domains","description":"Registers the apex through the customer assumed role — AWS bills the customer account directly. Persists a PENDING_REGISTRATION row immediately; the poller drives it to PENDING_CERT once AWS finishes. Subdomains are rejected; register the apex and CNAME the subdomain to it.","parameters":[{"name":"projectId","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterProjectDomainRequestDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}},"400":{"description":"Invalid hostname / subdomain / project missing AWS connection"},"409":{"description":"Hostname already bound"}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/{id}/check":{"post":{"operationId":"ProjectDomainController_check","summary":"Force-poll the domain status (cert + DNS)","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/{id}/auto-renew":{"post":{"operationId":"ProjectDomainController_setAutoRenew","summary":"Toggle AWS auto-renewal for a registered domain","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAutoRenewRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}},"400":{"description":"Domain is not StrictOps-registered"}},"tags":["Project Domains"]}},"/projects/{projectId}/domains/{id}/renew":{"post":{"operationId":"ProjectDomainController_renew","summary":"Renew the domain registration for N more years","parameters":[{"name":"projectId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewProjectDomainRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}}},"400":{"description":"Domain is not StrictOps-registered or registration not complete"}},"tags":["Project Domains"]}},"/v1/deployments":{"post":{"operationId":"V1DeploymentsController_createDeployment","summary":"Create deployment (Manual mode)","description":"Creates a new deployment using API token authentication. Use this endpoint from CI/CD pipelines or the StrictOps CLI. AWS credentials are resolved from the organization's stored connection.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateDeploymentRequestDto"}}}},"responses":{"201":{"description":"Deployment created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1CreateDeploymentResponseDto"}}}},"400":{"description":"Invalid request or missing AWS connection"},"401":{"description":"Unauthorized"}},"tags":["V1 Deployments"],"security":[{"bearer":[]}]}},"/v1/deployments/{id}":{"get":{"operationId":"V1DeploymentsController_getDeploymentStatus","summary":"Get deployment status","description":"Returns the current status of a deployment","parameters":[{"name":"id","required":true,"in":"path","description":"Deployment ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Deployment status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1DeploymentStatusResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Deployment not found"}},"tags":["V1 Deployments"],"security":[{"bearer":[]}]}},"/v1/whoami":{"get":{"operationId":"V1WhoamiController_whoami","summary":"Verify API token","description":"Returns organization info for the authenticated token. Used by the CLI to verify token validity.","parameters":[],"responses":{"200":{"description":"Token info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/V1WhoamiResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["V1"],"security":[{"bearer":[]}]}},"/billing/plans":{"get":{"operationId":"BillingController_getPlans","summary":"List pricing plans","description":"Returns all available pricing plans.","parameters":[],"responses":{"200":{"description":"Pricing plans","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingPlansResponseDto"}}}}},"tags":["Billing"]}},"/billing/subscription":{"get":{"operationId":"BillingController_getSubscription","summary":"Get subscription","description":"Returns the current subscription for an organization.","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Current subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionResponseDto"}}}}},"tags":["Billing"]}},"/billing/invoices":{"get":{"operationId":"BillingController_listInvoices","summary":"List invoices","description":"Returns paginated invoices for an organization.","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"offset","required":false,"in":"query","description":"Number of rows to skip (default 0)","schema":{}},{"name":"limit","required":false,"in":"query","description":"Page size (default 20, max 100)","schema":{}}],"responses":{"200":{"description":"Invoice list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponseDto"}}}}},"tags":["Billing"]}},"/billing/change-plan":{"post":{"operationId":"BillingController_changePlan","summary":"Change subscription plan (in-place)","description":"Swaps the price on the existing Stripe subscription. Use this for Pro ↔ Team changes when the org already has an active sub. For first-time upgrades from FREE, use POST /billing/checkout instead.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanRequestDto"}}}},"responses":{"200":{"description":"Plan changed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePlanResponseDto"}}}},"400":{"description":"No existing subscription, invalid tier, or contact-sales tier"}},"tags":["Billing"]}},"/billing/checkout":{"post":{"operationId":"BillingController_createCheckoutSession","summary":"Create checkout session","description":"Creates a Stripe checkout session for subscribing to a plan.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutSessionRequestDto"}}}},"responses":{"201":{"description":"Checkout session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionResponseDto"}}}},"400":{"description":"Invalid tier or missing Stripe price"}},"tags":["Billing"]}},"/billing/portal":{"post":{"operationId":"BillingController_createBillingPortalSession","summary":"Create billing portal session","description":"Creates a Stripe billing portal session for managing subscription.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillingPortalRequestDto"}}}},"responses":{"201":{"description":"Portal session created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPortalResponseDto"}}}},"404":{"description":"No subscription found"}},"tags":["Billing"]}},"/billing/cancel":{"post":{"operationId":"BillingController_cancelSubscription","summary":"Cancel subscription","description":"Cancels the subscription at the end of the current billing period.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionRequestDto"}}}},"responses":{"200":{"description":"Subscription canceled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingActionResponseDto"}}}},"404":{"description":"No active subscription found"}},"tags":["Billing"]}},"/billing/resume":{"post":{"operationId":"BillingController_resumeSubscription","summary":"Resume subscription","description":"Resumes a subscription that was set to cancel at period end.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionRequestDto"}}}},"responses":{"200":{"description":"Subscription resumed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingActionResponseDto"}}}},"404":{"description":"No subscription found"}},"tags":["Billing"]}},"/billing/webhook":{"post":{"operationId":"BillingController_handleWebhook","summary":"Stripe webhook","description":"Receives Stripe webhook events.","parameters":[],"responses":{"200":{"description":"Webhook processed"}},"tags":["Billing"]}},"/admin/organizations/{id}/subscription-tier":{"post":{"operationId":"AdminController_setSubscriptionTier","summary":"Set org subscription tier (admin only)","description":"Direct override of Organization.subscriptionTier. Does not touch the Stripe Subscription row. Refuses when a Stripe-managed subscription exists at a different tier unless force=true.","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"force","required":false,"in":"query","description":"Override drift protection","schema":{}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSubscriptionTierRequestDto"}}}},"responses":{"200":{"description":"Tier updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetSubscriptionTierResponseDto"}}}},"400":{"description":"Invalid tier or drift detected (use force=true to override)"},"403":{"description":"strictops_admin role required"},"404":{"description":"Organization not found"}},"tags":["Admin"],"security":[{"bearer":[]}]}},"/services/{serviceId}/monitoring/metrics":{"get":{"operationId":"MonitoringController_queryMetrics","summary":"Query metric datapoints from CloudWatch","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}},{"name":"metrics","required":true,"in":"query","description":"Metric names to query","schema":{"type":"array","items":{"type":"string"}}},{"name":"from","required":true,"in":"query","description":"Start time (ISO 8601)","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","description":"End time (ISO 8601)","schema":{"type":"string"}},{"name":"period","required":false,"in":"query","description":"Period in seconds (60, 300, or 3600)","schema":{"default":60,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsQueryResponseDto"}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/health":{"get":{"operationId":"MonitoringController_getHealth","summary":"Get service health status","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthStatusResponseDto"}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/config":{"get":{"operationId":"MonitoringController_getConfig","summary":"Get monitoring config","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitoringConfigResponseDto"}}}}},"tags":["Monitoring"]},"put":{"operationId":"MonitoringController_updateConfig","summary":"Update monitoring config","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMonitoringConfigDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonitoringConfigResponseDto"}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/alarms":{"get":{"operationId":"MonitoringController_listAlarms","summary":"List alarm configs","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AlarmConfigResponseDto"}}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/alarms/{metricName}":{"put":{"operationId":"MonitoringController_upsertAlarm","summary":"Create or update alarm threshold","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"metricName","required":true,"in":"path","description":"Metric name","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertAlarmDto"}}}},"responses":{"200":{"description":""}},"tags":["Monitoring"]},"delete":{"operationId":"MonitoringController_deleteAlarm","summary":"Delete alarm","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"metricName","required":true,"in":"path","description":"Metric name","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/alarms/provision":{"post":{"operationId":"MonitoringController_provisionAlarms","summary":"Provision default alarms in customer AWS account","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionAlarmsDto"}}}},"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/alerts":{"get":{"operationId":"MonitoringController_listAlerts","summary":"List alert events","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AlertEventResponseDto"}}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/scaling":{"get":{"operationId":"MonitoringController_getScaling","summary":"Get scaling config and recent actions","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScalingStatusResponseDto"}}}}},"tags":["Monitoring"]},"put":{"operationId":"MonitoringController_updateScaling","summary":"Update scaling config","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateScalingConfigDto"}}}},"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/scaling/execute":{"post":{"operationId":"MonitoringController_executeScale","summary":"Execute manual scale","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteScaleDto"}}}},"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/scaling/actions/{actionId}/approve":{"post":{"operationId":"MonitoringController_approveAction","summary":"Approve a pending scaling action","parameters":[{"name":"actionId","required":true,"in":"path","description":"Scaling action ID","schema":{"type":"string"}},{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{}}],"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/scaling/actions/{actionId}/reject":{"post":{"operationId":"MonitoringController_rejectAction","summary":"Reject a pending scaling action","parameters":[{"name":"actionId","required":true,"in":"path","description":"Scaling action ID","schema":{"type":"string"}},{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{}}],"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/scaling/history":{"get":{"operationId":"MonitoringController_getScalingHistory","summary":"Get scaling action history","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}},{"name":"offset","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ScalingActionResponseDto"}}}}}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/deploy-markers":{"get":{"operationId":"MonitoringController_getDeployMarkers","summary":"Get deploy markers for chart overlay","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","schema":{"type":"string"}},{"name":"from","required":true,"in":"query","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/certificates":{"get":{"operationId":"MonitoringController_getCertificates","summary":"Get certificate expiry status","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/quotas":{"get":{"operationId":"MonitoringController_getQuotas","summary":"Get service quota warnings","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/services/{serviceId}/monitoring/cost":{"get":{"operationId":"MonitoringController_getCost","summary":"Estimated monthly cost projection for a service","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"query","description":"Environment name","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CostProjectionDto"}}}}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/dashboard":{"get":{"operationId":"AlertChannelController_getDashboard","summary":"Org-wide monitoring dashboard summary","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgDashboardDto"}}}}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/alerts/events":{"get":{"operationId":"AlertChannelController_listOrgAlertEvents","summary":"Org-wide alert event feed across all services","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by alarm state (e.g. ALARM, OK)","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"Start of time range (ISO 8601)","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"End of time range (ISO 8601)","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgAlertEventListDto"}}}}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/channels":{"get":{"operationId":"AlertChannelController_listChannels","summary":"List alert channels for org","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]},"post":{"operationId":"AlertChannelController_createChannel","summary":"Create alert channel","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlertChannelDto"}}}},"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/channels/stats":{"get":{"operationId":"AlertChannelController_getChannelStats","summary":"Org-wide alert-channel delivery stats (last 30 days)","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelDeliveryStatsDto"}}}}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/channels/{channelId}":{"put":{"operationId":"AlertChannelController_updateChannel","summary":"Update alert channel","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"channelId","required":true,"in":"path","description":"Alert channel ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertChannelDto"}}}},"responses":{"200":{"description":""}},"tags":["Monitoring"]},"delete":{"operationId":"AlertChannelController_deleteChannel","summary":"Delete alert channel","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"channelId","required":true,"in":"path","description":"Alert channel ID","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Monitoring"]}},"/organizations/{orgId}/monitoring/channels/{channelId}/test":{"post":{"operationId":"AlertChannelController_testChannel","summary":"Send test notification","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"channelId","required":true,"in":"path","description":"Alert channel ID","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"tags":["Monitoring"]}},"/projects/{projectId}/monitoring/service-health":{"post":{"operationId":"ProjectMonitoringController_serviceHealth","summary":"Batch service health (status, replicas, CPU, memory, uptime) for a project","parameters":[{"name":"projectId","required":true,"in":"path","description":"Project ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceHealthBatchQueryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceHealthBatchResponseDto"}}}}},"tags":["Monitoring"]}},"/dashboard/summary":{"get":{"operationId":"DashboardController_getSummary","summary":"Get dashboard summary","description":"Returns aggregated dashboard data for the specified organization","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"projectId","required":false,"in":"query","description":"Project ID for project-scoped summary","schema":{"type":"string"}}],"responses":{"200":{"description":"Dashboard summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardSummaryDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Dashboard"]}},"/teardown/projects/{projectName}/services/{serviceName}/environments/{environment}":{"delete":{"operationId":"TeardownController_deleteServiceFromEnvironment","summary":"Tear down a service from an environment","parameters":[{"name":"projectName","required":true,"in":"path","description":"Project name","schema":{"type":"string"}},{"name":"serviceName","required":true,"in":"path","description":"Service name","schema":{"type":"string"}},{"name":"environment","required":true,"in":"path","description":"Environment name","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"dryRun","required":false,"in":"query","description":"Preview what would be deleted","schema":{"default":false,"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownRequestDto"}}}},"responses":{"200":{"description":"Teardown result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownResultDto"}}}},"400":{"description":"Invalid request or missing confirmation"},"409":{"description":"Active deployments in progress"}},"tags":["Teardown"]}},"/teardown/projects/{projectName}/services/{serviceName}/environments":{"delete":{"operationId":"TeardownController_deleteServiceFromEnvironments","summary":"Tear down a service from multiple environments in one operation","parameters":[{"name":"projectName","required":true,"in":"path","description":"Project name","schema":{"type":"string"}},{"name":"serviceName","required":true,"in":"path","description":"Service name","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"dryRun","required":false,"in":"query","description":"Preview what would be deleted","schema":{"default":false,"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceEnvironmentsTeardownRequestDto"}}}},"responses":{"200":{"description":"Teardown result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownResultDto"}}}},"400":{"description":"Invalid request or missing confirmation"},"409":{"description":"Active deployments in progress"}},"tags":["Teardown"]}},"/teardown/projects/{projectName}/environments/{environment}":{"delete":{"operationId":"TeardownController_deleteEnvironment","summary":"Tear down an entire environment","parameters":[{"name":"projectName","required":true,"in":"path","description":"Project name","schema":{"type":"string"}},{"name":"environment","required":true,"in":"path","description":"Environment name","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"dryRun","required":false,"in":"query","description":"Preview what would be deleted","schema":{"default":false,"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownRequestDto"}}}},"responses":{"200":{"description":"Teardown result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownResultDto"}}}},"400":{"description":"Invalid request or missing confirmation"},"409":{"description":"Active deployments in progress"}},"tags":["Teardown"]}},"/teardown/projects/{projectName}":{"delete":{"operationId":"TeardownController_deleteProject","summary":"Tear down an entire project","parameters":[{"name":"projectName","required":true,"in":"path","description":"Project name","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"dryRun","required":false,"in":"query","description":"Preview what would be deleted","schema":{"default":false,"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownRequestDto"}}}},"responses":{"200":{"description":"Teardown result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeardownResultDto"}}}},"400":{"description":"Invalid request or missing confirmation"},"409":{"description":"Active deployments in progress"}},"tags":["Teardown"]}},"/environments":{"get":{"operationId":"EnvironmentController_listEnvironments","summary":"List environments","description":"Returns environments for a project","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of environments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Environments"]}},"/environments/{id}":{"get":{"operationId":"EnvironmentController_getEnvironment","summary":"Get environment","description":"Returns a single environment by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Environment ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Environment details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Environment not found"}},"tags":["Environments"]},"delete":{"operationId":"EnvironmentController_removeEnvironment","summary":"Remove environment","description":"Removes a single NOT_FOUND environment from the database","parameters":[{"name":"id","required":true,"in":"path","description":"Environment ID","schema":{"type":"string"}}],"responses":{"204":{"description":"Environment removed"},"400":{"description":"Environment is not NOT_FOUND"},"401":{"description":"Unauthorized"},"404":{"description":"Environment not found"}},"tags":["Environments"]}},"/environments/{id}/check":{"post":{"operationId":"EnvironmentController_checkEnvironmentStatus","summary":"Check environment status","description":"Checks the current CloudFormation stack status for an environment","parameters":[{"name":"id","required":true,"in":"path","description":"Environment ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Status check result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentCheckResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Environment not found"}},"tags":["Environments"]}},"/environments/{id}/recover":{"post":{"operationId":"EnvironmentController_recoverStack","summary":"Recover a stuck stack","description":"Recovers an environment whose CloudFormation stack is in a terminal failure state. Resumes a stuck rollback in place (UPDATE_ROLLBACK_FAILED) so live resources are preserved, or deletes a stack that never reached a working state so the next deploy recreates it. Rejects stacks that aren't in a recoverable failed state.","parameters":[{"name":"id","required":true,"in":"path","description":"Environment ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Recovery initiated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentRecoverResponseDto"}}}},"400":{"description":"Stack is not in a recoverable failed state"},"401":{"description":"Unauthorized"},"404":{"description":"Environment not found"}},"tags":["Environments"]}},"/environments/check-all":{"post":{"operationId":"EnvironmentController_checkAllEnvironments","summary":"Check all environments","description":"Checks CloudFormation stack status for all environments in a project","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Bulk check results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkEnvironmentCheckResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Environments"]}},"/environments/cleanup":{"post":{"operationId":"EnvironmentController_cleanupNotFound","summary":"Bulk remove NOT_FOUND environments","description":"Deletes all NOT_FOUND environments for a project from the database","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Cleanup result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvironmentCleanupResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Environments"]}},"/organizations/slug-availability":{"get":{"operationId":"OrganizationController_checkSlugAvailability","summary":"Check organization slug availability","parameters":[{"name":"slug","required":true,"in":"query","description":"Organization slug to check","schema":{"type":"string"}}],"responses":{"200":{"description":"Organization slug availability","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationSlugAvailabilityResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Organizations"]}},"/organizations/{id}":{"get":{"operationId":"OrganizationController_getOrganization","summary":"Get organization","description":"Returns an organization by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Organization details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"}},"tags":["Organizations"]},"put":{"operationId":"OrganizationController_updateOrganization","summary":"Update organization","description":"Updates an organization name, first-time slug, or AI feature opt-in","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationRequestDto"}}}},"responses":{"200":{"description":"Organization updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponseDto"}}}},"400":{"description":"Invalid organization slug or immutable slug update"},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"},"409":{"description":"Organization slug is already taken"}},"tags":["Organizations"]}},"/organizations/{id}/invites":{"post":{"operationId":"OrganizationController_createInvite","summary":"Invite a team member","description":"Creates a 7-day invite link and sends an invitation email","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTeamInviteRequestDto"}}}},"responses":{"201":{"description":"Invite created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInviteResponseDto"}}}},"401":{"description":"Unauthorized"},"409":{"description":"Active invite already exists or user is already a member"}},"tags":["Organizations"]}},"/organizations/{id}/invites/{token}/accept":{"post":{"operationId":"OrganizationController_acceptInvite","summary":"Accept a team invite","description":"Adds the authenticated user to the organization","parameters":[{"name":"id","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"token","required":true,"in":"path","description":"Invite token","schema":{"type":"string"}}],"responses":{"200":{"description":"Invite accepted"},"400":{"description":"Invite expired or already accepted"},"401":{"description":"Unauthorized"},"404":{"description":"Invite not found"}},"tags":["Organizations"]}},"/templates":{"get":{"operationId":"TemplatesController_listTemplates","summary":"List project templates","description":"Returns available project templates for bootstrapping","parameters":[],"responses":{"200":{"description":"List of templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TemplateListResponseDto"}}}}},"tags":["Templates"]}},"/templates/services":{"get":{"operationId":"TemplatesController_listServiceTemplates","summary":"List service templates","description":"Returns available service templates, optionally filtered by type","parameters":[{"name":"type","required":false,"in":"query","description":"Filter by service type","schema":{"enum":["WEB","API","WORKER"],"type":"string"}}],"responses":{"200":{"description":"List of service templates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceTemplateListResponseDto"}}}}},"tags":["Templates"]}},"/pricing/catalog":{"get":{"operationId":"PricingController_getCatalog","summary":"Pricing catalog","description":"Indicative per-size and per-resource monthly pricing for the onboarding cost estimate","parameters":[],"responses":{"200":{"description":"Pricing catalog","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingCatalogResponseDto"}}}}},"tags":["Pricing"]}},"/aws-connections":{"post":{"operationId":"AwsConnectionController_create","summary":"Create AWS connection","description":"Creates a new AWS connection for the organization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAwsConnectionRequestDto"}}}},"responses":{"201":{"description":"AWS connection created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsConnectionDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"409":{"description":"Connection with this name already exists"}},"tags":["AWS Connections"]},"get":{"operationId":"AwsConnectionController_list","summary":"List AWS connections","description":"Returns AWS connections for the organization","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of AWS connections","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsConnectionListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["AWS Connections"]}},"/aws-connections/{id}":{"get":{"operationId":"AwsConnectionController_getById","summary":"Get AWS connection","description":"Returns an AWS connection by ID","parameters":[{"name":"id","required":true,"in":"path","description":"AWS connection ID","schema":{"type":"string"}}],"responses":{"200":{"description":"AWS connection details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsConnectionDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"AWS connection not found"}},"tags":["AWS Connections"]},"put":{"operationId":"AwsConnectionController_update","summary":"Update AWS connection","description":"Updates an AWS connection","parameters":[{"name":"id","required":true,"in":"path","description":"AWS connection ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAwsConnectionRequestDto"}}}},"responses":{"200":{"description":"AWS connection updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AwsConnectionDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"AWS connection not found"},"409":{"description":"Connection with this name already exists"}},"tags":["AWS Connections"]},"delete":{"operationId":"AwsConnectionController_delete","summary":"Delete AWS connection","description":"Deletes an AWS connection (fails if projects still reference it)","parameters":[{"name":"id","required":true,"in":"path","description":"AWS connection ID","schema":{"type":"string"}}],"responses":{"200":{"description":"AWS connection deleted"},"400":{"description":"Cannot delete — projects still reference this connection"},"401":{"description":"Unauthorized"},"404":{"description":"AWS connection not found"}},"tags":["AWS Connections"]}},"/v1/services/{serviceId}/env/{environment}":{"get":{"operationId":"EnvVarsController_listEnvVars","summary":"List environment variables for a service","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"path","description":"Environment name (e.g. dev, prod)","schema":{"type":"string"}},{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Environment variables","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnvVarListResponseDto"}}}},"400":{"description":"Missing project context"},"404":{"description":"Service or project not found"}},"tags":["Environment Variables"],"security":[{"bearer":[]}]},"put":{"operationId":"EnvVarsController_setEnvVars","summary":"Set environment variables for a service (batch upsert)","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"path","description":"Environment name (e.g. dev, prod)","schema":{"type":"string"}},{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetEnvVarsRequestDto"}}}},"responses":{"200":{"description":"Variables set"},"400":{"description":"Invalid request"},"404":{"description":"Service or project not found"}},"tags":["Environment Variables"],"security":[{"bearer":[]}]}},"/v1/services/{serviceId}/env/{environment}/{name}":{"delete":{"operationId":"EnvVarsController_deleteEnvVar","summary":"Delete an environment variable","parameters":[{"name":"serviceId","required":true,"in":"path","description":"Service ID","schema":{"type":"string"}},{"name":"environment","required":true,"in":"path","description":"Environment name (e.g. dev, prod)","schema":{"type":"string"}},{"name":"name","required":true,"in":"path","description":"Variable name","schema":{"type":"string"}},{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Variable deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteEnvVarResponseDto"}}}},"400":{"description":"Missing project context"},"404":{"description":"Service or project not found"}},"tags":["Environment Variables"],"security":[{"bearer":[]}]}},"/resources/overview":{"get":{"operationId":"ResourceController_getOverview","summary":"Get resource overview","description":"Returns aggregated resource counts by type for a project","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Resource overview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceOverviewResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Resources"]}},"/resources/compute-cost":{"get":{"operationId":"ResourceController_getComputeCost","summary":"Project compute cost","description":"Indicative monthly Fargate compute for the project (services × environments), to combine with the per-resource infra cost for a unified project total","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Project compute cost","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectComputeCostDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Resources"]}},"/resources":{"get":{"operationId":"ResourceController_listResources","summary":"List resources","description":"Returns resources for a project, optionally filtered by type","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}},{"name":"type","required":false,"in":"query","description":"Filter by resource type","schema":{"enum":["DATABASE","IMAGE_STORE","STORAGE","QUEUE","CACHE"],"type":"string"}}],"responses":{"200":{"description":"List of resources","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceListResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Resources"]}},"/resources/cost-actuals":{"get":{"operationId":"ResourceController_getCostActuals","summary":"Project cost actuals","description":"Real AWS spend for the project from Cost Explorer, per-resource where attributable. Falls back to basis \"indicative\" when actuals are unavailable (role lacks ce:GetCostAndUsage, cost-allocation tags not activated, or no spend yet). Cached daily (#1258)","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Project cost actuals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCostActualsDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Resources"]}},"/resources/{id}":{"get":{"operationId":"ResourceController_getResource","summary":"Get resource","description":"Returns a single resource by ID","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Resource details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/resources/{id}/health-check":{"post":{"operationId":"ResourceController_checkHealth","summary":"Check resource health","description":"Runs a live health check against AWS for this resource","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Health check result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceHealthCheckResponseDto"}}}},"400":{"description":"Bad request (no AWS connection)"},"401":{"description":"Unauthorized"},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/resources/{id}/metrics":{"get":{"operationId":"ResourceController_getMetrics","summary":"Query CloudWatch metrics for a resource","description":"RDS/SQS/S3/ElastiCache metrics by resource type","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}},{"name":"metrics","required":false,"in":"query","description":"Metric keys to query; all for the resource type if omitted","schema":{"type":"array","items":{"type":"string"}}},{"name":"from","required":true,"in":"query","description":"Start time (ISO 8601)","schema":{"type":"string"}},{"name":"to","required":true,"in":"query","description":"End time (ISO 8601)","schema":{"type":"string"}},{"name":"period","required":false,"in":"query","description":"Period in seconds","schema":{"default":300,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceMetricsResponseDto"}}}}},"tags":["Resources"]}},"/resources/{id}/detail":{"get":{"operationId":"ResourceController_getDetail","summary":"Per-type resource detail","description":"Capacity gauges plus the type-specific detail block (database/cache/storage/queue/image) for the detail page","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceDetailDto"}}}},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/resources/{id}/cost":{"get":{"operationId":"ResourceController_getCost","summary":"Per-resource cost","description":"Month-to-date / projected / breakdown for the detail-page Cost section. Returns Cost Explorer actuals (basis \"actual\") when attributable, else indicative (#1258)","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceCostDto"}}}},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/resources/{id}/images":{"get":{"operationId":"ResourceController_getImages","summary":"List ECR images","description":"Returns container images for an IMAGE_STORE resource","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number (0-indexed)","schema":{"type":"string"}},{"name":"pageSize","required":false,"in":"query","description":"Items per page","schema":{"type":"string"}},{"name":"tag","required":false,"in":"query","description":"Filter by tag prefix","schema":{"type":"string"}}],"responses":{"200":{"description":"List of ECR images","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EcrImageListResponseDto"}}}},"400":{"description":"Resource is not an image store or missing AWS connection"},"401":{"description":"Unauthorized"},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/resources/sync":{"post":{"operationId":"ResourceController_syncResources","summary":"Sync resources from AWS","description":"Discovers resources from CloudFormation stacks and upserts them","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"201":{"description":"Sync result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceSyncResponseDto"}}}},"400":{"description":"Bad request (no AWS connection)"},"401":{"description":"Unauthorized"}},"tags":["Resources"]}},"/resources/{id}/force-delete":{"delete":{"operationId":"ResourceController_forceDeleteDatabase","summary":"Force delete a retained database","description":"Disables deletion protection and deletes the RDS instance from the customer AWS account","parameters":[{"name":"id","required":true,"in":"path","description":"Resource ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForceDeleteDatabaseRequestDto"}}}},"responses":{"200":{"description":"Database deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForceDeleteDatabaseResponseDto"}}}},"400":{"description":"Bad request (not a retained database, invalid confirmation, or no AWS connection)"},"401":{"description":"Unauthorized"},"404":{"description":"Resource not found"}},"tags":["Resources"]}},"/organizations/{orgId}/cost/summary":{"get":{"operationId":"OrgCostController_getSummary","summary":"Org cost summary","description":"Org-wide infrastructure spend rollup: month-to-date, projected month-end and last month, with per-project rows split into compute and resources. Basis \"partial\"/\"indicative\" when Cost Explorer data is missing for some or all projects","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Org cost summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCostSummaryDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Cost"]}},"/organizations/{orgId}/cost/daily":{"get":{"operationId":"OrgCostController_getDaily","summary":"Org daily cost series","description":"Org-wide daily spend for the current month with a trailing-average projection to month-end, plus the full prior month for comparison. Values are per-day (not cumulative)","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"range","required":false,"in":"query","description":"Series range: \"month\" (default) or \"ytd\". A cold YTD request backfills closed-month caches from Cost Explorer, so the first call can be slow","schema":{"enum":["month","ytd"],"type":"string"}}],"responses":{"200":{"description":"Org daily cost series","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCostDailyDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Cost"]}},"/organizations/{orgId}/cost/by-type":{"get":{"operationId":"OrgCostController_getByType","summary":"Org spend by resource type","description":"Month-to-date org spend grouped into donut buckets: compute (untagged remainder incl. shared infra), databases, storage, cache, queues, image stores, other. Sums to the same MTD total as the by-project rows","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Org spend by type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCostByTypeDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Cost"]}},"/organizations/{orgId}/cost/movers":{"get":{"operationId":"OrgCostController_getMovers","summary":"Org top cost movers","description":"Largest month-over-month spend deltas across the org: per-resource projected-month vs prior-month, plus each project’s compute remainder. Ranked by absolute delta, both directions","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max movers to return (default 8, max 50)","schema":{"type":"string"}}],"responses":{"200":{"description":"Org top cost movers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgCostMoversDto"}}}},"401":{"description":"Unauthorized"}},"tags":["Cost"]}},"/service-dependencies":{"post":{"operationId":"ServiceDependencyController_createDependency","summary":"Create dependency","description":"Creates a dependency link between a service and a target service or resource","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateServiceDependencyRequestDto"}}}},"responses":{"201":{"description":"Dependency created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceDependencyResponseDto"}}}},"400":{"description":"Invalid request"},"404":{"description":"Target not found"}},"tags":["Service Dependencies"]},"get":{"operationId":"ServiceDependencyController_listByService","summary":"List dependencies by service","description":"Returns all dependencies for a given service","parameters":[{"name":"serviceId","required":true,"in":"query","description":"Service ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of dependencies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceDependencyListResponseDto"}}}}},"tags":["Service Dependencies"]}},"/service-dependencies/by-project":{"get":{"operationId":"ServiceDependencyController_listByProject","summary":"List dependencies by project","description":"Returns all dependencies for all services in a project","parameters":[{"name":"projectId","required":true,"in":"query","description":"Project ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of dependencies","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceDependencyListResponseDto"}}}}},"tags":["Service Dependencies"]}},"/service-dependencies/{id}":{"delete":{"operationId":"ServiceDependencyController_deleteDependency","summary":"Delete dependency","description":"Removes a dependency link","parameters":[{"name":"id","required":true,"in":"path","description":"Dependency ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Dependency deleted"},"404":{"description":"Dependency not found"}},"tags":["Service Dependencies"]}},"/notifications":{"get":{"operationId":"NotificationController_listNotifications","summary":"List notifications for the current user","parameters":[{"name":"page","required":false,"in":"query","description":"Page number (0-indexed)","schema":{"default":0,"type":"number"}},{"name":"pageSize","required":false,"in":"query","description":"Number of items per page","schema":{"minimum":1,"maximum":100,"default":20,"type":"number"}},{"name":"sortBy","required":false,"in":"query","description":"Field to sort by","schema":{"type":"string"}},{"name":"sortDir","required":false,"in":"query","description":"Sort direction","schema":{"default":"desc","enum":["asc","desc"],"type":"string"}},{"name":"search","required":false,"in":"query","description":"Search query to filter results","schema":{"type":"string"}},{"name":"unreadOnly","required":false,"in":"query","description":"Only return unread notifications","schema":{"default":false,"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationListResponseDto"}}}}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/notifications/unread-count":{"get":{"operationId":"NotificationController_getUnreadCount","summary":"Get unread notification count","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountResponseDto"}}}}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/notifications/{id}/read":{"post":{"operationId":"NotificationController_markRead","summary":"Mark a notification as read","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/notifications/read-all":{"post":{"operationId":"NotificationController_markAllRead","summary":"Mark all notifications as read","parameters":[],"responses":{"200":{"description":""}},"tags":["Notifications"],"security":[{"bearer":[]}]}},"/organizations/{orgId}/incidents":{"get":{"operationId":"IncidentsController_list","summary":"List incidents with summary stats (MTTA/MTTR/open/this-month)","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","schema":{"default":0,"type":"number"}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"type":"number"}},{"name":"severity","required":false,"in":"query","schema":{"enum":["SEV1","SEV2","SEV3"],"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"enum":["TRIGGERED","ACKED","RESOLVED"],"type":"string"}},{"name":"serviceId","required":false,"in":"query","schema":{"type":"string"}},{"name":"environment","required":false,"in":"query","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"ISO date lower bound on startedAt","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO date upper bound on startedAt","schema":{"type":"string"}},{"name":"hideResolved","required":false,"in":"query","description":"Exclude resolved incidents","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentListResponseDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/incidents/{id}":{"get":{"operationId":"IncidentsController_get","summary":"Get an incident with its correlated timeline","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","description":"Incident ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentDetailDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/incidents/{id}/ack":{"post":{"operationId":"IncidentsController_ack","summary":"Acknowledge an incident (stops escalation, sets MTTA)","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","description":"Incident ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentActionResponseDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/incidents/{id}/resolve":{"post":{"operationId":"IncidentsController_resolve","summary":"Resolve an incident","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","description":"Incident ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentActionResponseDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/incidents/{id}/silence":{"post":{"operationId":"IncidentsController_silence","summary":"Silence incident sends for a window","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","description":"Incident ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SilenceIncidentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentActionResponseDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/incidents/{id}/postmortem":{"post":{"operationId":"IncidentsController_postmortem","summary":"Save the incident postmortem (posts to Slack on save)","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","description":"Incident ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostmortemDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IncidentActionResponseDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/alert-rules":{"get":{"operationId":"AlertRuleController_list","summary":"List alert rules","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleListResponseDto"}}}}},"tags":["Incidents"]},"post":{"operationId":"AlertRuleController_create","summary":"Create an alert rule","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAlertRuleDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleDto"}}}}},"tags":["Incidents"]}},"/organizations/{orgId}/alert-rules/{ruleId}":{"put":{"operationId":"AlertRuleController_update","summary":"Update an alert rule","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"ruleId","required":true,"in":"path","description":"Alert rule ID","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertRuleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertRuleDto"}}}}},"tags":["Incidents"]},"delete":{"operationId":"AlertRuleController_remove","summary":"Delete an alert rule","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"ruleId","required":true,"in":"path","description":"Alert rule ID","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Incidents"]}},"/organizations/{orgId}/alert-rules/{ruleId}/test":{"post":{"operationId":"AlertRuleController_test","summary":"Send a test alert through the rule channels","parameters":[{"name":"orgId","required":true,"in":"path","description":"Organization ID","schema":{"type":"string"}},{"name":"ruleId","required":true,"in":"path","description":"Alert rule ID","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestAlertResponseDto"}}}}},"tags":["Incidents"]}},"/ai-assistant/chat":{"post":{"operationId":"AiAssistantController_sendMessage","summary":"Send a chat message","description":"Sends a message to the AI assistant and receives a response. Creates a new conversation if conversationId is not provided.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendChatMessageRequestDto"}}}},"responses":{"201":{"description":"Message sent and response received","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendChatMessageResponseDto"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"404":{"description":"Conversation not found"}},"tags":["AI Assistant"]}},"/ai-assistant/quota":{"get":{"operationId":"AiAssistantController_getQuota","summary":"Get AI chat freemium quota","description":"Returns the org's monthly question count + limit. limit is null for tiers without a cap (PRO+). resetAt is the start of the next calendar month UTC.","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Current quota state"}},"tags":["AI Assistant"]}},"/ai-assistant/conversations":{"get":{"operationId":"AiAssistantController_listConversations","summary":"List conversations","description":"Returns a list of conversations for the user within the organization.","parameters":[{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}},{"name":"userId","required":true,"in":"query","description":"User ID","schema":{"type":"string"}}],"responses":{"200":{"description":"List of conversations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListConversationsResponseDto"}}}},"401":{"description":"Unauthorized"}},"tags":["AI Assistant"]}},"/ai-assistant/conversations/{id}":{"get":{"operationId":"AiAssistantController_getConversation","summary":"Get conversation detail","description":"Returns the full conversation including all messages.","parameters":[{"name":"id","required":true,"in":"path","description":"Conversation ID","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationDetailDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Conversation not found"}},"tags":["AI Assistant"]},"delete":{"operationId":"AiAssistantController_deleteConversation","summary":"Delete conversation","description":"Deletes a conversation and all its messages.","parameters":[{"name":"id","required":true,"in":"path","description":"Conversation ID","schema":{"type":"string"}},{"name":"organizationId","required":true,"in":"query","description":"Organization ID","schema":{"type":"string"}}],"responses":{"200":{"description":"Conversation deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteConversationResponseDto"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Conversation not found"}},"tags":["AI Assistant"]}}},"info":{"title":"StrictOps Control Plane API","description":"API for managing deployments, logs, and GitHub integration for StrictOps","version":"1.0","contact":{}},"tags":[{"name":"Health","description":"Health check endpoints"},{"name":"Deployments","description":"Deployment management endpoints"},{"name":"Logs","description":"CloudWatch logs endpoints"},{"name":"Discovery","description":"AWS resource discovery endpoints"},{"name":"GitHub","description":"GitHub integration endpoints"},{"name":"Billing","description":"Pricing and subscription management"}],"servers":[],"components":{"securitySchemes":{"JWT":{"scheme":"bearer","bearerFormat":"JWT","type":"http","description":"Enter your JWT token"}},"schemas":{"ProjectSummaryDto":{"type":"object","properties":{"id":{"type":"string","description":"Project ID"},"name":{"type":"string","description":"Project name"},"slug":{"type":"string","description":"Project slug"}},"required":["id","name","slug"]},"UserProfileDto":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"email":{"type":"string","description":"User email"},"name":{"type":"string","description":"User display name"},"organizationId":{"type":"string","description":"Organization ID"},"organizationName":{"type":"string","description":"Organization name"},"organizationSlug":{"type":"string","description":"Organization slug","nullable":true},"role":{"type":"string","description":"User role in organization"},"projects":{"description":"Projects in the organization","type":"array","items":{"$ref":"#/components/schemas/ProjectSummaryDto"}}},"required":["id","email","organizationId","organizationName","role","projects"]},"DeployRequestDto":{"type":"object","properties":{"strictopsYaml":{"type":"string","description":"Contents of strictops.yml file"},"imageUri":{"type":"string","description":"URI of the Docker image to deploy"},"region":{"type":"string","description":"AWS region"},"accountId":{"type":"string","description":"AWS account ID"},"vpcId":{"type":"string","description":"VPC ID"},"publicSubnetIds":{"description":"List of public subnet IDs","type":"array","items":{"type":"string"}},"environmentName":{"type":"string","description":"Target environment name"},"environments":{"description":"List of environments to deploy","type":"array","items":{"type":"string"}},"clusterName":{"type":"string","description":"ECS cluster name"},"logGroupName":{"type":"string","description":"CloudWatch log group name"},"stackName":{"type":"string","description":"CloudFormation stack name"},"templateVersion":{"type":"string","description":"Template version"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume for deployment"},"externalId":{"type":"string","description":"External ID for assuming the role"}},"required":["strictopsYaml","imageUri","roleArn","externalId"]},"DeployResponseDto":{"type":"object","properties":{"templateVersion":{"type":"string","description":"Template version used for deployment"},"environments":{"type":"object","description":"Deployment results per environment","additionalProperties":{"type":"object"}}},"required":["templateVersion","environments"]},"DeploymentListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Deployment ID"},"serviceId":{"type":"string","description":"Service ID"},"serviceName":{"type":"string","description":"Service name","nullable":true},"serviceType":{"type":"string","description":"Service type","nullable":true,"enum":["WEB","API","WORKER"]},"repoFullName":{"type":"string","description":"Full repository name","nullable":true},"commitSha":{"type":"string","description":"Git commit SHA","nullable":true},"environment":{"type":"string","description":"Target environment"},"deploymentType":{"type":"string","description":"Deployment type","nullable":true,"enum":["PROJECT_BOOTSTRAP","SERVICE_BOOTSTRAP","SERVICE_DEPLOY","MANUAL_DEPLOY","TEARDOWN_SERVICE","TEARDOWN_ENVIRONMENT","TEARDOWN_PROJECT"]},"environments":{"description":"Target environments","type":"array","items":{"type":"string"}},"serviceNames":{"description":"Service names involved","type":"array","items":{"type":"string"}},"status":{"type":"string","description":"Deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"errorMessage":{"type":"string","description":"Error message if deployment failed","nullable":true},"serviceUrl":{"type":"string","description":"Deployed service URL","nullable":true},"stackId":{"type":"string","description":"CloudFormation stack ID","nullable":true},"region":{"type":"string","description":"AWS region","nullable":true},"createdAt":{"type":"string","description":"When deployment was created"},"completedAt":{"type":"string","description":"When deployment completed","nullable":true},"archivedAt":{"type":"string","description":"When deployment was archived","nullable":true}},"required":["id","serviceId","environment","environments","serviceNames","status","createdAt"]},"PaginationMeta":{"type":"object","properties":{"page":{"type":"number","description":"Current page number (0-indexed)"},"pageSize":{"type":"number","description":"Number of items per page"},"totalCount":{"type":"number","description":"Total number of items across all pages"},"totalPages":{"type":"number","description":"Total number of pages"},"hasNextPage":{"type":"boolean","description":"Whether there is a next page"},"hasPreviousPage":{"type":"boolean","description":"Whether there is a previous page"}},"required":["page","pageSize","totalCount","totalPages","hasNextPage","hasPreviousPage"]},"DeploymentListResponseDto":{"type":"object","properties":{"deployments":{"description":"List of deployments","type":"array","items":{"$ref":"#/components/schemas/DeploymentListItemDto"}},"pagination":{"description":"Pagination metadata","allOf":[{"$ref":"#/components/schemas/PaginationMeta"}]}},"required":["deployments","pagination"]},"ActiveTeardownDto":{"type":"object","properties":{"id":{"type":"string","description":"Deployment ID"},"deploymentType":{"type":"string","description":"Deployment type","enum":["TEARDOWN_SERVICE","TEARDOWN_ENVIRONMENT","TEARDOWN_PROJECT"]},"status":{"type":"string","description":"Deployment status","enum":["QUEUED","RUNNING"]},"requestPayload":{"type":"object","description":"Request payload with teardown parameters"},"createdAt":{"type":"string","description":"When the teardown was created"}},"required":["id","deploymentType","status","requestPayload","createdAt"]},"ActiveTeardownListDto":{"type":"object","properties":{"teardowns":{"description":"Active teardown deployments","type":"array","items":{"$ref":"#/components/schemas/ActiveTeardownDto"}}},"required":["teardowns"]},"RollbackRequestDto":{"type":"object","properties":{"strictopsYaml":{"type":"string","description":"Contents of strictops.yml file"},"imageUri":{"type":"string","description":"URI of the Docker image to rollback to"},"region":{"type":"string","description":"AWS region"},"accountId":{"type":"string","description":"AWS account ID"},"vpcId":{"type":"string","description":"VPC ID"},"publicSubnetIds":{"description":"List of public subnet IDs","type":"array","items":{"type":"string"}},"targetTemplateVersion":{"type":"string","description":"Template version to rollback to"},"environmentName":{"type":"string","description":"Target environment name"},"clusterName":{"type":"string","description":"ECS cluster name"},"logGroupName":{"type":"string","description":"CloudWatch log group name"},"stackName":{"type":"string","description":"CloudFormation stack name"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume for rollback"},"externalId":{"type":"string","description":"External ID for assuming the role"}},"required":["strictopsYaml","imageUri","targetTemplateVersion","roleArn","externalId"]},"EcsDeployResultDto":{"type":"object","properties":{"serviceName":{"type":"string","description":"Service name"},"clusterArn":{"type":"string","description":"ARN of the ECS cluster"},"serviceArn":{"type":"string","description":"ARN of the ECS service"},"taskDefinitionArn":{"type":"string","description":"ARN of the task definition"},"executionRoleArn":{"type":"string","description":"ARN of the execution role"},"taskRoleArn":{"type":"string","description":"ARN of the task role"},"serviceUrl":{"type":"object","description":"URL where the service is accessible","nullable":true},"logGroupName":{"type":"string","description":"CloudWatch log group name"},"loadBalancerDnsName":{"type":"object","description":"DNS name of the load balancer","nullable":true},"repositoryUri":{"type":"string","description":"URI of the ECR repository"},"repositoryName":{"type":"string","description":"Name of the ECR repository"},"templateVersion":{"type":"string","description":"Template version used for deployment"}},"required":["serviceName","clusterArn","serviceArn","taskDefinitionArn","executionRoleArn","taskRoleArn","serviceUrl","logGroupName","loadBalancerDnsName","repositoryUri","repositoryName","templateVersion"]},"CancelDeploymentResponseDto":{"type":"object","properties":{"cancelled":{"type":"boolean"},"teardownDeploymentId":{"type":"string"}},"required":["cancelled"]},"ServiceEndpointCustomHostnameDto":{"type":"object","properties":{"hostname":{"type":"string","description":"Custom hostname configured for this service/environment"},"status":{"type":"string","description":"Provisioning status of the hostname","enum":["PENDING_REGISTRATION","PENDING_DNS","PENDING_CERT","ACTIVE","FAILED","DISABLED"]}},"required":["hostname","status"]},"ServiceEndpointDto":{"type":"object","properties":{"environmentName":{"type":"string","description":"Environment name"},"serviceName":{"type":"string","description":"Service name"},"strictopsHostname":{"type":"string","description":"StrictOps-managed hostname for this service/environment"},"strictopsUrl":{"type":"string","description":"Full URL using the StrictOps hostname (https)"},"customHostnames":{"description":"Customer-configured custom hostnames bound to this service/environment","type":"array","items":{"$ref":"#/components/schemas/ServiceEndpointCustomHostnameDto"}},"albUrl":{"type":"string","description":"Raw ALB URL exposed by the load balancer","nullable":true}},"required":["environmentName","serviceName","strictopsHostname","strictopsUrl","customHostnames"]},"DeploymentStepDto":{"type":"object","properties":{"name":{"type":"string","description":"Step name identifier"},"label":{"type":"string","description":"Human-readable step label"},"stepOrder":{"type":"number","description":"Step order in sequence"},"status":{"type":"string","description":"Step status","enum":["PENDING","RUNNING","COMPLETED","FAILED"]},"errorMessage":{"type":"string","description":"Error message if step failed","nullable":true},"metadata":{"type":"object","description":"Step metadata","nullable":true},"startedAt":{"type":"string","description":"When the step started","nullable":true},"completedAt":{"type":"string","description":"When the step completed","nullable":true}},"required":["name","label","stepOrder","status"]},"DeploymentProgressResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Deployment ID"},"serviceId":{"type":"string","description":"Service ID"},"repoFullName":{"type":"string","description":"Full repository name","nullable":true},"commitSha":{"type":"string","description":"Git commit SHA","nullable":true},"environment":{"type":"string","description":"Target environment"},"deploymentType":{"type":"string","description":"Deployment type","nullable":true,"enum":["PROJECT_BOOTSTRAP","SERVICE_BOOTSTRAP","SERVICE_DEPLOY","MANUAL_DEPLOY","TEARDOWN_SERVICE","TEARDOWN_ENVIRONMENT","TEARDOWN_PROJECT"]},"status":{"type":"string","description":"Deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"errorMessage":{"type":"string","description":"Error message if deployment failed","nullable":true},"errorStep":{"type":"string","description":"Step where error occurred","nullable":true},"actionsRunUrl":{"type":"string","description":"GitHub Actions run URL","nullable":true},"serviceUrl":{"type":"string","description":"Deployed service URL","nullable":true},"serviceUrls":{"type":"object","description":"Service URLs per environment","additionalProperties":{"type":"string"},"nullable":true,"example":{"dev":"http://dev-alb-123.us-east-1.elb.amazonaws.com","prod":"http://prod-alb-456.us-east-1.elb.amazonaws.com"}},"serviceEndpoints":{"description":"Rich per-service endpoint info (StrictOps hostname, custom hostnames with status, ALB URL)","nullable":true,"type":"array","items":{"$ref":"#/components/schemas/ServiceEndpointDto"}},"stackId":{"type":"string","description":"CloudFormation stack ID","nullable":true},"region":{"type":"string","description":"AWS region","nullable":true},"requestPayload":{"type":"object","description":"Original request payload"},"resultPayload":{"type":"object","description":"Deployment result payload","nullable":true},"startedAt":{"type":"string","description":"When deployment started","nullable":true},"completedAt":{"type":"string","description":"When deployment completed","nullable":true},"createdAt":{"type":"string","description":"When deployment was created"},"steps":{"description":"Deployment steps","type":"array","items":{"$ref":"#/components/schemas/DeploymentStepDto"}},"diagnosis":{"type":"object","description":"AI root-cause diagnosis for FAILED deploys (#1186). Best-effort: present when the LLM call succeeded; null otherwise.","nullable":true}},"required":["id","serviceId","environment","status","requestPayload","createdAt","steps"]},"CloudWatchLogEventDto":{"type":"object","properties":{"message":{"type":"string","description":"Log message"},"timestamp":{"type":"number","description":"Timestamp in Unix milliseconds"},"ingestionTime":{"type":"number","description":"Ingestion time in Unix milliseconds"},"logStreamName":{"type":"string","description":"Name of the log stream"},"eventId":{"type":"string","description":"Event ID"}},"required":["message","timestamp"]},"LogQueryResultDto":{"type":"object","properties":{"logGroupName":{"type":"string","description":"CloudWatch log group name"},"logStreamPrefix":{"type":"string","description":"Log stream prefix"},"events":{"description":"Log events","type":"array","items":{"$ref":"#/components/schemas/CloudWatchLogEventDto"}},"nextToken":{"type":"string","description":"Pagination token for next page"}},"required":["logGroupName","logStreamPrefix","events"]},"HealthResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"Overall health status"},"database":{"type":"string","description":"Database connection status","enum":["ok","error","disabled"]}},"required":["ok","database"]},"DiscoveryRequestDto":{"type":"object","properties":{"region":{"type":"string","description":"AWS region"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"}},"required":["roleArn","externalId"]},"DiscoveryDefaultsDto":{"type":"object","properties":{"region":{"type":"string","description":"Default AWS region"},"accountId":{"type":"string","description":"AWS account ID"},"vpcId":{"type":"string","description":"Default VPC ID"},"publicSubnetIds":{"description":"List of public subnet IDs","type":"array","items":{"type":"string"}},"strictopsTemplate":{"type":"string","description":"Default strictops.yml template"}},"required":["region","accountId","vpcId","publicSubnetIds","strictopsTemplate"]},"AwsVpcSubnetOptionDto":{"type":"object","properties":{"subnetId":{"type":"string","description":"Subnet ID"},"availabilityZone":{"type":"string","description":"Availability zone"},"cidrBlock":{"type":"string","description":"CIDR block"},"isDefault":{"type":"boolean","description":"Whether this is the default subnet"}},"required":["subnetId","isDefault"]},"AwsVpcOptionDto":{"type":"object","properties":{"vpcId":{"type":"string","description":"VPC ID"},"name":{"type":"string","description":"VPC name"},"cidrBlock":{"type":"string","description":"CIDR block"},"isDefault":{"type":"boolean","description":"Whether this is the default VPC"},"subnets":{"description":"Subnets in this VPC","type":"array","items":{"$ref":"#/components/schemas/AwsVpcSubnetOptionDto"}}},"required":["vpcId","isDefault","subnets"]},"SizingProfileDto":{"type":"object","properties":{"name":{"type":"string","description":"Profile name (small, medium, large)","example":"small"},"cpu":{"type":"string","description":"CPU allocation","example":"256"},"memory":{"type":"string","description":"Memory allocation","example":"512"}},"required":["name","cpu","memory"]},"DiscoveryOptionsDto":{"type":"object","properties":{"regions":{"description":"Available AWS regions","type":"array","items":{"type":"string"}},"vpcs":{"description":"Available VPCs","type":"array","items":{"$ref":"#/components/schemas/AwsVpcOptionDto"}},"sizingProfiles":{"description":"Available sizing profiles","type":"array","items":{"$ref":"#/components/schemas/SizingProfileDto"}}},"required":["regions","vpcs","sizingProfiles"]},"DiscoveryResponseDto":{"type":"object","properties":{"defaults":{"description":"Default configuration values","allOf":[{"$ref":"#/components/schemas/DiscoveryDefaultsDto"}]},"options":{"description":"Available configuration options","allOf":[{"$ref":"#/components/schemas/DiscoveryOptionsDto"}]}},"required":["defaults","options"]},"ProfileSizingDto":{"type":"object","properties":{"name":{"type":"string","description":"Profile name","example":"small"},"cpu":{"type":"string","description":"CPU units (e.g. 512)","example":"512"},"memory":{"type":"string","description":"Memory in MB (e.g. 1024)","example":"1024"}},"required":["name","cpu","memory"]},"EnvironmentResourceDefaultsDto":{"type":"object","properties":{"logRetentionDays":{"type":"number","description":"Log retention in days","example":90},"rdsInstanceClass":{"type":"string","description":"RDS instance class","example":"db.t3.small"},"rdsMultiAz":{"type":"boolean","description":"Whether RDS is multi-AZ","example":true},"rdsDeletionProtection":{"type":"boolean","description":"Whether deletion protection is enabled","example":true},"rdsBackupRetentionDays":{"type":"number","description":"Backup retention in days","example":7}},"required":["logRetentionDays","rdsInstanceClass","rdsMultiAz","rdsDeletionProtection","rdsBackupRetentionDays"]},"EnvironmentDefaultsGroupDto":{"type":"object","properties":{"prod":{"description":"Production environment defaults","allOf":[{"$ref":"#/components/schemas/EnvironmentResourceDefaultsDto"}]},"nonprod":{"description":"Non-production environment defaults","allOf":[{"$ref":"#/components/schemas/EnvironmentResourceDefaultsDto"}]}},"required":["prod","nonprod"]},"DatabaseDefaultsDto":{"type":"object","properties":{"engine":{"type":"string","description":"Database engine","example":"postgres"},"engineVersion":{"type":"string","description":"Engine version","example":"16.3"},"allocatedStorageGb":{"type":"number","description":"Initial storage in GB","example":20},"maxAllocatedStorageGb":{"type":"number","description":"Maximum storage in GB","example":100},"encrypted":{"type":"boolean","description":"Whether storage is encrypted","example":true},"storageType":{"type":"string","description":"Storage type","example":"gp3"}},"required":["engine","engineVersion","allocatedStorageGb","maxAllocatedStorageGb","encrypted","storageType"]},"CacheDefaultsDto":{"type":"object","properties":{"engine":{"type":"string","description":"Cache engine","example":"redis"},"engineVersion":{"type":"string","description":"Engine version","example":"7.1"},"nodeType":{"type":"string","description":"Default node type","example":"cache.t3.micro"},"encrypted":{"type":"boolean","description":"Whether encryption is enabled","example":true}},"required":["engine","engineVersion","nodeType","encrypted"]},"StorageDefaultsDto":{"type":"object","properties":{"encryption":{"type":"string","description":"Encryption algorithm","example":"AES256"},"versioning":{"type":"boolean","description":"Whether versioning is enabled","example":true},"publicAccessBlocked":{"type":"boolean","description":"Whether public access is blocked","example":true},"deletionPolicy":{"type":"string","description":"Deletion policy","example":"RETAIN"}},"required":["encryption","versioning","publicAccessBlocked","deletionPolicy"]},"QueueDefaultsDto":{"type":"object","properties":{"messageRetentionDays":{"type":"number","description":"Message retention in days","example":14},"deadLetterQueue":{"type":"boolean","description":"Whether a dead-letter queue is created","example":true},"maxReceiveCount":{"type":"number","description":"Max receive count before dead-letter","example":3},"deletionPolicy":{"type":"string","description":"Deletion policy","example":"RETAIN"}},"required":["messageRetentionDays","deadLetterQueue","maxReceiveCount","deletionPolicy"]},"InfrastructureDefaultsResponseDto":{"type":"object","properties":{"profiles":{"description":"Available sizing profiles","type":"array","items":{"$ref":"#/components/schemas/ProfileSizingDto"}},"defaultReplicas":{"type":"number","description":"Default number of replicas","example":1},"environment":{"description":"Per-environment resource defaults","allOf":[{"$ref":"#/components/schemas/EnvironmentDefaultsGroupDto"}]},"database":{"description":"Database defaults","allOf":[{"$ref":"#/components/schemas/DatabaseDefaultsDto"}]},"cache":{"description":"Cache defaults","allOf":[{"$ref":"#/components/schemas/CacheDefaultsDto"}]},"storage":{"description":"Storage defaults","allOf":[{"$ref":"#/components/schemas/StorageDefaultsDto"}]},"queue":{"description":"Queue defaults","allOf":[{"$ref":"#/components/schemas/QueueDefaultsDto"}]}},"required":["profiles","defaultReplicas","environment","database","cache","storage","queue"]},"AwsSetupRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID to look up stored AWS connection"},"region":{"type":"string","description":"AWS region"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role (optional if organizationId provided)"}},"required":["roleArn"]},"RoleValidationDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"Whether the role was successfully assumed"},"error":{"type":"string","description":"Validation error message"}},"required":["ok"]},"AwsSetupResponseDto":{"type":"object","properties":{"roleValidation":{"description":"Role validation result","allOf":[{"$ref":"#/components/schemas/RoleValidationDto"}]},"discovery":{"description":"Discovered AWS environment","allOf":[{"$ref":"#/components/schemas/DiscoveryResponseDto"}]}},"required":["roleValidation","discovery"]},"SmartSetupRequestDto":{"type":"object","properties":{"orgName":{"type":"string","description":"Organization name"},"installationId":{"type":"number","description":"GitHub installation ID"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region"}},"required":["orgName","installationId","roleArn"]},"OrganizationSetupDto":{"type":"object","properties":{"name":{"type":"string","description":"Organization name"},"slug":{"type":"string","description":"Organization slug"}},"required":["name","slug"]},"GitHubSetupDto":{"type":"object","properties":{"installationId":{"type":"number","description":"GitHub installation ID"}},"required":["installationId"]},"AwsSetupDto":{"type":"object","properties":{"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"}},"required":["roleArn","externalId"]},"SmartSetupDefaultsDto":{"type":"object","properties":{"environments":{"description":"Default deployment environments","type":"array","items":{"type":"string"}},"sizingProfile":{"type":"string","description":"Default sizing profile"},"repositoryVisibility":{"type":"string","description":"Default repository visibility","enum":["private","public"]},"template":{"type":"string","description":"Default app template","example":"nextjs"}},"required":["environments","sizingProfile","repositoryVisibility","template"]},"SmartSetupOptionsDto":{"type":"object","properties":{"environments":{"description":"Supported deployment environments","type":"array","items":{"type":"string"}},"repositoryVisibilities":{"type":"array","description":"Repository visibility options","items":{"type":"string","enum":["private","public"]}},"templates":{"description":"Supported templates","type":"array","items":{"type":"string"}}},"required":["environments","repositoryVisibilities","templates"]},"SmartSetupResponseDto":{"type":"object","properties":{"organization":{"description":"Organization details","allOf":[{"$ref":"#/components/schemas/OrganizationSetupDto"}]},"github":{"description":"GitHub connection info","allOf":[{"$ref":"#/components/schemas/GitHubSetupDto"}]},"aws":{"description":"AWS connection info","allOf":[{"$ref":"#/components/schemas/AwsSetupDto"}]},"discovery":{"description":"Discovered AWS environment","allOf":[{"$ref":"#/components/schemas/DiscoveryResponseDto"}]},"defaults":{"description":"Default values applied for onboarding","allOf":[{"$ref":"#/components/schemas/SmartSetupDefaultsDto"}]},"options":{"description":"Available onboarding options","allOf":[{"$ref":"#/components/schemas/SmartSetupOptionsDto"}]}},"required":["organization","github","aws","discovery","defaults","options"]},"OnboardingProgressRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"step":{"type":"string","description":"Current onboarding step","example":"connect-aws"},"data":{"type":"object","description":"Progress payload"}},"required":["organizationId","step"]},"OnboardingProgressResponseDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"step":{"type":"string","description":"Current onboarding step"},"data":{"type":"object","description":"Progress payload"},"updatedAt":{"type":"string","description":"Last updated timestamp"}},"required":["organizationId","step","updatedAt"]},"SaveGitHubInstallationRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"installationId":{"type":"number","description":"GitHub App installation ID"}},"required":["organizationId","installationId"]},"GitHubInstallationResponseDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"installationId":{"type":"number","description":"GitHub App installation ID"},"createdAt":{"type":"string","description":"Created timestamp"},"updatedAt":{"type":"string","description":"Last updated timestamp"}},"required":["organizationId","installationId","createdAt","updatedAt"]},"GitHubInstallationsListResponseDto":{"type":"object","properties":{"installations":{"description":"GitHub installations for the organization","type":"array","items":{"$ref":"#/components/schemas/GitHubInstallationResponseDto"}}},"required":["installations"]},"AnalyzeRepoRequestDto":{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner (organization or user)"},"repo":{"type":"string","description":"Repository name"},"installationId":{"type":"number","description":"GitHub App installation ID"}},"required":["owner","repo","installationId"]},"DetectedConfigDto":{"type":"object","properties":{"framework":{"type":"string","description":"Detected framework","nullable":true},"version":{"type":"string","description":"Detected framework version","nullable":true},"language":{"type":"string","description":"Detected language","nullable":true},"port":{"type":"number","description":"Detected port","nullable":true},"hasDockerfile":{"type":"boolean","description":"Whether repository has a Dockerfile"},"hasStrictOpsYml":{"type":"boolean","description":"Whether repository has strictops.yml"},"hasHealthEndpoint":{"type":"boolean","description":"Whether repository has a health endpoint"},"packageManager":{"type":"string","description":"Detected package manager","nullable":true}},"required":["hasDockerfile","hasStrictOpsYml","hasHealthEndpoint"]},"SuggestedConfigDto":{"type":"object","properties":{"serviceName":{"type":"string","description":"Suggested service name"},"type":{"type":"string","description":"Suggested service type"},"port":{"type":"number","description":"Suggested port"},"profile":{"type":"string","description":"Suggested sizing profile"},"replicas":{"type":"number","description":"Suggested number of replicas"},"healthCheckPath":{"type":"string","description":"Suggested health check path"}},"required":["serviceName","type","port","profile","replicas","healthCheckPath"]},"AnalyzeRepoResponseDto":{"type":"object","properties":{"detected":{"description":"Detected configuration","allOf":[{"$ref":"#/components/schemas/DetectedConfigDto"}]},"suggestions":{"description":"Suggested configuration","allOf":[{"$ref":"#/components/schemas/SuggestedConfigDto"}]},"missingFiles":{"description":"List of missing files required for deployment","type":"array","items":{"type":"string"}}},"required":["detected","suggestions","missingFiles"]},"DetectRequestDto":{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner (organization or user)"},"repo":{"type":"string","description":"Repository name"},"installationId":{"type":"number","description":"GitHub App installation ID"},"branch":{"type":"string","description":"Branch to scan (defaults to the repo HEAD)"},"scope":{"type":"string","description":"Detection scope: full project or a single service","enum":["project","service"]}},"required":["owner","repo","installationId"]},"DetectedServiceDto":{"type":"object","properties":{"name":{"type":"string","description":"Inferred service name"},"type":{"type":"string","description":"Service type","enum":["web","api","worker","cron"]},"framework":{"type":"string","description":"Detected framework","nullable":true},"language":{"type":"string","description":"Detected language","nullable":true},"port":{"type":"number","description":"Inferred port","nullable":true},"root":{"type":"string","description":"Build context directory (monorepo root)"},"profile":{"type":"string","description":"Sizing profile"},"healthCheckPath":{"type":"string","description":"Health check path"}},"required":["name","type","root","profile","healthCheckPath"]},"SuggestedResourceDto":{"type":"object","properties":{"kind":{"type":"string","description":"Resource kind","enum":["postgres","redis","s3","queue"]},"name":{"type":"string","description":"Suggested resource name"},"envKey":{"type":"string","description":"Connection env var injected into linked services"},"linkedServiceNames":{"description":"Service names this resource auto-links to","type":"array","items":{"type":"string"}}},"required":["kind","name","envKey","linkedServiceNames"]},"DetectResponseDto":{"type":"object","properties":{"services":{"description":"Detected services","type":"array","items":{"$ref":"#/components/schemas/DetectedServiceDto"}},"resources":{"description":"Suggested managed resources","type":"array","items":{"$ref":"#/components/schemas/SuggestedResourceDto"}},"reasoning":{"description":"Plain-language reasoning trail","type":"array","items":{"type":"string"}}},"required":["services","resources","reasoning"]},"GenerateConfigRequestDto":{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner (organization or user)"},"repo":{"type":"string","description":"Repository name"},"serviceName":{"type":"string","description":"Service name"},"profile":{"type":"string","description":"Sizing profile","enum":["small","medium","large"]},"replicas":{"type":"number","description":"Number of replicas"},"healthCheckPath":{"type":"string","description":"Health check path"},"environments":{"description":"Environments to deploy","type":"array","items":{"type":"string"}},"type":{"type":"string","description":"Service type (web, api, worker)"},"port":{"type":"number","description":"Detected port"}},"required":["owner","repo","serviceName"]},"GeneratedFileDto":{"type":"object","properties":{"path":{"type":"string","description":"File path"},"content":{"type":"string","description":"File content"}},"required":["path","content"]},"GenerateConfigResponseDto":{"type":"object","properties":{"files":{"description":"Generated files","type":"array","items":{"$ref":"#/components/schemas/GeneratedFileDto"}}},"required":["files"]},"VerifySetupRequestDto":{"type":"object","properties":{"owner":{"type":"string","description":"Repository owner (organization or user)"},"repo":{"type":"string","description":"Repository name"},"installationId":{"type":"number","description":"GitHub App installation ID"}},"required":["owner","repo","installationId"]},"VerifySetupResponseDto":{"type":"object","properties":{"valid":{"type":"boolean","description":"Whether all checks passed"},"checks":{"type":"object","description":"Individual check results"}},"required":["valid","checks"]},"GitHubOwnerDto":{"type":"object","properties":{"login":{"type":"string","description":"GitHub account login name"},"type":{"type":"string","description":"Account type","enum":["User","Organization"]},"avatarUrl":{"type":"string","description":"Avatar URL"}},"required":["login","type"]},"GitHubOwnersResponseDto":{"type":"object","properties":{"owners":{"description":"Available GitHub owners","type":"array","items":{"$ref":"#/components/schemas/GitHubOwnerDto"}}},"required":["owners"]},"GitHubRepositoryDto":{"type":"object","properties":{"id":{"type":"number","description":"GitHub repository ID"},"name":{"type":"string","description":"Repository name"},"fullName":{"type":"string","description":"Full repository name (owner/repo)"},"ownerLogin":{"type":"string","description":"Owner login name"},"defaultBranch":{"type":"string","description":"Default branch name"},"private":{"type":"boolean","description":"Whether the repository is private"},"language":{"type":"string","description":"Primary programming language","nullable":true},"description":{"type":"string","description":"Repository description","nullable":true},"updatedAt":{"type":"string","description":"Last updated timestamp (ISO 8601)","nullable":true}},"required":["id","name","fullName","ownerLogin","private"]},"GitHubRepositoriesResponseDto":{"type":"object","properties":{"repositories":{"description":"List of repositories","type":"array","items":{"$ref":"#/components/schemas/GitHubRepositoryDto"}}},"required":["repositories"]},"GitHubBranchDto":{"type":"object","properties":{"name":{"type":"string","description":"Branch name"},"protected":{"type":"boolean","description":"Whether the branch is protected"},"isDefault":{"type":"boolean","description":"Whether this is the repository default branch"}},"required":["name","protected","isDefault"]},"GitHubBranchesResponseDto":{"type":"object","properties":{"branches":{"description":"List of branches, default branch first","type":"array","items":{"$ref":"#/components/schemas/GitHubBranchDto"}}},"required":["branches"]},"GitHubInstallationItemDto":{"type":"object","properties":{"installationId":{"type":"number","description":"GitHub App installation ID"},"account":{"description":"GitHub account info","allOf":[{"$ref":"#/components/schemas/GitHubOwnerDto"}]}},"required":["installationId","account"]},"GitHubInstallationsResponseDto":{"type":"object","properties":{"installations":{"description":"List of existing GitHub App installations","type":"array","items":{"$ref":"#/components/schemas/GitHubInstallationItemDto"}}},"required":["installations"]},"GitHubInstallUrlResponseDto":{"type":"object","properties":{"url":{"type":"string","description":"GitHub App installation URL"}},"required":["url"]},"GitHubInstallCallbackResponseDto":{"type":"object","properties":{"installationId":{"type":"number","description":"GitHub installation ID"},"tokenExpiresAt":{"type":"string","description":"Token expiration timestamp"},"setupAction":{"type":"string","description":"Setup action type"},"state":{"type":"string","description":"OAuth state parameter"}},"required":["installationId","tokenExpiresAt"]},"GitHubBootstrapRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"projectId":{"type":"string","description":"Project ID"},"serviceId":{"type":"string","description":"Service ID"},"installationId":{"type":"number","description":"GitHub installation ID"},"owner":{"type":"string","description":"GitHub repository owner"},"repoName":{"type":"string","description":"Repository name"},"description":{"type":"string","description":"Repository description"},"private":{"type":"boolean","description":"Whether the repository should be private"},"templateVersion":{"type":"string","description":"Template version"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region"},"accountId":{"type":"string","description":"AWS account ID"},"vpcId":{"type":"string","description":"VPC ID"},"publicSubnetIds":{"description":"List of public subnet IDs","type":"array","items":{"type":"string"}},"strictopsApiUrl":{"type":"string","description":"StrictOps API URL"},"retryFromDeploymentId":{"type":"string","description":"ID of failed deployment being retried"}},"required":["organizationId","serviceId","installationId","owner","repoName","roleArn","externalId"]},"AsyncGitHubBootstrapResponseDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID to track progress"},"status":{"type":"string","description":"Initial deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]}},"required":["deploymentId","status"]},"ProjectBootstrapRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"projectId":{"type":"string","description":"Project ID (created if not provided)"},"templateId":{"type":"string","description":"Template ID (e.g., saas-starter, nextjs, api-only)"},"projectName":{"type":"string","description":"Project name (used for repo prefix and project slug)"},"installationId":{"type":"number","description":"GitHub installation ID"},"owner":{"type":"string","description":"GitHub repository owner"},"private":{"type":"boolean","description":"Whether repositories should be private"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region"},"accountId":{"type":"string","description":"AWS account ID"},"vpcId":{"type":"string","description":"VPC ID"},"publicSubnetIds":{"description":"List of public subnet IDs","type":"array","items":{"type":"string"}},"awsConnectionId":{"type":"string","description":"AWS connection ID to link to the project"},"stackStrategy":{"type":"string","description":"Stack strategy: SHARED puts all envs in one stack, SPLIT isolates prod","enum":["SHARED","SPLIT","ISOLATED"]},"environments":{"description":"Environment names (e.g. dev, stage, prod). Falls back to template defaults if not provided.","type":"array","items":{"type":"string"}},"productionEnvironments":{"description":"Names of production environments (e.g. prod). Used for stack grouping and workflow config.","type":"array","items":{"type":"string"}},"customDomains":{"type":"array","description":"Optional custom hostnames to bind to (service, environment) pairs after the project + services are created. Each row is created via ProjectDomainService and is best-effort — a failure here does not fail the bootstrap.","items":{"type":"object","properties":{"serviceName":{"type":"string"},"environmentName":{"type":"string"},"hostname":{"type":"string"}}}}},"required":["organizationId","templateId","projectName","installationId","owner","roleArn","externalId"]},"ProjectBootstrapServiceInfoDto":{"type":"object","properties":{"id":{"type":"string","description":"Service ID"},"name":{"type":"string","description":"Service name"},"repoName":{"type":"string","description":"Repository name"}},"required":["id","name","repoName"]},"ProjectBootstrapResponseDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID to track progress"},"projectId":{"type":"string","description":"Project ID"},"services":{"description":"Created services","type":"array","items":{"$ref":"#/components/schemas/ProjectBootstrapServiceInfoDto"}},"status":{"type":"string","description":"Initial deployment status","enum":["QUEUED"]}},"required":["deploymentId","projectId","services","status"]},"OnboardingProvisionRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"projectId":{"type":"string","description":"Project ID (update existing); created if omitted"},"projectName":{"type":"string","description":"Project name (slugified for the project)"},"installationId":{"type":"number","description":"GitHub installation ID (existing-repo source)"},"repo":{"type":"object","description":"Existing repository the services live in (owner/name/branch). Services point at this repo via their root subdirs.","properties":{"owner":{"type":"string"},"name":{"type":"string"},"branch":{"type":"string"}}},"awsConnectionId":{"type":"string","description":"AWS connection ID"},"region":{"type":"string","description":"AWS region"},"environments":{"description":"Environment names","type":"array","items":{"type":"string"}},"productionEnvironments":{"description":"Production environment names","type":"array","items":{"type":"string"}},"stackStrategy":{"type":"string","description":"Stack strategy","enum":["SHARED","SPLIT","ISOLATED"]},"services":{"type":"array","description":"Services to create. Rich config (cpu/memory/port/healthCheckPath/env) is persisted to Service.metadata and threaded into the deploy. A service may carry its own repoOwner/repoName/repoBranch (for multi-repo projects); when omitted it falls back to the top-level `repo`.","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["WEB","API","WORKER","CRON"]},"schedule":{"type":"string"},"profile":{"type":"string","enum":["SMALL","MEDIUM","LARGE"]},"root":{"type":"string"},"cpu":{"type":"number"},"memory":{"type":"number"},"port":{"type":"number"},"healthCheckPath":{"type":"string"},"env":{"type":"object"},"repoOwner":{"type":"string"},"repoName":{"type":"string"},"repoBranch":{"type":"string"},"installationId":{"type":"number"}}}},"resources":{"type":"array","description":"Managed resources to provision and link.","items":{"type":"object","properties":{"kind":{"type":"string","enum":["postgres","redis","s3","queue"]},"name":{"type":"string"},"config":{"type":"object"},"linkedServiceNames":{"type":"array","items":{"type":"string"}}}}},"existingResourceLinks":{"type":"array","description":"Link the new service(s) to the project's EXISTING resources (services/new). Each links to the named services, or all created services.","items":{"type":"object","properties":{"resourceId":{"type":"string"},"serviceNames":{"type":"array","items":{"type":"string"}}}}}},"required":["organizationId","projectName","services"]},"OnboardingProvisionResponseDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID to track progress"},"projectId":{"type":"string","description":"Project ID"},"services":{"description":"Created services","type":"array","items":{"$ref":"#/components/schemas/ProjectBootstrapServiceInfoDto"}}},"required":["deploymentId","projectId","services"]},"AddServiceResponseDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID to track progress"},"projectId":{"type":"string","description":"Project ID"},"serviceId":{"type":"string","description":"The created service ID"}},"required":["deploymentId","projectId","serviceId"]},"GitHubWebhookResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"Whether the webhook was processed successfully"},"event":{"type":"string","description":"GitHub event type"},"action":{"type":"string","description":"Event action"}},"required":["ok","event"]},"CreateApiTokenRequestDto":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable name for the token"},"organizationId":{"type":"string","description":"Organization ID the token belongs to"},"projectId":{"type":"string","description":"Project ID to scope the token to"},"serviceId":{"type":"string","description":"Service ID to scope the token to"},"permissions":{"description":"Token permissions","type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","description":"Token expiration date (ISO 8601)"}},"required":["name","organizationId"]},"CreateApiTokenResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Token ID"},"name":{"type":"string","description":"Human-readable name for the token"},"token":{"type":"string","description":"The plaintext token (only shown once)"},"tokenPrefix":{"type":"string","description":"Token prefix for identification"},"permissions":{"description":"Token permissions","type":"array","items":{"type":"string"}},"expiresAt":{"type":"string","description":"Token expiration date","nullable":true},"createdAt":{"type":"string","description":"When the token was created"}},"required":["id","name","token","tokenPrefix","permissions","createdAt"]},"ApiTokenListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Token ID"},"name":{"type":"string","description":"Human-readable name for the token"},"tokenPrefix":{"type":"string","description":"Token prefix for identification"},"permissions":{"description":"Token permissions","type":"array","items":{"type":"string"}},"projectId":{"type":"string","description":"Project ID the token is scoped to","nullable":true},"serviceId":{"type":"string","description":"Service ID the token is scoped to","nullable":true},"lastUsedAt":{"type":"string","description":"When the token was last used","nullable":true},"expiresAt":{"type":"string","description":"Token expiration date","nullable":true},"createdAt":{"type":"string","description":"When the token was created"},"revokedAt":{"type":"string","description":"When the token was revoked","nullable":true}},"required":["id","name","tokenPrefix","permissions","createdAt"]},"ApiTokenListResponseDto":{"type":"object","properties":{"tokens":{"description":"List of API tokens","type":"array","items":{"$ref":"#/components/schemas/ApiTokenListItemDto"}}},"required":["tokens"]},"RevokeApiTokenResponseDto":{"type":"object","properties":{"revoked":{"type":"boolean","description":"Whether the token was revoked"}},"required":["revoked"]},"PreviewNewServiceDto":{"type":"object","properties":{"name":{"type":"string","description":"Service name"},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER","CRON"]},"profile":{"type":"string","description":"Service profile","enum":["SMALL","MEDIUM","LARGE"]},"environments":{"description":"Environments for this service","type":"array","items":{"type":"string"}}},"required":["name"]},"PreviewYamlRequestDto":{"type":"object","properties":{"projectId":{"type":"string","description":"Project ID"},"newService":{"description":"New service to include in the preview","allOf":[{"$ref":"#/components/schemas/PreviewNewServiceDto"}]}},"required":["projectId"]},"PreviewYamlResponseDto":{"type":"object","properties":{"yaml":{"type":"string","description":"Generated strictops.yml content"}},"required":["yaml"]},"CreateServiceDependencyInputDto":{"type":"object","properties":{"targetType":{"type":"string","description":"Type of dependency target","enum":["SERVICE","RESOURCE"]},"targetServiceId":{"type":"string","description":"Target service ID (when targetType is SERVICE)"},"targetResourceId":{"type":"string","description":"Target resource ID (when targetType is RESOURCE)"},"envVarName":{"type":"string","description":"Environment variable name (e.g. DATABASE_URL)"},"envVarTemplate":{"type":"string","description":"Optional env var value template override"}},"required":["targetType","envVarName"]},"CreateServiceRequestDto":{"type":"object","properties":{"name":{"type":"string","description":"Service name"},"projectId":{"type":"string","description":"Project ID the service belongs to"},"repositoryUrl":{"type":"string","description":"Repository URL (e.g., https://github.com/org/repo)"},"installationId":{"type":"number","description":"GitHub App installation ID"},"integrationMode":{"type":"string","description":"Integration mode","enum":["GITHUB_APP","MANUAL"]},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER","CRON"]},"schedule":{"type":"string","description":"Cron schedule (5-field). Required for CRON services."},"profile":{"type":"string","description":"Service profile (sizing)","enum":["SMALL","MEDIUM","LARGE"]},"environments":{"description":"Environment names to create for this service","type":"array","items":{"type":"string"}},"deploy":{"type":"boolean","description":"If true, triggers a deployment after creating the service"},"dependencies":{"description":"Dependencies to create for this service","type":"array","items":{"$ref":"#/components/schemas/CreateServiceDependencyInputDto"}}},"required":["name","projectId"]},"ServiceEnvironmentUrlDto":{"type":"object","properties":{"environmentName":{"type":"string","description":"Environment name (e.g. production, dev)"},"url":{"type":"string","description":"Deployed service URL","nullable":true},"deploymentId":{"type":"string","description":"Deployment ID that produced this URL"},"lastDeployedAt":{"type":"string","description":"When the deployment completed","nullable":true}},"required":["environmentName","deploymentId"]},"ServiceResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Service ID"},"name":{"type":"string","description":"Service name"},"projectId":{"type":"string","description":"Project ID"},"repositoryUrl":{"type":"string","description":"Repository URL","nullable":true},"installationId":{"type":"number","description":"GitHub App installation ID","nullable":true},"integrationMode":{"type":"string","description":"Integration mode","enum":["GITHUB_APP","MANUAL"]},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER","CRON"]},"schedule":{"type":"string","description":"Cron schedule (CRON services only)","nullable":true},"profile":{"type":"string","description":"Service profile","enum":["SMALL","MEDIUM","LARGE"]},"createdAt":{"type":"string","description":"When the service was created"},"updatedAt":{"type":"string","description":"When the service was last updated"},"environmentUrls":{"description":"Deployed environment URLs","type":"array","items":{"$ref":"#/components/schemas/ServiceEnvironmentUrlDto"}}},"required":["id","name","projectId","integrationMode","type","profile","createdAt","updatedAt","environmentUrls"]},"CreateServiceWithDeployResponseDto":{"type":"object","properties":{"service":{"description":"Created service","allOf":[{"$ref":"#/components/schemas/ServiceResponseDto"}]},"deploymentId":{"type":"string","description":"Deployment ID if deploy was requested","nullable":true},"status":{"type":"string","description":"Deployment status","nullable":true}},"required":["service"]},"ServiceListResponseDto":{"type":"object","properties":{"services":{"description":"List of services","type":"array","items":{"$ref":"#/components/schemas/ServiceResponseDto"}}},"required":["services"]},"CreateProjectRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID the project belongs to"},"name":{"type":"string","description":"Project name"},"description":{"type":"string","description":"Project description"},"defaultEnvironments":{"description":"Default environments for new services","type":"array","items":{"type":"string"}},"productionEnvironments":{"description":"Environments classified as production","type":"array","items":{"type":"string"}},"awsConnectionId":{"type":"string","description":"AWS connection ID to link to this project"},"stackStrategy":{"type":"string","description":"Stack strategy: SHARED puts all envs in one stack, SPLIT isolates prod","enum":["SHARED","SPLIT","ISOLATED"]}},"required":["organizationId","name"]},"ProjectResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Project ID"},"organizationId":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Project name"},"slug":{"type":"string","description":"Project slug (unique per org)"},"description":{"type":"string","description":"Project description","nullable":true},"defaultEnvironments":{"description":"Default environments for new services","type":"array","items":{"type":"string"}},"productionEnvironments":{"description":"Environments classified as production","type":"array","items":{"type":"string"}},"stackStrategy":{"type":"string","description":"Stack strategy (SHARED or SPLIT)","enum":["SHARED","SPLIT","ISOLATED"]},"awsConnectionId":{"type":"string","description":"Linked AWS connection ID","nullable":true},"currentYaml":{"type":"string","description":"Current generated strictops.yml content","nullable":true},"currentYamlAt":{"type":"string","description":"When the current YAML was last updated","nullable":true},"createdAt":{"type":"string","description":"When the project was created"},"updatedAt":{"type":"string","description":"When the project was last updated"},"health":{"type":"string","description":"Project health derived from its latest deployment (SUCCEEDED → HEALTHY, FAILED → DOWN, in-progress → DEGRADED, none → IDLE)","enum":["HEALTHY","DEGRADED","DOWN","IDLE"]}},"required":["id","organizationId","name","slug","defaultEnvironments","productionEnvironments","stackStrategy","createdAt","updatedAt","health"]},"ProjectListResponseDto":{"type":"object","properties":{"projects":{"description":"List of projects","type":"array","items":{"$ref":"#/components/schemas/ProjectResponseDto"}}},"required":["projects"]},"UpdateProjectRequestDto":{"type":"object","properties":{"name":{"type":"string","description":"Project name"},"description":{"type":"string","description":"Project description"},"defaultEnvironments":{"description":"Default environments for new services","type":"array","items":{"type":"string"}},"productionEnvironments":{"description":"Environments classified as production","type":"array","items":{"type":"string"}},"awsConnectionId":{"type":"string","description":"AWS connection ID to link to this project"},"stackStrategy":{"type":"string","description":"Stack strategy: SHARED puts all envs in one stack, SPLIT isolates prod","enum":["SHARED","SPLIT","ISOLATED"]}}},"CreateProjectDomainRequestDto":{"type":"object","properties":{"serviceName":{"type":"string","description":"Service the domain is bound to"},"environmentName":{"type":"string","description":"Environment the domain is bound to (e.g. prod, staging)"},"hostname":{"type":"string","description":"Custom hostname (e.g. api.acme.com or acme.com)"}},"required":["serviceName","environmentName","hostname"]},"ProjectDomainResponseDto":{"type":"object","properties":{"id":{"type":"string"},"projectId":{"type":"string"},"serviceName":{"type":"string"},"environmentName":{"type":"string"},"hostname":{"type":"string"},"dnsModel":{"type":"string","enum":["SUBDOMAIN_CNAME","APEX_DELEGATED"]},"status":{"type":"string","enum":["PENDING_REGISTRATION","PENDING_DNS","PENDING_CERT","ACTIVE","FAILED","DISABLED"]},"instructions":{"type":"object","description":"Customer-facing setup instructions (validation records, CNAME target, nameservers)"},"autoRenew":{"type":"boolean","description":"AWS auto-renewal flag (true if AWS will auto-renew the registration)"},"registrationExpiresAt":{"type":"string","description":"Registration expiry ISO timestamp (only set for StrictOps-registered domains)"},"lastCheckedAt":{"type":"object"},"lastError":{"type":"object"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","projectId","serviceName","environmentName","hostname","dnsModel","status","autoRenew","createdAt","updatedAt"]},"ProjectDomainListResponseDto":{"type":"object","properties":{"domains":{"type":"array","items":{"$ref":"#/components/schemas/ProjectDomainResponseDto"}}},"required":["domains"]},"DomainPriceDto":{"type":"object","properties":{"price":{"type":"number","description":"Numeric price in the given currency"},"currency":{"type":"string","description":"ISO currency code (typically USD)"}},"required":["price","currency"]},"DomainAvailabilityResponseDto":{"type":"object","properties":{"hostname":{"type":"string","description":"Normalized hostname checked"},"available":{"type":"boolean","description":"True only when AWS reports AVAILABLE"},"availabilityCode":{"type":"string","description":"Raw availability code from AWS Route53 Domains","enum":["AVAILABLE","AVAILABLE_RESERVED","AVAILABLE_PREORDER","UNAVAILABLE","UNAVAILABLE_PREMIUM","UNAVAILABLE_RESTRICTED","RESERVED","DONT_KNOW"]},"tld":{"type":"string","description":"Final TLD label (e.g. com, dev, io)"},"registrationPrice":{"description":"Registration price (first year)","allOf":[{"$ref":"#/components/schemas/DomainPriceDto"}]},"renewalPrice":{"description":"Annual renewal price","allOf":[{"$ref":"#/components/schemas/DomainPriceDto"}]}},"required":["hostname","available","availabilityCode","tld"]},"WhoisExtraParamDto":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"WhoisContactDto":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phoneNumber":{"type":"string","description":"E.164 format, e.g. +1.2125551234"},"addressLine1":{"type":"string"},"addressLine2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string","description":"ISO 3166-2 subdivision code"},"countryCode":{"type":"string","description":"ISO 3166-1 alpha-2 country code (e.g. US, BR, GB)"},"zipCode":{"type":"string"},"contactType":{"type":"string","enum":["PERSON","COMPANY","ASSOCIATION","PUBLIC_BODY","RESELLER"]},"organizationName":{"type":"string"},"extraParams":{"description":"TLD-specific fields (e.g. .co.uk registrantType)","type":"array","items":{"$ref":"#/components/schemas/WhoisExtraParamDto"}}},"required":["firstName","lastName","email","phoneNumber","addressLine1","city","countryCode","zipCode"]},"RegisterProjectDomainRequestDto":{"type":"object","properties":{"serviceName":{"type":"string"},"environmentName":{"type":"string"},"hostname":{"type":"string","description":"Apex domain to register (e.g. acme.com). Subdomains are rejected."},"contact":{"$ref":"#/components/schemas/WhoisContactDto"},"years":{"type":"number","description":"Years to register; AWS minimum is 1, max is 10. Defaults to 1."},"autoRenew":{"type":"boolean","description":"Default true. Enables AWS auto-renewal."}},"required":["serviceName","environmentName","hostname","contact"]},"UpdateAutoRenewRequestDto":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Set to true to enable AWS auto-renewal; false to disable."}},"required":["enabled"]},"RenewProjectDomainRequestDto":{"type":"object","properties":{"years":{"type":"number","description":"Additional years to extend the registration. AWS min 1, max 10."}},"required":["years"]},"V1CreateDeploymentRequestDto":{"type":"object","properties":{"strictopsYaml":{"type":"string","description":"Contents of strictops.yml file"},"imageUri":{"type":"string","description":"URI of the Docker image to deploy"},"imageUris":{"type":"object","description":"Per-service image URIs, keyed by service name. Takes precedence over imageUri when present (multi-service repos build one image per service)."},"projectId":{"type":"string","description":"Project ID (required if org has multiple projects)"},"serviceId":{"type":"string","description":"Service ID (required if token is not scoped to a service)"},"environment":{"type":"string","description":"Target environment name (defaults to \"production\")"},"commitSha":{"type":"string","description":"Git commit SHA for tracking"}},"required":["strictopsYaml","imageUri"]},"V1CreateDeploymentResponseDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID to track progress"},"status":{"type":"string","description":"Initial deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]}},"required":["deploymentId","status"]},"V1DeploymentStatusResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Deployment ID"},"serviceId":{"type":"string","description":"Service ID"},"environment":{"type":"string","description":"Target environment"},"status":{"type":"string","description":"Deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"errorMessage":{"type":"string","description":"Error message if deployment failed","nullable":true},"serviceUrl":{"type":"string","description":"Deployed service URL","nullable":true},"stackId":{"type":"string","description":"CloudFormation stack ID","nullable":true},"region":{"type":"string","description":"AWS region","nullable":true},"createdAt":{"type":"string","description":"When deployment was created"},"completedAt":{"type":"string","description":"When deployment completed","nullable":true}},"required":["id","serviceId","environment","status","createdAt"]},"V1WhoamiResponseDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"organizationName":{"type":"string","description":"Organization name"}},"required":["organizationId","organizationName"]},"PricingPlanDto":{"type":"object","properties":{"tier":{"type":"string","description":"Tier identifier","enum":["FREE","PRO","TEAM","ENTERPRISE"]},"name":{"type":"string","description":"Display name"},"monthlyPrice":{"type":"number","description":"Monthly price in USD; null for contact-sales plans","nullable":true},"features":{"description":"List of included features","type":"array","items":{"type":"string"}},"contactSalesOnly":{"type":"boolean","description":"When true, this plan is sales-assisted only — UI renders a contact CTA and checkout is rejected"}},"required":["tier","name","features","contactSalesOnly"]},"PricingPlansResponseDto":{"type":"object","properties":{"plans":{"description":"Available pricing plans","type":"array","items":{"$ref":"#/components/schemas/PricingPlanDto"}}},"required":["plans"]},"SubscriptionResponseDto":{"type":"object","properties":{"tier":{"type":"string","description":"Current subscription tier","enum":["FREE","PRO","TEAM","ENTERPRISE"]},"status":{"type":"string","description":"Subscription status"},"stripeCustomerId":{"type":"string","description":"Stripe customer ID","nullable":true},"stripeSubscriptionId":{"type":"string","description":"Stripe subscription ID","nullable":true},"currentPeriodEnd":{"type":"string","description":"Current period end date","nullable":true},"cancelAtPeriodEnd":{"type":"boolean","description":"Whether subscription cancels at period end"},"trialEnd":{"type":"string","description":"ISO timestamp when the active trial ends; null when not in trial","nullable":true},"billingEmail":{"type":"string","description":"Email invoices are sent to; null when unknown or Stripe is unreachable","nullable":true},"paymentBrand":{"type":"string","description":"Card brand of the default payment method (e.g. \"visa\"); null when none on file","nullable":true},"paymentLast4":{"type":"string","description":"Last four digits of the default payment method; null when none on file","nullable":true}},"required":["tier","status","cancelAtPeriodEnd"]},"InvoiceDto":{"type":"object","properties":{"id":{"type":"string","description":"Invoice ID"},"stripeInvoiceId":{"type":"string","description":"Stripe invoice ID"},"amountDue":{"type":"number","description":"Amount due in the smallest currency unit (cents)"},"amountPaid":{"type":"number","description":"Amount paid in the smallest currency unit (cents)"},"currency":{"type":"string","description":"ISO-4217 currency code"},"status":{"type":"string","description":"Invoice status (paid / failed / draft)"},"invoiceUrl":{"type":"string","description":"Stripe-hosted invoice URL","nullable":true},"paidAt":{"type":"string","description":"ISO timestamp when the invoice was paid","nullable":true},"createdAt":{"type":"string","description":"ISO timestamp when the row was created"}},"required":["id","stripeInvoiceId","amountDue","amountPaid","currency","status","createdAt"]},"InvoiceListResponseDto":{"type":"object","properties":{"invoices":{"description":"Invoice rows for this page","type":"array","items":{"$ref":"#/components/schemas/InvoiceDto"}},"total":{"type":"number","description":"Total number of invoices for the org (across all pages)"}},"required":["invoices","total"]},"ChangePlanRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"tier":{"type":"string","description":"Target pricing tier","enum":["PRO","TEAM"]}},"required":["organizationId","tier"]},"ChangePlanResponseDto":{"type":"object","properties":{"tier":{"type":"string","description":"New tier"},"status":{"type":"string","description":"Resulting Stripe subscription status"}},"required":["tier","status"]},"CreateCheckoutSessionRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"email":{"type":"string","description":"Contact email for the customer"},"organizationName":{"type":"string","description":"Organization display name"},"tier":{"type":"string","description":"Target pricing tier","enum":["PRO","TEAM"]},"successUrl":{"type":"string","description":"URL to redirect to after successful checkout (may include {CHECKOUT_SESSION_ID})"},"cancelUrl":{"type":"string","description":"URL to redirect to if checkout is canceled"}},"required":["organizationId","email","organizationName","tier","successUrl","cancelUrl"]},"CheckoutSessionResponseDto":{"type":"object","properties":{"checkoutUrl":{"type":"string","description":"Stripe checkout session URL"}},"required":["checkoutUrl"]},"CreateBillingPortalRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"returnUrl":{"type":"string","description":"URL to return to after portal session"}},"required":["organizationId","returnUrl"]},"BillingPortalResponseDto":{"type":"object","properties":{"portalUrl":{"type":"string","description":"Stripe billing portal URL"}},"required":["portalUrl"]},"CancelSubscriptionRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"}},"required":["organizationId"]},"BillingActionResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the action succeeded"}},"required":["success"]},"SetSubscriptionTierRequestDto":{"type":"object","properties":{"tier":{"type":"string","description":"Target tier","enum":["FREE","PRO","TEAM","ENTERPRISE"]}},"required":["tier"]},"SetSubscriptionTierResponseDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"tier":{"type":"string","description":"New tier"},"previousTier":{"type":"string","description":"Previous tier"}},"required":["organizationId","tier","previousTier"]},"MetricDatapointResponseDto":{"type":"object","properties":{"metric":{"type":"string","description":"Metric name"},"value":{"type":"number","description":"Metric value"},"timestamp":{"type":"string","description":"Timestamp (ISO 8601)"}},"required":["metric","value","timestamp"]},"MetricsQueryResponseDto":{"type":"object","properties":{"serviceId":{"type":"string","description":"Service ID"},"environment":{"type":"string","description":"Environment name"},"datapoints":{"description":"Metric datapoints","type":"array","items":{"$ref":"#/components/schemas/MetricDatapointResponseDto"}}},"required":["serviceId","environment","datapoints"]},"HealthStatusMetricDto":{"type":"object","properties":{"metric":{"type":"string","description":"Metric name"},"value":{"type":"number","description":"Latest value"},"status":{"type":"string","description":"Metric status"}},"required":["metric","value","status"]},"HealthStatusResponseDto":{"type":"object","properties":{"status":{"type":"string","description":"Overall health status","enum":["healthy","degraded","unhealthy"]},"metrics":{"description":"Individual metric statuses","type":"array","items":{"$ref":"#/components/schemas/HealthStatusMetricDto"}},"checkedAt":{"type":"string","description":"Time of health check (ISO 8601)"}},"required":["status","metrics","checkedAt"]},"MonitoringConfigResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Config ID"},"serviceId":{"type":"string","description":"Service ID"},"environment":{"type":"string","description":"Environment name"},"enabled":{"type":"boolean","description":"Whether monitoring is enabled"},"createdAt":{"type":"string","description":"Created at (ISO 8601)"},"updatedAt":{"type":"string","description":"Updated at (ISO 8601)"}},"required":["id","serviceId","environment","enabled","createdAt","updatedAt"]},"UpdateMonitoringConfigDto":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"},"enabled":{"type":"boolean","description":"Whether monitoring is enabled"}},"required":["environment","enabled"]},"AlarmConfigResponseDto":{"type":"object","properties":{"id":{"type":"string"},"metricName":{"type":"string"},"threshold":{"type":"number"},"comparisonOp":{"type":"string"},"evaluationPeriods":{"type":"number"},"period":{"type":"number"},"statistic":{"type":"string"},"enabled":{"type":"boolean"},"alarmArn":{"type":"string"},"snsTopicArn":{"type":"string"}},"required":["id","metricName","threshold","comparisonOp","evaluationPeriods","period","statistic","enabled"]},"UpsertAlarmDto":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"},"threshold":{"type":"number","description":"Alarm threshold"},"comparisonOp":{"type":"string"},"evaluationPeriods":{"type":"number"},"period":{"type":"number"},"statistic":{"type":"string"},"enabled":{"type":"boolean"}},"required":["environment","threshold"]},"ProvisionAlarmsDto":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"}},"required":["environment"]},"AlertEventResponseDto":{"type":"object","properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"environment":{"type":"string"},"metricName":{"type":"string"},"alarmName":{"type":"string"},"state":{"type":"string"},"previousState":{"type":"string"},"reason":{"type":"string"},"value":{"type":"number"},"threshold":{"type":"number"},"timestamp":{"type":"string"}},"required":["id","serviceId","environment","metricName","alarmName","state","timestamp"]},"ScalingConfigResponseDto":{"type":"object","properties":{"id":{"type":"string"},"mode":{"type":"string"},"minTasks":{"type":"number"},"maxTasks":{"type":"number"},"targetCpuPercent":{"type":"number"},"targetMemPercent":{"type":"number"},"cooldownSeconds":{"type":"number"},"scaleUpStep":{"type":"number"},"scaleDownStep":{"type":"number"}},"required":["id","mode","minTasks","maxTasks","targetCpuPercent","targetMemPercent","cooldownSeconds","scaleUpStep","scaleDownStep"]},"ScalingActionResponseDto":{"type":"object","properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"environment":{"type":"string"},"direction":{"type":"string"},"fromTasks":{"type":"number"},"toTasks":{"type":"number"},"reason":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"expiresAt":{"type":"string"},"executedAt":{"type":"string"},"createdAt":{"type":"string"}},"required":["id","serviceId","environment","direction","fromTasks","toTasks","reason","status","mode","createdAt"]},"ScalingStatusResponseDto":{"type":"object","properties":{"config":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ScalingConfigResponseDto"}]},"recentActions":{"type":"array","items":{"$ref":"#/components/schemas/ScalingActionResponseDto"}}},"required":["config","recentActions"]},"UpdateScalingConfigDto":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"},"mode":{"type":"string"},"minTasks":{"type":"number"},"maxTasks":{"type":"number"},"targetCpuPercent":{"type":"number"},"targetMemPercent":{"type":"number"},"cooldownSeconds":{"type":"number"},"scaleUpStep":{"type":"number"},"scaleDownStep":{"type":"number"}},"required":["environment"]},"ExecuteScaleDto":{"type":"object","properties":{"environment":{"type":"string","description":"Environment name"},"desiredTasks":{"type":"number","description":"Desired task count"}},"required":["environment","desiredTasks"]},"CostProjectionDto":{"type":"object","properties":{"profile":{"type":"string"},"vcpu":{"type":"number","description":"vCPU per task"},"memoryGb":{"type":"number","description":"Memory (GB) per task"},"tasks":{"type":"number","description":"Current desired task count"},"vcpuHours":{"type":"number","description":"Projected vCPU-hours per month"},"gbHours":{"type":"number","description":"Projected GB-hours per month"},"perTaskMonthlyUsd":{"type":"number","description":"Estimated monthly cost per task (USD)"},"estimatedMonthlyUsd":{"type":"number","description":"Estimated monthly cost for all tasks (USD)"}},"required":["profile","vcpu","memoryGb","tasks","vcpuHours","gbHours","perTaskMonthlyUsd","estimatedMonthlyUsd"]},"OrgDashboardDto":{"type":"object","properties":{"serviceCount":{"type":"number"},"environmentCount":{"type":"number"},"servicesWithOpenAlerts":{"type":"number","description":"Services with a firing alarm in the last 24h"},"scalingActions7d":{"type":"number","description":"Scaling actions in the last 7 days"},"baselineMonthlyUsd":{"type":"number","description":"Indicative monthly cost assuming one task per service (USD)"}},"required":["serviceCount","environmentCount","servicesWithOpenAlerts","scalingActions7d","baselineMonthlyUsd"]},"OrgAlertEventDto":{"type":"object","properties":{"id":{"type":"string"},"serviceId":{"type":"string"},"serviceName":{"type":"string"},"environment":{"type":"string"},"metricName":{"type":"string"},"alarmName":{"type":"string"},"state":{"type":"string"},"previousState":{"type":"string"},"reason":{"type":"string"},"value":{"type":"number"},"threshold":{"type":"number"},"timestamp":{"type":"string"}},"required":["id","serviceId","serviceName","environment","metricName","alarmName","state","timestamp"]},"OrgAlertEventListDto":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/OrgAlertEventDto"}}},"required":["events"]},"ChannelDeliveryStatsDto":{"type":"object","properties":{"deliveries30d":{"type":"number","description":"Alert-channel deliveries in the last 30 days"},"failed":{"type":"number","description":"Failed deliveries in the last 30 days"}},"required":["deliveries30d","failed"]},"CreateAlertChannelDto":{"type":"object","properties":{"type":{"type":"string","description":"Channel type","enum":["email","slack","webhook","pagerduty"]},"name":{"type":"string","description":"Channel name"},"config":{"type":"object","description":"Channel config (type-specific)"},"isDefault":{"type":"boolean"}},"required":["type","name","config"]},"UpdateAlertChannelDto":{"type":"object","properties":{"name":{"type":"string"},"config":{"type":"object"},"enabled":{"type":"boolean"}}},"ServiceHealthTargetDto":{"type":"object","properties":{"serviceId":{"type":"string","description":"Service ID"},"environment":{"type":"string","description":"Environment name to report on"}},"required":["serviceId","environment"]},"ServiceHealthBatchQueryDto":{"type":"object","properties":{"targets":{"description":"Service + environment pairs to fetch health for","type":"array","items":{"$ref":"#/components/schemas/ServiceHealthTargetDto"}}},"required":["targets"]},"ServiceHealthDto":{"type":"object","properties":{"serviceId":{"type":"string","description":"Service ID"},"environment":{"type":"string","description":"Environment name"},"status":{"type":"string","description":"Derived status","enum":["HEALTHY","DEGRADED","DOWN","IDLE"]},"runningCount":{"type":"number","description":"Running task count","nullable":true},"desiredCount":{"type":"number","description":"Desired task count","nullable":true},"cpu":{"type":"number","description":"Latest CPU utilization (percent)","nullable":true},"memory":{"type":"number","description":"Latest memory utilization (percent)","nullable":true},"uptime24h":{"type":"number","description":"Availability over the last 24h (percent)","nullable":true},"deploymentStatus":{"type":"string","description":"ECS deployment rollout state","nullable":true},"lastSampleAt":{"type":"string","description":"Timestamp of the latest metric sample (ISO 8601)","nullable":true}},"required":["serviceId","environment","status","runningCount","desiredCount","cpu","memory","uptime24h","deploymentStatus","lastSampleAt"]},"ServiceHealthBatchResponseDto":{"type":"object","properties":{"results":{"description":"Health results per requested target","type":"array","items":{"$ref":"#/components/schemas/ServiceHealthDto"}}},"required":["results"]},"EnvironmentHealthDto":{"type":"object","properties":{"healthy":{"type":"number","description":"Number of healthy (ACTIVE) environments"},"total":{"type":"number","description":"Total number of environments"}},"required":["healthy","total"]},"DeploymentCountsDto":{"type":"object","properties":{"total":{"type":"number","description":"Total number of deployments"},"succeeded":{"type":"number","description":"Number of succeeded deployments"},"failed":{"type":"number","description":"Number of failed deployments"},"running":{"type":"number","description":"Number of running deployments"},"queued":{"type":"number","description":"Number of queued deployments"}},"required":["total","succeeded","failed","running","queued"]},"LatestEnvironmentDto":{"type":"object","properties":{"name":{"type":"string","description":"Environment name"},"status":{"type":"string","description":"Status of the latest deployment","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"region":{"type":"string","description":"AWS region"},"lastDeployedAt":{"type":"string","description":"When the latest deployment completed or was created","nullable":true},"serviceUrl":{"type":"string","description":"Deployed service URL","nullable":true},"deploymentId":{"type":"string","description":"Deployment ID of the latest deployment"},"repoFullName":{"type":"string","description":"Full repository name","nullable":true}},"required":["name","status","region","deploymentId"]},"DashboardServiceDto":{"type":"object","properties":{"id":{"type":"string","description":"Service ID"},"name":{"type":"string","description":"Service name"},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER"]},"profile":{"type":"string","description":"Service profile","enum":["SMALL","MEDIUM","LARGE"]},"latestDeploymentStatus":{"type":"string","description":"Status of the latest deployment","nullable":true},"latestDeploymentAt":{"type":"string","description":"When the latest deployment completed","nullable":true}},"required":["id","name","type","profile"]},"DashboardResourceCountsDto":{"type":"object","properties":{"databases":{"type":"number","description":"Number of databases"},"imageStores":{"type":"number","description":"Number of image stores"},"storage":{"type":"number","description":"Number of storage buckets"},"queues":{"type":"number","description":"Number of queues"},"caches":{"type":"number","description":"Number of caches"}},"required":["databases","imageStores","storage","queues","caches"]},"RecentDeploymentDto":{"type":"object","properties":{"id":{"type":"string","description":"Deployment ID"},"serviceName":{"type":"string","description":"Service name"},"environment":{"type":"string","description":"Target environment"},"status":{"type":"string","description":"Deployment status","enum":["QUEUED","RUNNING","SUCCEEDED","FAILED"]},"createdAt":{"type":"string","description":"When the deployment was created"},"completedAt":{"type":"string","description":"When the deployment completed","nullable":true}},"required":["id","serviceName","environment","status","createdAt"]},"DashboardSummaryDto":{"type":"object","properties":{"environmentCount":{"type":"number","description":"Number of environments"},"serviceCount":{"type":"number","description":"Number of distinct services"},"environmentHealth":{"description":"Environment health counts","allOf":[{"$ref":"#/components/schemas/EnvironmentHealthDto"}]},"deploymentCounts":{"description":"Deployment counts by status","allOf":[{"$ref":"#/components/schemas/DeploymentCountsDto"}]},"latestEnvironments":{"description":"Latest deployment per environment","type":"array","items":{"$ref":"#/components/schemas/LatestEnvironmentDto"}},"services":{"description":"Services with latest deployment status","type":"array","items":{"$ref":"#/components/schemas/DashboardServiceDto"}},"resourceCounts":{"description":"Resource counts by type","allOf":[{"$ref":"#/components/schemas/DashboardResourceCountsDto"}]},"recentDeployments":{"description":"Last 10 deployments","type":"array","items":{"$ref":"#/components/schemas/RecentDeploymentDto"}}},"required":["environmentCount","serviceCount","environmentHealth","deploymentCounts","latestEnvironments","services","resourceCounts","recentDeployments"]},"TeardownRequestDto":{"type":"object","properties":{"roleArn":{"type":"string","description":"ARN of the IAM role to assume for teardown"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region (defaults to us-east-1)"},"confirm":{"type":"string","description":"Confirmation string required when dryRun is false"},"retainResources":{"type":"boolean","description":"Whether to retain databases and storage after teardown (default: true)","default":true}},"required":["roleArn","externalId"]},"ResourceInfoDto":{"type":"object","properties":{"arn":{"type":"string","description":"Resource ARN"},"resourceType":{"type":"string","description":"Resource type (e.g. cloudformation:stack, ecs:service)"},"action":{"type":"string","description":"Action that will be taken","enum":["delete","update","retain"]},"retainable":{"type":"boolean","description":"Whether this resource is kept when \"retain resources\" is on (stateful: DB, cache, queues, storage, ECR, and their secrets). The Console applies the toggle client-side from this flag."}},"required":["arn","resourceType","action"]},"TeardownResultDto":{"type":"object","properties":{"dryRun":{"type":"boolean","description":"Whether this was a dry run"},"stacksDeleted":{"description":"Stacks that were deleted","type":"array","items":{"type":"string"}},"stacksUpdated":{"description":"Stacks that were updated (partial removal)","type":"array","items":{"type":"string"}},"resourcesDiscovered":{"description":"Resources discovered in scope","type":"array","items":{"$ref":"#/components/schemas/ResourceInfoDto"}},"deploymentsArchived":{"type":"number","description":"Number of deployment records archived"},"warning":{"type":"string","description":"Warning about shared stack or other affected resources"},"deploymentId":{"type":"string","description":"Deployment ID for async teardown tracking (non-dry-run only)"}},"required":["dryRun","stacksDeleted","stacksUpdated","resourcesDiscovered","deploymentsArchived"]},"ServiceEnvironmentsTeardownRequestDto":{"type":"object","properties":{"roleArn":{"type":"string","description":"ARN of the IAM role to assume for teardown"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region (defaults to us-east-1)"},"confirm":{"type":"string","description":"Confirmation string required when dryRun is false"},"retainResources":{"type":"boolean","description":"Whether to retain databases and storage after teardown (default: true)","default":true},"environments":{"description":"Environments to remove the service from","type":"array","items":{"type":"string"}}},"required":["roleArn","externalId","environments"]},"EnvironmentResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Environment ID"},"name":{"type":"string","description":"Environment name (e.g., dev, prod)"},"projectId":{"type":"string","description":"Project ID"},"stackName":{"type":"string","description":"CloudFormation stack name","nullable":true},"status":{"type":"string","description":"Environment status","enum":["ACTIVE","DRIFTED","NOT_FOUND","UNKNOWN"]},"lastCheckedAt":{"type":"string","description":"Last time status was checked","nullable":true},"lastCheckError":{"type":"string","description":"Last check error message","nullable":true},"createdAt":{"type":"string","description":"When the environment was created"},"updatedAt":{"type":"string","description":"When the environment was last updated"}},"required":["id","name","projectId","status","createdAt","updatedAt"]},"EnvironmentListResponseDto":{"type":"object","properties":{"environments":{"description":"List of environments","type":"array","items":{"$ref":"#/components/schemas/EnvironmentResponseDto"}}},"required":["environments"]},"EnvironmentCheckResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Environment ID"},"status":{"type":"string","description":"Updated status","enum":["ACTIVE","DRIFTED","NOT_FOUND","UNKNOWN"]},"lastCheckError":{"type":"string","description":"Error message if check failed","nullable":true},"lastCheckedAt":{"type":"string","description":"When the check was performed"}},"required":["id","status","lastCheckedAt"]},"EnvironmentRecoverResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Environment ID"},"action":{"type":"string","description":"Recovery action taken. CONTINUE_UPDATE_ROLLBACK resumes a stuck rollback in place (no downtime); DELETE removes a stack that never reached a working state so the next deploy recreates it.","enum":["CONTINUE_UPDATE_ROLLBACK","DELETE"]},"stackStatus":{"type":"string","description":"CloudFormation stack status after the recovery was initiated"},"status":{"type":"string","description":"Updated environment status","enum":["ACTIVE","DRIFTED","NOT_FOUND","UNKNOWN"]},"lastCheckedAt":{"type":"string","description":"When the recovery was initiated"}},"required":["id","action","stackStatus","status","lastCheckedAt"]},"BulkEnvironmentCheckResponseDto":{"type":"object","properties":{"results":{"description":"Results for each checked environment","type":"array","items":{"$ref":"#/components/schemas/EnvironmentCheckResponseDto"}}},"required":["results"]},"EnvironmentCleanupResponseDto":{"type":"object","properties":{"removed":{"type":"number","description":"Number of NOT_FOUND environments removed"}},"required":["removed"]},"OrganizationSlugAvailabilityResponseDto":{"type":"object","properties":{"slug":{"type":"string","description":"Validated organization slug"},"available":{"type":"boolean","description":"Whether the slug can be claimed"},"reason":{"type":"string","description":"Reason the slug cannot be claimed"},"suggestions":{"description":"Claimable alternative slugs to suggest when this one is unavailable","type":"array","items":{"type":"string"}}},"required":["slug","available","suggestions"]},"OrganizationResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Organization name"},"slug":{"type":"string","description":"Organization slug","nullable":true},"subscriptionTier":{"type":"string","description":"Subscription tier"},"logAnalysisEnabled":{"type":"boolean","description":"Whether the org has opted into AI log analysis on failed deploys"},"budgetMonthlyUsd":{"type":"number","description":"Org monthly infrastructure budget in whole USD; null when unset","nullable":true},"createdAt":{"type":"string","description":"When the organization was created"},"updatedAt":{"type":"string","description":"When the organization was last updated"}},"required":["id","name","subscriptionTier","logAnalysisEnabled","createdAt","updatedAt"]},"UpdateOrganizationRequestDto":{"type":"object","properties":{"name":{"type":"string","description":"Organization name"},"slug":{"type":"string","description":"Organization slug"},"logAnalysisEnabled":{"type":"boolean","description":"Per-org opt-in for sending failed-deploy logs to OpenAI/Anthropic for AI-assisted root cause analysis. Requires the control plane to also have LOG_ANALYSIS_ENABLED=true."},"budgetMonthlyUsd":{"type":"number","description":"Org monthly infrastructure budget in whole USD for the cost page burn indicator; null clears it","nullable":true}}},"CreateTeamInviteRequestDto":{"type":"object","properties":{"email":{"type":"string","description":"Email address to invite"},"role":{"type":"string","description":"Role to assign (defaults to customer)"}},"required":["email"]},"TeamInviteResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Invite ID"},"invitedEmail":{"type":"string","description":"Invited email address"},"role":{"type":"string","description":"Role that will be assigned on acceptance"},"expiresAt":{"type":"string","description":"When the invite expires"},"acceptedAt":{"type":"string","description":"When the invite was accepted, if at all","nullable":true},"createdAt":{"type":"string","description":"When the invite was created"}},"required":["id","invitedEmail","role","expiresAt","acceptedAt","createdAt"]},"TemplateServiceDto":{"type":"object","properties":{"name":{"type":"string","description":"Service name"},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER"]},"profile":{"type":"string","description":"Sizing profile","enum":["SMALL","MEDIUM","LARGE"]},"template":{"type":"string","description":"Template identifier"},"repositoryName":{"type":"string","description":"Repository name pattern"},"buildContext":{"type":"string","description":"Docker build context"},"dockerfile":{"type":"string","description":"Dockerfile path"}},"required":["name","type","profile","template"]},"TemplateResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Template ID"},"label":{"type":"string","description":"Display label"},"description":{"type":"string","description":"Template description"},"services":{"description":"Services included in the template","type":"array","items":{"$ref":"#/components/schemas/TemplateServiceDto"}},"database":{"type":"boolean","description":"Whether the template includes a database"},"defaultEnvironments":{"description":"Default environment names","type":"array","items":{"type":"string"}},"packageManager":{"type":"string","description":"Package manager used by generated workflows"}},"required":["id","label","description","services","database","defaultEnvironments"]},"TemplateListResponseDto":{"type":"object","properties":{"templates":{"description":"Available project templates","type":"array","items":{"$ref":"#/components/schemas/TemplateResponseDto"}}},"required":["templates"]},"ServiceTemplateDto":{"type":"object","properties":{"id":{"type":"string","description":"Template ID"},"label":{"type":"string","description":"Display label"},"description":{"type":"string","description":"Template description"},"type":{"type":"string","description":"Service type","enum":["WEB","API","WORKER"]},"repoUrl":{"type":"string","description":"Template repository URL"},"template":{"type":"string","description":"Template identifier"}},"required":["id","label","description","type","repoUrl","template"]},"ServiceTemplateListResponseDto":{"type":"object","properties":{"templates":{"description":"Available service templates","type":"array","items":{"$ref":"#/components/schemas/ServiceTemplateDto"}}},"required":["templates"]},"SizePriceDto":{"type":"object","properties":{"key":{"type":"string","description":"Size key (small/medium/large)"},"label":{"type":"string","description":"Short label (S/M/L)"},"cpu":{"type":"number","description":"vCPU"},"memory":{"type":"number","description":"Memory in GB"},"monthly":{"type":"number","description":"Indicative monthly USD per instance"}},"required":["key","label","cpu","memory","monthly"]},"ResourcePriceDto":{"type":"object","properties":{"kind":{"type":"string","description":"Resource kind (postgres/redis/s3/queue)"},"label":{"type":"string","description":"Display label"},"monthly":{"type":"number","description":"Indicative monthly USD base cost"}},"required":["kind","label","monthly"]},"CustomComputePricingDto":{"type":"object","properties":{"cpuCoefficient":{"type":"number","description":"Monthly USD per vCPU"},"memoryCoefficient":{"type":"number","description":"Monthly USD per GB of memory"}},"required":["cpuCoefficient","memoryCoefficient"]},"FargateRateDto":{"type":"object","properties":{"vcpuHourUsd":{"type":"number","description":"USD per vCPU-hour"},"gbHourUsd":{"type":"number","description":"USD per GB-hour"},"hoursPerMonth":{"type":"number","description":"Hours billed per month"}},"required":["vcpuHourUsd","gbHourUsd","hoursPerMonth"]},"InstanceRateDto":{"type":"object","properties":{"instanceClass":{"type":"string","description":"Instance class (e.g. db.t4g.micro)"},"monthly":{"type":"number","description":"Indicative monthly USD"}},"required":["instanceClass","monthly"]},"CacheNodeRateDto":{"type":"object","properties":{"nodeType":{"type":"string","description":"Node type (e.g. cache.t3.micro)"},"monthly":{"type":"number","description":"Indicative monthly USD"}},"required":["nodeType","monthly"]},"InfraRatesDto":{"type":"object","properties":{"albMonthly":{"type":"number","description":"Monthly USD per Application Load Balancer (base)"},"rdsInstance":{"description":"RDS instance class → monthly USD","type":"array","items":{"$ref":"#/components/schemas/InstanceRateDto"}},"rdsStorageGbMonthly":{"type":"number","description":"RDS storage USD per GB-month"},"cacheNode":{"description":"ElastiCache node type → monthly USD","type":"array","items":{"$ref":"#/components/schemas/CacheNodeRateDto"}},"s3GbMonthly":{"type":"number","description":"S3 storage USD per GB-month"},"ecrGbMonthly":{"type":"number","description":"ECR storage USD per GB-month"},"sqsBaseMonthly":{"type":"number","description":"SQS indicative monthly base USD"}},"required":["albMonthly","rdsInstance","rdsStorageGbMonthly","cacheNode","s3GbMonthly","ecrGbMonthly","sqsBaseMonthly"]},"PricingCatalogResponseDto":{"type":"object","properties":{"sizes":{"description":"Per-size compute pricing","type":"array","items":{"$ref":"#/components/schemas/SizePriceDto"}},"resources":{"description":"Per-resource base pricing","type":"array","items":{"$ref":"#/components/schemas/ResourcePriceDto"}},"customCompute":{"description":"Coefficients for custom-compute estimation","allOf":[{"$ref":"#/components/schemas/CustomComputePricingDto"}]},"fargate":{"description":"Fargate compute unit rates","allOf":[{"$ref":"#/components/schemas/FargateRateDto"}]},"infra":{"description":"Infrastructure unit rates (ALB, RDS, cache, storage, queues)","allOf":[{"$ref":"#/components/schemas/InfraRatesDto"}]},"currency":{"type":"string","description":"Currency code","example":"USD"}},"required":["sizes","resources","customCompute","fargate","infra","currency"]},"CreateAwsConnectionRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Connection name (unique within org)"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region"}},"required":["organizationId","name","roleArn","externalId"]},"AwsConnectionDto":{"type":"object","properties":{"id":{"type":"string","description":"Connection ID"},"organizationId":{"type":"string","description":"Organization ID"},"name":{"type":"string","description":"Connection name"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region","nullable":true},"createdAt":{"type":"string","description":"Created timestamp"},"updatedAt":{"type":"string","description":"Last updated timestamp"}},"required":["id","organizationId","name","roleArn","externalId","createdAt","updatedAt"]},"AwsConnectionListResponseDto":{"type":"object","properties":{"connections":{"description":"List of AWS connections","type":"array","items":{"$ref":"#/components/schemas/AwsConnectionDto"}}},"required":["connections"]},"UpdateAwsConnectionRequestDto":{"type":"object","properties":{"name":{"type":"string","description":"Connection name"},"roleArn":{"type":"string","description":"ARN of the IAM role to assume"},"externalId":{"type":"string","description":"External ID for assuming the role"},"region":{"type":"string","description":"AWS region"}}},"EnvVarDto":{"type":"object","properties":{"name":{"type":"string","description":"Variable name","example":"DATABASE_URL"},"value":{"type":"string","description":"Variable value (masked for secrets)","example":"postgres://..."},"isSecret":{"type":"boolean","description":"Whether this variable is stored as SecureString"}},"required":["name","value","isSecret"]},"EnvVarListResponseDto":{"type":"object","properties":{"variables":{"description":"Environment variables","type":"array","items":{"$ref":"#/components/schemas/EnvVarDto"}},"serviceName":{"type":"string","description":"Service name"},"environment":{"type":"string","description":"Environment name"}},"required":["variables","serviceName","environment"]},"SetEnvVarItemDto":{"type":"object","properties":{"name":{"type":"string","description":"Variable name (uppercase letters, digits, underscores)","example":"API_KEY"},"value":{"type":"string","description":"Variable value"},"secret":{"type":"boolean","description":"Store as SecureString","default":false}},"required":["name","value"]},"SetEnvVarsRequestDto":{"type":"object","properties":{"variables":{"description":"Variables to set","type":"array","items":{"$ref":"#/components/schemas/SetEnvVarItemDto"}}},"required":["variables"]},"DeleteEnvVarResponseDto":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the variable was deleted"}},"required":["deleted"]},"ResourceCountsDto":{"type":"object","properties":{"total":{"type":"number","description":"Total count"},"active":{"type":"number","description":"Active count"},"failed":{"type":"number","description":"Failed count"}},"required":["total","active","failed"]},"ResourceOverviewResponseDto":{"type":"object","properties":{"databases":{"description":"Database resource counts","allOf":[{"$ref":"#/components/schemas/ResourceCountsDto"}]},"imageStores":{"description":"Image store resource counts","allOf":[{"$ref":"#/components/schemas/ResourceCountsDto"}]},"storage":{"description":"Storage resource counts","allOf":[{"$ref":"#/components/schemas/ResourceCountsDto"}]},"queues":{"description":"Queue resource counts","allOf":[{"$ref":"#/components/schemas/ResourceCountsDto"}]},"cache":{"description":"Cache resource counts","allOf":[{"$ref":"#/components/schemas/ResourceCountsDto"}]}},"required":["databases","imageStores","storage","queues","cache"]},"ProjectComputeCostDto":{"type":"object","properties":{"computeMonthlyUsd":{"type":"number","description":"Indicative monthly Fargate compute for the project (services × environments)"},"serviceCount":{"type":"number","description":"Number of services in the project"},"environmentCount":{"type":"number","description":"Number of environments in the project"}},"required":["computeMonthlyUsd","serviceCount","environmentCount"]},"CostLineDto":{"type":"object","properties":{"label":{"type":"string","description":"Line-item label, e.g. the instance class"},"detail":{"type":"string","description":"Human-readable derivation, e.g. \"$0.2548/hr × 730 hr\""},"usd":{"type":"number","description":"Monthly USD for this line","nullable":true}},"required":["label","detail"]},"UtilizationDto":{"type":"object","properties":{"metric":{"type":"string","description":"Primary metric key (storage/memory/depth/size)"},"pct":{"type":"number","description":"Percentage used; null for value-only signals","nullable":true},"sub":{"type":"string","description":"Human-readable value, e.g. \"142 / 200 GB\""}},"required":["metric","sub"]},"ResourceResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Resource ID"},"projectId":{"type":"string","description":"Project ID"},"type":{"type":"string","description":"Resource type","enum":["DATABASE","IMAGE_STORE","STORAGE","QUEUE","CACHE"]},"name":{"type":"string","description":"Resource name"},"stackName":{"type":"string","description":"CloudFormation stack name","nullable":true},"status":{"type":"string","description":"Resource status","enum":["ACTIVE","CREATING","FAILED","DELETING","NOT_FOUND","RETAINED","UNKNOWN"]},"region":{"type":"string","description":"AWS region","nullable":true},"endpoint":{"type":"string","description":"Connection endpoint","nullable":true},"port":{"type":"string","description":"Connection port","nullable":true},"engine":{"type":"string","description":"Database engine (e.g. postgres)","nullable":true},"engineVersion":{"type":"string","description":"Database engine version","nullable":true},"instanceClass":{"type":"string","description":"Database instance class","nullable":true},"secretArn":{"type":"string","description":"Secrets Manager ARN for credentials","nullable":true},"securityGroupId":{"type":"string","description":"Security group ID","nullable":true},"repositoryUri":{"type":"string","description":"ECR repository URI","nullable":true},"repositoryName":{"type":"string","description":"ECR repository name","nullable":true},"metadata":{"type":"object","description":"Additional metadata","nullable":true},"lastSyncedAt":{"type":"string","description":"Last time this resource was synced from AWS","nullable":true},"lastSyncError":{"type":"string","description":"Last sync error message","nullable":true},"healthStatus":{"type":"string","description":"Live health status from AWS","nullable":true,"enum":["healthy","warning","error","unknown"]},"lastHealthCheckedAt":{"type":"string","description":"When the health was last checked","nullable":true},"monthlyCostUsd":{"type":"number","description":"Estimated monthly cost in USD; null when not estimable","nullable":true},"costBasis":{"type":"string","description":"How the cost was derived","enum":["deterministic","usage-based"]},"costBreakdown":{"description":"Per-line derivation of the monthly estimate","type":"array","items":{"$ref":"#/components/schemas/CostLineDto"}},"connectedServices":{"description":"Service names that consume this resource (blast radius); null until derived","nullable":true,"type":"array","items":{"type":"string"}},"utilization":{"description":"Primary utilization summary for the usage bar; null when no data","nullable":true,"allOf":[{"$ref":"#/components/schemas/UtilizationDto"}]},"upgradeTo":{"type":"string","description":"Suggested engine upgrade target (e.g. \"PG 16\"); null when current","nullable":true},"lastBackupAt":{"type":"string","description":"Timestamp of the latest restorable point / backup (RDS); null when unavailable","nullable":true},"createdAt":{"type":"string","description":"When the resource record was created"},"updatedAt":{"type":"string","description":"When the resource record was last updated"}},"required":["id","projectId","type","name","status","costBasis","costBreakdown","createdAt","updatedAt"]},"ResourceListResponseDto":{"type":"object","properties":{"resources":{"description":"List of resources","type":"array","items":{"$ref":"#/components/schemas/ResourceResponseDto"}}},"required":["resources"]},"ResourceActualLineDto":{"type":"object","properties":{"resourceId":{"type":"string","description":"Matched resource id; null when the spend could not be attributed to a resource","nullable":true},"resourceTag":{"type":"string","description":"Value of the strictops:resource cost-allocation tag (\"\" for unattributed)"},"total":{"type":"number","description":"Actual spend for the period, USD"},"daily":{"description":"Daily spend series for the period","type":"array","items":{"type":"number"}}},"required":["resourceTag","total","daily"]},"ProjectCostActualsDto":{"type":"object","properties":{"period":{"type":"string","description":"Current month the actuals cover, \"YYYY-MM\" (UTC)"},"projectTotalUsd":{"type":"number","description":"Actual project spend month-to-date, USD (0 when basis is \"indicative\")"},"lastMonthTotalUsd":{"type":"number","description":"Prior full-month actual total, USD; null when unavailable","nullable":true},"daily":{"description":"Daily project spend series for the current month","type":"array","items":{"type":"number"}},"byResource":{"description":"Per-resource actual breakdown","type":"array","items":{"$ref":"#/components/schemas/ResourceActualLineDto"}},"basis":{"type":"string","description":"Source of the figures. Actuals cover infra (RDS/S3/cache/queue); Fargate compute stays indicative","enum":["indicative","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["period","projectTotalUsd","daily","byResource","basis","currency"]},"ResourceHealthCheckResponseDto":{"type":"object","properties":{"resourceId":{"type":"string","description":"Resource ID"},"healthStatus":{"type":"string","description":"Health status","enum":["healthy","warning","error","unknown","not_found"]},"checkedAt":{"type":"string","description":"When the check was performed"},"details":{"type":"object","description":"Additional health check details","nullable":true}},"required":["resourceId","healthStatus","checkedAt"]},"ResourceMetricDatapointDto":{"type":"object","properties":{"metric":{"type":"string"},"value":{"type":"number"},"timestamp":{"type":"string"}},"required":["metric","value","timestamp"]},"ResourceMetricsResponseDto":{"type":"object","properties":{"resourceId":{"type":"string"},"type":{"type":"string","description":"Resource type (DATABASE/QUEUE/STORAGE/CACHE)"},"datapoints":{"type":"array","items":{"$ref":"#/components/schemas/ResourceMetricDatapointDto"}}},"required":["resourceId","type","datapoints"]},"UtilizationGaugeDto":{"type":"object","properties":{"label":{"type":"string","description":"Gauge label, e.g. \"Storage\", \"Connections\", \"Memory\""},"pct":{"type":"number","description":"Percent used (0-100)"},"sub":{"type":"string","description":"Human-readable detail, e.g. \"142 / 200 GB\""}},"required":["label","pct","sub"]},"DatabaseTopologyNodeDto":{"type":"object","properties":{"role":{"type":"string","description":"Role, e.g. \"Primary\" or \"Read replica\""},"instanceClass":{"type":"string","description":"Instance class","nullable":true},"az":{"type":"string","description":"Availability zone","nullable":true},"state":{"type":"string","description":"Health state","enum":["healthy","warning","error","unknown"]},"lagMs":{"type":"number","description":"Replica lag in milliseconds","nullable":true}},"required":["role","state"]},"DatabaseParameterDto":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"string"}},"required":["key","value"]},"DatabaseMaintenanceDto":{"type":"object","properties":{"currentVersion":{"type":"string","nullable":true},"upgradeTo":{"type":"string","description":"Available upgrade target","nullable":true},"autoMinorVersionUpgrade":{"type":"boolean"},"maintenanceWindow":{"type":"string","nullable":true},"backupRetentionDays":{"type":"number","description":"Backup retention in days","nullable":true}},"required":["autoMinorVersionUpgrade"]},"DatabaseSnapshotDto":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string","nullable":true},"sizeGb":{"type":"number","nullable":true},"type":{"type":"string","enum":["automated","manual"]}},"required":["id","type"]},"DatabaseDetailDto":{"type":"object","properties":{"topology":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseTopologyNodeDto"}},"parameters":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseParameterDto"}},"maintenance":{"$ref":"#/components/schemas/DatabaseMaintenanceDto"},"snapshots":{"type":"array","items":{"$ref":"#/components/schemas/DatabaseSnapshotDto"}},"lastBackupAt":{"type":"string","description":"Latest restorable point","nullable":true},"pitrEnabled":{"type":"boolean","description":"Point-in-time recovery enabled"}},"required":["topology","parameters","maintenance","snapshots","pitrEnabled"]},"CacheNodeConfigDto":{"type":"object","properties":{"nodeType":{"type":"string","nullable":true},"nodes":{"type":"string","description":"Topology summary, e.g. \"1 primary + 1 replica\""},"clusterMode":{"type":"boolean"},"failover":{"type":"boolean","description":"Automatic failover / Multi-AZ"},"multiAz":{"type":"boolean"}},"required":["nodes","clusterMode","failover","multiAz"]},"CacheDetailDto":{"type":"object","properties":{"node":{"$ref":"#/components/schemas/CacheNodeConfigDto"},"keyspaceAvailable":{"type":"boolean","description":"Whether keyspace stats are available (needs an in-VPC agent; false for now)"}},"required":["node","keyspaceAvailable"]},"StorageClassDto":{"type":"object","properties":{"label":{"type":"string","description":"Storage class label, e.g. \"Standard\""},"sizeBytes":{"type":"number"}},"required":["label","sizeBytes"]},"StorageLifecycleRuleDto":{"type":"object","properties":{"id":{"type":"string"},"scope":{"type":"string","description":"Scope, e.g. \"prefix: raw/\""},"action":{"type":"string","description":"Action summary"},"enabled":{"type":"boolean"}},"required":["id","scope","action","enabled"]},"StorageConfigDto":{"type":"object","properties":{"versioning":{"type":"string"},"encryption":{"type":"string"},"publicAccess":{"type":"string"},"replication":{"type":"string"}},"required":["versioning","encryption","publicAccess","replication"]},"StorageDetailDto":{"type":"object","properties":{"storageClasses":{"type":"array","items":{"$ref":"#/components/schemas/StorageClassDto"}},"lifecycle":{"type":"array","items":{"$ref":"#/components/schemas/StorageLifecycleRuleDto"}},"config":{"$ref":"#/components/schemas/StorageConfigDto"}},"required":["storageClasses","lifecycle","config"]},"QueueConfigDto":{"type":"object","properties":{"retentionSeconds":{"type":"number","nullable":true},"visibilityTimeoutSeconds":{"type":"number","nullable":true},"deliveryDelaySeconds":{"type":"number","nullable":true},"maxMessageBytes":{"type":"number","nullable":true},"fifo":{"type":"boolean"}},"required":["fifo"]},"QueueDlqDto":{"type":"object","properties":{"name":{"type":"string","nullable":true},"depth":{"type":"number","description":"Messages currently in the DLQ","nullable":true},"maxReceiveCount":{"type":"number","nullable":true}}},"QueueDetailDto":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/QueueConfigDto"},"dlq":{"description":"Dead-letter queue; null when none configured","nullable":true,"allOf":[{"$ref":"#/components/schemas/QueueDlqDto"}]},"consumers":{"description":"Service names consuming this queue (from connectedServices)","type":"array","items":{"type":"string"}}},"required":["config","consumers"]},"ImageRetentionRuleDto":{"type":"object","properties":{"description":{"type":"string"},"scope":{"type":"string"}},"required":["description","scope"]},"ImageStoreConfigDto":{"type":"object","properties":{"scanOnPush":{"type":"boolean"},"tagImmutability":{"type":"boolean"},"encryption":{"type":"string"},"visibility":{"type":"string"}},"required":["scanOnPush","tagImmutability","encryption","visibility"]},"ImageScanCountsDto":{"type":"object","properties":{"critical":{"type":"number"},"high":{"type":"number"},"medium":{"type":"number"},"low":{"type":"number"}},"required":["critical","high","medium","low"]},"ImageStoreDetailDto":{"type":"object","properties":{"retention":{"type":"array","items":{"$ref":"#/components/schemas/ImageRetentionRuleDto"}},"config":{"$ref":"#/components/schemas/ImageStoreConfigDto"},"scan":{"description":"Aggregate scan findings across recent images","allOf":[{"$ref":"#/components/schemas/ImageScanCountsDto"}]}},"required":["retention","config","scan"]},"ResourceDetailDto":{"type":"object","properties":{"resourceId":{"type":"string"},"type":{"type":"string","enum":["DATABASE","IMAGE_STORE","STORAGE","QUEUE","CACHE"]},"gauges":{"description":"Capacity gauges for the type (storage/connections/memory…)","type":"array","items":{"$ref":"#/components/schemas/UtilizationGaugeDto"}},"database":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/DatabaseDetailDto"}]},"cache":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/CacheDetailDto"}]},"storage":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/StorageDetailDto"}]},"queue":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/QueueDetailDto"}]},"imageStore":{"nullable":true,"allOf":[{"$ref":"#/components/schemas/ImageStoreDetailDto"}]}},"required":["resourceId","type","gauges"]},"ResourceCostBreakdownLineDto":{"type":"object","properties":{"item":{"type":"string","description":"Component, e.g. \"Instance\", \"Storage\", \"Requests\""},"meta":{"type":"string","description":"Detail, e.g. \"db.r6g.large · 730h\""},"now":{"type":"number","description":"This month (projected to month end)"},"last":{"type":"number","description":"Last month total, null until Cost Explorer actuals (#1258)","nullable":true}},"required":["item","meta","now","last"]},"ResourceCostDto":{"type":"object","properties":{"mtd":{"type":"number","description":"Month-to-date spend"},"projected":{"type":"number","description":"Projected full-month spend"},"lastMonth":{"type":"number","description":"Prior month total, null until Cost Explorer actuals (#1258)","nullable":true},"avgDay":{"type":"number","description":"Average per day (trailing)"},"trend":{"type":"number","description":"Percent change vs last month (projected)"},"daily":{"description":"Daily spend series for the month","type":"array","items":{"type":"number"}},"breakdown":{"type":"array","items":{"$ref":"#/components/schemas/ResourceCostBreakdownLineDto"}},"basis":{"type":"string","description":"Source of the figures","enum":["indicative","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["mtd","projected","lastMonth","avgDay","trend","daily","breakdown","basis","currency"]},"EcrImageDto":{"type":"object","properties":{"digest":{"type":"string","description":"Image digest (sha256)"},"tags":{"description":"Image tags","type":"array","items":{"type":"string"}},"sizeBytes":{"type":"number","description":"Image size in bytes"},"pushedAt":{"type":"string","description":"When the image was pushed","nullable":true},"lastPulledAt":{"type":"string","description":"When the image was last pulled","nullable":true},"scan":{"description":"Vulnerability scan finding counts by severity; null when not scanned","nullable":true,"allOf":[{"$ref":"#/components/schemas/ImageScanCountsDto"}]}},"required":["digest","tags","sizeBytes"]},"EcrImageListResponseDto":{"type":"object","properties":{"items":{"description":"List of images","type":"array","items":{"$ref":"#/components/schemas/EcrImageDto"}},"pagination":{"description":"Pagination metadata","allOf":[{"$ref":"#/components/schemas/PaginationMeta"}]}},"required":["items","pagination"]},"ResourceSyncResponseDto":{"type":"object","properties":{"synced":{"type":"number","description":"Total resources synced"},"created":{"type":"number","description":"Resources created"},"updated":{"type":"number","description":"Resources updated"},"errors":{"description":"Errors encountered during sync","type":"array","items":{"type":"string"}}},"required":["synced","created","updated","errors"]},"ForceDeleteDatabaseRequestDto":{"type":"object","properties":{"confirm":{"type":"string","description":"Confirmation string: \"delete {resource name}\""},"createFinalSnapshot":{"type":"boolean","description":"Create a final RDS snapshot before deletion","default":false}},"required":["confirm"]},"ForceDeleteDatabaseResponseDto":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the deletion was successful"},"resourceId":{"type":"string","description":"ID of the deleted resource"},"snapshotId":{"type":"string","description":"ID of the final snapshot, if one was created","nullable":true}},"required":["success","resourceId","snapshotId"]},"OrgCostProjectLineDto":{"type":"object","properties":{"projectId":{"type":"string","description":"Project ID"},"name":{"type":"string","description":"Project name"},"mtdUsd":{"type":"number","description":"Actual project spend month-to-date, USD; null when the current month has no Cost Explorer data","nullable":true},"computeUsd":{"type":"number","description":"MTD spend not attributed to a tagged resource: Fargate compute plus shared infra (ALB, data transfer), USD"},"resourcesUsd":{"type":"number","description":"MTD spend attributed to tagged resources (databases, storage, cache, queues), USD"},"projectedUsd":{"type":"number","description":"Projected full-month spend (trailing-average continuation of the daily series), USD"},"lastMonthUsd":{"type":"number","description":"Prior full-month actual total, USD; null when unavailable","nullable":true},"deltaPct":{"type":"number","description":"Projected month vs last month, percent; null when either side is missing","nullable":true},"serviceCount":{"type":"number","description":"Number of services in the project"},"basis":{"type":"string","description":"Source of this row. \"indicative\" rows have no Cost Explorer data and report zeros","enum":["indicative","actual"]}},"required":["projectId","name","computeUsd","resourcesUsd","projectedUsd","serviceCount","basis"]},"OrgCostSummaryDto":{"type":"object","properties":{"period":{"type":"string","description":"Current month the rollup covers, \"YYYY-MM\" (UTC)"},"daysElapsed":{"type":"number","description":"Completed UTC days of the current month covered by the actuals"},"daysInMonth":{"type":"number","description":"Days in the current month"},"mtdUsd":{"type":"number","description":"Actual org-wide infrastructure spend month-to-date, USD"},"projectedUsd":{"type":"number","description":"Projected org-wide full-month spend, USD"},"lastMonthUsd":{"type":"number","description":"Prior full-month org-wide actual total, USD; null when no project has last-month data","nullable":true},"budgetMonthlyUsd":{"type":"number","description":"Org monthly infrastructure budget, USD; null when unset","nullable":true},"byProject":{"description":"Per-project rollup rows, largest current spend first","type":"array","items":{"$ref":"#/components/schemas/OrgCostProjectLineDto"}},"basis":{"type":"string","description":"\"actual\" when every project has Cost Explorer data, \"partial\" when only some do, \"indicative\" when none do","enum":["indicative","partial","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["period","daysElapsed","daysInMonth","mtdUsd","projectedUsd","byProject","basis","currency"]},"OrgCostDayDto":{"type":"object","properties":{"date":{"type":"string","description":"UTC day, \"YYYY-MM-DD\""},"usd":{"type":"number","description":"Spend for the day, USD (non-cumulative)"}},"required":["date","usd"]},"OrgCostDailyDto":{"type":"object","properties":{"period":{"type":"string","description":"Current month, \"YYYY-MM\" (UTC)"},"range":{"type":"string","description":"Range the daily series covers: the current month, or the whole year to date","enum":["month","ytd"]},"daily":{"description":"Org-wide actual spend per completed UTC day over the range; months with no data are skipped","type":"array","items":{"$ref":"#/components/schemas/OrgCostDayDto"}},"projection":{"description":"Forecast for the remaining days of the month (trailing-average rate), continuing `daily`","type":"array","items":{"$ref":"#/components/schemas/OrgCostDayDto"}},"lastMonthPeriod":{"type":"string","description":"Prior month, \"YYYY-MM\""},"lastMonthDaily":{"description":"Org-wide actual spend per day of the full prior month (ghost line); empty until refreshed caches include it","type":"array","items":{"$ref":"#/components/schemas/OrgCostDayDto"}},"basis":{"type":"string","description":"\"actual\" when every project has Cost Explorer data, \"partial\" when only some do, \"indicative\" when none do","enum":["indicative","partial","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["period","range","daily","projection","lastMonthPeriod","lastMonthDaily","basis","currency"]},"OrgCostTypeBucketDto":{"type":"object","properties":{"type":{"type":"string","description":"Bucket key: \"compute\" (untagged remainder), a resource kind, or \"other\" (tagged spend matching no resource)","enum":["compute","db","store","cache","queue","image","other"]},"usd":{"type":"number","description":"Month-to-date spend in the bucket, USD"}},"required":["type","usd"]},"OrgCostByTypeDto":{"type":"object","properties":{"period":{"type":"string","description":"Current month the buckets cover, \"YYYY-MM\" (UTC)"},"buckets":{"description":"Non-empty spend buckets; together they sum to totalUsd","type":"array","items":{"$ref":"#/components/schemas/OrgCostTypeBucketDto"}},"totalUsd":{"type":"number","description":"Org-wide month-to-date spend across all buckets, USD"},"basis":{"type":"string","description":"\"actual\" when every project has Cost Explorer data, \"partial\" when only some do, \"indicative\" when none do","enum":["indicative","partial","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["period","buckets","totalUsd","basis","currency"]},"OrgCostMoverDto":{"type":"object","properties":{"name":{"type":"string","description":"Display name, \"<project> · <resource tag>\" (or \"· compute\" for the project remainder)"},"projectId":{"type":"string","description":"Project ID"},"resourceId":{"type":"string","description":"Matched resource ID; null for compute rows and unattributed tags","nullable":true},"type":{"type":"string","description":"Bucket key of the mover","enum":["compute","db","store","cache","queue","image","other"]},"currentUsd":{"type":"number","description":"Projected full-month spend for the current month, USD (0 when the spend disappeared)"},"lastMonthUsd":{"type":"number","description":"Prior full-month spend, USD (0 when the spend is new this month)"},"deltaUsd":{"type":"number","description":"currentUsd − lastMonthUsd, USD; negative when spend went down"}},"required":["name","projectId","type","currentUsd","lastMonthUsd","deltaUsd"]},"OrgCostMoversDto":{"type":"object","properties":{"period":{"type":"string","description":"Current month the comparison covers, \"YYYY-MM\" (UTC)"},"movers":{"description":"Largest month-over-month deltas, ranked by absolute value","type":"array","items":{"$ref":"#/components/schemas/OrgCostMoverDto"}},"basis":{"type":"string","description":"\"actual\" when every project has Cost Explorer data, \"partial\" when only some do, \"indicative\" when none do","enum":["indicative","partial","actual"]},"currency":{"type":"string","description":"Currency code"}},"required":["period","movers","basis","currency"]},"CreateServiceDependencyRequestDto":{"type":"object","properties":{"serviceId":{"type":"string","description":"Service ID that has the dependency"},"targetType":{"type":"string","description":"Type of dependency target","enum":["SERVICE","RESOURCE"]},"targetServiceId":{"type":"string","description":"Target service ID (when targetType is SERVICE)"},"targetResourceId":{"type":"string","description":"Target resource ID (when targetType is RESOURCE)"},"envVarName":{"type":"string","description":"Environment variable name (e.g. DATABASE_URL)"},"envVarTemplate":{"type":"string","description":"Optional env var value template override"}},"required":["serviceId","targetType","envVarName"]},"ServiceDependencyResponseDto":{"type":"object","properties":{"id":{"type":"string","description":"Dependency ID"},"serviceId":{"type":"string","description":"Service ID"},"targetType":{"type":"string","description":"Target type","enum":["SERVICE","RESOURCE"]},"targetServiceId":{"type":"string","description":"Target service ID","nullable":true},"targetResourceId":{"type":"string","description":"Target resource ID","nullable":true},"envVarName":{"type":"string","description":"Environment variable name"},"envVarTemplate":{"type":"string","description":"Env var value template","nullable":true},"targetServiceName":{"type":"string","description":"Target service name","nullable":true},"targetResourceName":{"type":"string","description":"Target resource name","nullable":true},"targetResourceType":{"type":"string","description":"Target resource type","nullable":true},"createdAt":{"type":"string","description":"When created"},"updatedAt":{"type":"string","description":"When last updated"}},"required":["id","serviceId","targetType","envVarName","createdAt","updatedAt"]},"ServiceDependencyListResponseDto":{"type":"object","properties":{"dependencies":{"description":"List of service dependencies","type":"array","items":{"$ref":"#/components/schemas/ServiceDependencyResponseDto"}}},"required":["dependencies"]},"NotificationResponseDto":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["DEPLOY_SUCCESS","DEPLOY_FAILED","TEARDOWN_COMPLETE","TEARDOWN_FAILED","ALERT_TRIGGERED","ALERT_RESOLVED"]},"title":{"type":"string"},"body":{"type":"string"},"metadata":{"type":"object","nullable":true},"read":{"type":"boolean"},"createdAt":{"type":"string"}},"required":["id","type","title","body","read","createdAt"]},"NotificationListResponseDto":{"type":"object","properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/NotificationResponseDto"}},"pagination":{"$ref":"#/components/schemas/PaginationMeta"}},"required":["notifications","pagination"]},"UnreadCountResponseDto":{"type":"object","properties":{"count":{"type":"number"}},"required":["count"]},"IncidentSummaryDto":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string","description":"Human reference, e.g. INC-0042"},"title":{"type":"string"},"severity":{"type":"string","enum":["SEV1","SEV2","SEV3"]},"status":{"type":"string","enum":["TRIGGERED","ACKED","RESOLVED"]},"ruleId":{"type":"object","nullable":true},"ruleName":{"type":"object","nullable":true},"serviceId":{"type":"object","nullable":true},"serviceName":{"type":"object","nullable":true},"environment":{"type":"string"},"notifiedChannels":{"type":"array","items":{"type":"string"}},"startedAt":{"type":"string","description":"ISO timestamp"},"ackedAt":{"type":"object","nullable":true},"ackedByName":{"type":"object","nullable":true},"resolvedAt":{"type":"object","nullable":true},"resolvedBy":{"type":"object","nullable":true},"durationSeconds":{"type":"object","nullable":true,"description":"Seconds; null while ongoing"},"mttaSeconds":{"type":"object","nullable":true},"silencedUntil":{"type":"object","nullable":true,"description":"ISO timestamp until which sends are paused"}},"required":["id","reference","title","severity","status","environment","notifiedChannels","startedAt"]},"IncidentSummaryStatsDto":{"type":"object","properties":{"mttaSeconds":{"type":"object","nullable":true,"description":"Mean time to acknowledge, seconds"},"mttrSeconds":{"type":"object","nullable":true,"description":"Mean time to resolve, seconds"},"openCount":{"type":"number","description":"Open (not resolved) incident count"},"thisMonthCount":{"type":"number","description":"Incidents started this calendar month"}},"required":["openCount","thisMonthCount"]},"PaginationMetaDto":{"type":"object","properties":{"page":{"type":"number"},"pageSize":{"type":"number"},"totalCount":{"type":"number"},"totalPages":{"type":"number"}},"required":["page","pageSize","totalCount","totalPages"]},"IncidentListResponseDto":{"type":"object","properties":{"incidents":{"type":"array","items":{"$ref":"#/components/schemas/IncidentSummaryDto"}},"summary":{"$ref":"#/components/schemas/IncidentSummaryStatsDto"},"pagination":{"$ref":"#/components/schemas/PaginationMetaDto"}},"required":["incidents","summary","pagination"]},"IncidentEventDto":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string","description":"ISO timestamp"},"type":{"type":"string","description":"deploy|metric|alert|notify|escalate|ack|recover|resolve|silence"},"title":{"type":"string"},"body":{"type":"string"},"metadata":{"type":"object","nullable":true}},"required":["id","at","type","title","body"]},"IncidentDeliveryDto":{"type":"object","properties":{"id":{"type":"string"},"channelType":{"type":"string","description":"slack|email|webhook|pagerduty|whatsapp"},"channelName":{"type":"string"},"target":{"type":"string","nullable":true},"status":{"type":"string","description":"delivered|failed|pending|read|acked"},"detail":{"type":"string","nullable":true},"at":{"type":"string","description":"ISO timestamp"}},"required":["id","channelType","channelName","status","at"]},"IncidentDetailDto":{"type":"object","properties":{"id":{"type":"string"},"reference":{"type":"string","description":"Human reference, e.g. INC-0042"},"title":{"type":"string"},"severity":{"type":"string","enum":["SEV1","SEV2","SEV3"]},"status":{"type":"string","enum":["TRIGGERED","ACKED","RESOLVED"]},"ruleId":{"type":"object","nullable":true},"ruleName":{"type":"object","nullable":true},"serviceId":{"type":"object","nullable":true},"serviceName":{"type":"object","nullable":true},"environment":{"type":"string"},"notifiedChannels":{"type":"array","items":{"type":"string"}},"startedAt":{"type":"string","description":"ISO timestamp"},"ackedAt":{"type":"object","nullable":true},"ackedByName":{"type":"object","nullable":true},"resolvedAt":{"type":"object","nullable":true},"resolvedBy":{"type":"object","nullable":true},"durationSeconds":{"type":"object","nullable":true,"description":"Seconds; null while ongoing"},"mttaSeconds":{"type":"object","nullable":true},"silencedUntil":{"type":"object","nullable":true,"description":"ISO timestamp until which sends are paused"},"metricName":{"type":"string","nullable":true},"postmortem":{"type":"string","nullable":true,"description":"Postmortem markdown"},"events":{"type":"array","items":{"$ref":"#/components/schemas/IncidentEventDto"}},"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/IncidentDeliveryDto"}}},"required":["id","reference","title","severity","status","environment","notifiedChannels","startedAt","events","deliveries"]},"IncidentActionResponseDto":{"type":"object","properties":{"incident":{"$ref":"#/components/schemas/IncidentDetailDto"}},"required":["incident"]},"SilenceIncidentDto":{"type":"object","properties":{"minutes":{"type":"number","description":"Minutes to silence sends","default":60}},"required":["minutes"]},"PostmortemDto":{"type":"object","properties":{"text":{"type":"string","description":"Postmortem markdown"}},"required":["text"]},"AlertRuleDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"enabled":{"type":"boolean"},"severity":{"type":"string","enum":["SEV1","SEV2","SEV3"]},"metric":{"type":"string","description":"5xx|p95|p99|cpu|mem|health|deploy|ssl"},"op":{"type":"object","nullable":true},"threshold":{"type":"object","nullable":true},"window":{"type":"object","nullable":true},"event":{"type":"object","nullable":true},"scopeService":{"type":"string"},"scopeEnv":{"type":"string"},"channels":{"type":"array","items":{"type":"string"}},"escalationAfterMin":{"type":"object","nullable":true},"escalationAction":{"type":"object","nullable":true},"lastFiredAt":{"type":"object","nullable":true},"fired30d":{"type":"number"}},"required":["id","name","enabled","severity","metric","scopeService","scopeEnv","channels","fired30d"]},"AlertRuleListResponseDto":{"type":"object","properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/AlertRuleDto"}},"enabledCount":{"type":"number"},"fired30dTotal":{"type":"number"}},"required":["rules","enabledCount","fired30dTotal"]},"CreateAlertRuleDto":{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean","default":true},"severity":{"type":"string","enum":["SEV1","SEV2","SEV3"]},"metric":{"type":"string","enum":["5xx","p95","p99","cpu","mem","health","deploy","ssl"]},"op":{"type":"string","enum":[">","<","="]},"threshold":{"type":"string"},"window":{"type":"string"},"event":{"type":"string"},"scopeService":{"type":"string","default":"any"},"scopeEnv":{"type":"string","default":"any"},"channels":{"description":"Channel keys","type":"array","items":{"type":"string"}},"escalationAfterMin":{"type":"number","nullable":true},"escalationAction":{"type":"string","enum":["whatsapp_here","secondary_oncall","email_admins"]}},"required":["name","severity","metric","channels"]},"UpdateAlertRuleDto":{"type":"object","properties":{"name":{"type":"string"},"enabled":{"type":"boolean"},"severity":{"type":"string","enum":["SEV1","SEV2","SEV3"]},"metric":{"type":"string"},"op":{"type":"string"},"threshold":{"type":"string"},"window":{"type":"string"},"event":{"type":"string"},"scopeService":{"type":"string"},"scopeEnv":{"type":"string"},"channels":{"type":"array","items":{"type":"string"}},"escalationAfterMin":{"type":"object","nullable":true},"escalationAction":{"type":"object","nullable":true}}},"TestAlertResponseDto":{"type":"object","properties":{"delivered":{"type":"number"},"failed":{"type":"number"}},"required":["delivered","failed"]},"ChatMessageContextDto":{"type":"object","properties":{"deploymentId":{"type":"string","description":"Deployment ID for context"},"serviceId":{"type":"string","description":"Service ID for context"},"currentPage":{"type":"string","description":"Current page or route the user is on"}}},"SendChatMessageRequestDto":{"type":"object","properties":{"organizationId":{"type":"string","description":"Organization ID"},"userId":{"type":"string","description":"User ID"},"message":{"type":"string","description":"The message content"},"conversationId":{"type":"string","description":"Conversation ID to continue (omit for new conversation)"},"context":{"description":"Context information for the conversation","allOf":[{"$ref":"#/components/schemas/ChatMessageContextDto"}]}},"required":["organizationId","userId","message"]},"ChatSourceDto":{"type":"object","properties":{"type":{"type":"string","description":"Source type (documentation, schema, error_catalog)"},"path":{"type":"string","description":"Source path or identifier"},"excerpt":{"type":"string","description":"Relevant excerpt from the source"}},"required":["type","path"]},"ChatMessageDto":{"type":"object","properties":{"id":{"type":"string","description":"Message ID"},"role":{"type":"string","description":"Role (USER or ASSISTANT)","enum":["USER","ASSISTANT"]},"content":{"type":"string","description":"Message content"},"sources":{"description":"Sources used (for assistant messages)","type":"array","items":{"$ref":"#/components/schemas/ChatSourceDto"}},"createdAt":{"type":"string","description":"When the message was created"}},"required":["id","role","content","createdAt"]},"SendChatMessageResponseDto":{"type":"object","properties":{"conversationId":{"type":"string","description":"Conversation ID"},"message":{"description":"The assistant response message","allOf":[{"$ref":"#/components/schemas/ChatMessageDto"}]}},"required":["conversationId","message"]},"ConversationListItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Conversation ID"},"title":{"type":"string","description":"Conversation title"},"createdAt":{"type":"string","description":"When the conversation was created"},"updatedAt":{"type":"string","description":"When the conversation was last updated"}},"required":["id","createdAt","updatedAt"]},"ListConversationsResponseDto":{"type":"object","properties":{"conversations":{"description":"List of conversations","type":"array","items":{"$ref":"#/components/schemas/ConversationListItemDto"}}},"required":["conversations"]},"ConversationDetailDto":{"type":"object","properties":{"id":{"type":"string","description":"Conversation ID"},"title":{"type":"string","description":"Conversation title"},"context":{"description":"Context information","allOf":[{"$ref":"#/components/schemas/ChatMessageContextDto"}]},"messages":{"description":"Messages in the conversation","type":"array","items":{"$ref":"#/components/schemas/ChatMessageDto"}},"createdAt":{"type":"string","description":"When the conversation was created"}},"required":["id","messages","createdAt"]},"DeleteConversationResponseDto":{"type":"object","properties":{"deleted":{"type":"boolean","description":"Whether the conversation was deleted"}},"required":["deleted"]}}}}