diff --git a/prisma/migrations/20240306212205_add_convertibles/migration.sql b/prisma/migrations/20240306212205_add_convertibles/migration.sql new file mode 100644 index 000000000..82ad2548c --- /dev/null +++ b/prisma/migrations/20240306212205_add_convertibles/migration.sql @@ -0,0 +1,108 @@ +/* + Warnings: + + - You are about to drop the column `notes` on the `Option` table. All the data in the column will be lost. + - You are about to drop the column `notes` on the `Share` table. All the data in the column will be lost. + +*/ +-- CreateEnum +CREATE TYPE "SafeTypeEnum" AS ENUM ('PRE_MONEY', 'POST_MONEY', 'UNCAPPED'); + +-- CreateEnum +CREATE TYPE "SafeStatusEnum" AS ENUM ('DRAFT', 'ACTIVE', 'PENDING', 'EXPIRED', 'CANCELLED'); + +-- CreateEnum +CREATE TYPE "ConvertibleStatusEnum" AS ENUM ('DRAFT', 'ACTIVE', 'PENDING', 'EXPIRED', 'CANCELLED'); + +-- CreateEnum +CREATE TYPE "ConvertibleTypeEnum" AS ENUM ('CCD', 'OCD', 'NOTE'); + +-- CreateEnum +CREATE TYPE "ConvertibleInterestMethodEnum" AS ENUM ('SIMPLE', 'COMPOUND'); + +-- CreateEnum +CREATE TYPE "ConvertibleInterestAccrualEnum" AS ENUM ('DAILY', 'MONTHLY', 'SEMI_ANNUALLY', 'ANNUALLY', 'YEARLY', 'CONTINUOUSLY'); + +-- CreateEnum +CREATE TYPE "ConvertibleInterestPaymentScheduleEnum" AS ENUM ('DEFERRED', 'PAY_AT_MATURITY'); + +-- AlterTable +ALTER TABLE "Document" ADD COLUMN "convertibleNoteId" TEXT, +ADD COLUMN "safeId" TEXT; + +-- AlterTable +ALTER TABLE "Option" DROP COLUMN "notes"; + +-- AlterTable +ALTER TABLE "Share" DROP COLUMN "notes"; + +-- CreateTable +CREATE TABLE "Safe" ( + "id" TEXT NOT NULL, + "publicId" TEXT NOT NULL, + "type" "SafeTypeEnum" NOT NULL, + "status" "SafeStatusEnum" NOT NULL DEFAULT 'DRAFT', + "capital" DOUBLE PRECISION NOT NULL, + "valuationCap" DOUBLE PRECISION, + "discountRate" DOUBLE PRECISION, + "mfn" BOOLEAN, + "proRata" BOOLEAN, + "additionalTerms" TEXT, + "stakeholderId" TEXT NOT NULL, + "companyId" TEXT NOT NULL, + "issueDate" TIMESTAMP(3) NOT NULL, + "boardApprovalDate" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Safe_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "ConvertibleNote" ( + "id" TEXT NOT NULL, + "publicId" TEXT NOT NULL, + "status" "ConvertibleStatusEnum" NOT NULL DEFAULT 'DRAFT', + "type" "ConvertibleTypeEnum" NOT NULL DEFAULT 'NOTE', + "capital" DOUBLE PRECISION NOT NULL, + "conversionCap" DOUBLE PRECISION, + "discountRate" DOUBLE PRECISION, + "mfn" BOOLEAN, + "additionalTerms" TEXT, + "interestRate" DOUBLE PRECISION, + "interestMethod" "ConvertibleInterestMethodEnum", + "interestAccrual" "ConvertibleInterestAccrualEnum", + "interestPaymentSchedule" "ConvertibleInterestPaymentScheduleEnum", + "stakeholderId" TEXT NOT NULL, + "companyId" TEXT NOT NULL, + "issueDate" TIMESTAMP(3) NOT NULL, + "boardApprovalDate" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "ConvertibleNote_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "Safe_companyId_idx" ON "Safe"("companyId"); + +-- CreateIndex +CREATE INDEX "Safe_stakeholderId_idx" ON "Safe"("stakeholderId"); + +-- CreateIndex +CREATE UNIQUE INDEX "Safe_publicId_companyId_key" ON "Safe"("publicId", "companyId"); + +-- CreateIndex +CREATE INDEX "ConvertibleNote_companyId_idx" ON "ConvertibleNote"("companyId"); + +-- CreateIndex +CREATE INDEX "ConvertibleNote_stakeholderId_idx" ON "ConvertibleNote"("stakeholderId"); + +-- CreateIndex +CREATE UNIQUE INDEX "ConvertibleNote_publicId_companyId_key" ON "ConvertibleNote"("publicId", "companyId"); + +-- CreateIndex +CREATE INDEX "Document_safeId_idx" ON "Document"("safeId"); + +-- CreateIndex +CREATE INDEX "Document_convertibleNoteId_idx" ON "Document"("convertibleNoteId"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e233640b6..8eab4ea8f 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -81,18 +81,20 @@ model Company { state String zipcode String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - users Member[] - audits Audit[] - shareClasses ShareClass[] - equityPlans EquityPlan[] - documents Document[] - templates Template[] - stakeholders Stakeholder[] - investments Investment[] - shares Share[] - options Option[] + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + users Member[] + audits Audit[] + shareClasses ShareClass[] + equityPlans EquityPlan[] + documents Document[] + templates Template[] + stakeholders Stakeholder[] + investments Investment[] + shares Share[] + options Option[] + safes Safe[] + convertibleNotes ConvertibleNote[] @@unique([publicId]) } @@ -167,9 +169,11 @@ model Stakeholder { companyId String company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) - investments Investment[] - shares Share[] - options Option[] + investments Investment[] + shares Share[] + options Option[] + safes Safe[] + convertibleNotes ConvertibleNote[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -177,31 +181,6 @@ model Stakeholder { @@index([companyId]) } -model Investment { - id String @id @default(cuid()) - amount Float // Amount of money invested - shares BigInt // Number of shares issued to the investor at the time of investment - date DateTime - comments String? - - shareClassId String - shareClass ShareClass @relation(fields: [shareClassId], references: [id], onDelete: Cascade) - - companyId String - company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) - - // Investors => StakeholderRelationshipEnum["INVESTOR"] - stakeholderId String - stakeholder Stakeholder @relation(fields: [stakeholderId], references: [id], onDelete: Cascade) - - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - - @@index([companyId]) - @@index([stakeholderId]) - @@index([shareClassId]) -} - model Audit { id String @id @default(cuid()) companyId String @@ -332,6 +311,12 @@ model Document { optionId String? option Option? @relation(fields: [optionId], references: [id], onDelete: SetNull) + safeId String? + safe Safe? @relation(fields: [safeId], references: [id], onDelete: SetNull) + + convertibleNoteId String? + convertibleNote ConvertibleNote? @relation(fields: [convertibleNoteId], references: [id], onDelete: SetNull) + createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@ -341,6 +326,8 @@ model Document { @@index([companyId]) @@index([shareId]) @@index([optionId]) + @@index([safeId]) + @@index([convertibleNoteId]) } enum FieldTypes { @@ -452,7 +439,6 @@ enum ShareLegendsEnum { model Share { id String @id @default(cuid()) status SecuritiesStatusEnum @default(DRAFT) - notes String? certificateId String quantity Int // Number of shares @@ -504,8 +490,7 @@ enum OptionStatusEnum { } model Option { - id String @id @default(cuid()) - notes String? + id String @id @default(cuid()) quantity Int exercisePrice Float @@ -537,3 +522,141 @@ model Option { @@index([equityPlanId]) @@index([stakeholderId]) } + +model Investment { + id String @id @default(cuid()) + amount Float // Amount of money invested + shares BigInt // Number of shares issued to the investor at the time of investment + date DateTime + comments String? + + shareClassId String + shareClass ShareClass @relation(fields: [shareClassId], references: [id], onDelete: Cascade) + + companyId String + company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) + + // Investors => StakeholderRelationshipEnum["INVESTOR"] + stakeholderId String + stakeholder Stakeholder @relation(fields: [stakeholderId], references: [id], onDelete: Cascade) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@index([companyId]) + @@index([stakeholderId]) + @@index([shareClassId]) +} + +enum SafeTypeEnum { + PRE_MONEY + POST_MONEY + UNCAPPED +} + +enum SafeStatusEnum { + DRAFT + ACTIVE + PENDING + EXPIRED + CANCELLED +} + +model Safe { + id String @id @default(cuid()) + publicId String // eg. SAFE-01 + type SafeTypeEnum + status SafeStatusEnum @default(DRAFT) + capital Float // Amount of money invested + + valuationCap Float? + discountRate Float? + mfn Boolean? // Most Favored Nation + proRata Boolean? // Pro Rata Rights + additionalTerms String? + + documents Document[] + + stakeholderId String + stakeholder Stakeholder @relation(fields: [stakeholderId], references: [id], onDelete: Cascade) + + companyId String + company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) + + issueDate DateTime + boardApprovalDate DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@unique([publicId, companyId]) + @@index([companyId]) + @@index([stakeholderId]) +} + +enum ConvertibleStatusEnum { + DRAFT + ACTIVE + PENDING + EXPIRED + CANCELLED +} + +enum ConvertibleTypeEnum { + CCD // Compulsory Convertible Debenture + OCD // Optionally Convertible Debenture + NOTE // Simple Convertible note +} + +enum ConvertibleInterestMethodEnum { + SIMPLE + COMPOUND +} + +enum ConvertibleInterestAccrualEnum { + DAILY + MONTHLY + SEMI_ANNUALLY + ANNUALLY + YEARLY + CONTINUOUSLY +} + +enum ConvertibleInterestPaymentScheduleEnum { + DEFERRED + PAY_AT_MATURITY +} + +model ConvertibleNote { + id String @id @default(cuid()) + publicId String // eg. CN-01 + status ConvertibleStatusEnum @default(DRAFT) + type ConvertibleTypeEnum @default(NOTE) + capital Float // Amount of money invested + + conversionCap Float? + discountRate Float? + mfn Boolean? // Most Favored Nation + additionalTerms String? + + interestRate Float? + interestMethod ConvertibleInterestMethodEnum? + interestAccrual ConvertibleInterestAccrualEnum? + interestPaymentSchedule ConvertibleInterestPaymentScheduleEnum? + + documents Document[] + + stakeholderId String + stakeholder Stakeholder @relation(fields: [stakeholderId], references: [id], onDelete: Cascade) + + companyId String + company Company @relation(fields: [companyId], references: [id], onDelete: Cascade) + + issueDate DateTime + boardApprovalDate DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@unique([publicId, companyId]) + @@index([companyId]) + @@index([stakeholderId]) +}