{
  "repo": "tidbcloud/ecosystem-service",
  "binary": "worker",
  "binary_path": "cmd/worker/main.go",
  "dependencies": {
    "HTTP GET /metrics": {
      "infrastructure": {},
      "services": []
    },
    "Runtime GitHubAppWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Fetch all pending GitHub App tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.GetTasksByStatus(ctx, Pending)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update task message on error",
              "conditions": ["Error occurs"],
              "implementation": "w.gitHubAppTaskDao.UpdateTaskMessage(ctx, task, message)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update branch previous status",
              "conditions": ["Branch status changed"],
              "implementation": "w.gitHubAppTaskDao.UpdateBranchPreviousStatus(ctx, task, status)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Dropped",
              "conditions": ["Task dropped"],
              "implementation": "w.gitHubAppTaskDao.UpdateTasksStatus(ctx, Dropped, taskIDs)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Completed",
              "conditions": ["Task completed successfully"],
              "implementation": "w.gitHubAppTaskDao.UpdateTasksStatus(ctx, Completed, taskIDs)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Timeout",
              "conditions": ["Task timeout"],
              "implementation": "w.gitHubAppTaskDao.UpdateTasksStatus(ctx, Timeout, taskIDs)"
            }
          ]
        }
      },
      "services": [
        {
          "name": "branch",
          "target_interface": "BranchService.GetBranch",
          "operation_type": "grpc_unary",
          "target_repo": "tidbcloud/serverless-service",
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "gRPC GetBranch",
              "trigger": "Get branch status for task",
              "conditions": ["Always"],
              "implementation": "w.gitHubApp.BranchSvc.GetBranch(ctx, clusterID, branchID)"
            }
          ]
        },
        {
          "name": "github-api",
          "target_interface": "PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}",
          "operation_type": "http_patch",
          "target_repo": "github/api",
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "HTTP PATCH",
              "trigger": "Update GitHub check run status",
              "conditions": ["Always"],
              "implementation": "w.gitHubApp.UpdateCheckRun(ctx, installationID, owner, repo, sha, prNumber, conclusion, text, externalID, checkRunID, summary, action)"
            }
          ]
        },
        {
          "name": "github-api",
          "target_interface": "GET /repos/{owner}/{repo}/issues/{issue_number}/comments",
          "operation_type": "http_get",
          "target_repo": "github/api",
          "conditions": ["Branch status changed"],
          "operations": [
            {
              "operation": "HTTP GET",
              "trigger": "List issue comments to find bot comment",
              "conditions": ["Branch status changed"],
              "implementation": "githubClient.Issues.ListComments(ctx, owner, repo, prNumber, nil)"
            }
          ]
        },
        {
          "name": "github-api",
          "target_interface": "POST /repos/{owner}/{repo}/issues/{issue_number}/comments",
          "operation_type": "http_post",
          "target_repo": "github/api",
          "conditions": ["Bot comment not found"],
          "operations": [
            {
              "operation": "HTTP POST",
              "trigger": "Create new issue comment",
              "conditions": ["No existing bot comment"],
              "implementation": "githubClient.Issues.CreateComment(ctx, owner, repo, prNumber, comment)"
            }
          ]
        },
        {
          "name": "github-api",
          "target_interface": "PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}",
          "operation_type": "http_patch",
          "target_repo": "github/api",
          "conditions": ["Bot comment found"],
          "operations": [
            {
              "operation": "HTTP PATCH",
              "trigger": "Update existing issue comment",
              "conditions": ["Existing bot comment found"],
              "implementation": "githubClient.Issues.EditComment(ctx, owner, repo, commentID, comment)"
            }
          ]
        }
      ]
    },
    "Runtime GitHubAppCleanWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "DELETE",
              "trigger": "Delete old completed tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.DeleteTasksByStatusAndAge(ctx, Completed, age)"
            },
            {
              "operation": "DELETE",
              "trigger": "Delete old dropped tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.DeleteTasksByStatusAndAge(ctx, Dropped, age)"
            },
            {
              "operation": "DELETE",
              "trigger": "Delete old timeout tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.DeleteTasksByStatusAndAge(ctx, Timeout, age)"
            }
          ]
        }
      },
      "services": []
    },
    "Runtime GitHubAppMetricWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Count pending tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.CountTasksByStatus(ctx, Pending)"
            },
            {
              "operation": "SELECT",
              "trigger": "Count completed tasks",
              "conditions": ["Always"],
              "implementation": "w.gitHubAppTaskDao.CountTasksByStatus(ctx, Completed)"
            }
          ]
        }
      },
      "services": []
    },
    "Runtime VercelWebhookWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Fetch all pending Vercel webhook tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.GetTasksByStatus(ctx, Pending)"
            },
            {
              "operation": "SELECT",
              "trigger": "Get cluster connection by Vercel project ID",
              "conditions": ["Always"],
              "implementation": "w.clusterConnDAO.GetVercelConnectionByVercelProjectID(ctx, vercelProjectID)"
            },
            {
              "operation": "SELECT",
              "trigger": "Get check by deployment ID",
              "conditions": ["Always"],
              "implementation": "w.checkDAO.GetCheckByDeploymentID(ctx, deploymentID)"
            },
            {
              "operation": "SELECT",
              "trigger": "Get environment identifier for git branch",
              "conditions": ["Branch is ACTIVE"],
              "implementation": "w.branchEnvIDDAO.GetEnvironmentIdentifierByGitBranch(ctx, gitHubRepoID, gitBranchRef, connectionID)"
            },
            {
              "operation": "INSERT",
              "trigger": "Create environment identifier",
              "conditions": ["Branch is ACTIVE", "Envs created successfully"],
              "implementation": "w.branchEnvIDDAO.CreateEnvironmentIdentifier"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Dropped",
              "conditions": ["Task dropped"],
              "implementation": "w.branchDAO.UpdateTasksStatus(ctx, Dropped, taskIDs)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Completed",
              "conditions": ["Task completed successfully"],
              "implementation": "w.branchDAO.UpdateTasksStatus(ctx, Completed, taskIDs)"
            },
            {
              "operation": "UPDATE",
              "trigger": "Update tasks status to Timeout",
              "conditions": ["Task timeout"],
              "implementation": "w.branchDAO.UpdateTasksStatus(ctx, Timeout, taskIDs)"
            },
            {
              "operation": "DELETE",
              "trigger": "Delete environment identifier",
              "conditions": ["Env vars deleted from Vercel manually"],
              "implementation": "w.branchEnvIDDAO.DeleteEnvironmentIdentifier(ctx, envID)"
            }
          ]
        }
      },
      "services": [
        {
          "name": "branch",
          "target_interface": "BranchService.GetBranch",
          "operation_type": "grpc_unary",
          "target_repo": "tidbcloud/serverless-service",
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "gRPC GetBranch",
              "trigger": "Get branch status for task",
              "conditions": ["Always"],
              "implementation": "w.branchSvc.GetBranch(ctx, clusterID, branchID)"
            }
          ]
        },
        {
          "name": "vercel-api",
          "target_interface": "PATCH /v1/deployments/{id}/checks/{checkId}",
          "operation_type": "http_patch",
          "target_repo": "vercel/platform",
          "conditions": ["Timeout or error"],
          "operations": [
            {
              "operation": "HTTP PATCH",
              "trigger": "Update Vercel check with failed conclusion",
              "conditions": ["Timeout or unrecoverable error"],
              "implementation": "w.vercelAPIClient.UpdateCheck(ctx, deploymentID, checkID, conclusion, detailsUrl, name, teamID, accessToken)"
            }
          ]
        },
        {
          "name": "vercel-api",
          "target_interface": "POST /v1/integration/configurations/{id}/projects/{projectId}/env",
          "operation_type": "http_post",
          "target_repo": "vercel/platform",
          "conditions": ["Branch is ACTIVE", "No existing envs"],
          "operations": [
            {
              "operation": "HTTP POST",
              "trigger": "Create Vercel environment variables for branch",
              "conditions": ["Branch status is ACTIVE", "Environment identifier not found"],
              "implementation": "w.branchLogic.CreateVercelEnvs"
            }
          ]
        },
        {
          "name": "vercel-api",
          "target_interface": "PATCH /v1/projects/{projectId}/env/{envId}",
          "operation_type": "http_patch",
          "target_repo": "vercel/platform",
          "conditions": ["Branch is ACTIVE", "Existing envs found"],
          "operations": [
            {
              "operation": "HTTP PATCH",
              "trigger": "Update existing Vercel environment variables",
              "conditions": ["Branch status is ACTIVE", "Environment identifier found"],
              "implementation": "w.branchLogic.UpdateVercelEnvs"
            }
          ]
        },
        {
          "name": "vercel-api",
          "target_interface": "DELETE /v1/projects/{projectId}/env",
          "operation_type": "http_delete",
          "target_repo": "vercel/platform",
          "conditions": ["Env vars deleted manually from Vercel"],
          "operations": [
            {
              "operation": "HTTP DELETE",
              "trigger": "Delete Vercel environment variables",
              "conditions": ["Vercel API returns 404 Not Found"],
              "implementation": "w.vercelAPIClient.DeleteEnvironmentVariables(ctx, projectID, teamID, envsToDelete, accessToken)"
            }
          ]
        }
      ]
    },
    "Runtime VercelWebhookMetricWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "SELECT",
              "trigger": "Count pending tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.CountTasksByStatus(ctx, Pending)"
            },
            {
              "operation": "SELECT",
              "trigger": "Count completed tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.CountTasksByStatus(ctx, Completed)"
            }
          ]
        }
      },
      "services": []
    },
    "Runtime VercelWebhookCleanWorker.Run": {
      "infrastructure": {
        "mysql": {
          "conditions": ["Always"],
          "operations": [
            {
              "operation": "DELETE",
              "trigger": "Delete old completed tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.DeleteTasksByStatusAndAge(ctx, Completed, age)"
            },
            {
              "operation": "DELETE",
              "trigger": "Delete old dropped tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.DeleteTasksByStatusAndAge(ctx, Dropped, age)"
            },
            {
              "operation": "DELETE",
              "trigger": "Delete old timeout tasks",
              "conditions": ["Always"],
              "implementation": "w.branchDAO.DeleteTasksByStatusAndAge(ctx, Timeout, age)"
            }
          ]
        }
      },
      "services": []
    }
  }
}
