From 217011aac772e9b62532c1735d454fb453a7719d Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Tue, 21 Jan 2025 23:23:50 -0800 Subject: [PATCH 1/2] fix: Refactor gh integration --- apps/event-worker/src/job-dispatch/github.ts | 144 +- .../(app)/_components/CreateDeployment.tsx | 5 - .../hooks/CreateHookDialog.tsx | 4 - .../[deploymentSlug]/hooks/EditHookDialog.tsx | 4 - .../runbooks/create/CreateRunbookForm.tsx | 1 - ...nDropdown.tsx => EntityActionDropdown.tsx} | 22 +- ...rgDialog.tsx => GithubAddEntityDialog.tsx} | 32 +- ...edOrgs.tsx => GithubConnectedEntities.tsx} | 59 +- ...ialog.tsx => GithubRemoveEntityDialog.tsx} | 17 +- ...SelectPreconnectedEntityDialogContent.tsx} | 59 +- .../(integration)/github/page.tsx | 4 +- .../src/app/api/github/installation/route.ts | 112 +- apps/webservice/src/app/api/github/octokit.ts | 4 + .../form/job-agent/JobAgentConfig.tsx | 28 +- .../form/job-agent/JobAgentGitHubConfig.tsx | 245 +- packages/api/src/router/github.ts | 374 +- packages/db/drizzle/0061_left_jocasta.sql | 26 + packages/db/drizzle/meta/0061_snapshot.json | 4979 +++++++++++++++++ packages/db/drizzle/meta/_journal.json | 9 +- packages/db/src/schema/github.ts | 26 +- packages/db/src/schema/job.ts | 2 +- packages/validators/src/github/index.ts | 1 + 22 files changed, 5625 insertions(+), 532 deletions(-) rename apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/{OrgActionDropdown.tsx => EntityActionDropdown.tsx} (69%) rename apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/{GithubAddOrgDialog.tsx => GithubAddEntityDialog.tsx} (84%) rename apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/{GithubConnectedOrgs.tsx => GithubConnectedEntities.tsx} (67%) rename apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/{GithubRemoveOrgDialog.tsx => GithubRemoveEntityDialog.tsx} (81%) rename apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/{SelectPreconnectedOrgDialogContent.tsx => SelectPreconnectedEntityDialogContent.tsx} (69%) create mode 100644 packages/db/drizzle/0061_left_jocasta.sql create mode 100644 packages/db/drizzle/meta/0061_snapshot.json diff --git a/apps/event-worker/src/job-dispatch/github.ts b/apps/event-worker/src/job-dispatch/github.ts index eb47fb3f5..f6824d4e5 100644 --- a/apps/event-worker/src/job-dispatch/github.ts +++ b/apps/event-worker/src/job-dispatch/github.ts @@ -4,7 +4,7 @@ import { and, eq, takeFirstOrNull } from "@ctrlplane/db"; import { db } from "@ctrlplane/db/client"; import { environment, - githubOrganization, + githubEntity, job, releaseJobTrigger, runbook, @@ -18,29 +18,15 @@ import { JobStatus } from "@ctrlplane/validators/jobs"; import { getInstallationOctokit } from "../github-utils.js"; -export const dispatchGithubJob = async (je: Job) => { - logger.info(`Dispatching github job ${je.id}...`); - - const config = je.jobAgentConfig; - const parsed = configSchema.safeParse(config); - if (!parsed.success) { - logger.error( - `Invalid job agent config for job ${je.id}: ${parsed.error.message}`, - ); - await db - .update(job) - .set({ - status: JobStatus.InvalidJobAgent, - message: `Invalid job agent config for job ${je.id}: ${parsed.error.message}`, - }) - .where(eq(job.id, je.id)); - return; - } - - const releaseGhOrgResult = await db +const getGithubEntity = async ( + jobId: string, + installationId: number, + owner: string, +) => { + const releaseGhEntityPromise = db .select() - .from(githubOrganization) - .innerJoin(workspace, eq(githubOrganization.workspaceId, workspace.id)) + .from(githubEntity) + .innerJoin(workspace, eq(githubEntity.workspaceId, workspace.id)) .innerJoin(system, eq(system.workspaceId, workspace.id)) .innerJoin(environment, eq(environment.systemId, system.id)) .innerJoin( @@ -49,43 +35,77 @@ export const dispatchGithubJob = async (je: Job) => { ) .where( and( - eq(githubOrganization.installationId, parsed.data.installationId), - eq(githubOrganization.organizationName, parsed.data.owner), - eq(releaseJobTrigger.jobId, je.id), + eq(githubEntity.installationId, installationId), + eq(githubEntity.slug, owner), + eq(releaseJobTrigger.jobId, jobId), ), ) .then(takeFirstOrNull); - const runbookGhOrgResult = await db + const runbookGhEntityPromise = db .select() - .from(githubOrganization) - .innerJoin(workspace, eq(githubOrganization.workspaceId, workspace.id)) + .from(githubEntity) + .innerJoin(workspace, eq(githubEntity.workspaceId, workspace.id)) .innerJoin(system, eq(system.workspaceId, workspace.id)) .innerJoin(runbook, eq(runbook.systemId, system.id)) .innerJoin(runbookJobTrigger, eq(runbookJobTrigger.runbookId, runbook.id)) .where( and( - eq(githubOrganization.installationId, parsed.data.installationId), - eq(githubOrganization.organizationName, parsed.data.owner), - eq(runbookJobTrigger.jobId, je.id), + eq(githubEntity.installationId, installationId), + eq(githubEntity.slug, owner), + eq(runbookJobTrigger.jobId, jobId), ), ) .then(takeFirstOrNull); - const ghOrgResult = releaseGhOrgResult ?? runbookGhOrgResult; - if (ghOrgResult == null) { + const [releaseGhEntityResult, runbookGhEntityResult] = await Promise.all([ + releaseGhEntityPromise, + runbookGhEntityPromise, + ]); + + return ( + releaseGhEntityResult?.github_entity ?? runbookGhEntityResult?.github_entity + ); +}; + +export const dispatchGithubJob = async (je: Job) => { + logger.info(`Dispatching github job ${je.id}...`); + + const config = je.jobAgentConfig; + const parsed = configSchema.safeParse(config); + if (!parsed.success) { + logger.error( + `Invalid job agent config for job ${je.id}: ${parsed.error.message}`, + ); + await db + .update(job) + .set({ + status: JobStatus.InvalidJobAgent, + message: `Invalid job agent config for job ${je.id}: ${parsed.error.message}`, + }) + .where(eq(job.id, je.id)); + return; + } + + const { data: parsedConfig } = parsed; + + const ghEntity = await getGithubEntity( + je.id, + parsedConfig.installationId, + parsedConfig.owner, + ); + if (ghEntity == null) { await db .update(job) .set({ status: JobStatus.InvalidIntegration, - message: `GitHub organization not found for job ${je.id}`, + message: `GitHub entity not found for job ${je.id}`, }) .where(eq(job.id, je.id)); return; } - const ghOrg = ghOrgResult.github_organization; - const octokit = getInstallationOctokit(parsed.data.installationId); + const octokit = getInstallationOctokit(ghEntity.installationId); if (octokit == null) { logger.error(`GitHub bot not configured for job ${je.id}`); await db @@ -100,28 +120,46 @@ export const dispatchGithubJob = async (je: Job) => { const installationToken = (await octokit.auth({ type: "installation", - installationId: parsed.data.installationId, + installationId: parsedConfig.installationId, })) as { token: string }; + const headers = { + "X-GitHub-Api-Version": "2022-11-28", + authorization: `Bearer ${installationToken.token}`, + }; + + const ref = + parsedConfig.ref ?? + (await octokit.rest.repos + .get({ ...parsedConfig, headers }) + .then((r) => r.data.default_branch)); + + if (ref == null) { + logger.error(`Failed to get ref for github action job ${je.id}`); + await db + .update(job) + .set({ + status: JobStatus.InvalidJobAgent, + message: "Failed to get ref for github action job", + }) + .where(eq(job.id, je.id)); + return; + } + logger.info(`Creating workflow dispatch for job ${je.id}...`, { - owner: parsed.data.owner, - repo: parsed.data.repo, - workflow_id: parsed.data.workflowId, - ref: ghOrg.branch, - inputs: { - job_id: je.id, - }, + owner: parsedConfig.owner, + repo: parsedConfig.repo, + workflow_id: parsedConfig.workflowId, + ref, + inputs: { job_id: je.id }, }); await octokit.actions.createWorkflowDispatch({ - owner: parsed.data.owner, - repo: parsed.data.repo, - workflow_id: parsed.data.workflowId, - ref: ghOrg.branch, + owner: parsedConfig.owner, + repo: parsedConfig.repo, + workflow_id: parsedConfig.workflowId, + ref, inputs: { job_id: je.id }, - headers: { - "X-GitHub-Api-Version": "2022-11-28", - authorization: `Bearer ${installationToken.token}`, - }, + headers, }); }; diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/_components/CreateDeployment.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/_components/CreateDeployment.tsx index 64a3645c9..0305de03e 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/_components/CreateDeployment.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/_components/CreateDeployment.tsx @@ -235,11 +235,6 @@ export const CreateDeploymentDialog: React.FC<{ jobAgent={selectedJobAgent} value={value ?? {}} onChange={onChange} - githubFormStyleConfig={{ - className: - "flex flex-col gap-2 items-center w-[450px]", - buttonWidth: "w-[450px]", - }} /> diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/CreateHookDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/CreateHookDialog.tsx index fa5861056..287f383a2 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/CreateHookDialog.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/CreateHookDialog.tsx @@ -206,10 +206,6 @@ export const CreateHookDialog: React.FC = ({ jobAgent={jobAgent} value={value ?? {}} onChange={onChange} - githubFormStyleConfig={{ - className: "flex flex-col gap-2 items-center w-[450px]", - buttonWidth: "w-[450px]", - }} /> diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/EditHookDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/EditHookDialog.tsx index 9425ae31d..b679e37cc 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/EditHookDialog.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/deployments/[deploymentSlug]/hooks/EditHookDialog.tsx @@ -210,10 +210,6 @@ export const EditHookDialog: React.FC = ({ jobAgent={jobAgent} value={value ?? {}} onChange={onChange} - githubFormStyleConfig={{ - className: "flex flex-col gap-2 items-center w-[450px]", - buttonWidth: "w-[450px]", - }} /> diff --git a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/runbooks/create/CreateRunbookForm.tsx b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/runbooks/create/CreateRunbookForm.tsx index e8705690c..d35983940 100644 --- a/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/runbooks/create/CreateRunbookForm.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/(app)/systems/[systemSlug]/runbooks/create/CreateRunbookForm.tsx @@ -188,7 +188,6 @@ export const CreateRunbook: React.FC<{ workspace={workspace} value={value} onChange={onChange} - githubFormStyleConfig={{ buttonWidth: "w-72" }} /> diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/OrgActionDropdown.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx similarity index 69% rename from apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/OrgActionDropdown.tsx rename to apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx index 02bdb2f9d..0af3d236c 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/OrgActionDropdown.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx @@ -11,20 +11,16 @@ import { } from "@ctrlplane/ui/dropdown-menu"; import { DisconnectDropdownActionButton } from "./DisconnectDropdownActionButton"; -import { GithubRemoveOrgDialog } from "./GithubRemoveOrgDialog"; +import { GithubRemoveEntityDialog } from "./GithubRemoveEntityDialog"; -type OrgActionDropdownProps = { - githubConfig: { - url: string; - botName: string; - clientId: string; - }; - org: schema.GithubOrganization; +type EntityActionDropdownProps = { + githubConfig: { url: string; botName: string; clientId: string }; + entity: schema.GithubEntity; }; -export const OrgActionDropdown: React.FC = ({ +export const EntityActionDropdown: React.FC = ({ githubConfig, - org, + entity, }) => { return ( @@ -37,7 +33,7 @@ export const OrgActionDropdown: React.FC = ({ @@ -46,9 +42,9 @@ export const OrgActionDropdown: React.FC = ({ - + - + ); diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddOrgDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddEntityDialog.tsx similarity index 84% rename from apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddOrgDialog.tsx rename to apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddEntityDialog.tsx index 027816f40..8c3437ed9 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddOrgDialog.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubAddEntityDialog.tsx @@ -17,26 +17,26 @@ import { DialogTrigger, } from "@ctrlplane/ui/dialog"; -import type { GithubOrg } from "./SelectPreconnectedOrgDialogContent"; -import { SelectPreconnectedOrgDialogContent } from "./SelectPreconnectedOrgDialogContent"; +import { SelectPreconnectedEntityDialogContent } from "./SelectPreconnectedEntityDialogContent"; -type GithubAddOrgDialogProps = { +type GithubAddEntityDialogProps = { githubUser: GithubUser; children: React.ReactNode; - githubConfig: { - url: string; - botName: string; - clientId: string; - }; - validOrgsToAdd: GithubOrg[]; + githubConfig: { url: string; botName: string; clientId: string }; + validEntitiesToAdd: { + installationId: number; + type: "user" | "organization"; + slug: string; + avatarUrl: string; + }[]; workspaceId: string; }; -export const GithubAddOrgDialog: React.FC = ({ +export const GithubAddEntityDialog: React.FC = ({ githubUser, children, githubConfig, - validOrgsToAdd, + validEntitiesToAdd, workspaceId, }) => { const [dialogStep, setDialogStep] = useState<"choose-org" | "pre-connected">( @@ -52,7 +52,7 @@ export const GithubAddOrgDialog: React.FC = ({ <> Connect a new Organization - {validOrgsToAdd.length === 0 && ( + {validEntitiesToAdd.length === 0 && ( Install the ctrlplane Github app on an organization to connect it to your workspace. @@ -60,7 +60,7 @@ export const GithubAddOrgDialog: React.FC = ({ )} - {validOrgsToAdd.length > 0 && ( + {validEntitiesToAdd.length > 0 && ( Connect an organization @@ -99,7 +99,7 @@ export const GithubAddOrgDialog: React.FC = ({ - {validOrgsToAdd.length > 0 && ( + {validEntitiesToAdd.length > 0 && (
{githubUser != null ? ( - - + ) : ( @@ -95,32 +94,38 @@ export const GithubConnectedOrgs: React.FC = async ({ )} - {githubOrgsInstalled.length > 0 && ( + {githubEntitiesInstalled.length > 0 && ( <>
- {githubOrgsInstalled.map((org) => ( -
+ {githubEntitiesInstalled.map((entity) => ( +
- +

- {org.organizationName} + {entity.slug}

- {org.addedByUser != null && ( + {entity.addedByUser != null && (

- Enabled by {org.addedByUser.githubUsername} on{" "} - {org.createdAt.toLocaleDateString()} + Enabled by {entity.addedByUser.githubUsername} on{" "} + {entity.createdAt.toLocaleDateString()}

)}
- +
))}
diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveOrgDialog.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveEntityDialog.tsx similarity index 81% rename from apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveOrgDialog.tsx rename to apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveEntityDialog.tsx index 53a2e35d7..8ef1c6dfb 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveOrgDialog.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/GithubRemoveEntityDialog.tsx @@ -18,21 +18,20 @@ import { buttonVariants } from "@ctrlplane/ui/button"; import { api } from "~/trpc/react"; -type GithubRemoveOrgDialogProps = { - githubOrganization: schema.GithubOrganization; +type GithubRemoveEntityDialogProps = { + githubEntity: schema.GithubEntity; children: React.ReactNode; }; -export const GithubRemoveOrgDialog: React.FC = ({ - githubOrganization, - children, -}) => { +export const GithubRemoveEntityDialog: React.FC< + GithubRemoveEntityDialogProps +> = ({ githubEntity, children }) => { const router = useRouter(); - const githubOrgDelete = api.github.organizations.delete.useMutation(); + const githubEntityDelete = api.github.entities.delete.useMutation(); - const { id, workspaceId } = githubOrganization; + const { id, workspaceId } = githubEntity; const handleDelete = () => - githubOrgDelete + githubEntityDelete .mutateAsync({ id, workspaceId }) .then(() => router.refresh()); diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedOrgDialogContent.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx similarity index 69% rename from apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedOrgDialogContent.tsx rename to apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx index 43bdee711..415f254b7 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedOrgDialogContent.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx @@ -1,5 +1,4 @@ import type { GithubUser } from "@ctrlplane/db/schema"; -import type { RestEndpointMethodTypes } from "@octokit/rest"; import { useState } from "react"; import { useRouter } from "next/navigation"; @@ -17,52 +16,38 @@ import { Popover, PopoverContent, PopoverTrigger } from "@ctrlplane/ui/popover"; import { api } from "~/trpc/react"; -export type GithubOrg = - RestEndpointMethodTypes["orgs"]["get"]["response"]["data"] & { +type PreconnectedEntityComboboxProps = { + githubEntities: { installationId: number; - }; - -type PreconnectedOrgsComboboxProps = { - githubOrgs: GithubOrg[]; + type: "user" | "organization"; + slug: string; + avatarUrl: string; + }[]; githubUser: GithubUser; workspaceId: string; onNavigateBack: () => void; onSave: () => void; }; -export const SelectPreconnectedOrgDialogContent: React.FC< - PreconnectedOrgsComboboxProps -> = ({ githubOrgs, githubUser, workspaceId, onNavigateBack, onSave }) => { +export const SelectPreconnectedEntityDialogContent: React.FC< + PreconnectedEntityComboboxProps +> = ({ githubEntities, workspaceId, onNavigateBack, onSave }) => { const [open, setOpen] = useState(false); const [value, setValue] = useState(null); const [image, setImage] = useState(null); const router = useRouter(); const utils = api.useUtils(); - const githubOrgCreate = api.github.organizations.create.useMutation(); - const jobAgentCreate = api.job.agent.create.useMutation(); + const githubEntityCreate = api.github.entities.create.useMutation(); const handleSave = async () => { if (value == null) return; - const org = githubOrgs.find((o) => o.login === value); - if (org == null) return; - - await githubOrgCreate.mutateAsync({ - installationId: org.installationId, - workspaceId, - organizationName: org.login, - addedByUserId: githubUser.userId, - avatarUrl: org.avatar_url, - }); + const entity = githubEntities.find((e) => e.slug === value); + if (entity == null) return; - await jobAgentCreate.mutateAsync({ - name: org.login, - type: "github-app", + await githubEntityCreate.mutateAsync({ + ...entity, workspaceId, - config: { - installationId: org.installationId, - owner: org.login, - }, }); onSave(); @@ -102,23 +87,23 @@ export const SelectPreconnectedOrgDialogContent: React.FC< - {githubOrgs.map(({ id, login, avatar_url }) => ( + {githubEntities.map(({ slug, avatarUrl }) => ( { setValue(currentValue); - setImage(avatar_url); + setImage(avatarUrl); setOpen(false); }} className="w-full cursor-pointer" >
- - {login.slice(0, 2)} + + {slug.slice(0, 2)} - {login} + {slug}
))} @@ -136,7 +121,7 @@ export const SelectPreconnectedOrgDialogContent: React.FC< diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/page.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/page.tsx index d5dd85121..d3786e6d5 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/page.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/page.tsx @@ -9,7 +9,7 @@ import { Card } from "@ctrlplane/ui/card"; import { env } from "~/env"; import { api } from "~/trpc/server"; import { DeleteGithubUserButton } from "./DeleteGithubUserButton"; -import { GithubConnectedOrgs } from "./GithubConnectedOrgs"; +import { GithubConnectedEntities } from "./GithubConnectedEntities"; const githubAuthUrl = ( baseUrl: string, @@ -86,7 +86,7 @@ export default async function GitHubIntegrationPage({ {isGithubConfigured && ( - { + const orgData = await client.orgs.get({ + org: String(installationTargetId), + headers: { "X-GitHub-Api-Version": "2022-11-28" }, + }); + + return db + .insert(githubEntity) + .values({ + installationId, + type: "organization", + slug: orgData.data.login, + addedByUserId: userId, + workspaceId, + avatarUrl: orgData.data.avatar_url, + }) + .returning() + .then(takeFirst); +}; + +const createUserEntity = async ( + client: AuthedOctokitClient, + installationId: number, + installationTargetId: number, + workspaceId: string, + userId: string, +) => { + const userData = (await client.request("GET /user/{account_id}", { + account_id: installationTargetId, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + }, + })) as { data: { login: string; avatar_url: string } }; + + return db + .insert(githubEntity) + .values({ + installationId, + type: "user", + slug: userData.data.login, + addedByUserId: userId, + workspaceId, + avatarUrl: userData.data.avatar_url, + }) + .returning() + .then(takeFirst); +}; + export const GET = async (req: NextRequest) => { if (octokit == null) return NextResponse.json( @@ -82,53 +136,43 @@ export const GET = async (req: NextRequest) => { }, }); - if ( - installation.data.target_type !== "Organization" || - installation.data.account == null - ) { + if (installation.data.account == null) return NextResponse.json( - { error: "Invalid installation type" }, + { error: "Installation account not found" }, { status: BAD_REQUEST }, ); - } - const installationOctokit = getOctokitInstallation(installation.data.id); - if (installationOctokit == null) + const authedClient = getOctokitInstallation(installation.data.id); + if (authedClient == null) return NextResponse.json( { error: "Failed to get authenticated Github client" }, { status: INTERNAL_SERVER_ERROR }, ); - const targetId = installation.data.target_id; - const orgData = await installationOctokit.orgs.get({ - org: String(targetId), - headers: { - "X-GitHub-Api-Version": "2022-11-28", - }, - }); - - await api.github.organizations.create({ - workspaceId: activeWorkspace.id, - installationId: installation.data.id, - organizationName: orgData.data.login, - avatarUrl: orgData.data.avatar_url, - addedByUserId: u.id, - }); + const createEntity = + installation.data.target_type === "Organization" + ? createOrganizationEntity + : createUserEntity; + + const entity = await createEntity( + authedClient, + installation.data.id, + installation.data.target_id, + activeWorkspace.id, + u.id, + ); - await api.job.agent.create({ + await db.insert(jobAgent).values({ workspaceId: activeWorkspace.id, + name: entity.slug, type: "github-app", - name: orgData.data.login, config: { - installationId: installation.data.id, - owner: orgData.data.login, + installationId: entity.installationId, + owner: entity.slug, }, }); - const baseUrl = env.BASE_URL; - const workspaceSlug = activeWorkspace.slug; - return NextResponse.redirect( - `${baseUrl}/${workspaceSlug}/settings/workspace/integrations/github`, + `${env.BASE_URL}/${activeWorkspace.slug}/settings/workspace/integrations/github`, ); }; diff --git a/apps/webservice/src/app/api/github/octokit.ts b/apps/webservice/src/app/api/github/octokit.ts index 526901785..bb62b31af 100644 --- a/apps/webservice/src/app/api/github/octokit.ts +++ b/apps/webservice/src/app/api/github/octokit.ts @@ -34,3 +34,7 @@ export const getOctokitInstallation = (installationId: number) => }, }) : null; + +export type AuthedOctokitClient = NonNullable< + ReturnType +>; diff --git a/apps/webservice/src/components/form/job-agent/JobAgentConfig.tsx b/apps/webservice/src/components/form/job-agent/JobAgentConfig.tsx index 6e2fbfcea..81fd1db10 100644 --- a/apps/webservice/src/components/form/job-agent/JobAgentConfig.tsx +++ b/apps/webservice/src/components/form/job-agent/JobAgentConfig.tsx @@ -1,10 +1,11 @@ "use client"; import type { JobAgent } from "@ctrlplane/db/schema"; +import { IconLoader2 } from "@tabler/icons-react"; import { Input } from "@ctrlplane/ui/input"; -import type { JobAgentGithubStyleConfig } from "./JobAgentGitHubConfig"; +import { api } from "~/trpc/react"; import { JobAgentGitHubConfig } from "./JobAgentGitHubConfig"; import { JobAgentKubernetesConfig } from "./JobAgentKubernetesConfig"; @@ -13,7 +14,6 @@ type JobAgentConfigProps = { jobAgent?: JobAgent | null; value: Record; onChange: (v: Record) => void; - githubFormStyleConfig?: JobAgentGithubStyleConfig; }; export const JobAgentConfig: React.FC = ({ @@ -21,21 +21,33 @@ export const JobAgentConfig: React.FC = ({ jobAgent, value, onChange, - githubFormStyleConfig, }) => { + const repos = api.github.entities.repos.list.useQuery( + { + owner: jobAgent?.config.owner, + installationId: jobAgent?.config.installationId, + workspaceId: workspace.id, + }, + { enabled: jobAgent?.type === "github-app" }, + ); + if (jobAgent == null) return ; if (jobAgent.type === "kubernetes-job") return ; - if (jobAgent.type === "github-app") + if (jobAgent.type === "github-app" && repos.isLoading) + return ( +
+ Loading repositories... +
+ ); + if (jobAgent.type === "github-app" && repos.isSuccess) return ( ); - return ; + return ; }; diff --git a/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx b/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx index 1fcd92190..8990efb33 100644 --- a/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx +++ b/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx @@ -1,10 +1,9 @@ "use client"; -import type { JobAgent } from "@ctrlplane/db/schema"; -import { useEffect, useState } from "react"; -import { IconLoader2, IconSelector } from "@tabler/icons-react"; +import type { RouterOutputs } from "@ctrlplane/api"; +import { useState } from "react"; +import { IconSelector } from "@tabler/icons-react"; -import { cn } from "@ctrlplane/ui"; import { Button } from "@ctrlplane/ui/button"; import { Command, @@ -13,165 +12,109 @@ import { CommandItem, CommandList, } from "@ctrlplane/ui/command"; +import { Input } from "@ctrlplane/ui/input"; import { Popover, PopoverContent, PopoverTrigger } from "@ctrlplane/ui/popover"; -import { api } from "~/trpc/react"; - -export type JobAgentGithubStyleConfig = { - className?: string; - buttonWidth?: string; -}; +type Repo = RouterOutputs["github"]["entities"]["repos"]["list"][number]; export const JobAgentGitHubConfig: React.FC<{ value: Record; - jobAgent: JobAgent; - workspaceId: string; onChange: (v: Record) => void; - styleConfig?: JobAgentGithubStyleConfig; -}> = ({ value, jobAgent, workspaceId, onChange, styleConfig }) => { - const repos = api.github.organizations.repos.list.useQuery({ - owner: jobAgent.config.owner, - installationId: jobAgent.config.installationId, - workspaceId, - }); - + repos: Repo[]; +}> = ({ value, onChange, repos }) => { const [repoOpen, setRepoOpen] = useState(false); - const [repo, setRepo] = useState(value.repo ?? null); - - const workflows = api.github.organizations.repos.workflows.list.useQuery( - { - installationId: jobAgent.config.installationId, - repo: repo ?? "", - owner: jobAgent.config.owner, - workspaceId, - }, - { enabled: repo != null }, - ); - const [workflowOpen, setWorkflowOpen] = useState(false); - const [workflow, setWorkflow] = useState( - workflows.data?.find((w) => w.id === value.workflowId)?.name ?? null, - ); - - const handleFormChange = (workflow: string) => { - const workflowId = workflows.data?.find((w) => w.name === workflow)?.id; - if (workflowId == null) return; - onChange({ - installationId: jobAgent.config.installationId, - owner: jobAgent.config.owner, - repo, - workflowId, - }); - }; + const selectedRepo = repos.find((r) => r.name === value.repo); + const workflows = selectedRepo?.workflows ?? []; - useEffect(() => { - if (workflows.data != null && value.workflowId != null) - setWorkflow( - workflows.data.find((w) => w.id === value.workflowId)?.name ?? null, - ); - }, [workflows.data, value.workflowId]); + const selectedWorkflow = workflows.find((w) => w.id === value.workflowId); return ( -
-
- - - - - - - - - - {repos.data?.map((repo) => ( - { - setRepo(currentValue); - setRepoOpen(false); - }} - > - {repo.name} - - ))} - {repos.isLoading && ( - - - Loading repositories... - - )} - - - - - -
-
- - - - - - - - - - {(workflows.data == null || workflows.data.length === 0) && ( - No workflows found - )} - {workflows.data?.map((wf) => ( - { - setWorkflow(currentValue); - setWorkflowOpen(false); - handleFormChange(currentValue); - }} - > - {wf.name} - - ))} - {workflows.isLoading && ( - - - Loading workflows... - - )} - - - - - -
+
+ + + + + + + + + + {repos.map((repo) => ( + { + onChange({ ...value, repo: currentValue }); + setRepoOpen(false); + }} + > + {repo.name} + + ))} + + + + + + + + + + + + + + + + {workflows.map((wf) => ( + { + onChange({ + ...value, + workflowId: Number.parseInt(currentValue), + }); + setWorkflowOpen(false); + }} + > + {wf.name} + + ))} + + + + + + + onChange({ ...value, ref: e.target.value })} + />
); }; diff --git a/packages/api/src/router/github.ts b/packages/api/src/router/github.ts index 5529dbcf4..c1f37f672 100644 --- a/packages/api/src/router/github.ts +++ b/packages/api/src/router/github.ts @@ -8,8 +8,8 @@ import { z } from "zod"; import { and, eq, takeFirst, takeFirstOrNull } from "@ctrlplane/db"; import { - githubOrganization, - githubOrganizationInsert, + githubEntity, + githubEntityInsert, githubUser, jobAgent, } from "@ctrlplane/db/schema"; @@ -43,6 +43,8 @@ const getOctokitInstallation = (installationId: number) => }, }); +type InstallationOctokitClient = ReturnType; + const getOctokit = () => { if (octokit == null) throw new TRPCError({ @@ -82,6 +84,83 @@ const userRouter = createTRPCRouter({ ), }); +type Workflow = + RestEndpointMethodTypes["actions"]["listRepoWorkflows"]["response"]["data"]["workflows"][number]; + +type Repo = + RestEndpointMethodTypes["repos"]["listForOrg"]["response"]["data"][number] & { + workflows: Workflow[]; + }; + +const getWorkflows = async ( + page: number, + fetchedWorkflows: Workflow[], + repo: RestEndpointMethodTypes["repos"]["listForOrg"]["response"]["data"][number], + installationOctokit: InstallationOctokitClient, + installationToken: { token: string }, +) => { + const { data } = await installationOctokit.actions.listRepoWorkflows({ + repo: repo.name, + owner: repo.owner.login, + page, + per_page: 100, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + authorization: `Bearer ${installationToken.token}`, + }, + }); + const workflows = [...data.workflows, ...fetchedWorkflows]; + if (data.workflows.length < 100) return workflows; + return getWorkflows( + page + 1, + workflows, + repo, + installationOctokit, + installationToken, + ); +}; + +const getRepos = async ( + page: number, + fetchedRepos: Repo[], + installationOctokit: InstallationOctokitClient, + installationToken: { token: string }, + owner: string, +) => { + const { data } = await installationOctokit.repos.listForOrg({ + org: owner, + per_page: 100, + page, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + authorization: `Bearer ${installationToken.token}`, + }, + }); + + const reposWithWorkflows = await Promise.all( + data.map(async (repo) => { + const workflows = await getWorkflows( + 1, + [], + repo, + installationOctokit, + installationToken, + ); + return { ...repo, workflows }; + }), + ); + + const repos = [...reposWithWorkflows, ...fetchedRepos]; + if (reposWithWorkflows.length < 100) return repos; + return getRepos( + page + 1, + repos, + installationOctokit, + installationToken, + owner, + ); +}; + const reposRouter = createTRPCRouter({ list: protectedProcedure .meta({ @@ -98,97 +177,38 @@ const reposRouter = createTRPCRouter({ workspaceId: z.string().uuid(), }), ) - .query(({ input }) => - octokit?.apps - .getInstallation({ + .query(async ({ input }) => { + const { data: installation } = + (await octokit?.apps.getInstallation({ installation_id: input.installationId, - }) - .then(async ({ data: installation }) => { - const installationOctokit = getOctokitInstallation(installation.id); - const installationToken = (await installationOctokit.auth({ - type: "installation", - installationId: installation.id, - })) as { token: string }; - - type Repo = - RestEndpointMethodTypes["repos"]["listForOrg"]["response"]["data"][number]; - const repos: Repo[] = []; - - const getRepos = async (page: number) => { - const { data } = await installationOctokit.repos.listForOrg({ - org: input.owner, - per_page: 100, - page, - headers: { - "X-GitHub-Api-Version": "2022-11-28", - authorization: `Bearer ${installationToken.token}`, - }, - }); - repos.push(...data); - if (data.length < 100) return; - return getRepos(page + 1); - }; + })) ?? {}; - await getRepos(1); - return repos; - }), - ), + if (installation == null) + throw new TRPCError({ + code: "NOT_FOUND", + message: "Installation not found", + }); - workflows: createTRPCRouter({ - list: protectedProcedure - .meta({ - authorizationCheck: ({ canUser, input }) => - canUser.perform(Permission.WorkspaceListIntegrations).on({ - type: "workspace", - id: input.workspaceId, - }), - }) - .input( - z.object({ - installationId: z.number(), - owner: z.string(), - repo: z.string(), - workspaceId: z.string().uuid(), - }), - ) - .query(async ({ input }) => { - const installationOctokit = getOctokitInstallation( - input.installationId, - ); + const installationOctokit = getOctokitInstallation(installation.id); + const installationToken = (await installationOctokit.auth({ + type: "installation", + installationId: installation.id, + })) as { token: string }; - const installationToken = (await installationOctokit.auth({ - type: "installation", - installationId: input.installationId, - })) as { token: string }; - - const workflows: RestEndpointMethodTypes["actions"]["listRepoWorkflows"]["response"]["data"]["workflows"] = - []; - - const getWorkflows = async (page: number) => { - const { data } = await installationOctokit.actions.listRepoWorkflows({ - ...input, - page, - per_page: 100, - headers: { - "X-GitHub-Api-Version": "2022-11-28", - authorization: `Bearer ${installationToken.token}`, - }, - }); - workflows.push(...data.workflows); - if (data.workflows.length < 100) return; - return getWorkflows(page + 1); - }; - - await getWorkflows(1); - return workflows; - }), - }), + return getRepos( + 1, + [], + installationOctokit, + installationToken, + input.owner, + ); + }), }); export const githubRouter = createTRPCRouter({ user: userRouter, - organizations: createTRPCRouter({ + entities: createTRPCRouter({ byGithubUserId: protectedProcedure .meta({ authorizationCheck: ({ canUser, input }) => @@ -203,61 +223,89 @@ export const githubRouter = createTRPCRouter({ workspaceId: z.string().uuid(), }), ) - .query(({ input }) => - getOctokit() - .apps.listInstallations({ - headers: { - "X-GitHub-Api-Version": "2022-11-28", - }, - }) - .then(({ data: installations }) => - Promise.all( - installations - .filter((i) => i.target_type === "Organization") - .map(async (i) => { - const installationOctokit = getOctokitInstallation(i.id); - - const installationToken = (await installationOctokit.auth({ - type: "installation", - installationId: i.id, - })) as { token: string }; - - const members: RestEndpointMethodTypes["orgs"]["listMembers"]["response"]["data"][number][] = - []; - - const getMembers = async (page: number) => { - const { data } = await installationOctokit.orgs.listMembers( - { - org: i.account?.login ?? "", - per_page: 100, - page, - headers: { - "X-GitHub-Api-Version": "2022-11-28", - authorization: `Bearer ${installationToken.token}`, - }, - }, - ); - members.push(...data); - if (data.length < 100) return; - return getMembers(page + 1); - }; - - await getMembers(1); - const isUserInGithubOrg = - members.find((m) => m.id === input.githubUserId) != null; - if (!isUserInGithubOrg) return null; - - const orgData = await installationOctokit.orgs.get({ - org: i.account?.login ?? "", - headers: { - "X-GitHub-Api-Version": "2022-11-28", - }, - }); - return _.merge(orgData.data, { installationId: i.id }); - }), - ).then((orgs) => orgs.filter(isPresent)), - ), - ), + .query(async ({ input }) => { + const installations = await getOctokit().apps.listInstallations({ + headers: { "X-GitHub-Api-Version": "2022-11-28" }, + }); + + const orgPromises = installations.data + .filter((i) => i.target_type === "Organization") + .map(async (installation) => { + const installationOctokit = getOctokitInstallation(installation.id); + const installationToken = (await installationOctokit.auth({ + type: "installation", + installationId: installation.id, + })) as { token: string }; + + type Member = + RestEndpointMethodTypes["orgs"]["listMembers"]["response"]["data"][number]; + + const getMembers = async ( + page: number, + fetchedMembers: Member[], + ): Promise => { + const { data } = await installationOctokit.orgs.listMembers({ + org: installation.account?.login ?? "", + per_page: 100, + page, + headers: { + "X-GitHub-Api-Version": "2022-11-28", + authorization: `Bearer ${installationToken.token}`, + }, + }); + const members = [...data, ...fetchedMembers]; + if (data.length < 100) return members; + return getMembers(page + 1, members); + }; + + const members = await getMembers(1, []); + const isUserInGithubOrg = + members.find((m) => m.id === input.githubUserId) != null; + if (!isUserInGithubOrg) return null; + + const orgData = await installationOctokit.orgs.get({ + org: installation.account?.login ?? "", + headers: { + "X-GitHub-Api-Version": "2022-11-28", + }, + }); + return { + installationId: installation.id, + type: "organization" as const, + slug: orgData.data.login, + avatarUrl: orgData.data.avatar_url, + }; + }); + + const orgs = await Promise.all(orgPromises); + + const personalEntityPromise = installations.data + .filter((i) => i.target_type === "User") + .map(async (installation) => { + const installationOctokit = getOctokitInstallation(installation.id); + + const userData = (await installationOctokit.request( + "GET /user/{account_id}", + { + account_id: installation.target_id.toString(), + headers: { "X-GitHub-Api-Version": "2022-11-28" }, + }, + )) as { data: { login: string; avatar_url: string } }; + + return { + installationId: installation.id, + type: "user" as const, + slug: userData.data.login, + avatarUrl: userData.data.avatar_url, + }; + }); + + const personalEntity = await Promise.all(personalEntityPromise).then( + (entities) => entities.at(0), + ); + + return [...orgs, personalEntity].filter(isPresent); + }), list: protectedProcedure .meta({ @@ -271,15 +319,15 @@ export const githubRouter = createTRPCRouter({ .query(({ ctx, input }) => ctx.db .select() - .from(githubOrganization) + .from(githubEntity) .leftJoin( githubUser, - eq(githubOrganization.addedByUserId, githubUser.userId), + eq(githubEntity.addedByUserId, githubUser.userId), ) - .where(eq(githubOrganization.workspaceId, input)) + .where(eq(githubEntity.workspaceId, input)) .then((orgs) => orgs.map((o) => ({ - ...o.github_organization, + ...o.github_entity, addedByUser: o.github_user, })), ), @@ -293,13 +341,27 @@ export const githubRouter = createTRPCRouter({ id: input.workspaceId, }), }) - .input(githubOrganizationInsert) + .input(githubEntityInsert) .mutation(({ ctx, input }) => - ctx.db - .insert(githubOrganization) - .values(input) - .returning() - .then(takeFirst), + ctx.db.transaction(async (db) => { + const entity = await db + .insert(githubEntity) + .values({ ...input, addedByUserId: ctx.session.user.id }) + .returning() + .then(takeFirst); + + await db.insert(jobAgent).values({ + workspaceId: entity.workspaceId, + name: entity.slug, + type: "github-app", + config: { + installationId: entity.installationId, + owner: entity.slug, + }, + }); + + return entity; + }), ), delete: protectedProcedure @@ -318,16 +380,16 @@ export const githubRouter = createTRPCRouter({ ) .mutation(({ ctx, input }) => ctx.db.transaction(async (db) => { - const deletedOrg = await db - .delete(githubOrganization) - .where(eq(githubOrganization.id, input.id)) + const deletedEntity = await db + .delete(githubEntity) + .where(eq(githubEntity.id, input.id)) .returning() .then(takeFirstOrNull); - if (deletedOrg == null) + if (deletedEntity == null) throw new TRPCError({ code: "NOT_FOUND", - message: "Organization not found", + message: "Entity not found", }); await db @@ -335,8 +397,8 @@ export const githubRouter = createTRPCRouter({ .where( and( eq(jobAgent.type, "github-app"), - eq(jobAgent.name, deletedOrg.organizationName), - eq(jobAgent.workspaceId, deletedOrg.workspaceId), + eq(jobAgent.name, deletedEntity.slug), + eq(jobAgent.workspaceId, deletedEntity.workspaceId), ), ); }), diff --git a/packages/db/drizzle/0061_left_jocasta.sql b/packages/db/drizzle/0061_left_jocasta.sql new file mode 100644 index 000000000..b58f7ecbb --- /dev/null +++ b/packages/db/drizzle/0061_left_jocasta.sql @@ -0,0 +1,26 @@ +DO $$ BEGIN + CREATE TYPE "public"."github_entity_type" AS ENUM('organization', 'user'); +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "github_organization" RENAME TO "github_entity";--> statement-breakpoint +ALTER TABLE "github_entity" RENAME COLUMN "organization_name" TO "slug";--> statement-breakpoint +ALTER TABLE "github_entity" DROP CONSTRAINT "github_organization_added_by_user_id_user_id_fk"; +--> statement-breakpoint +ALTER TABLE "github_entity" DROP CONSTRAINT "github_organization_workspace_id_workspace_id_fk"; +--> statement-breakpoint +ALTER TABLE "github_entity" ADD COLUMN "type" "github_entity_type" DEFAULT 'organization' NOT NULL;--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "github_entity" ADD CONSTRAINT "github_entity_added_by_user_id_user_id_fk" FOREIGN KEY ("added_by_user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "github_entity" ADD CONSTRAINT "github_entity_workspace_id_workspace_id_fk" FOREIGN KEY ("workspace_id") REFERENCES "public"."workspace"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "github_entity" DROP COLUMN IF EXISTS "branch"; \ No newline at end of file diff --git a/packages/db/drizzle/meta/0061_snapshot.json b/packages/db/drizzle/meta/0061_snapshot.json new file mode 100644 index 000000000..e9878fbb1 --- /dev/null +++ b/packages/db/drizzle/meta/0061_snapshot.json @@ -0,0 +1,4979 @@ +{ + "id": "5185264c-ad66-4ea6-a8db-165a0651f4b9", + "prevId": "0a18eae1-ff6d-49b4-bead-b5595baadfac", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "providerAccountId": { + "name": "providerAccountId", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "token_type": { + "name": "token_type", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "account_userId_user_id_fk": { + "name": "account_userId_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "account_provider_providerAccountId_pk": { + "name": "account_provider_providerAccountId_pk", + "columns": [ + "provider", + "providerAccountId" + ] + } + }, + "uniqueConstraints": {} + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "sessionToken": { + "name": "sessionToken", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "userId": { + "name": "userId", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "session_userId_user_id_fk": { + "name": "session_userId_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "userId" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "emailVerified": { + "name": "emailVerified", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "varchar(255)", + "primaryKey": false, + "notNull": false + }, + "active_workspace_id": { + "name": "active_workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "null" + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "null" + } + }, + "indexes": {}, + "foreignKeys": { + "user_active_workspace_id_workspace_id_fk": { + "name": "user_active_workspace_id_workspace_id_fk", + "tableFrom": "user", + "tableTo": "workspace", + "columnsFrom": [ + "active_workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.user_api_key": { + "name": "user_api_key", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "varchar(255)", + "primaryKey": false, + "notNull": true + }, + "key_preview": { + "name": "key_preview", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key_hash": { + "name": "key_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key_prefix": { + "name": "key_prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "user_api_key_key_prefix_key_hash_index": { + "name": "user_api_key_key_prefix_key_hash_index", + "columns": [ + { + "expression": "key_prefix", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_api_key_user_id_user_id_fk": { + "name": "user_api_key_user_id_user_id_fk", + "tableFrom": "user_api_key", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.dashboard": { + "name": "dashboard", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "dashboard_workspace_id_workspace_id_fk": { + "name": "dashboard_workspace_id_workspace_id_fk", + "tableFrom": "dashboard", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.dashboard_widget": { + "name": "dashboard_widget", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "dashboard_id": { + "name": "dashboard_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "widget": { + "name": "widget", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "x": { + "name": "x", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "y": { + "name": "y", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "w": { + "name": "w", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "h": { + "name": "h", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "dashboard_widget_dashboard_id_dashboard_id_fk": { + "name": "dashboard_widget_dashboard_id_dashboard_id_fk", + "tableFrom": "dashboard_widget", + "tableTo": "dashboard", + "columnsFrom": [ + "dashboard_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment_variable": { + "name": "deployment_variable", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "default_value_id": { + "name": "default_value_id", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "schema": { + "name": "schema", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "deployment_variable_deployment_id_key_index": { + "name": "deployment_variable_deployment_id_key_index", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_variable_deployment_id_deployment_id_fk": { + "name": "deployment_variable_deployment_id_deployment_id_fk", + "tableFrom": "deployment_variable", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployment_variable_default_value_id_deployment_variable_value_id_fk": { + "name": "deployment_variable_default_value_id_deployment_variable_value_id_fk", + "tableFrom": "deployment_variable", + "tableTo": "deployment_variable_value", + "columnsFrom": [ + "default_value_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment_variable_set": { + "name": "deployment_variable_set", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "variable_set_id": { + "name": "variable_set_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "deployment_variable_set_deployment_id_variable_set_id_index": { + "name": "deployment_variable_set_deployment_id_variable_set_id_index", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "variable_set_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_variable_set_deployment_id_deployment_id_fk": { + "name": "deployment_variable_set_deployment_id_deployment_id_fk", + "tableFrom": "deployment_variable_set", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployment_variable_set_variable_set_id_variable_set_id_fk": { + "name": "deployment_variable_set_variable_set_id_variable_set_id_fk", + "tableFrom": "deployment_variable_set", + "tableTo": "variable_set", + "columnsFrom": [ + "variable_set_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment_variable_value": { + "name": "deployment_variable_value", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "variable_id": { + "name": "variable_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "resource_filter": { + "name": "resource_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "NULL" + } + }, + "indexes": { + "deployment_variable_value_variable_id_value_index": { + "name": "deployment_variable_value_variable_id_value_index", + "columns": [ + { + "expression": "variable_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "value", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_variable_value_variable_id_deployment_variable_id_fk": { + "name": "deployment_variable_value_variable_id_deployment_variable_id_fk", + "tableFrom": "deployment_variable_value", + "tableTo": "deployment_variable", + "columnsFrom": [ + "variable_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "restrict" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment": { + "name": "deployment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "system_id": { + "name": "system_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_agent_id": { + "name": "job_agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_agent_config": { + "name": "job_agent_config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "retry_count": { + "name": "retry_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "timeout": { + "name": "timeout", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "resource_filter": { + "name": "resource_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "NULL" + } + }, + "indexes": { + "deployment_system_id_slug_index": { + "name": "deployment_system_id_slug_index", + "columns": [ + { + "expression": "system_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_system_id_system_id_fk": { + "name": "deployment_system_id_system_id_fk", + "tableFrom": "deployment", + "tableTo": "system", + "columnsFrom": [ + "system_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployment_job_agent_id_job_agent_id_fk": { + "name": "deployment_job_agent_id_job_agent_id_fk", + "tableFrom": "deployment", + "tableTo": "job_agent", + "columnsFrom": [ + "job_agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.deployment_meta_dependency": { + "name": "deployment_meta_dependency", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "depends_on_id": { + "name": "depends_on_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "deployment_meta_dependency_depends_on_id_deployment_id_index": { + "name": "deployment_meta_dependency_depends_on_id_deployment_id_index", + "columns": [ + { + "expression": "depends_on_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "deployment_meta_dependency_deployment_id_deployment_id_fk": { + "name": "deployment_meta_dependency_deployment_id_deployment_id_fk", + "tableFrom": "deployment_meta_dependency", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "deployment_meta_dependency_depends_on_id_deployment_id_fk": { + "name": "deployment_meta_dependency_depends_on_id_deployment_id_fk", + "tableFrom": "deployment_meta_dependency", + "tableTo": "deployment", + "columnsFrom": [ + "depends_on_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment": { + "name": "environment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "system_id": { + "name": "system_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "policy_id": { + "name": "policy_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resource_filter": { + "name": "resource_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "NULL" + } + }, + "indexes": { + "environment_system_id_name_index": { + "name": "environment_system_id_name_index", + "columns": [ + { + "expression": "system_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_system_id_system_id_fk": { + "name": "environment_system_id_system_id_fk", + "tableFrom": "environment", + "tableTo": "system", + "columnsFrom": [ + "system_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_id_environment_policy_id_fk": { + "name": "environment_policy_id_environment_policy_id_fk", + "tableFrom": "environment", + "tableTo": "environment_policy", + "columnsFrom": [ + "policy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_metadata": { + "name": "environment_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "environment_id": { + "name": "environment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "environment_metadata_key_environment_id_index": { + "name": "environment_metadata_key_environment_id_index", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_metadata_environment_id_environment_id_fk": { + "name": "environment_metadata_environment_id_environment_id_fk", + "tableFrom": "environment_metadata", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_policy": { + "name": "environment_policy", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_id": { + "name": "system_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "approval_required": { + "name": "approval_required", + "type": "environment_policy_approval_requirement", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'manual'" + }, + "success_status": { + "name": "success_status", + "type": "environment_policy_deployment_success_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'all'" + }, + "minimum_success": { + "name": "minimum_success", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "concurrency_limit": { + "name": "concurrency_limit", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": "NULL" + }, + "rollout_duration": { + "name": "rollout_duration", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "minimum_release_interval": { + "name": "minimum_release_interval", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "release_sequencing": { + "name": "release_sequencing", + "type": "release_sequencing_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'cancel'" + } + }, + "indexes": {}, + "foreignKeys": { + "environment_policy_system_id_system_id_fk": { + "name": "environment_policy_system_id_system_id_fk", + "tableFrom": "environment_policy", + "tableTo": "system", + "columnsFrom": [ + "system_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_policy_approval": { + "name": "environment_policy_approval", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "policy_id": { + "name": "policy_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "release_id": { + "name": "release_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "approval_status_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "environment_policy_approval_policy_id_release_id_index": { + "name": "environment_policy_approval_policy_id_release_id_index", + "columns": [ + { + "expression": "policy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "release_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_policy_approval_policy_id_environment_policy_id_fk": { + "name": "environment_policy_approval_policy_id_environment_policy_id_fk", + "tableFrom": "environment_policy_approval", + "tableTo": "environment_policy", + "columnsFrom": [ + "policy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_approval_release_id_release_id_fk": { + "name": "environment_policy_approval_release_id_release_id_fk", + "tableFrom": "environment_policy_approval", + "tableTo": "release", + "columnsFrom": [ + "release_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_approval_user_id_user_id_fk": { + "name": "environment_policy_approval_user_id_user_id_fk", + "tableFrom": "environment_policy_approval", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_policy_deployment": { + "name": "environment_policy_deployment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "policy_id": { + "name": "policy_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "environment_policy_deployment_policy_id_environment_id_index": { + "name": "environment_policy_deployment_policy_id_environment_id_index", + "columns": [ + { + "expression": "policy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_policy_deployment_policy_id_environment_policy_id_fk": { + "name": "environment_policy_deployment_policy_id_environment_policy_id_fk", + "tableFrom": "environment_policy_deployment", + "tableTo": "environment_policy", + "columnsFrom": [ + "policy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_deployment_environment_id_environment_id_fk": { + "name": "environment_policy_deployment_environment_id_environment_id_fk", + "tableFrom": "environment_policy_deployment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_policy_release_channel": { + "name": "environment_policy_release_channel", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "policy_id": { + "name": "policy_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "environment_policy_release_channel_policy_id_channel_id_index": { + "name": "environment_policy_release_channel_policy_id_channel_id_index", + "columns": [ + { + "expression": "policy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "environment_policy_release_channel_policy_id_deployment_id_index": { + "name": "environment_policy_release_channel_policy_id_deployment_id_index", + "columns": [ + { + "expression": "policy_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_policy_release_channel_policy_id_environment_policy_id_fk": { + "name": "environment_policy_release_channel_policy_id_environment_policy_id_fk", + "tableFrom": "environment_policy_release_channel", + "tableTo": "environment_policy", + "columnsFrom": [ + "policy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_release_channel_channel_id_release_channel_id_fk": { + "name": "environment_policy_release_channel_channel_id_release_channel_id_fk", + "tableFrom": "environment_policy_release_channel", + "tableTo": "release_channel", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_policy_release_channel_deployment_id_deployment_id_fk": { + "name": "environment_policy_release_channel_deployment_id_deployment_id_fk", + "tableFrom": "environment_policy_release_channel", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_policy_release_window": { + "name": "environment_policy_release_window", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "policy_id": { + "name": "policy_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "timestamp (0) with time zone", + "primaryKey": false, + "notNull": true + }, + "end_time": { + "name": "end_time", + "type": "timestamp (0) with time zone", + "primaryKey": false, + "notNull": true + }, + "recurrence": { + "name": "recurrence", + "type": "recurrence_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "environment_policy_release_window_policy_id_environment_policy_id_fk": { + "name": "environment_policy_release_window_policy_id_environment_policy_id_fk", + "tableFrom": "environment_policy_release_window", + "tableTo": "environment_policy", + "columnsFrom": [ + "policy_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.environment_release_channel": { + "name": "environment_release_channel", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "environment_id": { + "name": "environment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "environment_release_channel_environment_id_channel_id_index": { + "name": "environment_release_channel_environment_id_channel_id_index", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "environment_release_channel_environment_id_deployment_id_index": { + "name": "environment_release_channel_environment_id_deployment_id_index", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_release_channel_environment_id_environment_id_fk": { + "name": "environment_release_channel_environment_id_environment_id_fk", + "tableFrom": "environment_release_channel", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_release_channel_channel_id_release_channel_id_fk": { + "name": "environment_release_channel_channel_id_release_channel_id_fk", + "tableFrom": "environment_release_channel", + "tableTo": "release_channel", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_release_channel_deployment_id_deployment_id_fk": { + "name": "environment_release_channel_deployment_id_deployment_id_fk", + "tableFrom": "environment_release_channel", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.event": { + "name": "event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.hook": { + "name": "hook", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope_type": { + "name": "scope_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope_id": { + "name": "scope_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.runhook": { + "name": "runhook", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "hook_id": { + "name": "hook_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "runbook_id": { + "name": "runbook_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "runhook_hook_id_runbook_id_index": { + "name": "runhook_hook_id_runbook_id_index", + "columns": [ + { + "expression": "hook_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "runbook_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "runhook_hook_id_hook_id_fk": { + "name": "runhook_hook_id_hook_id_fk", + "tableFrom": "runhook", + "tableTo": "hook", + "columnsFrom": [ + "hook_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "runhook_runbook_id_runbook_id_fk": { + "name": "runhook_runbook_id_runbook_id_fk", + "tableFrom": "runhook", + "tableTo": "runbook", + "columnsFrom": [ + "runbook_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.github_entity": { + "name": "github_entity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "installation_id": { + "name": "installation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "github_entity_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'organization'" + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "added_by_user_id": { + "name": "added_by_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "avatar_url": { + "name": "avatar_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "unique_installation_workspace": { + "name": "unique_installation_workspace", + "columns": [ + { + "expression": "installation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "github_entity_added_by_user_id_user_id_fk": { + "name": "github_entity_added_by_user_id_user_id_fk", + "tableFrom": "github_entity", + "tableTo": "user", + "columnsFrom": [ + "added_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "github_entity_workspace_id_workspace_id_fk": { + "name": "github_entity_workspace_id_workspace_id_fk", + "tableFrom": "github_entity", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.github_user": { + "name": "github_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "github_user_id": { + "name": "github_user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "github_username": { + "name": "github_username", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "github_user_user_id_user_id_fk": { + "name": "github_user_user_id_user_id_fk", + "tableFrom": "github_user", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.job_resource_relationship": { + "name": "job_resource_relationship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "resource_identifier": { + "name": "resource_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "job_resource_relationship_job_id_resource_identifier_index": { + "name": "job_resource_relationship_job_id_resource_identifier_index", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "job_resource_relationship_job_id_job_id_fk": { + "name": "job_resource_relationship_job_id_job_id_fk", + "tableFrom": "job_resource_relationship", + "tableTo": "job", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource": { + "name": "resource", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "locked_at": { + "name": "locked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "resource_identifier_workspace_id_index": { + "name": "resource_identifier_workspace_id_index", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_provider_id_resource_provider_id_fk": { + "name": "resource_provider_id_resource_provider_id_fk", + "tableFrom": "resource", + "tableTo": "resource_provider", + "columnsFrom": [ + "provider_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "resource_workspace_id_workspace_id_fk": { + "name": "resource_workspace_id_workspace_id_fk", + "tableFrom": "resource", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_metadata": { + "name": "resource_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "resource_metadata_key_resource_id_index": { + "name": "resource_metadata_key_resource_id_index", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_metadata_resource_id_resource_id_fk": { + "name": "resource_metadata_resource_id_resource_id_fk", + "tableFrom": "resource_metadata", + "tableTo": "resource", + "columnsFrom": [ + "resource_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_relationship": { + "name": "resource_relationship", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "from_identifier": { + "name": "from_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_identifier": { + "name": "to_identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "resource_relationship_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "resource_relationship_to_identifier_from_identifier_index": { + "name": "resource_relationship_to_identifier_from_identifier_index", + "columns": [ + { + "expression": "to_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "from_identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_relationship_workspace_id_workspace_id_fk": { + "name": "resource_relationship_workspace_id_workspace_id_fk", + "tableFrom": "resource_relationship", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_schema": { + "name": "resource_schema", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "json_schema": { + "name": "json_schema", + "type": "json", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "resource_schema_version_kind_workspace_id_index": { + "name": "resource_schema_version_kind_workspace_id_index", + "columns": [ + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_schema_workspace_id_workspace_id_fk": { + "name": "resource_schema_workspace_id_workspace_id_fk", + "tableFrom": "resource_schema", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_variable": { + "name": "resource_variable", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "sensitive": { + "name": "sensitive", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "resource_variable_resource_id_key_index": { + "name": "resource_variable_resource_id_key_index", + "columns": [ + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_variable_resource_id_resource_id_fk": { + "name": "resource_variable_resource_id_resource_id_fk", + "tableFrom": "resource_variable", + "tableTo": "resource", + "columnsFrom": [ + "resource_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_view": { + "name": "resource_view", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "filter": { + "name": "filter", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "resource_view_workspace_id_workspace_id_fk": { + "name": "resource_view_workspace_id_workspace_id_fk", + "tableFrom": "resource_view", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.azure_tenant": { + "name": "azure_tenant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "azure_tenant_tenant_id_index": { + "name": "azure_tenant_tenant_id_index", + "columns": [ + { + "expression": "tenant_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "azure_tenant_workspace_id_workspace_id_fk": { + "name": "azure_tenant_workspace_id_workspace_id_fk", + "tableFrom": "azure_tenant", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_provider": { + "name": "resource_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "resource_provider_workspace_id_name_index": { + "name": "resource_provider_workspace_id_name_index", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "resource_provider_workspace_id_workspace_id_fk": { + "name": "resource_provider_workspace_id_workspace_id_fk", + "tableFrom": "resource_provider", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_provider_aws": { + "name": "resource_provider_aws", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "resource_provider_id": { + "name": "resource_provider_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "aws_role_arns": { + "name": "aws_role_arns", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "import_eks": { + "name": "import_eks", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "import_vpc": { + "name": "import_vpc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "resource_provider_aws_resource_provider_id_resource_provider_id_fk": { + "name": "resource_provider_aws_resource_provider_id_resource_provider_id_fk", + "tableFrom": "resource_provider_aws", + "tableTo": "resource_provider", + "columnsFrom": [ + "resource_provider_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_provider_azure": { + "name": "resource_provider_azure", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "resource_provider_id": { + "name": "resource_provider_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tenant_id": { + "name": "tenant_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "resource_provider_azure_resource_provider_id_resource_provider_id_fk": { + "name": "resource_provider_azure_resource_provider_id_resource_provider_id_fk", + "tableFrom": "resource_provider_azure", + "tableTo": "resource_provider", + "columnsFrom": [ + "resource_provider_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "resource_provider_azure_tenant_id_azure_tenant_id_fk": { + "name": "resource_provider_azure_tenant_id_azure_tenant_id_fk", + "tableFrom": "resource_provider_azure", + "tableTo": "azure_tenant", + "columnsFrom": [ + "tenant_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.resource_provider_google": { + "name": "resource_provider_google", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "resource_provider_id": { + "name": "resource_provider_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_ids": { + "name": "project_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "import_gke": { + "name": "import_gke", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "import_namespaces": { + "name": "import_namespaces", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "import_vcluster": { + "name": "import_vcluster", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "import_vms": { + "name": "import_vms", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "import_vpc": { + "name": "import_vpc", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "resource_provider_google_resource_provider_id_resource_provider_id_fk": { + "name": "resource_provider_google_resource_provider_id_resource_provider_id_fk", + "tableFrom": "resource_provider_google", + "tableTo": "resource_provider", + "columnsFrom": [ + "resource_provider_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.release": { + "name": "release", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "release_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'ready'" + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "release_deployment_id_version_index": { + "name": "release_deployment_id_version_index", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "release_deployment_id_deployment_id_fk": { + "name": "release_deployment_id_deployment_id_fk", + "tableFrom": "release", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.release_channel": { + "name": "release_channel", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false, + "default": "''" + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "release_filter": { + "name": "release_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "NULL" + } + }, + "indexes": { + "release_channel_deployment_id_name_index": { + "name": "release_channel_deployment_id_name_index", + "columns": [ + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "release_channel_deployment_id_deployment_id_fk": { + "name": "release_channel_deployment_id_deployment_id_fk", + "tableFrom": "release_channel", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.release_dependency": { + "name": "release_dependency", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "release_id": { + "name": "release_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "deployment_id": { + "name": "deployment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "release_filter": { + "name": "release_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "NULL" + } + }, + "indexes": { + "release_dependency_release_id_deployment_id_index": { + "name": "release_dependency_release_id_deployment_id_index", + "columns": [ + { + "expression": "release_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deployment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "release_dependency_release_id_release_id_fk": { + "name": "release_dependency_release_id_release_id_fk", + "tableFrom": "release_dependency", + "tableTo": "release", + "columnsFrom": [ + "release_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "release_dependency_deployment_id_deployment_id_fk": { + "name": "release_dependency_deployment_id_deployment_id_fk", + "tableFrom": "release_dependency", + "tableTo": "deployment", + "columnsFrom": [ + "deployment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.release_job_trigger": { + "name": "release_job_trigger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "release_job_trigger_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "caused_by_id": { + "name": "caused_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "release_id": { + "name": "release_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "release_job_trigger_job_id_job_id_fk": { + "name": "release_job_trigger_job_id_job_id_fk", + "tableFrom": "release_job_trigger", + "tableTo": "job", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "release_job_trigger_caused_by_id_user_id_fk": { + "name": "release_job_trigger_caused_by_id_user_id_fk", + "tableFrom": "release_job_trigger", + "tableTo": "user", + "columnsFrom": [ + "caused_by_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "release_job_trigger_release_id_release_id_fk": { + "name": "release_job_trigger_release_id_release_id_fk", + "tableFrom": "release_job_trigger", + "tableTo": "release", + "columnsFrom": [ + "release_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "release_job_trigger_resource_id_resource_id_fk": { + "name": "release_job_trigger_resource_id_resource_id_fk", + "tableFrom": "release_job_trigger", + "tableTo": "resource", + "columnsFrom": [ + "resource_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "release_job_trigger_environment_id_environment_id_fk": { + "name": "release_job_trigger_environment_id_environment_id_fk", + "tableFrom": "release_job_trigger", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "release_job_trigger_job_id_unique": { + "name": "release_job_trigger_job_id_unique", + "nullsNotDistinct": false, + "columns": [ + "job_id" + ] + } + } + }, + "public.release_metadata": { + "name": "release_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "release_id": { + "name": "release_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "release_metadata_key_release_id_index": { + "name": "release_metadata_key_release_id_index", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "release_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "release_metadata_release_id_release_id_fk": { + "name": "release_metadata_release_id_release_id_fk", + "tableFrom": "release_metadata", + "tableTo": "release", + "columnsFrom": [ + "release_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.system": { + "name": "system", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "system_workspace_id_slug_index": { + "name": "system_workspace_id_slug_index", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "system_workspace_id_workspace_id_fk": { + "name": "system_workspace_id_workspace_id_fk", + "tableFrom": "system", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.runbook": { + "name": "runbook", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_id": { + "name": "system_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "job_agent_id": { + "name": "job_agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_agent_config": { + "name": "job_agent_config", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + } + }, + "indexes": {}, + "foreignKeys": { + "runbook_system_id_system_id_fk": { + "name": "runbook_system_id_system_id_fk", + "tableFrom": "runbook", + "tableTo": "system", + "columnsFrom": [ + "system_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "runbook_job_agent_id_job_agent_id_fk": { + "name": "runbook_job_agent_id_job_agent_id_fk", + "tableFrom": "runbook", + "tableTo": "job_agent", + "columnsFrom": [ + "job_agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.runbook_job_trigger": { + "name": "runbook_job_trigger", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "runbook_id": { + "name": "runbook_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "runbook_job_trigger_job_id_job_id_fk": { + "name": "runbook_job_trigger_job_id_job_id_fk", + "tableFrom": "runbook_job_trigger", + "tableTo": "job", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "runbook_job_trigger_runbook_id_runbook_id_fk": { + "name": "runbook_job_trigger_runbook_id_runbook_id_fk", + "tableFrom": "runbook_job_trigger", + "tableTo": "runbook", + "columnsFrom": [ + "runbook_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "runbook_job_trigger_job_id_unique": { + "name": "runbook_job_trigger_job_id_unique", + "nullsNotDistinct": false, + "columns": [ + "job_id" + ] + } + } + }, + "public.team": { + "name": "team", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "team_workspace_id_workspace_id_fk": { + "name": "team_workspace_id_workspace_id_fk", + "tableFrom": "team", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.team_member": { + "name": "team_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "team_id": { + "name": "team_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "team_member_team_id_user_id_index": { + "name": "team_member_team_id_user_id_index", + "columns": [ + { + "expression": "team_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "team_member_team_id_team_id_fk": { + "name": "team_member_team_id_team_id_fk", + "tableFrom": "team_member", + "tableTo": "team", + "columnsFrom": [ + "team_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "team_member_user_id_user_id_fk": { + "name": "team_member_user_id_user_id_fk", + "tableFrom": "team_member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.job": { + "name": "job", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_agent_id": { + "name": "job_agent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "job_agent_config": { + "name": "job_agent_config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "job_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "job_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'policy_passing'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "job_created_at_idx": { + "name": "job_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "job_status_idx": { + "name": "job_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "job_job_agent_id_job_agent_id_fk": { + "name": "job_job_agent_id_job_agent_id_fk", + "tableFrom": "job", + "tableTo": "job_agent", + "columnsFrom": [ + "job_agent_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.job_metadata": { + "name": "job_metadata", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "job_metadata_key_job_id_index": { + "name": "job_metadata_key_job_id_index", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "job_metadata_job_id_job_id_fk": { + "name": "job_metadata_job_id_job_id_fk", + "tableFrom": "job_metadata", + "tableTo": "job", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.job_variable": { + "name": "job_variable", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "job_id": { + "name": "job_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "sensitive": { + "name": "sensitive", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "job_variable_job_id_key_index": { + "name": "job_variable_job_id_key_index", + "columns": [ + { + "expression": "job_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "job_variable_job_id_job_id_fk": { + "name": "job_variable_job_id_job_id_fk", + "tableFrom": "job_variable", + "tableTo": "job", + "columnsFrom": [ + "job_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.workspace": { + "name": "workspace", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "google_service_account_email": { + "name": "google_service_account_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "aws_role_arn": { + "name": "aws_role_arn", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_slug_unique": { + "name": "workspace_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + } + }, + "public.workspace_email_domain_matching": { + "name": "workspace_email_domain_matching", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "verified": { + "name": "verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "verification_code": { + "name": "verification_code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "verification_email": { + "name": "verification_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "workspace_email_domain_matching_workspace_id_domain_index": { + "name": "workspace_email_domain_matching_workspace_id_domain_index", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "domain", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "workspace_email_domain_matching_workspace_id_workspace_id_fk": { + "name": "workspace_email_domain_matching_workspace_id_workspace_id_fk", + "tableFrom": "workspace_email_domain_matching", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_email_domain_matching_role_id_role_id_fk": { + "name": "workspace_email_domain_matching_role_id_role_id_fk", + "tableFrom": "workspace_email_domain_matching", + "tableTo": "role", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.variable_set": { + "name": "variable_set", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "system_id": { + "name": "system_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "variable_set_system_id_system_id_fk": { + "name": "variable_set_system_id_system_id_fk", + "tableFrom": "variable_set", + "tableTo": "system", + "columnsFrom": [ + "system_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.variable_set_environment": { + "name": "variable_set_environment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "variable_set_id": { + "name": "variable_set_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "variable_set_environment_variable_set_id_variable_set_id_fk": { + "name": "variable_set_environment_variable_set_id_variable_set_id_fk", + "tableFrom": "variable_set_environment", + "tableTo": "variable_set", + "columnsFrom": [ + "variable_set_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "variable_set_environment_environment_id_environment_id_fk": { + "name": "variable_set_environment_environment_id_environment_id_fk", + "tableFrom": "variable_set_environment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.variable_set_value": { + "name": "variable_set_value", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "variable_set_id": { + "name": "variable_set_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "variable_set_value_variable_set_id_key_index": { + "name": "variable_set_value_variable_set_id_key_index", + "columns": [ + { + "expression": "variable_set_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "variable_set_value_variable_set_id_variable_set_id_fk": { + "name": "variable_set_value_variable_set_id_variable_set_id_fk", + "tableFrom": "variable_set_value", + "tableTo": "variable_set", + "columnsFrom": [ + "variable_set_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.workspace_invite_token": { + "name": "workspace_invite_token", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "workspace_invite_token_role_id_role_id_fk": { + "name": "workspace_invite_token_role_id_role_id_fk", + "tableFrom": "workspace_invite_token", + "tableTo": "role", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invite_token_workspace_id_workspace_id_fk": { + "name": "workspace_invite_token_workspace_id_workspace_id_fk", + "tableFrom": "workspace_invite_token", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "workspace_invite_token_created_by_user_id_fk": { + "name": "workspace_invite_token_created_by_user_id_fk", + "tableFrom": "workspace_invite_token", + "tableTo": "user", + "columnsFrom": [ + "created_by" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "workspace_invite_token_token_unique": { + "name": "workspace_invite_token_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + } + }, + "public.resource_metadata_group": { + "name": "resource_metadata_group", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "keys": { + "name": "keys", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "include_null_combinations": { + "name": "include_null_combinations", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "resource_metadata_group_workspace_id_workspace_id_fk": { + "name": "resource_metadata_group_workspace_id_workspace_id_fk", + "tableFrom": "resource_metadata_group", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.runbook_variable": { + "name": "runbook_variable", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "runbook_id": { + "name": "runbook_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "schema": { + "name": "schema", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "runbook_variable_runbook_id_key_index": { + "name": "runbook_variable_runbook_id_key_index", + "columns": [ + { + "expression": "runbook_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "runbook_variable_runbook_id_runbook_id_fk": { + "name": "runbook_variable_runbook_id_runbook_id_fk", + "tableFrom": "runbook_variable", + "tableTo": "runbook", + "columnsFrom": [ + "runbook_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.entity_role": { + "name": "entity_role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "entity_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "scope_id": { + "name": "scope_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "scope_type": { + "name": "scope_type", + "type": "scope_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "entity_role_role_id_entity_type_entity_id_scope_id_scope_type_index": { + "name": "entity_role_role_id_entity_type_entity_id_scope_id_scope_type_index", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "scope_type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "entity_role_role_id_role_id_fk": { + "name": "entity_role_role_id_role_id_fk", + "tableFrom": "entity_role", + "tableTo": "role", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.role": { + "name": "role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "role_workspace_id_workspace_id_fk": { + "name": "role_workspace_id_workspace_id_fk", + "tableFrom": "role", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.role_permission": { + "name": "role_permission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "role_id": { + "name": "role_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "permission": { + "name": "permission", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "role_permission_role_id_permission_index": { + "name": "role_permission_role_id_permission_index", + "columns": [ + { + "expression": "role_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "permission", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "role_permission_role_id_role_id_fk": { + "name": "role_permission_role_id_role_id_fk", + "tableFrom": "role_permission", + "tableTo": "role", + "columnsFrom": [ + "role_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "public.job_agent": { + "name": "job_agent", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config": { + "name": "config", + "type": "json", + "primaryKey": false, + "notNull": true, + "default": "'{}'" + } + }, + "indexes": { + "job_agent_workspace_id_name_index": { + "name": "job_agent_workspace_id_name_index", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "job_agent_workspace_id_workspace_id_fk": { + "name": "job_agent_workspace_id_workspace_id_fk", + "tableFrom": "job_agent", + "tableTo": "workspace", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": { + "public.environment_policy_approval_requirement": { + "name": "environment_policy_approval_requirement", + "schema": "public", + "values": [ + "manual", + "automatic" + ] + }, + "public.approval_status_type": { + "name": "approval_status_type", + "schema": "public", + "values": [ + "pending", + "approved", + "rejected" + ] + }, + "public.environment_policy_deployment_success_type": { + "name": "environment_policy_deployment_success_type", + "schema": "public", + "values": [ + "all", + "some", + "optional" + ] + }, + "public.recurrence_type": { + "name": "recurrence_type", + "schema": "public", + "values": [ + "hourly", + "daily", + "weekly", + "monthly" + ] + }, + "public.release_sequencing_type": { + "name": "release_sequencing_type", + "schema": "public", + "values": [ + "wait", + "cancel" + ] + }, + "public.github_entity_type": { + "name": "github_entity_type", + "schema": "public", + "values": [ + "organization", + "user" + ] + }, + "public.resource_relationship_type": { + "name": "resource_relationship_type", + "schema": "public", + "values": [ + "associated_with", + "depends_on" + ] + }, + "public.release_job_trigger_type": { + "name": "release_job_trigger_type", + "schema": "public", + "values": [ + "new_release", + "release_updated", + "new_resource", + "resource_changed", + "api", + "redeploy", + "force_deploy", + "new_environment", + "variable_changed", + "retry" + ] + }, + "public.release_status": { + "name": "release_status", + "schema": "public", + "values": [ + "building", + "ready", + "failed" + ] + }, + "public.job_reason": { + "name": "job_reason", + "schema": "public", + "values": [ + "policy_passing", + "policy_override", + "env_policy_override", + "config_policy_override" + ] + }, + "public.job_status": { + "name": "job_status", + "schema": "public", + "values": [ + "cancelled", + "skipped", + "in_progress", + "action_required", + "pending", + "failure", + "invalid_job_agent", + "invalid_integration", + "external_run_not_found", + "successful" + ] + }, + "public.entity_type": { + "name": "entity_type", + "schema": "public", + "values": [ + "user", + "team" + ] + }, + "public.scope_type": { + "name": "scope_type", + "schema": "public", + "values": [ + "release", + "releaseChannel", + "resource", + "resourceProvider", + "resourceMetadataGroup", + "workspace", + "environment", + "environmentPolicy", + "deploymentVariable", + "variableSet", + "system", + "deployment", + "job", + "jobAgent", + "runbook", + "resourceView" + ] + } + }, + "schemas": {}, + "sequences": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index 6aa028421..a432fd456 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -428,6 +428,13 @@ "when": 1737443067443, "tag": "0060_stale_warlock", "breakpoints": true + }, + { + "idx": 61, + "version": "7", + "when": 1737499140460, + "tag": "0061_left_jocasta", + "breakpoints": true } ] -} +} \ No newline at end of file diff --git a/packages/db/src/schema/github.ts b/packages/db/src/schema/github.ts index 659154096..90e1af23f 100644 --- a/packages/db/src/schema/github.ts +++ b/packages/db/src/schema/github.ts @@ -1,6 +1,7 @@ import type { InferInsertModel, InferSelectModel } from "drizzle-orm"; import { integer, + pgEnum, pgTable, text, timestamp, @@ -23,12 +24,18 @@ export const githubUser = pgTable("github_user", { export type GithubUser = InferSelectModel; -export const githubOrganization = pgTable( - "github_organization", +export const githubEntityType = pgEnum("github_entity_type", [ + "organization", + "user", +]); + +export const githubEntity = pgTable( + "github_entity", { id: uuid("id").primaryKey().defaultRandom(), installationId: integer("installation_id").notNull(), - organizationName: text("organization_name").notNull(), + type: githubEntityType("type").notNull().default("organization"), + slug: text("slug").notNull(), addedByUserId: uuid("added_by_user_id") .notNull() .references(() => user.id, { onDelete: "cascade" }), @@ -39,7 +46,6 @@ export const githubOrganization = pgTable( createdAt: timestamp("created_at", { withTimezone: true }) .notNull() .defaultNow(), - branch: text("branch").notNull().default("main"), }, (t) => ({ unique: uniqueIndex("unique_installation_workspace").on( @@ -49,9 +55,9 @@ export const githubOrganization = pgTable( }), ); -export type GithubOrganization = InferSelectModel; -export type GithubOrganizationInsert = InferInsertModel< - typeof githubOrganization ->; - -export const githubOrganizationInsert = createInsertSchema(githubOrganization); +export type GithubEntity = InferSelectModel; +export type GithubEntityInsert = InferInsertModel; +export const githubEntityInsert = createInsertSchema(githubEntity).omit({ + id: true, + addedByUserId: true, +}); diff --git a/packages/db/src/schema/job.ts b/packages/db/src/schema/job.ts index b40f0d7bc..eadba687a 100644 --- a/packages/db/src/schema/job.ts +++ b/packages/db/src/schema/job.ts @@ -51,7 +51,6 @@ import { jobResourceRelationship, resource } from "./resource.js"; // if adding a new status, update the validators package @ctrlplane/validators/src/jobs/index.ts export const jobStatus = pgEnum("job_status", [ - "successful", "cancelled", "skipped", "in_progress", @@ -61,6 +60,7 @@ export const jobStatus = pgEnum("job_status", [ "invalid_job_agent", "invalid_integration", "external_run_not_found", + "successful", ]); export const jobReason = pgEnum("job_reason", [ diff --git a/packages/validators/src/github/index.ts b/packages/validators/src/github/index.ts index 150931f44..4c1c8f718 100644 --- a/packages/validators/src/github/index.ts +++ b/packages/validators/src/github/index.ts @@ -5,6 +5,7 @@ export const configSchema = z.object({ owner: z.string().min(1), repo: z.string().min(1), workflowId: z.number(), + ref: z.string().min(1).optional().nullable(), }); export enum GithubEvent { From 9fcf3ca46cfe3deb71de14633583f928891c0cd8 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Tue, 21 Jan 2025 23:48:06 -0800 Subject: [PATCH 2/2] cleanup --- apps/event-worker/src/job-dispatch/github.ts | 8 +- .../github/EntityActionDropdown.tsx | 11 +- .../SelectPreconnectedEntityDialogContent.tsx | 4 +- .../form/job-agent/JobAgentGitHubConfig.tsx | 2 +- packages/api/src/router/github.ts | 13 +- packages/db/drizzle/meta/0061_snapshot.json | 761 +++++------------- packages/db/drizzle/meta/_journal.json | 2 +- 7 files changed, 207 insertions(+), 594 deletions(-) diff --git a/apps/event-worker/src/job-dispatch/github.ts b/apps/event-worker/src/job-dispatch/github.ts index f6824d4e5..b1878755f 100644 --- a/apps/event-worker/src/job-dispatch/github.ts +++ b/apps/event-worker/src/job-dispatch/github.ts @@ -132,7 +132,13 @@ export const dispatchGithubJob = async (je: Job) => { parsedConfig.ref ?? (await octokit.rest.repos .get({ ...parsedConfig, headers }) - .then((r) => r.data.default_branch)); + .then((r) => r.data.default_branch) + .catch((e) => { + logger.error(`Failed to get ref for github action job ${je.id}`, { + error: e, + }); + return null; + })); if (ref == null) { logger.error(`Failed to get ref for github action job ${je.id}`); diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx index 0af3d236c..69533e653 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/EntityActionDropdown.tsx @@ -22,6 +22,11 @@ export const EntityActionDropdown: React.FC = ({ githubConfig, entity, }) => { + const { type, slug, installationId } = entity; + const link = + type === "organization" + ? `${githubConfig.url}/organizations/${slug}/settings/installations/${installationId}` + : `${githubConfig.url}/settings/installations/${installationId}`; return ( @@ -32,11 +37,7 @@ export const EntityActionDropdown: React.FC = ({ - + Configure diff --git a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx index 415f254b7..d3733255f 100644 --- a/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx +++ b/apps/webservice/src/app/[workspaceSlug]/settings/workspace/integrations/(integration)/github/SelectPreconnectedEntityDialogContent.tsx @@ -87,9 +87,9 @@ export const SelectPreconnectedEntityDialogContent: React.FC< - {githubEntities.map(({ slug, avatarUrl }) => ( + {githubEntities.map(({ installationId, slug, avatarUrl }) => ( { setValue(currentValue); diff --git a/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx b/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx index 8990efb33..f1b01abb2 100644 --- a/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx +++ b/apps/webservice/src/components/form/job-agent/JobAgentGitHubConfig.tsx @@ -110,7 +110,7 @@ export const JobAgentGitHubConfig: React.FC<{ onChange({ ...value, ref: e.target.value })} diff --git a/packages/api/src/router/github.ts b/packages/api/src/router/github.ts index c1f37f672..b93aaf40e 100644 --- a/packages/api/src/router/github.ts +++ b/packages/api/src/router/github.ts @@ -178,16 +178,9 @@ const reposRouter = createTRPCRouter({ }), ) .query(async ({ input }) => { - const { data: installation } = - (await octokit?.apps.getInstallation({ - installation_id: input.installationId, - })) ?? {}; - - if (installation == null) - throw new TRPCError({ - code: "NOT_FOUND", - message: "Installation not found", - }); + const { data: installation } = await getOctokit().apps.getInstallation({ + installation_id: input.installationId, + }); const installationOctokit = getOctokitInstallation(installation.id); const installationToken = (await installationOctokit.auth({ diff --git a/packages/db/drizzle/meta/0061_snapshot.json b/packages/db/drizzle/meta/0061_snapshot.json index e9878fbb1..0e81cb07c 100644 --- a/packages/db/drizzle/meta/0061_snapshot.json +++ b/packages/db/drizzle/meta/0061_snapshot.json @@ -81,12 +81,8 @@ "name": "account_userId_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["userId"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -94,10 +90,7 @@ "compositePrimaryKeys": { "account_provider_providerAccountId_pk": { "name": "account_provider_providerAccountId_pk", - "columns": [ - "provider", - "providerAccountId" - ] + "columns": ["provider", "providerAccountId"] } }, "uniqueConstraints": {} @@ -131,12 +124,8 @@ "name": "session_userId_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["userId"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -200,12 +189,8 @@ "name": "user_active_workspace_id_workspace_id_fk", "tableFrom": "user", "tableTo": "workspace", - "columnsFrom": [ - "active_workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["active_workspace_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -289,12 +274,8 @@ "name": "user_api_key_user_id_user_id_fk", "tableFrom": "user_api_key", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -351,12 +332,8 @@ "name": "dashboard_workspace_id_workspace_id_fk", "tableFrom": "dashboard", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -425,12 +402,8 @@ "name": "dashboard_widget_dashboard_id_dashboard_id_fk", "tableFrom": "dashboard_widget", "tableTo": "dashboard", - "columnsFrom": [ - "dashboard_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["dashboard_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -510,12 +483,8 @@ "name": "deployment_variable_deployment_id_deployment_id_fk", "tableFrom": "deployment_variable", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -523,12 +492,8 @@ "name": "deployment_variable_default_value_id_deployment_variable_value_id_fk", "tableFrom": "deployment_variable", "tableTo": "deployment_variable_value", - "columnsFrom": [ - "default_value_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["default_value_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -588,12 +553,8 @@ "name": "deployment_variable_set_deployment_id_deployment_id_fk", "tableFrom": "deployment_variable_set", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -601,12 +562,8 @@ "name": "deployment_variable_set_variable_set_id_variable_set_id_fk", "tableFrom": "deployment_variable_set", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -673,12 +630,8 @@ "name": "deployment_variable_value_variable_id_deployment_variable_id_fk", "tableFrom": "deployment_variable_value", "tableTo": "deployment_variable", - "columnsFrom": [ - "variable_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "restrict" } @@ -784,12 +737,8 @@ "name": "deployment_system_id_system_id_fk", "tableFrom": "deployment", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -797,12 +746,8 @@ "name": "deployment_job_agent_id_job_agent_id_fk", "tableFrom": "deployment", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -861,12 +806,8 @@ "name": "deployment_meta_dependency_deployment_id_deployment_id_fk", "tableFrom": "deployment_meta_dependency", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -874,12 +815,8 @@ "name": "deployment_meta_dependency_depends_on_id_deployment_id_fk", "tableFrom": "deployment_meta_dependency", "tableTo": "deployment", - "columnsFrom": [ - "depends_on_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["depends_on_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -973,12 +910,8 @@ "name": "environment_system_id_system_id_fk", "tableFrom": "environment", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -986,12 +919,8 @@ "name": "environment_policy_id_environment_policy_id_fk", "tableFrom": "environment", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1057,12 +986,8 @@ "name": "environment_metadata_environment_id_environment_id_fk", "tableFrom": "environment_metadata", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1158,12 +1083,8 @@ "name": "environment_policy_system_id_system_id_fk", "tableFrom": "environment_policy", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1237,12 +1158,8 @@ "name": "environment_policy_approval_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1250,12 +1167,8 @@ "name": "environment_policy_approval_release_id_release_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1263,12 +1176,8 @@ "name": "environment_policy_approval_user_id_user_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1328,12 +1237,8 @@ "name": "environment_policy_deployment_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_deployment", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1341,12 +1246,8 @@ "name": "environment_policy_deployment_environment_id_environment_id_fk", "tableFrom": "environment_policy_deployment", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1433,12 +1334,8 @@ "name": "environment_policy_release_channel_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_release_channel", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1446,12 +1343,8 @@ "name": "environment_policy_release_channel_channel_id_release_channel_id_fk", "tableFrom": "environment_policy_release_channel", "tableTo": "release_channel", - "columnsFrom": [ - "channel_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["channel_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1459,12 +1352,8 @@ "name": "environment_policy_release_channel_deployment_id_deployment_id_fk", "tableFrom": "environment_policy_release_channel", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1515,12 +1404,8 @@ "name": "environment_policy_release_window_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_release_window", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1607,12 +1492,8 @@ "name": "environment_release_channel_environment_id_environment_id_fk", "tableFrom": "environment_release_channel", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1620,12 +1501,8 @@ "name": "environment_release_channel_channel_id_release_channel_id_fk", "tableFrom": "environment_release_channel", "tableTo": "release_channel", - "columnsFrom": [ - "channel_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["channel_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1633,12 +1510,8 @@ "name": "environment_release_channel_deployment_id_deployment_id_fk", "tableFrom": "environment_release_channel", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1775,12 +1648,8 @@ "name": "runhook_hook_id_hook_id_fk", "tableFrom": "runhook", "tableTo": "hook", - "columnsFrom": [ - "hook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["hook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1788,12 +1657,8 @@ "name": "runhook_runbook_id_runbook_id_fk", "tableFrom": "runhook", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1886,12 +1751,8 @@ "name": "github_entity_added_by_user_id_user_id_fk", "tableFrom": "github_entity", "tableTo": "user", - "columnsFrom": [ - "added_by_user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["added_by_user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1899,12 +1760,8 @@ "name": "github_entity_workspace_id_workspace_id_fk", "tableFrom": "github_entity", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1948,12 +1805,8 @@ "name": "github_user_user_id_user_id_fk", "tableFrom": "github_user", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2013,12 +1866,8 @@ "name": "job_resource_relationship_job_id_job_id_fk", "tableFrom": "job_resource_relationship", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2134,12 +1983,8 @@ "name": "resource_provider_id_resource_provider_id_fk", "tableFrom": "resource", "tableTo": "resource_provider", - "columnsFrom": [ - "provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["provider_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2147,12 +1992,8 @@ "name": "resource_workspace_id_workspace_id_fk", "tableFrom": "resource", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2218,12 +2059,8 @@ "name": "resource_metadata_resource_id_resource_id_fk", "tableFrom": "resource_metadata", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2296,12 +2133,8 @@ "name": "resource_relationship_workspace_id_workspace_id_fk", "tableFrom": "resource_relationship", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2379,12 +2212,8 @@ "name": "resource_schema_workspace_id_workspace_id_fk", "tableFrom": "resource_schema", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2457,12 +2286,8 @@ "name": "resource_variable_resource_id_resource_id_fk", "tableFrom": "resource_variable", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2513,12 +2338,8 @@ "name": "resource_view_workspace_id_workspace_id_fk", "tableFrom": "resource_view", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2572,12 +2393,8 @@ "name": "azure_tenant_workspace_id_workspace_id_fk", "tableFrom": "azure_tenant", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2644,12 +2461,8 @@ "name": "resource_provider_workspace_id_workspace_id_fk", "tableFrom": "resource_provider", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2701,12 +2514,8 @@ "name": "resource_provider_aws_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_aws", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2750,12 +2559,8 @@ "name": "resource_provider_azure_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_azure", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -2763,12 +2568,8 @@ "name": "resource_provider_azure_tenant_id_azure_tenant_id_fk", "tableFrom": "resource_provider_azure", "tableTo": "azure_tenant", - "columnsFrom": [ - "tenant_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2841,12 +2642,8 @@ "name": "resource_provider_google_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_google", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2940,12 +2737,8 @@ "name": "release_deployment_id_deployment_id_fk", "tableFrom": "release", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3019,12 +2812,8 @@ "name": "release_channel_deployment_id_deployment_id_fk", "tableFrom": "release_channel", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3091,12 +2880,8 @@ "name": "release_dependency_release_id_release_id_fk", "tableFrom": "release_dependency", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3104,12 +2889,8 @@ "name": "release_dependency_deployment_id_deployment_id_fk", "tableFrom": "release_dependency", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3179,12 +2960,8 @@ "name": "release_job_trigger_job_id_job_id_fk", "tableFrom": "release_job_trigger", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -3192,12 +2969,8 @@ "name": "release_job_trigger_caused_by_id_user_id_fk", "tableFrom": "release_job_trigger", "tableTo": "user", - "columnsFrom": [ - "caused_by_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["caused_by_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -3205,12 +2978,8 @@ "name": "release_job_trigger_release_id_release_id_fk", "tableFrom": "release_job_trigger", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3218,12 +2987,8 @@ "name": "release_job_trigger_resource_id_resource_id_fk", "tableFrom": "release_job_trigger", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3231,12 +2996,8 @@ "name": "release_job_trigger_environment_id_environment_id_fk", "tableFrom": "release_job_trigger", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3246,9 +3007,7 @@ "release_job_trigger_job_id_unique": { "name": "release_job_trigger_job_id_unique", "nullsNotDistinct": false, - "columns": [ - "job_id" - ] + "columns": ["job_id"] } } }, @@ -3310,12 +3069,8 @@ "name": "release_metadata_release_id_release_id_fk", "tableFrom": "release_metadata", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3388,12 +3143,8 @@ "name": "system_workspace_id_workspace_id_fk", "tableFrom": "system", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3450,12 +3201,8 @@ "name": "runbook_system_id_system_id_fk", "tableFrom": "runbook", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3463,12 +3210,8 @@ "name": "runbook_job_agent_id_job_agent_id_fk", "tableFrom": "runbook", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -3513,12 +3256,8 @@ "name": "runbook_job_trigger_job_id_job_id_fk", "tableFrom": "runbook_job_trigger", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3526,12 +3265,8 @@ "name": "runbook_job_trigger_runbook_id_runbook_id_fk", "tableFrom": "runbook_job_trigger", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3541,9 +3276,7 @@ "runbook_job_trigger_job_id_unique": { "name": "runbook_job_trigger_job_id_unique", "nullsNotDistinct": false, - "columns": [ - "job_id" - ] + "columns": ["job_id"] } } }, @@ -3577,12 +3310,8 @@ "name": "team_workspace_id_workspace_id_fk", "tableFrom": "team", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3642,12 +3371,8 @@ "name": "team_member_team_id_team_id_fk", "tableFrom": "team_member", "tableTo": "team", - "columnsFrom": [ - "team_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["team_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3655,12 +3380,8 @@ "name": "team_member_user_id_user_id_fk", "tableFrom": "team_member", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3784,12 +3505,8 @@ "name": "job_job_agent_id_job_agent_id_fk", "tableFrom": "job", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -3855,12 +3572,8 @@ "name": "job_metadata_job_id_job_id_fk", "tableFrom": "job_metadata", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3933,12 +3646,8 @@ "name": "job_variable_job_id_job_id_fk", "tableFrom": "job_variable", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -3989,9 +3698,7 @@ "workspace_slug_unique": { "name": "workspace_slug_unique", "nullsNotDistinct": false, - "columns": [ - "slug" - ] + "columns": ["slug"] } } }, @@ -4079,12 +3786,8 @@ "name": "workspace_email_domain_matching_workspace_id_workspace_id_fk", "tableFrom": "workspace_email_domain_matching", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4092,12 +3795,8 @@ "name": "workspace_email_domain_matching_role_id_role_id_fk", "tableFrom": "workspace_email_domain_matching", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4141,12 +3840,8 @@ "name": "variable_set_system_id_system_id_fk", "tableFrom": "variable_set", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4184,12 +3879,8 @@ "name": "variable_set_environment_variable_set_id_variable_set_id_fk", "tableFrom": "variable_set_environment", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4197,12 +3888,8 @@ "name": "variable_set_environment_environment_id_environment_id_fk", "tableFrom": "variable_set_environment", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4268,12 +3955,8 @@ "name": "variable_set_value_variable_set_id_variable_set_id_fk", "tableFrom": "variable_set_value", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4330,12 +4013,8 @@ "name": "workspace_invite_token_role_id_role_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4343,12 +4022,8 @@ "name": "workspace_invite_token_workspace_id_workspace_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4356,12 +4031,8 @@ "name": "workspace_invite_token_created_by_user_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "user", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["created_by"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4371,9 +4042,7 @@ "workspace_invite_token_token_unique": { "name": "workspace_invite_token_token_unique", "nullsNotDistinct": false, - "columns": [ - "token" - ] + "columns": ["token"] } } }, @@ -4426,12 +4095,8 @@ "name": "resource_metadata_group_workspace_id_workspace_id_fk", "tableFrom": "resource_metadata_group", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4517,12 +4182,8 @@ "name": "runbook_variable_runbook_id_runbook_id_fk", "tableFrom": "runbook_variable", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4620,12 +4281,8 @@ "name": "entity_role_role_id_role_id_fk", "tableFrom": "entity_role", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4669,12 +4326,8 @@ "name": "role_workspace_id_workspace_id_fk", "tableFrom": "role", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4734,12 +4387,8 @@ "name": "role_permission_role_id_role_id_fk", "tableFrom": "role_permission", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4812,12 +4461,8 @@ "name": "job_agent_workspace_id_workspace_id_fk", "tableFrom": "job_agent", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -4830,62 +4475,37 @@ "public.environment_policy_approval_requirement": { "name": "environment_policy_approval_requirement", "schema": "public", - "values": [ - "manual", - "automatic" - ] + "values": ["manual", "automatic"] }, "public.approval_status_type": { "name": "approval_status_type", "schema": "public", - "values": [ - "pending", - "approved", - "rejected" - ] + "values": ["pending", "approved", "rejected"] }, "public.environment_policy_deployment_success_type": { "name": "environment_policy_deployment_success_type", "schema": "public", - "values": [ - "all", - "some", - "optional" - ] + "values": ["all", "some", "optional"] }, "public.recurrence_type": { "name": "recurrence_type", "schema": "public", - "values": [ - "hourly", - "daily", - "weekly", - "monthly" - ] + "values": ["hourly", "daily", "weekly", "monthly"] }, "public.release_sequencing_type": { "name": "release_sequencing_type", "schema": "public", - "values": [ - "wait", - "cancel" - ] + "values": ["wait", "cancel"] }, "public.github_entity_type": { "name": "github_entity_type", "schema": "public", - "values": [ - "organization", - "user" - ] + "values": ["organization", "user"] }, "public.resource_relationship_type": { "name": "resource_relationship_type", "schema": "public", - "values": [ - "associated_with", - "depends_on" - ] + "values": ["associated_with", "depends_on"] }, "public.release_job_trigger_type": { "name": "release_job_trigger_type", @@ -4906,11 +4526,7 @@ "public.release_status": { "name": "release_status", "schema": "public", - "values": [ - "building", - "ready", - "failed" - ] + "values": ["building", "ready", "failed"] }, "public.job_reason": { "name": "job_reason", @@ -4941,10 +4557,7 @@ "public.entity_type": { "name": "entity_type", "schema": "public", - "values": [ - "user", - "team" - ] + "values": ["user", "team"] }, "public.scope_type": { "name": "scope_type", @@ -4976,4 +4589,4 @@ "schemas": {}, "tables": {} } -} \ No newline at end of file +} diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index a432fd456..0fce29ea3 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -437,4 +437,4 @@ "breakpoints": true } ] -} \ No newline at end of file +}