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

feat: create schema for convertibles (SAFE & Convertible notes) #176

Merged
merged 2 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions prisma/migrations/20240306212205_add_convertibles/migration.sql
Original file line number Diff line number Diff line change
@@ -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");
209 changes: 166 additions & 43 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
Expand Down Expand Up @@ -167,41 +169,18 @@ 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

@@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
Expand Down Expand Up @@ -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

Expand All @@ -341,6 +326,8 @@ model Document {
@@index([companyId])
@@index([shareId])
@@index([optionId])
@@index([safeId])
@@index([convertibleNoteId])
}

enum FieldTypes {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -504,8 +490,7 @@ enum OptionStatusEnum {
}

model Option {
id String @id @default(cuid())
notes String?
id String @id @default(cuid())
quantity Int
exercisePrice Float

Expand Down Expand Up @@ -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])
}
Loading