diff --git a/apps/webservice/src/app/api/v1/environments/route.ts b/apps/webservice/src/app/api/v1/environments/route.ts index 12f57ac7b..4972853e0 100644 --- a/apps/webservice/src/app/api/v1/environments/route.ts +++ b/apps/webservice/src/app/api/v1/environments/route.ts @@ -4,7 +4,7 @@ import { NextResponse } from "next/server"; import _ from "lodash"; import { z } from "zod"; -import { and, createEnv, eq, inArray } from "@ctrlplane/db"; +import { inArray, upsertEnv } from "@ctrlplane/db"; import * as schema from "@ctrlplane/db/schema"; import { createJobsForNewEnvironment } from "@ctrlplane/job-dispatch"; import { logger } from "@ctrlplane/logger"; @@ -16,10 +16,6 @@ import { request } from "../middleware"; const body = schema.createEnvironment.extend({ releaseChannels: z.array(z.string()), - expiresAt: z.coerce - .date() - .min(new Date(), "Expires at must be in the future") - .optional(), }); export const POST = request() @@ -33,35 +29,14 @@ export const POST = request() ), ) .handle<{ user: User; can: PermissionChecker; body: z.infer }>( - async (ctx) => { - const isInSystem = eq(schema.environment.systemId, ctx.body.systemId); - const isSameName = eq(schema.environment.name, ctx.body.name); - const existingEnvironment = await ctx.db.query.environment.findFirst({ - where: and(isInSystem, isSameName), - }); - - if (existingEnvironment != null) - return NextResponse.json( - { error: "Environment already exists", id: existingEnvironment.id }, - { status: 409 }, - ); - - try { - return ctx.db.transaction(async (tx) => { - const { - releaseChannels: deploymentVersionChannels, - metadata, - ...rest - } = ctx.body; - + ({ db, body }) => + db.transaction(async (tx) => { + try { const channels = await tx .select() .from(schema.deploymentVersionChannel) .where( - inArray( - schema.deploymentVersionChannel.id, - deploymentVersionChannels, - ), + inArray(schema.deploymentVersionChannel.id, body.releaseChannels), ) .then((rows) => _.uniqBy(rows, (r) => r.deploymentId).map((r) => ({ @@ -70,21 +45,21 @@ export const POST = request() })), ); - const environment = await createEnv(tx, { - ...rest, - metadata, + const environment = await upsertEnv(tx, { + ...body, versionChannels: channels, }); await createJobsForNewEnvironment(tx, environment); + const { metadata } = body; return NextResponse.json({ ...environment, metadata }); - }); - } catch (error) { - logger.error("Failed to create environment", { error }); - return NextResponse.json( - { error: "Failed to create environment" }, - { status: 500 }, - ); - } - }, + } catch (e) { + const error = e instanceof Error ? e.message : e; + logger.error("Failed to create environment", { error }); + return NextResponse.json( + { error: "Failed to create environment" }, + { status: 500 }, + ); + } + }), ); diff --git a/packages/api/src/router/environment.ts b/packages/api/src/router/environment.ts index 7ade0bf59..a463b7c9a 100644 --- a/packages/api/src/router/environment.ts +++ b/packages/api/src/router/environment.ts @@ -5,7 +5,6 @@ import { z } from "zod"; import { and, - createEnv, eq, inArray, isNotNull, @@ -13,6 +12,7 @@ import { ne, not, takeFirst, + upsertEnv, } from "@ctrlplane/db"; import { createEnvironment, @@ -213,7 +213,7 @@ export const environmentRouter = createTRPCRouter({ }) .input(createEnvironment) .mutation(({ ctx, input }) => - ctx.db.transaction((db) => createEnv(db, input)), + ctx.db.transaction((db) => upsertEnv(db, input)), ), update: protectedProcedure diff --git a/packages/api/src/router/system.ts b/packages/api/src/router/system.ts index f3bd30572..6d8dcfa81 100644 --- a/packages/api/src/router/system.ts +++ b/packages/api/src/router/system.ts @@ -7,7 +7,6 @@ import { and, asc, count, - createEnv, eq, ilike, isNotNull, @@ -15,6 +14,7 @@ import { or, takeFirst, takeFirstOrNull, + upsertEnv, } from "@ctrlplane/db"; import { createSystem, @@ -158,9 +158,9 @@ export const systemRouter = createTRPCRouter({ .then(takeFirst); await Promise.all([ - createEnv(db, { systemId: sys.id, name: "Production" }), - createEnv(db, { systemId: sys.id, name: "QA" }), - createEnv(db, { systemId: sys.id, name: "Staging" }), + upsertEnv(db, { systemId: sys.id, name: "Production" }), + upsertEnv(db, { systemId: sys.id, name: "QA" }), + upsertEnv(db, { systemId: sys.id, name: "Staging" }), ]); return sys; }), diff --git a/packages/db/drizzle/meta/0081_snapshot.json b/packages/db/drizzle/meta/0081_snapshot.json index a45bb7014..f480c2f04 100644 --- a/packages/db/drizzle/meta/0081_snapshot.json +++ b/packages/db/drizzle/meta/0081_snapshot.json @@ -81,12 +81,8 @@ "name": "account_userId_user_id_fk", "tableFrom": "account", "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["userId"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -94,10 +90,7 @@ "compositePrimaryKeys": { "account_provider_providerAccountId_pk": { "name": "account_provider_providerAccountId_pk", - "columns": [ - "provider", - "providerAccountId" - ] + "columns": ["provider", "providerAccountId"] } }, "uniqueConstraints": {} @@ -131,12 +124,8 @@ "name": "session_userId_user_id_fk", "tableFrom": "session", "tableTo": "user", - "columnsFrom": [ - "userId" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["userId"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -215,12 +204,8 @@ "name": "user_active_workspace_id_workspace_id_fk", "tableFrom": "user", "tableTo": "workspace", - "columnsFrom": [ - "active_workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["active_workspace_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -304,12 +289,8 @@ "name": "user_api_key_user_id_user_id_fk", "tableFrom": "user_api_key", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -366,12 +347,8 @@ "name": "dashboard_workspace_id_workspace_id_fk", "tableFrom": "dashboard", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -440,12 +417,8 @@ "name": "dashboard_widget_dashboard_id_dashboard_id_fk", "tableFrom": "dashboard_widget", "tableTo": "dashboard", - "columnsFrom": [ - "dashboard_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["dashboard_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -525,12 +498,8 @@ "name": "deployment_variable_deployment_id_deployment_id_fk", "tableFrom": "deployment_variable", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -538,12 +507,8 @@ "name": "deployment_variable_default_value_id_deployment_variable_value_id_fk", "tableFrom": "deployment_variable", "tableTo": "deployment_variable_value", - "columnsFrom": [ - "default_value_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["default_value_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -603,12 +568,8 @@ "name": "deployment_variable_set_deployment_id_deployment_id_fk", "tableFrom": "deployment_variable_set", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -616,12 +577,8 @@ "name": "deployment_variable_set_variable_set_id_variable_set_id_fk", "tableFrom": "deployment_variable_set", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -688,12 +645,8 @@ "name": "deployment_variable_value_variable_id_deployment_variable_id_fk", "tableFrom": "deployment_variable_value", "tableTo": "deployment_variable", - "columnsFrom": [ - "variable_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "restrict" } @@ -809,12 +762,8 @@ "name": "deployment_version_deployment_id_deployment_id_fk", "tableFrom": "deployment_version", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -888,12 +837,8 @@ "name": "deployment_version_channel_deployment_id_deployment_id_fk", "tableFrom": "deployment_version_channel", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -959,12 +904,8 @@ "name": "deployment_version_metadata_deployment_version_id_deployment_version_id_fk", "tableFrom": "deployment_version_metadata", "tableTo": "deployment_version", - "columnsFrom": [ - "deployment_version_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_version_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1031,12 +972,8 @@ "name": "deployment_version_dependency_deployment_version_id_deployment_version_id_fk", "tableFrom": "deployment_version_dependency", "tableTo": "deployment_version", - "columnsFrom": [ - "deployment_version_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_version_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1044,12 +981,8 @@ "name": "deployment_version_dependency_deployment_id_deployment_id_fk", "tableFrom": "deployment_version_dependency", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1155,12 +1088,8 @@ "name": "deployment_system_id_system_id_fk", "tableFrom": "deployment", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -1168,12 +1097,8 @@ "name": "deployment_job_agent_id_job_agent_id_fk", "tableFrom": "deployment", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1232,12 +1157,8 @@ "name": "deployment_meta_dependency_deployment_id_deployment_id_fk", "tableFrom": "deployment_meta_dependency", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -1245,12 +1166,8 @@ "name": "deployment_meta_dependency_depends_on_id_deployment_id_fk", "tableFrom": "deployment_meta_dependency", "tableTo": "deployment", - "columnsFrom": [ - "depends_on_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["depends_on_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -1310,12 +1227,8 @@ "name": "environment_policy_deployment_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_deployment", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1323,12 +1236,8 @@ "name": "environment_policy_deployment_environment_id_environment_id_fk", "tableFrom": "environment_policy_deployment", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1422,12 +1331,8 @@ "name": "environment_system_id_system_id_fk", "tableFrom": "environment", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1435,12 +1340,8 @@ "name": "environment_policy_id_environment_policy_id_fk", "tableFrom": "environment", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1506,12 +1407,8 @@ "name": "environment_metadata_environment_id_environment_id_fk", "tableFrom": "environment_metadata", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1613,12 +1510,8 @@ "name": "environment_policy_system_id_system_id_fk", "tableFrom": "environment_policy", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1626,12 +1519,8 @@ "name": "environment_policy_environment_id_environment_id_fk", "tableFrom": "environment_policy", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1712,12 +1601,8 @@ "name": "environment_policy_approval_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1725,12 +1610,8 @@ "name": "environment_policy_approval_release_id_deployment_version_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "deployment_version", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1738,12 +1619,8 @@ "name": "environment_policy_approval_user_id_user_id_fk", "tableFrom": "environment_policy_approval", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -1794,12 +1671,8 @@ "name": "environment_policy_release_window_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_release_window", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -1936,12 +1809,8 @@ "name": "runhook_hook_id_hook_id_fk", "tableFrom": "runhook", "tableTo": "hook", - "columnsFrom": [ - "hook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["hook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -1949,12 +1818,8 @@ "name": "runhook_runbook_id_runbook_id_fk", "tableFrom": "runhook", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2047,12 +1912,8 @@ "name": "github_entity_added_by_user_id_user_id_fk", "tableFrom": "github_entity", "tableTo": "user", - "columnsFrom": [ - "added_by_user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["added_by_user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -2060,12 +1921,8 @@ "name": "github_entity_workspace_id_workspace_id_fk", "tableFrom": "github_entity", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2109,12 +1966,8 @@ "name": "github_user_user_id_user_id_fk", "tableFrom": "github_user", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2174,12 +2027,8 @@ "name": "job_resource_relationship_job_id_job_id_fk", "tableFrom": "job_resource_relationship", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2295,12 +2144,8 @@ "name": "resource_provider_id_resource_provider_id_fk", "tableFrom": "resource", "tableTo": "resource_provider", - "columnsFrom": [ - "provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["provider_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" }, @@ -2308,12 +2153,8 @@ "name": "resource_workspace_id_workspace_id_fk", "tableFrom": "resource", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2379,12 +2220,8 @@ "name": "resource_metadata_resource_id_resource_id_fk", "tableFrom": "resource_metadata", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2457,12 +2294,8 @@ "name": "resource_relationship_workspace_id_workspace_id_fk", "tableFrom": "resource_relationship", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2541,12 +2374,8 @@ "name": "resource_release_resource_id_resource_id_fk", "tableFrom": "resource_release", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -2554,12 +2383,8 @@ "name": "resource_release_environment_id_environment_id_fk", "tableFrom": "resource_release", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -2567,12 +2392,8 @@ "name": "resource_release_deployment_id_deployment_id_fk", "tableFrom": "resource_release", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -2580,12 +2401,8 @@ "name": "resource_release_desired_release_id_release_id_fk", "tableFrom": "resource_release", "tableTo": "release", - "columnsFrom": [ - "desired_release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["desired_release_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -2663,12 +2480,8 @@ "name": "resource_schema_workspace_id_workspace_id_fk", "tableFrom": "resource_schema", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2741,12 +2554,8 @@ "name": "resource_variable_resource_id_resource_id_fk", "tableFrom": "resource_variable", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2797,12 +2606,8 @@ "name": "resource_view_workspace_id_workspace_id_fk", "tableFrom": "resource_view", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -2856,12 +2661,8 @@ "name": "azure_tenant_workspace_id_workspace_id_fk", "tableFrom": "azure_tenant", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2928,12 +2729,8 @@ "name": "resource_provider_workspace_id_workspace_id_fk", "tableFrom": "resource_provider", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -2985,12 +2782,8 @@ "name": "resource_provider_aws_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_aws", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3034,12 +2827,8 @@ "name": "resource_provider_azure_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_azure", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3047,12 +2836,8 @@ "name": "resource_provider_azure_tenant_id_azure_tenant_id_fk", "tableFrom": "resource_provider_azure", "tableTo": "azure_tenant", - "columnsFrom": [ - "tenant_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["tenant_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -3125,12 +2910,8 @@ "name": "resource_provider_google_resource_provider_id_resource_provider_id_fk", "tableFrom": "resource_provider_google", "tableTo": "resource_provider", - "columnsFrom": [ - "resource_provider_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_provider_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3203,12 +2984,8 @@ "name": "system_workspace_id_workspace_id_fk", "tableFrom": "system", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3265,12 +3042,8 @@ "name": "runbook_system_id_system_id_fk", "tableFrom": "runbook", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3278,12 +3051,8 @@ "name": "runbook_job_agent_id_job_agent_id_fk", "tableFrom": "runbook", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -3328,12 +3097,8 @@ "name": "runbook_job_trigger_job_id_job_id_fk", "tableFrom": "runbook_job_trigger", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3341,12 +3106,8 @@ "name": "runbook_job_trigger_runbook_id_runbook_id_fk", "tableFrom": "runbook_job_trigger", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3356,9 +3117,7 @@ "runbook_job_trigger_job_id_unique": { "name": "runbook_job_trigger_job_id_unique", "nullsNotDistinct": false, - "columns": [ - "job_id" - ] + "columns": ["job_id"] } } }, @@ -3392,12 +3151,8 @@ "name": "team_workspace_id_workspace_id_fk", "tableFrom": "team", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3457,12 +3212,8 @@ "name": "team_member_team_id_team_id_fk", "tableFrom": "team_member", "tableTo": "team", - "columnsFrom": [ - "team_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["team_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3470,12 +3221,8 @@ "name": "team_member_user_id_user_id_fk", "tableFrom": "team_member", "tableTo": "user", - "columnsFrom": [ - "user_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["user_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3599,12 +3346,8 @@ "name": "job_job_agent_id_job_agent_id_fk", "tableFrom": "job", "tableTo": "job_agent", - "columnsFrom": [ - "job_agent_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_agent_id"], + "columnsTo": ["id"], "onDelete": "set null", "onUpdate": "no action" } @@ -3670,12 +3413,8 @@ "name": "job_metadata_job_id_job_id_fk", "tableFrom": "job_metadata", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3748,12 +3487,8 @@ "name": "job_variable_job_id_job_id_fk", "tableFrom": "job_variable", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -3811,9 +3546,7 @@ "workspace_slug_unique": { "name": "workspace_slug_unique", "nullsNotDistinct": false, - "columns": [ - "slug" - ] + "columns": ["slug"] } } }, @@ -3901,12 +3634,8 @@ "name": "workspace_email_domain_matching_workspace_id_workspace_id_fk", "tableFrom": "workspace_email_domain_matching", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -3914,12 +3643,8 @@ "name": "workspace_email_domain_matching_role_id_role_id_fk", "tableFrom": "workspace_email_domain_matching", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -3963,12 +3688,8 @@ "name": "variable_set_system_id_system_id_fk", "tableFrom": "variable_set", "tableTo": "system", - "columnsFrom": [ - "system_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["system_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4006,12 +3727,8 @@ "name": "variable_set_environment_variable_set_id_variable_set_id_fk", "tableFrom": "variable_set_environment", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4019,12 +3736,8 @@ "name": "variable_set_environment_environment_id_environment_id_fk", "tableFrom": "variable_set_environment", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4090,12 +3803,8 @@ "name": "variable_set_value_variable_set_id_variable_set_id_fk", "tableFrom": "variable_set_value", "tableTo": "variable_set", - "columnsFrom": [ - "variable_set_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["variable_set_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4152,12 +3861,8 @@ "name": "workspace_invite_token_role_id_role_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4165,12 +3870,8 @@ "name": "workspace_invite_token_workspace_id_workspace_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4178,12 +3879,8 @@ "name": "workspace_invite_token_created_by_user_id_fk", "tableFrom": "workspace_invite_token", "tableTo": "user", - "columnsFrom": [ - "created_by" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["created_by"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4193,9 +3890,7 @@ "workspace_invite_token_token_unique": { "name": "workspace_invite_token_token_unique", "nullsNotDistinct": false, - "columns": [ - "token" - ] + "columns": ["token"] } } }, @@ -4248,12 +3943,8 @@ "name": "resource_metadata_group_workspace_id_workspace_id_fk", "tableFrom": "resource_metadata_group", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4339,12 +4030,8 @@ "name": "runbook_variable_runbook_id_runbook_id_fk", "tableFrom": "runbook_variable", "tableTo": "runbook", - "columnsFrom": [ - "runbook_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["runbook_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4442,12 +4129,8 @@ "name": "entity_role_role_id_role_id_fk", "tableFrom": "entity_role", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4491,12 +4174,8 @@ "name": "role_workspace_id_workspace_id_fk", "tableFrom": "role", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4556,12 +4235,8 @@ "name": "role_permission_role_id_role_id_fk", "tableFrom": "role_permission", "tableTo": "role", - "columnsFrom": [ - "role_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["role_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4634,12 +4309,8 @@ "name": "job_agent_workspace_id_workspace_id_fk", "tableFrom": "job_agent", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" } @@ -4726,12 +4397,8 @@ "name": "environment_policy_deployment_version_channel_policy_id_environment_policy_id_fk", "tableFrom": "environment_policy_deployment_version_channel", "tableTo": "environment_policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4739,12 +4406,8 @@ "name": "environment_policy_deployment_version_channel_channel_id_deployment_version_channel_id_fk", "tableFrom": "environment_policy_deployment_version_channel", "tableTo": "deployment_version_channel", - "columnsFrom": [ - "channel_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["channel_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4752,12 +4415,8 @@ "name": "environment_policy_deployment_version_channel_deployment_id_deployment_id_fk", "tableFrom": "environment_policy_deployment_version_channel", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4827,12 +4486,8 @@ "name": "release_job_trigger_job_id_job_id_fk", "tableFrom": "release_job_trigger", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -4840,12 +4495,8 @@ "name": "release_job_trigger_caused_by_id_user_id_fk", "tableFrom": "release_job_trigger", "tableTo": "user", - "columnsFrom": [ - "caused_by_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["caused_by_id"], + "columnsTo": ["id"], "onDelete": "no action", "onUpdate": "no action" }, @@ -4853,12 +4504,8 @@ "name": "release_job_trigger_deployment_version_id_deployment_version_id_fk", "tableFrom": "release_job_trigger", "tableTo": "deployment_version", - "columnsFrom": [ - "deployment_version_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_version_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4866,12 +4513,8 @@ "name": "release_job_trigger_resource_id_resource_id_fk", "tableFrom": "release_job_trigger", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -4879,12 +4522,8 @@ "name": "release_job_trigger_environment_id_environment_id_fk", "tableFrom": "release_job_trigger", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -4894,9 +4533,7 @@ "release_job_trigger_job_id_unique": { "name": "release_job_trigger_job_id_unique", "nullsNotDistinct": false, - "columns": [ - "job_id" - ] + "columns": ["job_id"] } } }, @@ -4957,12 +4594,8 @@ "name": "policy_workspace_id_workspace_id_fk", "tableFrom": "policy", "tableTo": "workspace", - "columnsFrom": [ - "workspace_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["workspace_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5026,12 +4659,8 @@ "name": "policy_rule_deny_window_policy_id_policy_id_fk", "tableFrom": "policy_rule_deny_window", "tableTo": "policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5077,12 +4706,8 @@ "name": "policy_target_policy_id_policy_id_fk", "tableFrom": "policy_target", "tableTo": "policy", - "columnsFrom": [ - "policy_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["policy_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5139,12 +4764,8 @@ "name": "release_version_id_deployment_version_id_fk", "tableFrom": "release", "tableTo": "deployment_version", - "columnsFrom": [ - "version_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["version_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -5152,12 +4773,8 @@ "name": "release_resource_id_resource_id_fk", "tableFrom": "release", "tableTo": "resource", - "columnsFrom": [ - "resource_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["resource_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -5165,12 +4782,8 @@ "name": "release_deployment_id_deployment_id_fk", "tableFrom": "release", "tableTo": "deployment", - "columnsFrom": [ - "deployment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["deployment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -5178,12 +4791,8 @@ "name": "release_environment_id_environment_id_fk", "tableFrom": "release", "tableTo": "environment", - "columnsFrom": [ - "environment_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["environment_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5228,12 +4837,8 @@ "name": "release_job_release_id_release_id_fk", "tableFrom": "release_job", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" }, @@ -5241,12 +4846,8 @@ "name": "release_job_job_id_job_id_fk", "tableFrom": "release_job", "tableTo": "job", - "columnsFrom": [ - "job_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["job_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5319,12 +4920,8 @@ "name": "release_variable_release_id_release_id_fk", "tableFrom": "release_variable", "tableTo": "release", - "columnsFrom": [ - "release_id" - ], - "columnsTo": [ - "id" - ], + "columnsFrom": ["release_id"], + "columnsTo": ["id"], "onDelete": "cascade", "onUpdate": "no action" } @@ -5337,79 +4934,47 @@ "public.system_role": { "name": "system_role", "schema": "public", - "values": [ - "user", - "admin" - ] + "values": ["user", "admin"] }, "public.deployment_version_status": { "name": "deployment_version_status", "schema": "public", - "values": [ - "building", - "ready", - "failed" - ] + "values": ["building", "ready", "failed"] }, "public.environment_policy_approval_requirement": { "name": "environment_policy_approval_requirement", "schema": "public", - "values": [ - "manual", - "automatic" - ] + "values": ["manual", "automatic"] }, "public.approval_status_type": { "name": "approval_status_type", "schema": "public", - "values": [ - "pending", - "approved", - "rejected" - ] + "values": ["pending", "approved", "rejected"] }, "public.environment_policy_deployment_success_type": { "name": "environment_policy_deployment_success_type", "schema": "public", - "values": [ - "all", - "some", - "optional" - ] + "values": ["all", "some", "optional"] }, "public.recurrence_type": { "name": "recurrence_type", "schema": "public", - "values": [ - "hourly", - "daily", - "weekly", - "monthly" - ] + "values": ["hourly", "daily", "weekly", "monthly"] }, "public.release_sequencing_type": { "name": "release_sequencing_type", "schema": "public", - "values": [ - "wait", - "cancel" - ] + "values": ["wait", "cancel"] }, "public.github_entity_type": { "name": "github_entity_type", "schema": "public", - "values": [ - "organization", - "user" - ] + "values": ["organization", "user"] }, "public.resource_relationship_type": { "name": "resource_relationship_type", "schema": "public", - "values": [ - "associated_with", - "depends_on" - ] + "values": ["associated_with", "depends_on"] }, "public.job_reason": { "name": "job_reason", @@ -5440,10 +5005,7 @@ "public.entity_type": { "name": "entity_type", "schema": "public", - "values": [ - "user", - "team" - ] + "values": ["user", "team"] }, "public.scope_type": { "name": "scope_type", @@ -5491,4 +5053,4 @@ "schemas": {}, "tables": {} } -} \ No newline at end of file +} diff --git a/packages/db/drizzle/meta/_journal.json b/packages/db/drizzle/meta/_journal.json index e74d8a792..88edbec0c 100644 --- a/packages/db/drizzle/meta/_journal.json +++ b/packages/db/drizzle/meta/_journal.json @@ -577,4 +577,4 @@ "breakpoints": true } ] -} \ No newline at end of file +} diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts index c2e112630..4bd860b0d 100644 --- a/packages/db/src/index.ts +++ b/packages/db/src/index.ts @@ -6,4 +6,4 @@ export { workspaceSchema, systemSchema, } from "./schema/index.js"; -export * from "./create-env.js"; +export * from "./upsert-env.js"; diff --git a/packages/db/src/create-env.ts b/packages/db/src/upsert-env.ts similarity index 55% rename from packages/db/src/create-env.ts rename to packages/db/src/upsert-env.ts index 5e2fa9170..764606d79 100644 --- a/packages/db/src/create-env.ts +++ b/packages/db/src/upsert-env.ts @@ -2,24 +2,36 @@ import type { z } from "zod"; import { eq } from "drizzle-orm"; import type { Tx } from "./common.js"; -import { takeFirst } from "./common.js"; +import { buildConflictUpdateColumns, takeFirst } from "./common.js"; import * as SCHEMA from "./schema/index.js"; import { environment, environmentPolicy } from "./schema/index.js"; -const createVersionChannels = ( +const upsertVersionChannels = ( db: Tx, policyId: string, deploymentVersionChannels: { channelId: string; deploymentId: string }[], ) => - db.insert(SCHEMA.environmentPolicyDeploymentVersionChannel).values( - deploymentVersionChannels.map(({ channelId, deploymentId }) => ({ - policyId, - channelId, - deploymentId, - })), - ); - -export const createEnv = async ( + db + .insert(SCHEMA.environmentPolicyDeploymentVersionChannel) + .values( + deploymentVersionChannels.map(({ channelId, deploymentId }) => ({ + policyId, + channelId, + deploymentId, + })), + ) + .onConflictDoUpdate({ + target: [ + SCHEMA.environmentPolicyDeploymentVersionChannel.policyId, + SCHEMA.environmentPolicyDeploymentVersionChannel.deploymentId, + ], + set: buildConflictUpdateColumns( + SCHEMA.environmentPolicyDeploymentVersionChannel, + ["channelId"], + ), + }); + +export const upsertEnv = async ( db: Tx, input: z.infer, ) => { @@ -35,6 +47,15 @@ export const createEnv = async ( const env = await db .insert(environment) .values({ ...input, policyId }) + .onConflictDoUpdate({ + target: [environment.name, environment.systemId], + set: buildConflictUpdateColumns(environment, [ + "description", + "directory", + "policyId", + "resourceSelector", + ]), + }) .returning() .then(takeFirst); @@ -48,7 +69,7 @@ export const createEnv = async ( ); if (versionChannels != null && versionChannels.length > 0) - await createVersionChannels(db, policyId, versionChannels); + await upsertVersionChannels(db, policyId, versionChannels); await db .update(environmentPolicy)