Database schema

This commit is contained in:
x032205
2025-12-04 15:06:12 -05:00
committed by =
parent 1269e7c245
commit 62cd45d0c5
12 changed files with 474 additions and 2 deletions

View File

@@ -571,7 +571,31 @@ import {
TWebhooksUpdate,
TWorkflowIntegrations,
TWorkflowIntegrationsInsert,
TWorkflowIntegrationsUpdate
TWorkflowIntegrationsUpdate,
TApprovalPolicies,
TApprovalPoliciesInsert,
TApprovalPoliciesUpdate,
TApprovalPolicyStepApprovers,
TApprovalPolicyStepApproversInsert,
TApprovalPolicyStepApproversUpdate,
TApprovalPolicySteps,
TApprovalPolicyStepsInsert,
TApprovalPolicyStepsUpdate,
TApprovalRequestApprovals,
TApprovalRequestApprovalsInsert,
TApprovalRequestApprovalsUpdate,
TApprovalRequestGrants,
TApprovalRequestGrantsInsert,
TApprovalRequestGrantsUpdate,
TApprovalRequestStepEligibleApprovers,
TApprovalRequestStepEligibleApproversInsert,
TApprovalRequestStepEligibleApproversUpdate,
TApprovalRequestSteps,
TApprovalRequestStepsInsert,
TApprovalRequestStepsUpdate,
TApprovalRequests,
TApprovalRequestsInsert,
TApprovalRequestsUpdate
} from "@app/db/schemas";
import {
TCertificateRequests,
@@ -1475,5 +1499,45 @@ declare module "knex/types/tables" {
TVaultExternalMigrationConfigsInsert,
TVaultExternalMigrationConfigsUpdate
>;
[TableName.ApprovalPolicies]: KnexOriginal.CompositeTableType<
TApprovalPolicies,
TApprovalPoliciesInsert,
TApprovalPoliciesUpdate
>;
[TableName.ApprovalPolicyStepApprovers]: KnexOriginal.CompositeTableType<
TApprovalPolicyStepApprovers,
TApprovalPolicyStepApproversInsert,
TApprovalPolicyStepApproversUpdate
>;
[TableName.ApprovalPolicySteps]: KnexOriginal.CompositeTableType<
TApprovalPolicySteps,
TApprovalPolicyStepsInsert,
TApprovalPolicyStepsUpdate
>;
[TableName.ApprovalRequestApprovals]: KnexOriginal.CompositeTableType<
TApprovalRequestApprovals,
TApprovalRequestApprovalsInsert,
TApprovalRequestApprovalsUpdate
>;
[TableName.ApprovalRequestGrants]: KnexOriginal.CompositeTableType<
TApprovalRequestGrants,
TApprovalRequestGrantsInsert,
TApprovalRequestGrantsUpdate
>;
[TableName.ApprovalRequestStepEligibleApprovers]: KnexOriginal.CompositeTableType<
TApprovalRequestStepEligibleApprovers,
TApprovalRequestStepEligibleApproversInsert,
TApprovalRequestStepEligibleApproversUpdate
>;
[TableName.ApprovalRequestSteps]: KnexOriginal.CompositeTableType<
TApprovalRequestSteps,
TApprovalRequestStepsInsert,
TApprovalRequestStepsUpdate
>;
[TableName.ApprovalRequests]: KnexOriginal.CompositeTableType<
TApprovalRequests,
TApprovalRequestsInsert,
TApprovalRequestsUpdate
>;
}
}

View File

@@ -0,0 +1,192 @@
import { Knex } from "knex";
import { TableName } from "../schemas";
import { createOnUpdateTrigger, dropOnUpdateTrigger } from "../utils";
export async function up(knex: Knex): Promise<void> {
if (!(await knex.schema.hasTable(TableName.ApprovalPolicies))) {
await knex.schema.createTable(TableName.ApprovalPolicies, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.string("projectId").notNullable().index();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.uuid("organizationId").notNullable().index();
t.foreign("organizationId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.string("type").notNullable().index();
t.string("name").notNullable();
t.boolean("isActive").defaultTo(true);
t.integer("maxRequestTtlSeconds").nullable();
t.jsonb("conditions").notNullable();
t.jsonb("constraints").notNullable();
t.timestamps(true, true, true);
});
await createOnUpdateTrigger(knex, TableName.ApprovalPolicies);
}
if (!(await knex.schema.hasTable(TableName.ApprovalPolicySteps))) {
await knex.schema.createTable(TableName.ApprovalPolicySteps, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("policyId").notNullable().index();
t.foreign("policyId").references("id").inTable(TableName.ApprovalPolicies).onDelete("CASCADE");
t.string("name").nullable();
t.integer("stepNumber").notNullable();
t.integer("requiredApprovals").notNullable();
t.boolean("notifyApprovers").defaultTo(false);
});
}
if (!(await knex.schema.hasTable(TableName.ApprovalPolicyStepApprovers))) {
await knex.schema.createTable(TableName.ApprovalPolicyStepApprovers, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("policyStepId").notNullable().index();
t.foreign("policyStepId").references("id").inTable(TableName.ApprovalPolicySteps).onDelete("CASCADE");
t.uuid("userId").nullable().index();
t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE");
t.uuid("groupId").nullable().index();
t.foreign("groupId").references("id").inTable(TableName.Groups).onDelete("CASCADE");
t.check('("userId" IS NOT NULL AND "groupId" IS NULL) OR ("userId" IS NULL AND "groupId" IS NOT NULL)');
});
}
if (!(await knex.schema.hasTable(TableName.ApprovalRequests))) {
await knex.schema.createTable(TableName.ApprovalRequests, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.string("projectId").notNullable().index();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.uuid("organizationId").notNullable().index();
t.foreign("organizationId").references("id").inTable(TableName.Organization).onDelete("CASCADE");
t.uuid("policyId").notNullable().index();
t.foreign("policyId").references("id").inTable(TableName.ApprovalPolicies).onDelete("CASCADE");
t.uuid("requesterId").notNullable().index();
t.foreign("requesterId").references("id").inTable(TableName.Users).onDelete("CASCADE");
// To be used in the event of requester deletion
t.string("requesterName").notNullable();
t.string("requesterEmail").notNullable();
t.string("type").notNullable().index();
t.string("status").notNullable().index();
t.text("justification").nullable();
t.integer("currentStep").notNullable();
t.jsonb("requestData").notNullable();
t.timestamp("expiresAt").nullable();
t.timestamps(true, true, true);
});
await createOnUpdateTrigger(knex, TableName.ApprovalRequests);
}
if (!(await knex.schema.hasTable(TableName.ApprovalRequestSteps))) {
await knex.schema.createTable(TableName.ApprovalRequestSteps, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("requestId").notNullable().index();
t.foreign("requestId").references("id").inTable(TableName.ApprovalRequests).onDelete("CASCADE");
t.integer("stepNumber").notNullable();
t.string("name").nullable();
t.string("status").notNullable().index();
t.integer("requiredApprovals").notNullable();
t.timestamp("startedAt").nullable();
t.timestamp("completedAt").nullable();
});
}
if (!(await knex.schema.hasTable(TableName.ApprovalRequestStepEligibleApprovers))) {
await knex.schema.createTable(TableName.ApprovalRequestStepEligibleApprovers, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("stepId").notNullable().index();
t.foreign("stepId").references("id").inTable(TableName.ApprovalRequestSteps).onDelete("CASCADE");
t.uuid("userId").nullable().index();
t.foreign("userId").references("id").inTable(TableName.Users).onDelete("CASCADE");
t.uuid("groupId").nullable().index();
t.foreign("groupId").references("id").inTable(TableName.Groups).onDelete("CASCADE");
t.check('("userId" IS NOT NULL AND "groupId" IS NULL) OR ("userId" IS NULL AND "groupId" IS NOT NULL)');
});
}
if (!(await knex.schema.hasTable(TableName.ApprovalRequestApprovals))) {
await knex.schema.createTable(TableName.ApprovalRequestApprovals, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.uuid("stepId").notNullable().index();
t.foreign("stepId").references("id").inTable(TableName.ApprovalRequestSteps).onDelete("CASCADE");
t.uuid("approverUserId").notNullable().index();
t.foreign("approverUserId").references("id").inTable(TableName.Users).onDelete("CASCADE");
t.string("decision").notNullable();
t.text("comment").nullable();
t.timestamp("createdAt").defaultTo(knex.fn.now());
});
}
if (!(await knex.schema.hasTable(TableName.ApprovalRequestGrants))) {
await knex.schema.createTable(TableName.ApprovalRequestGrants, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.string("projectId").notNullable().index();
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.uuid("requestId").notNullable().index();
t.foreign("requestId").references("id").inTable(TableName.ApprovalRequests).onDelete("CASCADE");
t.uuid("granteeUserId").notNullable().index();
t.foreign("granteeUserId").references("id").inTable(TableName.Users).onDelete("CASCADE");
t.uuid("revokedByUserId").nullable().index();
t.foreign("revokedByUserId").references("id").inTable(TableName.Users).onDelete("SET NULL");
t.text("revocationReason").nullable();
t.string("status").notNullable().index();
t.string("type").notNullable().index();
t.jsonb("attributes").notNullable();
t.timestamp("createdAt").defaultTo(knex.fn.now());
t.timestamp("expiresAt").nullable();
t.timestamp("revokedAt").nullable();
});
}
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.dropTableIfExists(TableName.ApprovalRequestGrants);
await knex.schema.dropTableIfExists(TableName.ApprovalRequestApprovals);
await knex.schema.dropTableIfExists(TableName.ApprovalRequestStepEligibleApprovers);
await knex.schema.dropTableIfExists(TableName.ApprovalRequestSteps);
await knex.schema.dropTableIfExists(TableName.ApprovalRequests);
await knex.schema.dropTableIfExists(TableName.ApprovalPolicyStepApprovers);
await knex.schema.dropTableIfExists(TableName.ApprovalPolicySteps);
await knex.schema.dropTableIfExists(TableName.ApprovalPolicies);
await dropOnUpdateTrigger(knex, TableName.ApprovalRequests);
await dropOnUpdateTrigger(knex, TableName.ApprovalPolicies);
}

View File

@@ -0,0 +1,26 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalPoliciesSchema = z.object({
id: z.string().uuid(),
projectId: z.string(),
organizationId: z.string().uuid(),
type: z.string(),
name: z.string(),
isActive: z.boolean().default(true).nullable().optional(),
maxRequestTtlSeconds: z.number().nullable().optional(),
conditions: z.unknown(),
constraints: z.unknown(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TApprovalPolicies = z.infer<typeof ApprovalPoliciesSchema>;
export type TApprovalPoliciesInsert = Omit<z.input<typeof ApprovalPoliciesSchema>, TImmutableDBKeys>;
export type TApprovalPoliciesUpdate = Partial<Omit<z.input<typeof ApprovalPoliciesSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,24 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalPolicyStepApproversSchema = z.object({
id: z.string().uuid(),
policyStepId: z.string().uuid(),
userId: z.string().uuid().nullable().optional(),
groupId: z.string().uuid().nullable().optional()
});
export type TApprovalPolicyStepApprovers = z.infer<typeof ApprovalPolicyStepApproversSchema>;
export type TApprovalPolicyStepApproversInsert = Omit<
z.input<typeof ApprovalPolicyStepApproversSchema>,
TImmutableDBKeys
>;
export type TApprovalPolicyStepApproversUpdate = Partial<
Omit<z.input<typeof ApprovalPolicyStepApproversSchema>, TImmutableDBKeys>
>;

View File

@@ -0,0 +1,21 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalPolicyStepsSchema = z.object({
id: z.string().uuid(),
policyId: z.string().uuid(),
name: z.string().nullable().optional(),
stepNumber: z.number(),
requiredApprovals: z.number(),
notifyApprovers: z.boolean().default(false).nullable().optional()
});
export type TApprovalPolicySteps = z.infer<typeof ApprovalPolicyStepsSchema>;
export type TApprovalPolicyStepsInsert = Omit<z.input<typeof ApprovalPolicyStepsSchema>, TImmutableDBKeys>;
export type TApprovalPolicyStepsUpdate = Partial<Omit<z.input<typeof ApprovalPolicyStepsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalRequestApprovalsSchema = z.object({
id: z.string().uuid(),
stepId: z.string().uuid(),
approverUserId: z.string().uuid(),
decision: z.string(),
comment: z.string().nullable().optional(),
createdAt: z.date().nullable().optional()
});
export type TApprovalRequestApprovals = z.infer<typeof ApprovalRequestApprovalsSchema>;
export type TApprovalRequestApprovalsInsert = Omit<z.input<typeof ApprovalRequestApprovalsSchema>, TImmutableDBKeys>;
export type TApprovalRequestApprovalsUpdate = Partial<
Omit<z.input<typeof ApprovalRequestApprovalsSchema>, TImmutableDBKeys>
>;

View File

@@ -0,0 +1,27 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalRequestGrantsSchema = z.object({
id: z.string().uuid(),
projectId: z.string(),
requestId: z.string().uuid(),
granteeUserId: z.string().uuid(),
revokedByUserId: z.string().uuid().nullable().optional(),
revocationReason: z.string().nullable().optional(),
status: z.string(),
type: z.string(),
attributes: z.unknown(),
createdAt: z.date().nullable().optional(),
expiresAt: z.date().nullable().optional(),
revokedAt: z.date().nullable().optional()
});
export type TApprovalRequestGrants = z.infer<typeof ApprovalRequestGrantsSchema>;
export type TApprovalRequestGrantsInsert = Omit<z.input<typeof ApprovalRequestGrantsSchema>, TImmutableDBKeys>;
export type TApprovalRequestGrantsUpdate = Partial<Omit<z.input<typeof ApprovalRequestGrantsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,24 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalRequestStepEligibleApproversSchema = z.object({
id: z.string().uuid(),
stepId: z.string().uuid(),
userId: z.string().uuid().nullable().optional(),
groupId: z.string().uuid().nullable().optional()
});
export type TApprovalRequestStepEligibleApprovers = z.infer<typeof ApprovalRequestStepEligibleApproversSchema>;
export type TApprovalRequestStepEligibleApproversInsert = Omit<
z.input<typeof ApprovalRequestStepEligibleApproversSchema>,
TImmutableDBKeys
>;
export type TApprovalRequestStepEligibleApproversUpdate = Partial<
Omit<z.input<typeof ApprovalRequestStepEligibleApproversSchema>, TImmutableDBKeys>
>;

View File

@@ -0,0 +1,23 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalRequestStepsSchema = z.object({
id: z.string().uuid(),
requestId: z.string().uuid(),
stepNumber: z.number(),
name: z.string().nullable().optional(),
status: z.string(),
requiredApprovals: z.number(),
startedAt: z.date().nullable().optional(),
completedAt: z.date().nullable().optional()
});
export type TApprovalRequestSteps = z.infer<typeof ApprovalRequestStepsSchema>;
export type TApprovalRequestStepsInsert = Omit<z.input<typeof ApprovalRequestStepsSchema>, TImmutableDBKeys>;
export type TApprovalRequestStepsUpdate = Partial<Omit<z.input<typeof ApprovalRequestStepsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,30 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const ApprovalRequestsSchema = z.object({
id: z.string().uuid(),
projectId: z.string(),
organizationId: z.string().uuid(),
policyId: z.string().uuid(),
requesterId: z.string().uuid(),
requesterName: z.string(),
requesterEmail: z.string(),
type: z.string(),
status: z.string(),
justification: z.string().nullable().optional(),
currentStep: z.number(),
requestData: z.unknown(),
expiresAt: z.date().nullable().optional(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TApprovalRequests = z.infer<typeof ApprovalRequestsSchema>;
export type TApprovalRequestsInsert = Omit<z.input<typeof ApprovalRequestsSchema>, TImmutableDBKeys>;
export type TApprovalRequestsUpdate = Partial<Omit<z.input<typeof ApprovalRequestsSchema>, TImmutableDBKeys>>;

View File

@@ -195,3 +195,11 @@ export * from "./users";
export * from "./vault-external-migration-configs";
export * from "./webhooks";
export * from "./workflow-integrations";
export * from "./approval-policies";
export * from "./approval-policy-step-approvers";
export * from "./approval-policy-steps";
export * from "./approval-request-approvals";
export * from "./approval-request-grants";
export * from "./approval-request-step-eligible-approvers";
export * from "./approval-request-steps";
export * from "./approval-requests";

View File

@@ -223,7 +223,17 @@ export enum TableName {
PkiAcmeOrder = "pki_acme_orders",
PkiAcmeOrderAuth = "pki_acme_order_auths",
PkiAcmeAuth = "pki_acme_auths",
PkiAcmeChallenge = "pki_acme_challenges"
PkiAcmeChallenge = "pki_acme_challenges",
// Approval Policies
ApprovalPolicies = "approval_policies",
ApprovalPolicySteps = "approval_policy_steps",
ApprovalPolicyStepApprovers = "approval_policy_step_approvers",
ApprovalRequests = "approval_requests",
ApprovalRequestSteps = "approval_request_steps",
ApprovalRequestStepEligibleApprovers = "approval_request_step_eligible_approvers",
ApprovalRequestApprovals = "approval_request_approvals",
ApprovalRequestGrants = "approval_request_grants"
}
export type TImmutableDBKeys = "id" | "createdAt" | "updatedAt" | "commitId";