@@ -82,25 +80,16 @@ export const RunbookVariableEditor = forwardRef<
{config?.type === "string" && (
-
+
)}
{config?.type === "boolean" && (
-
+
)}
{config?.type === "choice" && (
-
+
+ )}
+ {config?.type === "number" && (
+
)}
{JSON.stringify(config, null, 2)}
diff --git a/packages/api/src/router/deployment-variable.ts b/packages/api/src/router/deployment-variable.ts
index 3d4325cb0..23d92830a 100644
--- a/packages/api/src/router/deployment-variable.ts
+++ b/packages/api/src/router/deployment-variable.ts
@@ -1,20 +1,20 @@
+import type { DeploymentVariableValue } from "@ctrlplane/db/schema";
import _ from "lodash";
import { isPresent } from "ts-is-present";
import { z } from "zod";
-import { and, eq, takeFirst, takeFirstOrNull } from "@ctrlplane/db";
+import { and, asc, eq, sql, takeFirst, takeFirstOrNull } from "@ctrlplane/db";
import {
createDeploymentVariable,
createDeploymentVariableValue,
deployment,
deploymentVariable,
deploymentVariableValue,
- deploymentVariableValueTarget,
- deploymentVariableValueTargetFilter,
system,
target,
targetMatchesMetadata,
updateDeploymentVariable,
+ updateDeploymentVariableValue,
} from "@ctrlplane/db/schema";
import { Permission } from "@ctrlplane/validators/auth";
@@ -30,13 +30,66 @@ const valueRouter = createTRPCRouter({
.where(eq(deploymentVariable.id, input.variableId))
.then(takeFirst);
return canUser
- .perform(Permission.DeploymentUpdate)
+ .perform(Permission.DeploymentVariableCreate)
.on({ type: "deployment", id: variable.deploymentId });
},
})
.input(createDeploymentVariableValue)
.mutation(async ({ ctx, input }) =>
- ctx.db.insert(deploymentVariableValue).values(input).returning(),
+ ctx.db.transaction((tx) =>
+ tx
+ .insert(deploymentVariableValue)
+ .values(input)
+ .returning()
+ .then(takeFirst)
+ .then(async (value) => {
+ if (input.default)
+ await tx
+ .update(deploymentVariable)
+ .set({ defaultValueId: value.id })
+ .where(eq(deploymentVariable.id, input.variableId));
+
+ return value;
+ }),
+ ),
+ ),
+
+ update: protectedProcedure
+ .meta({
+ authorizationCheck: async ({ canUser, ctx, input }) => {
+ const value = await ctx.db
+ .select()
+ .from(deploymentVariableValue)
+ .where(eq(deploymentVariableValue.id, input.id))
+ .then(takeFirstOrNull);
+
+ if (value == null) return false;
+
+ return canUser.perform(Permission.DeploymentVariableUpdate).on({
+ type: "deploymentVariable",
+ id: value.variableId,
+ });
+ },
+ })
+ .input(
+ z.object({ id: z.string().uuid(), data: updateDeploymentVariableValue }),
+ )
+ .mutation(async ({ ctx, input }) =>
+ ctx.db
+ .update(deploymentVariableValue)
+ .set(input.data)
+ .where(eq(deploymentVariableValue.id, input.id))
+ .returning()
+ .then(takeFirst)
+ .then(async (value) => {
+ if (input.data.default)
+ await ctx.db
+ .update(deploymentVariable)
+ .set({ defaultValueId: value.id })
+ .where(eq(deploymentVariable.id, value.variableId));
+
+ return value;
+ }),
),
delete: protectedProcedure
@@ -51,7 +104,7 @@ const valueRouter = createTRPCRouter({
)
.where(eq(deploymentVariableValue.id, input))
.then(takeFirst);
- return canUser.perform(Permission.DeploymentUpdate).on({
+ return canUser.perform(Permission.DeploymentVariableUpdate).on({
type: "deployment",
id: value.deployment_variable.deploymentId,
});
@@ -69,80 +122,6 @@ const valueRouter = createTRPCRouter({
.returning()
.then(takeFirstOrNull);
}),
-
- setTarget: protectedProcedure
- .meta({
- authorizationCheck: ({ canUser, input }) =>
- canUser
- .perform(Permission.DeploymentUpdate)
- .on({ type: "target", id: input.targetId }),
- })
- .input(
- z.object({
- targetId: z.string().uuid(),
- variableId: z.string().uuid(),
- value: z.any(),
- }),
- )
- .mutation(async ({ ctx, input }) => {
- if (input.value == null) {
- const vv = await ctx.db
- .select()
- .from(deploymentVariableValue)
- .innerJoin(
- deploymentVariableValueTarget,
- eq(
- deploymentVariableValue.id,
- deploymentVariableValueTarget.variableValueId,
- ),
- )
- .where(
- and(
- eq(deploymentVariableValue.variableId, input.variableId),
- eq(deploymentVariableValueTarget.targetId, input.targetId),
- ),
- )
- .then(takeFirstOrNull);
-
- if (vv == null)
- // value is already not set.
- return;
-
- return ctx.db
- .delete(deploymentVariableValueTarget)
- .where(
- and(
- eq(
- deploymentVariableValueTarget.variableValueId,
- vv.deployment_variable_value.id,
- ),
- eq(deploymentVariableValueTarget.targetId, input.targetId),
- ),
- )
- .returning();
- }
-
- const value = await ctx.db
- .insert(deploymentVariableValue)
- .values({ variableId: input.variableId, value: input.value })
- .onConflictDoUpdate({
- target: [
- deploymentVariableValue.variableId,
- deploymentVariableValue.value,
- ],
- set: { value: input.value },
- })
- .returning()
- .then(takeFirst);
-
- return ctx.db
- .insert(deploymentVariableValueTarget)
- .values({
- variableValueId: value.id,
- targetId: input.targetId,
- })
- .returning();
- }),
});
export const deploymentVariableRouter = createTRPCRouter({
@@ -157,17 +136,6 @@ export const deploymentVariableRouter = createTRPCRouter({
})
.input(z.string().uuid())
.query(async ({ ctx, input }) => {
- const possibleValuesSubquery = ctx.db
- .select({
- id: deploymentVariableValue.id,
- value: deploymentVariableValue.value,
- variableId: deploymentVariableValue.variableId,
- })
- .from(deploymentVariableValue)
- .as("possible_values_subquery");
-
- // get all deployment variable value target filters matching the target
- // then get all the deployment variable values + the deployment variable itself
const deploymentVariables = await ctx.db
.select()
.from(target)
@@ -178,35 +146,22 @@ export const deploymentVariableRouter = createTRPCRouter({
deploymentVariable,
eq(deploymentVariable.deploymentId, deployment.id),
)
- .innerJoin(
- possibleValuesSubquery,
- eq(possibleValuesSubquery.variableId, deploymentVariable.id),
- )
.innerJoin(
deploymentVariableValue,
eq(deploymentVariableValue.variableId, deploymentVariable.id),
)
- .innerJoin(
- deploymentVariableValueTargetFilter,
- eq(
- deploymentVariableValueTargetFilter.variableValueId,
- deploymentVariableValue.id,
- ),
- )
.then((rows) =>
_.chain(rows)
.groupBy((r) => r.deployment_variable.id)
.map((r) => ({
...r[0]!.deployment_variable,
- targetFilter:
- r[0]!.deployment_variable_value_target_filter.targetFilter,
+ targetFilter: r[0]!.deployment_variable_value.targetFilter,
value: r[0]!.deployment_variable_value,
- possibleValues: r.map((r) => r.possible_values_subquery),
}))
.value(),
);
- const filterMatches = await Promise.all(
+ return Promise.all(
deploymentVariables.map(async (deploymentVariable) => {
const { targetFilter } = deploymentVariable;
@@ -226,44 +181,9 @@ export const deploymentVariableRouter = createTRPCRouter({
return {
...deploymentVariable,
value: deploymentVariable.value,
- possibleValues: deploymentVariable.possibleValues,
};
}),
).then((rows) => rows.filter(isPresent));
-
- // get all the deployment variable value targets that are direct matches
- // then get all the deployment variable values + the deployment variable itself
- const directMatches = await ctx.db
- .select()
- .from(deploymentVariable)
- .innerJoin(
- possibleValuesSubquery,
- eq(possibleValuesSubquery.variableId, deploymentVariable.id),
- )
- .innerJoin(
- deploymentVariableValue,
- eq(deploymentVariableValue.variableId, deploymentVariable.id),
- )
- .innerJoin(
- deploymentVariableValueTarget,
- eq(
- deploymentVariableValueTarget.variableValueId,
- deploymentVariableValue.id,
- ),
- )
- .where(eq(deploymentVariableValueTarget.targetId, input))
- .then((rows) =>
- _.chain(rows)
- .groupBy((row) => row.deployment_variable.id)
- .map((row) => ({
- ...row[0]!.deployment_variable,
- value: row[0]!.deployment_variable_value,
- possibleValues: row.map((r) => r.possible_values_subquery),
- }))
- .value(),
- );
-
- return [...filterMatches, ...directMatches];
}),
byDeploymentId: protectedProcedure
@@ -274,38 +194,47 @@ export const deploymentVariableRouter = createTRPCRouter({
.on({ type: "deployment", id: input }),
})
.input(z.string().uuid())
- .query(async ({ ctx, input }) =>
- ctx.db
- .select()
+ .query(async ({ ctx, input }) => {
+ const deploymentVariableValueSubquery = ctx.db
+ .select({
+ id: deploymentVariableValue.id,
+ value: deploymentVariableValue.value,
+ variableId: deploymentVariableValue.variableId,
+ targetFilter: deploymentVariableValue.targetFilter,
+ })
+ .from(deploymentVariableValue)
+ .orderBy(asc(deploymentVariableValue.value))
+ .groupBy(deploymentVariableValue.id)
+ .as("deployment_variable_value_subquery");
+
+ return ctx.db
+ .select({
+ deploymentVariable: deploymentVariable,
+ values: sql
`
+ coalesce(
+ array_agg(
+ case when ${deploymentVariableValueSubquery.id} is not null then
+ json_build_object(
+ 'id', ${deploymentVariableValueSubquery.id},
+ 'value', ${deploymentVariableValueSubquery.value},
+ 'variableId', ${deploymentVariableValueSubquery.variableId},
+ 'targetFilter', ${deploymentVariableValueSubquery.targetFilter}
+ )
+ else null end
+ ) filter (where ${deploymentVariableValueSubquery.id} is not null),
+ array[]::json[]
+ )
+ `.as("values"),
+ })
.from(deploymentVariable)
.leftJoin(
- deploymentVariableValue,
- eq(deploymentVariable.id, deploymentVariableValue.variableId),
- )
- .leftJoin(
- deploymentVariableValueTarget,
- eq(
- deploymentVariableValueTarget.variableValueId,
- deploymentVariableValue.id,
- ),
+ deploymentVariableValueSubquery,
+ eq(deploymentVariable.id, deploymentVariableValueSubquery.variableId),
)
- .where(eq(deploymentVariable.deploymentId, input))
- .then((rows) => {
- return _.chain(rows)
- .groupBy((row) => row.deployment_variable.id)
- .map((row) => ({
- ...row[0]!.deployment_variable,
- values: _.chain(row)
- .groupBy((r) => r.deployment_variable_value?.id)
- .map((r) => ({
- ...r[0]!.deployment_variable_value!,
- targets: r.map((r) => r.deployment_variable_value_target!),
- }))
- .value(),
- }))
- .value();
- }),
- ),
+ .groupBy(deploymentVariable.id)
+ .orderBy(asc(deploymentVariable.key))
+ .where(eq(deploymentVariable.deploymentId, input));
+ }),
create: protectedProcedure
.meta({
@@ -315,22 +244,38 @@ export const deploymentVariableRouter = createTRPCRouter({
.on({ type: "deployment", id: input.deploymentId }),
})
.input(createDeploymentVariable)
- .mutation(async ({ ctx, input }) =>
- ctx.db.insert(deploymentVariable).values(input).returning(),
- ),
+ .mutation(async ({ ctx, input }) => {
+ const variable = await ctx.db
+ .insert(deploymentVariable)
+ .values(input)
+ .returning()
+ .then(takeFirst);
+
+ if (input.config?.default) {
+ const value = await ctx.db
+ .insert(deploymentVariableValue)
+ .values({
+ variableId: variable.id,
+ value: input.config.default,
+ })
+ .returning()
+ .then(takeFirst);
+
+ await ctx.db
+ .update(deploymentVariable)
+ .set({ defaultValueId: value.id })
+ .where(eq(deploymentVariable.id, variable.id));
+ }
+
+ return variable;
+ }),
update: protectedProcedure
.meta({
- authorizationCheck: async ({ canUser, ctx, input }) => {
- const variable = await ctx.db
- .select()
- .from(deploymentVariable)
- .where(eq(deploymentVariable.id, input.id))
- .then(takeFirst);
- return canUser
- .perform(Permission.DeploymentUpdate)
- .on({ type: "deployment", id: variable.deploymentId });
- },
+ authorizationCheck: async ({ canUser, input }) =>
+ canUser
+ .perform(Permission.DeploymentVariableUpdate)
+ .on({ type: "deploymentVariable", id: input.id }),
})
.input(z.object({ id: z.string().uuid(), data: updateDeploymentVariable }))
.mutation(async ({ ctx, input }) =>
@@ -339,4 +284,21 @@ export const deploymentVariableRouter = createTRPCRouter({
.set(input.data)
.where(eq(deploymentVariable.id, input.id)),
),
+
+ delete: protectedProcedure
+ .meta({
+ authorizationCheck: async ({ canUser, input }) =>
+ canUser.perform(Permission.DeploymentVariableDelete).on({
+ type: "deploymentVariable",
+ id: input,
+ }),
+ })
+ .input(z.string().uuid())
+ .mutation(async ({ ctx, input }) => {
+ return ctx.db
+ .delete(deploymentVariable)
+ .where(eq(deploymentVariable.id, input))
+ .returning()
+ .then(takeFirstOrNull);
+ }),
});
diff --git a/packages/auth/src/utils/rbac.ts b/packages/auth/src/utils/rbac.ts
index 532edb2f6..472ceb030 100644
--- a/packages/auth/src/utils/rbac.ts
+++ b/packages/auth/src/utils/rbac.ts
@@ -4,6 +4,7 @@ import { and, eq, inArray, takeFirst } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import {
deployment,
+ deploymentVariable,
entityRole,
environment,
environmentPolicy,
@@ -205,6 +206,27 @@ const getDeploymentScopes = async (id: string) => {
];
};
+const getDeploymentVariableScopes = async (id: string) => {
+ const result = await db
+ .select()
+ .from(workspace)
+ .innerJoin(system, eq(system.workspaceId, workspace.id))
+ .innerJoin(deployment, eq(deployment.systemId, system.id))
+ .innerJoin(
+ deploymentVariable,
+ eq(deploymentVariable.deploymentId, deployment.id),
+ )
+ .where(eq(deploymentVariable.id, id))
+ .then(takeFirst);
+
+ return [
+ { type: "deploymentVariable" as const, id: result.deployment_variable.id },
+ { type: "deployment" as const, id: result.deployment.id },
+ { type: "system" as const, id: result.system.id },
+ { type: "workspace" as const, id: result.workspace.id },
+ ];
+};
+
const getRunbookScopes = async (id: string) => {
const result = await db
.select()
@@ -268,6 +290,7 @@ export const scopeHandlers: Record<
target: getTargetScopes,
targetProvider: getTargetProviderScopes,
deployment: getDeploymentScopes,
+ deploymentVariable: getDeploymentVariableScopes,
runbook: getRunbookScopes,
system: getSystemScopes,
workspace: getWorkspaceScopes,
diff --git a/packages/db/drizzle/0004_loving_dormammu.sql b/packages/db/drizzle/0004_loving_dormammu.sql
new file mode 100644
index 000000000..9ec2c2fb8
--- /dev/null
+++ b/packages/db/drizzle/0004_loving_dormammu.sql
@@ -0,0 +1,18 @@
+ALTER TYPE "scope_type" ADD VALUE 'deploymentVariable';--> statement-breakpoint
+DROP TABLE "deployment_variable_value_target";--> statement-breakpoint
+DROP TABLE "deployment_variable_value_target_filter";--> statement-breakpoint
+ALTER TABLE "deployment_variable_value" DROP CONSTRAINT "deployment_variable_value_variable_id_deployment_variable_id_fk";
+--> statement-breakpoint
+ALTER TABLE "deployment_variable" ADD COLUMN "default_value_id" uuid DEFAULT NULL;--> statement-breakpoint
+ALTER TABLE "deployment_variable_value" ADD COLUMN "target_filter" jsonb DEFAULT NULL;--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "deployment_variable" ADD CONSTRAINT "deployment_variable_default_value_id_deployment_variable_value_id_fk" FOREIGN KEY ("default_value_id") REFERENCES "public"."deployment_variable_value"("id") ON DELETE set null ON UPDATE no action;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
+--> statement-breakpoint
+DO $$ BEGIN
+ ALTER TABLE "deployment_variable_value" ADD CONSTRAINT "deployment_variable_value_variable_id_deployment_variable_id_fk" FOREIGN KEY ("variable_id") REFERENCES "public"."deployment_variable"("id") ON DELETE cascade ON UPDATE restrict;
+EXCEPTION
+ WHEN duplicate_object THEN null;
+END $$;
diff --git a/packages/db/drizzle/meta/0004_snapshot.json b/packages/db/drizzle/meta/0004_snapshot.json
new file mode 100644
index 000000000..2253a1c3e
--- /dev/null
+++ b/packages/db/drizzle/meta/0004_snapshot.json
@@ -0,0 +1,3434 @@
+{
+ "id": "b9a6539a-00f3-4d71-9809-0895dee19d99",
+ "prevId": "f4144a38-d3f7-4f98-b87f-04cf178943d7",
+ "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": "varchar(255)",
+ "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": "varchar(255)",
+ "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": "varchar(255)",
+ "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"
+ }
+ },
+ "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
+ },
+ "target_filter": {
+ "name": "target_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": "'{}'"
+ },
+ "github_config_file_id": {
+ "name": "github_config_file_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "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"
+ },
+ "deployment_github_config_file_id_github_config_file_id_fk": {
+ "name": "deployment_github_config_file_id_github_config_file_id_fk",
+ "tableFrom": "deployment",
+ "tableTo": "github_config_file",
+ "columnsFrom": ["github_config_file_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
+ },
+ "target_filter": {
+ "name": "target_filter",
+ "type": "jsonb",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "NULL"
+ },
+ "deleted_at": {
+ "name": "deleted_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false
+ }
+ },
+ "indexes": {},
+ "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_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_type": {
+ "name": "concurrency_type",
+ "type": "concurrency_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'all'"
+ },
+ "concurrency_limit": {
+ "name": "concurrency_limit",
+ "type": "integer",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 1
+ },
+ "duration": {
+ "name": "duration",
+ "type": "bigint",
+ "primaryKey": false,
+ "notNull": true,
+ "default": 0
+ },
+ "evaluate_with": {
+ "name": "evaluate_with",
+ "type": "evaluation_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'none'"
+ },
+ "evaluate": {
+ "name": "evaluate",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "''"
+ },
+ "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": "no action",
+ "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'"
+ }
+ },
+ "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"
+ }
+ },
+ "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_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.github_config_file": {
+ "name": "github_config_file",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "organization_id": {
+ "name": "organization_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "repository_name": {
+ "name": "repository_name",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "path": {
+ "name": "path",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "workspace_id": {
+ "name": "workspace_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "last_synced_at": {
+ "name": "last_synced_at",
+ "type": "timestamp with time zone",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {
+ "unique_organization_repository_path": {
+ "name": "unique_organization_repository_path",
+ "columns": [
+ {
+ "expression": "organization_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "repository_name",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "path",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "github_config_file_organization_id_github_organization_id_fk": {
+ "name": "github_config_file_organization_id_github_organization_id_fk",
+ "tableFrom": "github_config_file",
+ "tableTo": "github_organization",
+ "columnsFrom": ["organization_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "github_config_file_workspace_id_workspace_id_fk": {
+ "name": "github_config_file_workspace_id_workspace_id_fk",
+ "tableFrom": "github_config_file",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.github_organization": {
+ "name": "github_organization",
+ "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
+ },
+ "organization_name": {
+ "name": "organization_name",
+ "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()"
+ },
+ "branch": {
+ "name": "branch",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'main'"
+ }
+ },
+ "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_organization_added_by_user_id_user_id_fk": {
+ "name": "github_organization_added_by_user_id_user_id_fk",
+ "tableFrom": "github_organization",
+ "tableTo": "user",
+ "columnsFrom": ["added_by_user_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ },
+ "github_organization_workspace_id_workspace_id_fk": {
+ "name": "github_organization_workspace_id_workspace_id_fk",
+ "tableFrom": "github_organization",
+ "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.target": {
+ "name": "target",
+ "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": "'{}'"
+ },
+ "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
+ }
+ },
+ "indexes": {
+ "target_identifier_workspace_id_index": {
+ "name": "target_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": {
+ "target_provider_id_target_provider_id_fk": {
+ "name": "target_provider_id_target_provider_id_fk",
+ "tableFrom": "target",
+ "tableTo": "target_provider",
+ "columnsFrom": ["provider_id"],
+ "columnsTo": ["id"],
+ "onDelete": "set null",
+ "onUpdate": "no action"
+ },
+ "target_workspace_id_workspace_id_fk": {
+ "name": "target_workspace_id_workspace_id_fk",
+ "tableFrom": "target",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.target_metadata": {
+ "name": "target_metadata",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "target_id": {
+ "name": "target_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": {
+ "target_metadata_key_target_id_index": {
+ "name": "target_metadata_key_target_id_index",
+ "columns": [
+ {
+ "expression": "key",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ }
+ ],
+ "isUnique": true,
+ "concurrently": false,
+ "method": "btree",
+ "with": {}
+ }
+ },
+ "foreignKeys": {
+ "target_metadata_target_id_target_id_fk": {
+ "name": "target_metadata_target_id_target_id_fk",
+ "tableFrom": "target_metadata",
+ "tableTo": "target",
+ "columnsFrom": ["target_id"],
+ "columnsTo": ["id"],
+ "onDelete": "cascade",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.target_schema": {
+ "name": "target_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": {
+ "target_schema_version_kind_workspace_id_index": {
+ "name": "target_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": {
+ "target_schema_workspace_id_workspace_id_fk": {
+ "name": "target_schema_workspace_id_workspace_id_fk",
+ "tableFrom": "target_schema",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.target_provider": {
+ "name": "target_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": {
+ "target_provider_workspace_id_name_index": {
+ "name": "target_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": {
+ "target_provider_workspace_id_workspace_id_fk": {
+ "name": "target_provider_workspace_id_workspace_id_fk",
+ "tableFrom": "target_provider",
+ "tableTo": "workspace",
+ "columnsFrom": ["workspace_id"],
+ "columnsTo": ["id"],
+ "onDelete": "no action",
+ "onUpdate": "no action"
+ }
+ },
+ "compositePrimaryKeys": {},
+ "uniqueConstraints": {}
+ },
+ "public.target_provider_google": {
+ "name": "target_provider_google",
+ "schema": "",
+ "columns": {
+ "id": {
+ "name": "id",
+ "type": "uuid",
+ "primaryKey": true,
+ "notNull": true,
+ "default": "gen_random_uuid()"
+ },
+ "target_provider_id": {
+ "name": "target_provider_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "project_ids": {
+ "name": "project_ids",
+ "type": "text[]",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {},
+ "foreignKeys": {
+ "target_provider_google_target_provider_id_target_provider_id_fk": {
+ "name": "target_provider_google_target_provider_id_target_provider_id_fk",
+ "tableFrom": "target_provider_google",
+ "tableTo": "target_provider",
+ "columnsFrom": ["target_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()"
+ },
+ "version": {
+ "name": "version",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "notes": {
+ "name": "notes",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "''"
+ },
+ "deployment_id": {
+ "name": "deployment_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "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_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
+ },
+ "target_metadata_group_id": {
+ "name": "target_metadata_group_id",
+ "type": "uuid",
+ "primaryKey": false,
+ "notNull": false
+ },
+ "rule_type": {
+ "name": "rule_type",
+ "type": "release_dependency_rule_type",
+ "typeSchema": "public",
+ "primaryKey": false,
+ "notNull": true
+ },
+ "rule": {
+ "name": "rule",
+ "type": "text",
+ "primaryKey": false,
+ "notNull": true
+ }
+ },
+ "indexes": {
+ "release_dependency_release_id_deployment_id_target_metadata_group_id_index": {
+ "name": "release_dependency_release_id_deployment_id_target_metadata_group_id_index",
+ "columns": [
+ {
+ "expression": "release_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "deployment_id",
+ "isExpression": false,
+ "asc": true,
+ "nulls": "last"
+ },
+ {
+ "expression": "target_metadata_group_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"
+ },
+ "release_dependency_target_metadata_group_id_target_metadata_group_id_fk": {
+ "name": "release_dependency_target_metadata_group_id_target_metadata_group_id_fk",
+ "tableFrom": "release_dependency",
+ "tableTo": "target_metadata_group",
+ "columnsFrom": ["target_metadata_group_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
+ },
+ "target_id": {
+ "name": "target_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_target_id_target_id_fk": {
+ "name": "release_job_trigger_target_id_target_id_fk",
+ "tableFrom": "release_job_trigger",
+ "tableTo": "target",
+ "columnsFrom": ["target_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.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": true
+ },
+ "job_agent_config": {
+ "name": "job_agent_config",
+ "type": "json",
+ "primaryKey": false,
+ "notNull": true,
+ "default": "'{}'"
+ },
+ "external_run_id": {
+ "name": "external_run_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",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ },
+ "updated_at": {
+ "name": "updated_at",
+ "type": "timestamp",
+ "primaryKey": false,
+ "notNull": false,
+ "default": "now()"
+ }
+ },
+ "indexes": {},
+ "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": "no action",
+ "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
+ }
+ },
+ "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
+ }
+ },
+ "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_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": "text",
+ "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.target_metadata_group": {
+ "name": "target_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": {
+ "target_metadata_group_workspace_id_workspace_id_fk": {
+ "name": "target_metadata_group_workspace_id_workspace_id_fk",
+ "tableFrom": "target_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.concurrency_type": {
+ "name": "concurrency_type",
+ "schema": "public",
+ "values": ["all", "some"]
+ },
+ "public.environment_policy_deployment_success_type": {
+ "name": "environment_policy_deployment_success_type",
+ "schema": "public",
+ "values": ["all", "some", "optional"]
+ },
+ "public.evaluation_type": {
+ "name": "evaluation_type",
+ "schema": "public",
+ "values": ["semver", "regex", "none"]
+ },
+ "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.release_dependency_rule_type": {
+ "name": "release_dependency_rule_type",
+ "schema": "public",
+ "values": ["regex", "semver"]
+ },
+ "public.release_job_trigger_type": {
+ "name": "release_job_trigger_type",
+ "schema": "public",
+ "values": [
+ "new_release",
+ "new_target",
+ "target_changed",
+ "api",
+ "redeploy",
+ "force_deploy"
+ ]
+ },
+ "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": [
+ "completed",
+ "cancelled",
+ "skipped",
+ "in_progress",
+ "action_required",
+ "pending",
+ "failure",
+ "invalid_job_agent",
+ "invalid_integration",
+ "external_run_not_found"
+ ]
+ },
+ "public.entity_type": {
+ "name": "entity_type",
+ "schema": "public",
+ "values": ["user", "team"]
+ },
+ "public.scope_type": {
+ "name": "scope_type",
+ "schema": "public",
+ "values": [
+ "release",
+ "target",
+ "targetProvider",
+ "targetMetadataGroup",
+ "workspace",
+ "environment",
+ "environmentPolicy",
+ "deploymentVariable",
+ "variableSet",
+ "system",
+ "deployment",
+ "jobAgent",
+ "runbook"
+ ]
+ }
+ },
+ "schemas": {},
+ "sequences": {},
+ "_meta": {
+ "columns": {},
+ "schemas": {},
+ "tables": {}
+ }
+}
diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json
index c4a5bbe12..1556f3606 100644
--- a/packages/db/drizzle/meta/_journal.json
+++ b/packages/db/drizzle/meta/_journal.json
@@ -29,6 +29,13 @@
"when": 1727513481651,
"tag": "0003_outstanding_punisher",
"breakpoints": true
+ },
+ {
+ "idx": 4,
+ "version": "7",
+ "when": 1727634917358,
+ "tag": "0004_loving_dormammu",
+ "breakpoints": true
}
]
}
diff --git a/packages/db/src/schema/deployment-variables.ts b/packages/db/src/schema/deployment-variables.ts
index f9b183f66..6017c52dc 100644
--- a/packages/db/src/schema/deployment-variables.ts
+++ b/packages/db/src/schema/deployment-variables.ts
@@ -1,11 +1,23 @@
-import type { MetadataCondition } from "@ctrlplane/validators/targets";
+import type { TargetCondition } from "@ctrlplane/validators/targets";
+import type { VariableConfigType } from "@ctrlplane/validators/variables";
import type { InferInsertModel, InferSelectModel } from "drizzle-orm";
-import { jsonb, pgTable, text, uniqueIndex, uuid } from "drizzle-orm/pg-core";
+import type { AnyPgColumn, ColumnsWithTable } from "drizzle-orm/pg-core";
+import { sql } from "drizzle-orm";
+import {
+ foreignKey,
+ jsonb,
+ pgTable,
+ text,
+ uniqueIndex,
+ uuid,
+} from "drizzle-orm/pg-core";
import { createInsertSchema } from "drizzle-zod";
import { z } from "zod";
+import { targetCondition } from "@ctrlplane/validators/targets";
+import { VariableConfig } from "@ctrlplane/validators/variables";
+
import { deployment } from "./deployment.js";
-import { target } from "./target.js";
import { variableSet } from "./variable-sets.js";
export const deploymentVariable = pgTable(
@@ -17,14 +29,24 @@ export const deploymentVariable = pgTable(
deploymentId: uuid("deployment_id")
.notNull()
.references(() => deployment.id),
- schema: jsonb("schema").$type>(),
+ defaultValueId: uuid("default_value_id").default(sql`NULL`),
+ config: jsonb("schema").$type(),
},
- (t) => ({ uniq: uniqueIndex().on(t.deploymentId, t.key) }),
+ (t) => ({
+ uniq: uniqueIndex().on(t.deploymentId, t.key),
+ defaultValueIdFK: foreignKey(defaultValueIdFKConstraint).onDelete(
+ "set null",
+ ),
+ }),
);
export type DeploymentVariable = InferSelectModel;
+export type InsertDeploymentVariable = InferInsertModel<
+ typeof deploymentVariable
+>;
export const createDeploymentVariable = createInsertSchema(deploymentVariable, {
- schema: z.record(z.any()).optional(),
+ key: z.string().min(1),
+ config: VariableConfig,
}).omit({ id: true });
export const updateDeploymentVariable = createDeploymentVariable.partial();
@@ -32,64 +54,50 @@ export const deploymentVariableValue = pgTable(
"deployment_variable_value",
{
id: uuid("id").notNull().primaryKey().defaultRandom(),
- variableId: uuid("variable_id")
- .notNull()
- .references(() => deploymentVariable.id, { onDelete: "cascade" }),
+ variableId: uuid("variable_id").notNull(),
value: jsonb("value").$type().notNull(),
+ targetFilter: jsonb("target_filter")
+ .$type()
+ .default(sql`NULL`),
},
- (t) => ({ uniq: uniqueIndex().on(t.variableId, t.value) }),
+ (t) => ({
+ uniq: uniqueIndex().on(t.variableId, t.value),
+ variableIdFk: foreignKey({
+ columns: [t.variableId],
+ foreignColumns: [deploymentVariable.id],
+ })
+ .onUpdate("restrict")
+ .onDelete("cascade"),
+ }),
);
-export type DeploymentVariableValue = InferInsertModel<
+export type DeploymentVariableValue = InferSelectModel<
typeof deploymentVariableValue
>;
export const createDeploymentVariableValue = createInsertSchema(
deploymentVariableValue,
-).omit({
- id: true,
-});
+ { targetFilter: targetCondition },
+)
+ .omit({
+ id: true,
+ })
+ .extend({
+ default: z.boolean().optional(),
+ });
export const updateDeploymentVariableValue =
createDeploymentVariableValue.partial();
-export const deploymentVariableValueTargetFilter = pgTable(
- "deployment_variable_value_target_filter",
- {
- id: uuid("id").notNull().primaryKey().defaultRandom(),
- variableValueId: uuid("variable_value_id")
- .notNull()
- .references(() => deploymentVariableValue.id, { onDelete: "cascade" }),
- targetFilter: jsonb("target_filter").$type().notNull(),
- },
-);
-export type DeploymentVariableValueTargetFilter = InferInsertModel<
- typeof deploymentVariableValueTargetFilter
->;
-export const createDeploymentVariableValueTargetFilter = createInsertSchema(
- deploymentVariableValueTargetFilter,
-).omit({ id: true });
-export const updateDeploymentVariableValueTargetFilter =
- createDeploymentVariableValueTargetFilter.partial();
-
-export const deploymentVariableValueTarget = pgTable(
- "deployment_variable_value_target",
- {
- id: uuid("id").notNull().primaryKey().defaultRandom(),
- variableValueId: uuid("variable_value_id")
- .notNull()
- .references(() => deploymentVariableValue.id, { onDelete: "cascade" }),
- targetId: uuid("target_id")
- .notNull()
- .references(() => target.id, { onDelete: "cascade" }),
- },
- (t) => ({ uniq: uniqueIndex().on(t.variableValueId, t.targetId) }),
-);
-export type DeploymentVariableValueTarget = InferInsertModel<
- typeof deploymentVariableValueTarget
->;
-export const createDeploymentVariableValueTarget = createInsertSchema(
- deploymentVariableValueTarget,
-).omit({ id: true });
-export const updateDeploymentVariableValueTarget =
- createDeploymentVariableValueTarget.partial();
+// workaround for cirular reference - https://www.answeroverflow.com/m/1194395880523042936
+const defaultValueIdFKConstraint: {
+ columns: [AnyPgColumn<{ tableName: "deployment_variable" }>];
+ foreignColumns: ColumnsWithTable<
+ "deployment_variable",
+ "deployment_variable_value",
+ [AnyPgColumn<{ tableName: "deployment_variable" }>]
+ >;
+} = {
+ columns: [deploymentVariable.defaultValueId],
+ foreignColumns: [deploymentVariableValue.id],
+};
export const deploymentVariableSet = pgTable(
"deployment_variable_set",
diff --git a/packages/db/src/schema/rbac.ts b/packages/db/src/schema/rbac.ts
index 9822a5841..c5814063f 100644
--- a/packages/db/src/schema/rbac.ts
+++ b/packages/db/src/schema/rbac.ts
@@ -40,6 +40,7 @@ export const scopeType = pgEnum("scope_type", [
"workspace",
"environment",
"environmentPolicy",
+ "deploymentVariable",
"variableSet",
"system",
"deployment",
diff --git a/packages/db/src/schema/target.ts b/packages/db/src/schema/target.ts
index b62c96218..1e6726b44 100644
--- a/packages/db/src/schema/target.ts
+++ b/packages/db/src/schema/target.ts
@@ -154,6 +154,8 @@ const buildCondition = (tx: Tx, cond: TargetCondition): SQL => {
if (cond.type === "name") return like(target.name, cond.value);
+ if (cond.conditions.length === 0) return sql`FALSE`;
+
const subCon = cond.conditions.map((c) => buildCondition(tx, c));
const con = cond.operator === "and" ? and(...subCon)! : or(...subCon)!;
return cond.not ? not(con) : con;
diff --git a/packages/job-dispatch/src/job-creation.ts b/packages/job-dispatch/src/job-creation.ts
index 3dc162f83..83eb8971a 100644
--- a/packages/job-dispatch/src/job-creation.ts
+++ b/packages/job-dispatch/src/job-creation.ts
@@ -1,7 +1,7 @@
import type { Tx } from "@ctrlplane/db";
import _ from "lodash";
-import { and, eq, inArray, isNotNull, or, takeFirst } from "@ctrlplane/db";
+import { and, eq, isNotNull, or, takeFirst } from "@ctrlplane/db";
import { db } from "@ctrlplane/db/client";
import * as schema from "@ctrlplane/db/schema";
// import {
@@ -72,81 +72,6 @@ export const createTriggeredRunbookJob = async (
return job;
};
-export const createTriggeredReleaseJobs = async (
- db: Tx,
- releaseJobTriggers: schema.ReleaseJobTrigger[],
- status: schema.JobStatus = JobStatus.Pending,
-): Promise => {
- logger.info(`Creating triggered release jobs`, {
- releaseJobTriggersCount: releaseJobTriggers.length,
- status,
- });
-
- const insertJobs = await db
- .select()
- .from(schema.releaseJobTrigger)
- .leftJoin(
- schema.release,
- eq(schema.release.id, schema.releaseJobTrigger.releaseId),
- )
- .leftJoin(
- schema.deployment,
- eq(schema.deployment.id, schema.release.deploymentId),
- )
- .innerJoin(
- schema.jobAgent,
- eq(schema.jobAgent.id, schema.deployment.jobAgentId),
- )
- .where(
- inArray(
- schema.releaseJobTrigger.id,
- releaseJobTriggers.map((t) => t.id),
- ),
- );
-
- logger.debug(`Found jobs to insert`, { count: insertJobs.length });
-
- if (insertJobs.length === 0) {
- logger.info(`No jobs to insert, returning empty array`);
- return [];
- }
-
- const jobs = await db
- .insert(schema.job)
- .values(
- insertJobs.map((d) => ({
- jobAgentId: d.job_agent.id,
- jobAgentConfig: _.merge(
- d.job_agent.config,
- d.deployment?.jobAgentConfig ?? {},
- ),
- status,
- })),
- )
- .returning();
-
- logger.info(`Inserted jobs`, { count: jobs.length });
-
- // Update releaseJobTrigger with the new job ids
- await Promise.all(
- jobs.map((job, index) =>
- db
- .update(schema.releaseJobTrigger)
- .set({ jobId: job.id })
- .where(
- eq(
- schema.releaseJobTrigger.id,
- insertJobs[index]!.release_job_trigger.id,
- ),
- ),
- ),
- );
-
- logger.info(`Updated releaseJobTrigger with new job ids`);
-
- return jobs;
-};
-
/**
* When a job completes, there may be other jobs that should now be triggered
* because the completion of this job means that some policies are now passing.
diff --git a/packages/job-dispatch/src/job-variables-deployment.ts b/packages/job-dispatch/src/job-variables-deployment.ts
index cd5ccd78b..70ce86a6b 100644
--- a/packages/job-dispatch/src/job-variables-deployment.ts
+++ b/packages/job-dispatch/src/job-variables-deployment.ts
@@ -1,6 +1,7 @@
import type { Tx } from "@ctrlplane/db";
+import { isPresent } from "ts-is-present";
-import { and, eq, takeFirst, takeFirstOrNull } from "@ctrlplane/db";
+import { and, eq, takeFirstOrNull } from "@ctrlplane/db";
import * as schema from "@ctrlplane/db/schema";
export const createReleaseVariables = async (
@@ -59,13 +60,16 @@ const determineVariablesForReleaseJob = async (
determineReleaseVariableValue(
tx,
variable.deployment_variable.id,
+ variable.deployment_variable.defaultValueId,
jobTarget,
- ).then((value) =>
- jobVariables.push({
- jobId: job.id,
- key: variable.deployment_variable.key,
- value: value.value,
- }),
+ ).then(
+ (value) =>
+ value != null &&
+ jobVariables.push({
+ jobId: job.id,
+ key: variable.deployment_variable.key,
+ value: value.value,
+ }),
),
),
);
@@ -76,67 +80,44 @@ const determineVariablesForReleaseJob = async (
const determineReleaseVariableValue = async (
tx: Tx,
variableId: string,
+ defaultValueId: string | null,
jobTarget: schema.Target,
-): Promise => {
- // Check for a direct target match
- const directMatch = await tx
+): Promise => {
+ const deploymentVariableValues = await tx
.select()
.from(schema.deploymentVariableValue)
- .innerJoin(
- schema.deploymentVariableValueTarget,
- eq(
- schema.deploymentVariableValueTarget.variableValueId,
- schema.deploymentVariableValue.id,
- ),
- )
- .where(
- and(
- eq(schema.deploymentVariableValue.variableId, variableId),
- eq(schema.deploymentVariableValueTarget.targetId, jobTarget.id),
- ),
- )
- .then(takeFirstOrNull);
+ .orderBy(schema.deploymentVariableValue.value)
+ .where(eq(schema.deploymentVariableValue.variableId, variableId));
- if (directMatch != null) return directMatch.deployment_variable_value;
+ if (deploymentVariableValues.length === 0) return null;
- // Check for a match based on target filters
- const deploymentVariableValue = await tx
- .select()
- .from(schema.deploymentVariableValue)
- .innerJoin(
- schema.deploymentVariableValueTargetFilter,
- eq(
- schema.deploymentVariableValueTargetFilter.variableValueId,
- schema.deploymentVariableValue.id,
- ),
- )
- .where(eq(schema.deploymentVariableValue.variableId, variableId))
- .then(takeFirstOrNull);
+ const defaultValue = deploymentVariableValues.find(
+ (v) => v.id === defaultValueId,
+ );
+ const valuesWithFilters = deploymentVariableValues.filter(
+ (v) => v.targetFilter != null,
+ );
- if (deploymentVariableValue != null) {
- const filterMatch = await tx
- .select()
- .from(schema.target)
- .where(
- schema.targetMatchesMetadata(
- tx,
- deploymentVariableValue.deployment_variable_value_target_filter
- .targetFilter,
- ),
- )
- .limit(1)
- .then(takeFirstOrNull);
-
- if (filterMatch != null)
- return deploymentVariableValue.deployment_variable_value;
- }
-
- // If no specific match is found, return the default value (if any)
- const defaultValue = await tx
- .select()
- .from(schema.deploymentVariableValue)
- .where(eq(schema.deploymentVariableValue.variableId, variableId))
- .then(takeFirst);
+ const valuesMatchedByFilter = await Promise.all(
+ valuesWithFilters.map(async (value) => {
+ const matchedTarget = await tx
+ .select()
+ .from(schema.target)
+ .where(
+ and(
+ eq(schema.target.id, jobTarget.id),
+ schema.targetMatchesMetadata(tx, value.targetFilter),
+ ),
+ )
+ .then(takeFirstOrNull);
+
+ if (matchedTarget != null) return value;
+ }),
+ ).then((values) => values.filter(isPresent));
+
+ if (valuesMatchedByFilter.length > 0) return valuesMatchedByFilter[0]!;
+
+ if (defaultValue != null) return defaultValue;
- return defaultValue;
+ return deploymentVariableValues[0]!;
};
diff --git a/packages/job-dispatch/src/release-job-trigger.ts b/packages/job-dispatch/src/release-job-trigger.ts
index f75ee4073..1929f9b37 100644
--- a/packages/job-dispatch/src/release-job-trigger.ts
+++ b/packages/job-dispatch/src/release-job-trigger.ts
@@ -20,6 +20,8 @@ import {
targetMatchesMetadata,
} from "@ctrlplane/db/schema";
+import { createReleaseVariables } from "./job-variables-deployment.js";
+
type FilterFunc = (
tx: Tx,
insertReleaseJobTriggers: ReleaseJobTriggerInsert[],
@@ -207,6 +209,10 @@ class ReleaseJobTriggerBuilder {
.values(wtWithJobId)
.returning();
+ await Promise.all(
+ jobs.map((job) => createReleaseVariables(this.tx, job.id)),
+ );
+
for (const func of this._then) await func(this.tx, releaseJobTriggers);
return releaseJobTriggers;
diff --git a/packages/validators/src/auth/index.ts b/packages/validators/src/auth/index.ts
index 96de80b14..81d806c33 100644
--- a/packages/validators/src/auth/index.ts
+++ b/packages/validators/src/auth/index.ts
@@ -44,6 +44,10 @@ export enum Permission {
DeploymentDelete = "deployment.delete",
DeploymentList = "deployment.list",
+ DeploymentVariableCreate = "deploymentVariable.create",
+ DeploymentVariableUpdate = "deploymentVariable.update",
+ DeploymentVariableDelete = "deploymentVariable.delete",
+
ReleaseCreate = "release.create",
ReleaseGet = "release.get",
ReleaseList = "release.list",
diff --git a/packages/validators/src/variables/index.ts b/packages/validators/src/variables/index.ts
index abd38f812..f96723231 100644
--- a/packages/validators/src/variables/index.ts
+++ b/packages/validators/src/variables/index.ts
@@ -22,7 +22,7 @@ export const NumberVariableConfig = z.object({
maximum: z.number().optional(),
default: z.number().optional(),
});
-export type NumberSchemaConfigType = z.infer;
+export type NumberVariableConfigType = z.infer;
export const BooleanVariableConfig = z.object({
type: z.literal("boolean"),