Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement signing field groups and assigned groups #273

Merged
merged 12 commits into from
Feb 9, 2025
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
Warnings:

- You are about to drop the `Signature` table. If the table is not empty, all the data it contains will be lost.
- You are about to drop the `SignatureField` table. If the table is not empty, all the data it contains will be lost.

*/
-- CreateEnum
CREATE TYPE "SignatureBoxFieldType" AS ENUM ('SIGNATURE', 'CHECKBOX', 'TEXT_FIELD');

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_employeeId_fkey";

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_formInstanceId_fkey";

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_signerDepartmentId_fkey";

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_signerEmployeeId_fkey";

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_signerPositionId_fkey";

-- DropForeignKey
ALTER TABLE "Signature" DROP CONSTRAINT "Signature_signingEmployeeId_fkey";

-- DropForeignKey
ALTER TABLE "SignatureField" DROP CONSTRAINT "SignatureField_formTemplateId_fkey";

-- DropForeignKey
ALTER TABLE "_signerEmployeeList" DROP CONSTRAINT "_signerEmployeeList_A_fkey";

-- DropForeignKey
ALTER TABLE "_signerEmployeeList" DROP CONSTRAINT "_signerEmployeeList_B_fkey";

-- DropTable
DROP TABLE "Signature";

-- DropTable
DROP TABLE "SignatureField";

-- CreateTable
CREATE TABLE "FieldGroup" (
"id" UUID NOT NULL,
"name" VARCHAR(255) NOT NULL,
"order" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"formTemplateId" UUID NOT NULL,

CONSTRAINT "FieldGroup_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "TemplateBox" (
"id" UUID NOT NULL,
"type" "SignatureBoxFieldType" NOT NULL,
"x_coordinate" INTEGER NOT NULL,
"y_coordinate" INTEGER NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"fieldGroupId" UUID NOT NULL,

CONSTRAINT "TemplateBox_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "AssignedGroup" (
"id" UUID NOT NULL,
"order" INTEGER NOT NULL,
"signed" BOOLEAN NOT NULL DEFAULT false,
"signedDocLink" VARCHAR(255),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"signerPositionId" UUID,
"signerDepartmentId" UUID,
"signerEmployeeId" UUID,
"signingEmployeeId" UUID,
"signerType" "SignerType" NOT NULL,
"formInstanceId" UUID NOT NULL,
"fieldGroupId" UUID NOT NULL,

CONSTRAINT "AssignedGroup_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "InstanceBox" (
"id" UUID NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
"assignedGroupId" UUID NOT NULL,
"templateBoxId" UUID NOT NULL,

CONSTRAINT "InstanceBox_pkey" PRIMARY KEY ("id")
);

-- AddForeignKey
ALTER TABLE "FieldGroup" ADD CONSTRAINT "FieldGroup_formTemplateId_fkey" FOREIGN KEY ("formTemplateId") REFERENCES "FormTemplate"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "TemplateBox" ADD CONSTRAINT "TemplateBox_fieldGroupId_fkey" FOREIGN KEY ("fieldGroupId") REFERENCES "FieldGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_signerPositionId_fkey" FOREIGN KEY ("signerPositionId") REFERENCES "Position"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_signerDepartmentId_fkey" FOREIGN KEY ("signerDepartmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_signerEmployeeId_fkey" FOREIGN KEY ("signerEmployeeId") REFERENCES "Employee"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_signingEmployeeId_fkey" FOREIGN KEY ("signingEmployeeId") REFERENCES "Employee"("id") ON DELETE SET NULL ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_formInstanceId_fkey" FOREIGN KEY ("formInstanceId") REFERENCES "FormInstance"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "AssignedGroup" ADD CONSTRAINT "AssignedGroup_fieldGroupId_fkey" FOREIGN KEY ("fieldGroupId") REFERENCES "FieldGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "InstanceBox" ADD CONSTRAINT "InstanceBox_assignedGroupId_fkey" FOREIGN KEY ("assignedGroupId") REFERENCES "AssignedGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "InstanceBox" ADD CONSTRAINT "InstanceBox_templateBoxId_fkey" FOREIGN KEY ("templateBoxId") REFERENCES "TemplateBox"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_signerEmployeeList" ADD CONSTRAINT "_signerEmployeeList_A_fkey" FOREIGN KEY ("A") REFERENCES "AssignedGroup"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_signerEmployeeList" ADD CONSTRAINT "_signerEmployeeList_B_fkey" FOREIGN KEY ("B") REFERENCES "Employee"("id") ON DELETE CASCADE ON UPDATE CASCADE;
191 changes: 117 additions & 74 deletions apps/server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ enum SignerType {
USER_LIST
}

enum SignatureBoxFieldType {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Text box?

SIGNATURE
CHECKBOX
TEXT_FIELD
}

enum EmployeeScope {
BASE_USER
ADMIN
Expand All @@ -30,36 +36,11 @@ model Department {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

signatures Signature[]
assignedGroups AssignedGroup[]

positions Position[]
}

// `Employees` represent the people who work at the MFA.
//
// Each `Employee` corresponds to a user who holds a certain position.
model Employee {
id String @id @default(uuid()) @db.Uuid
firstName String @db.VarChar(255)
lastName String @db.VarChar(255)
email String @unique @db.VarChar(255)
signatureLink String @db.VarChar(255)
scope EmployeeScope @default(BASE_USER)
pswdHash String? @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
refreshToken String? @db.Text()

originatedForms FormInstance[]

position Position @relation(fields: [positionId], references: [id])
positionId String @db.Uuid

signerEmployeeSignatures Signature[] @relation("signerEmployee")
signerEmployeeListSignatures Signature[] @relation("signerEmployeeList")
signingEmployeeSignatures Signature[] @relation("signingEmployee")
}

// `Positions` represent the various positions that employees at the MFA can hold.
model Position {
id String @id @default(uuid()) @db.Uuid
Expand All @@ -68,34 +49,119 @@ model Position {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

signatures Signature[]
employees Employee[]
assignedGroups AssignedGroup[]
employees Employee[]

department Department @relation(fields: [departmentId], references: [id])
departmentId String @db.Uuid

@@unique([name, departmentId])
}

// `SignatureFields` represent each signature field that is required on a given form.
// A field may have a position specified, indicating that when a user creates an
// instance of the corresponding form, the field should default to the specified position.
// `Employees` represent the people who work at the MFA.
//
// Each `Employee` corresponds to a user who holds a certain position.
model Employee {
id String @id @default(uuid()) @db.Uuid
firstName String @db.VarChar(255)
lastName String @db.VarChar(255)
email String @unique @db.VarChar(255)
signatureLink String @db.VarChar(255)
scope EmployeeScope @default(BASE_USER)
pswdHash String? @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
refreshToken String? @db.Text()

originatedForms FormInstance[]

position Position @relation(fields: [positionId], references: [id])
positionId String @db.Uuid

signerEmployeeAssignedGroups AssignedGroup[] @relation("signerEmployee")
signerEmployeeListAssignedGroups AssignedGroup[] @relation("signerEmployeeList")
signingEmployeeAssignedGroup AssignedGroup[] @relation("signingEmployee")
}

// A `FormTemplate` is a reference for a form that is used when creating forms initiated by users.
model FormTemplate {
id String @id @default(uuid()) @db.Uuid
name String @db.VarChar(255)
formDocLink String @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

fieldGroups FieldGroup[]
formInstances FormInstance[]
}

// `FieldGroups` represent a group of signature fields to be assigned together
// that are required on a given form.
// When new form instances are created, new `AssignedGroups` are also created
// based on the `FieldGroups` found on a form template.
//
// Each `SignatureField` also specifies its order on the form it is on.
// `SignatureFields` are used as subdocuments within `FormTemplates`.
model SignatureField {
// Each `FieldGroup` also specifies its order on the form it is on.
// `FieldGroups` are within `FormTemplates`.
model FieldGroup {
id String @id @default(uuid()) @db.Uuid
name String @db.VarChar(255)
order Int @db.Integer
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

formTemplate FormTemplate @relation(fields: [formTemplateId], references: [id])
formTemplateId String @db.Uuid
templateBoxes TemplateBox[]
assignedGroups AssignedGroup[]
}

// `TemplateBox` represent the actual signature boxes that are to be filled by the employees.
model TemplateBox {
id String @id @default(uuid()) @db.Uuid
type SignatureBoxFieldType
x_coordinate Int @db.Integer
y_coordinate Int @db.Integer
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

fieldGroup FieldGroup @relation(fields: [fieldGroupId], references: [id])
fieldGroupId String @db.Uuid
InstanceBox InstanceBox[]
}

// `FormInstances` represent instances of forms created by employees.
//
// They are created based on a given `FormTemplate`, and contain a
// list of `Signatures` that are to be filled by the requested employees.
//
// A `FormInstance` should be marked completed when all of its signatures
// have been collected and marked as completed.
model FormInstance {
id String @id @default(uuid()) @db.Uuid
name String @db.VarChar(255)
formDocLink String @db.VarChar(255)
completed Boolean @default(false)
markedCompleted Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
markedCompletedAt DateTime?

assignedGroups AssignedGroup[]

originator Employee @relation(fields: [originatorId], references: [id])
originatorId String @db.Uuid
formTemplate FormTemplate @relation(fields: [formTemplateId], references: [id])
formTemplateId String @db.Uuid
}

// `Signatures` represent the signatures required on a form. Each signature has a
// specified signer and its corresponding status which indicates if it has been signed.
// `AssignedGroups` represent groups of signatures required on a form to be signed by a
// specific employee, position, department, or an employee from a list. Each `AssignedGroup` has a
// corresponding status which indicates if it has been signed.
//
// `AssignedGroups` are derived from `FieldGroups` on a `FormTemplate` and are
// created when a new form instance is created. Each `AssignedGroup` has corresponding `InstanceBoxes`
// which are the actual signature boxes that are to be filled by the employees.
//
// A `Signature` will also carry over its order from the original `FormTemplate` order
// from which the `FormInstance` that the `Signature` belongs to was derived. If a `Signature`
Expand All @@ -104,7 +170,7 @@ model SignatureField {
//
// The signer position and the user signed by are populated when the signature has been
// completed, and are derived from the person who signed at that moment in time.
model Signature {
model AssignedGroup {
id String @id @default(uuid()) @db.Uuid
order Int @db.Integer
signed Boolean @default(false)
Expand All @@ -123,44 +189,21 @@ model Signature {
signingEmployeeId String? @db.Uuid
signerType SignerType

formInstance FormInstance @relation(fields: [formInstanceId], references: [id])
formInstanceId String @db.Uuid
}

// `FormInstances` represent instances of forms created by employees.
//
// They are created based on a given `FormTemplate`, and contain a
// list of `Signatures` that are to be filled by the requested employees.
//
// A `FormInstance` should be marked completed when all of its signatures
// have been collected and marked as completed.
model FormInstance {
id String @id @default(uuid()) @db.Uuid
name String @db.VarChar(255)
formDocLink String @db.VarChar(255)
completed Boolean @default(false)
markedCompleted Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
markedCompletedAt DateTime?

signatures Signature[]

originator Employee @relation(fields: [originatorId], references: [id])
originatorId String @db.Uuid
formTemplate FormTemplate @relation(fields: [formTemplateId], references: [id])
formTemplateId String @db.Uuid
formInstance FormInstance @relation(fields: [formInstanceId], references: [id])
formInstanceId String @db.Uuid
instanceBoxes InstanceBox[]
fieldGroup FieldGroup @relation(fields: [fieldGroupId], references: [id])
fieldGroupId String @db.Uuid
}

// A `FormTemplate` is a reference for a form that is used when creating forms initiated by users.
model FormTemplate {
id String @id @default(uuid()) @db.Uuid
name String @db.VarChar(255)
formDocLink String @db.VarChar(255)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// `InstanceBox` represent the signature boxes on an instantiated form that are to be filled by the employees.
model InstanceBox {
id String @id @default(uuid()) @db.Uuid
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt

signatureFields SignatureField[]
formInstances FormInstance[]
assignedGroup AssignedGroup @relation(fields: [assignedGroupId], references: [id])
assignedGroupId String @db.Uuid
templateBox TemplateBox @relation(fields: [templateBoxId], references: [id])
templateBoxId String @db.Uuid
}
Loading