diff --git a/prisma/migrations/20260619131445_vesting_cliff_in_months/migration.sql b/prisma/migrations/20260619131445_vesting_cliff_in_months/migration.sql new file mode 100644 index 000000000..62ae4769a --- /dev/null +++ b/prisma/migrations/20260619131445_vesting_cliff_in_months/migration.sql @@ -0,0 +1,20 @@ +/* + Vesting and cliff durations are now expressed in MONTHS instead of years. + + - Rename "vestingYears" -> "vestingMonths" and "cliffYears" -> "cliffMonths" + on the "Share" and "Option" tables. + - Convert existing values from years to months by multiplying by 12 + (e.g. a 4-year / 1-year-cliff grant becomes 48 / 12 months). +*/ + +-- AlterTable +ALTER TABLE "Share" RENAME COLUMN "vestingYears" TO "vestingMonths"; +ALTER TABLE "Share" RENAME COLUMN "cliffYears" TO "cliffMonths"; + +-- AlterTable +ALTER TABLE "Option" RENAME COLUMN "vestingYears" TO "vestingMonths"; +ALTER TABLE "Option" RENAME COLUMN "cliffYears" TO "cliffMonths"; + +-- Convert existing durations from years to months +UPDATE "Share" SET "vestingMonths" = "vestingMonths" * 12, "cliffMonths" = "cliffMonths" * 12; +UPDATE "Option" SET "vestingMonths" = "vestingMonths" * 12, "cliffMonths" = "cliffMonths" * 12; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7a2c88460..d4762b8a6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -690,8 +690,8 @@ model Share { debtCancelled Float? // Amount of debt cancelled otherContributions Float? // Other contributions - cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year - vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year + cliffMonths Int @default(0) // vesting cliff in months; 0 means immediate vesting + vestingMonths Int @default(0) // total vesting period in months; 0 means immediate vesting companyLegends ShareLegendsEnum[] @default([]) @@ -742,8 +742,8 @@ model Option { type OptionTypeEnum status OptionStatusEnum @default(DRAFT) - cliffYears Int @default(0) // 0 means immediate vesting, 1 means vesting starts after 1 year - vestingYears Int @default(0) // 0 means immediate vesting, 1 means vesting over 1 year + cliffMonths Int @default(0) // vesting cliff in months; 0 means immediate vesting + vestingMonths Int @default(0) // total vesting period in months; 0 means immediate vesting issueDate DateTime expirationDate DateTime diff --git a/src/components/securities/options/steps/vesting-details.tsx b/src/components/securities/options/steps/vesting-details.tsx index 969d826ee..48085d85c 100644 --- a/src/components/securities/options/steps/vesting-details.tsx +++ b/src/components/securities/options/steps/vesting-details.tsx @@ -32,8 +32,8 @@ import { EmptySelect } from "../../shared/EmptySelect"; const formSchema = z.object({ equityPlanId: z.string(), - cliffYears: z.coerce.number().min(0), - vestingYears: z.coerce.number().min(0), + cliffMonths: z.coerce.number().min(0), + vestingMonths: z.coerce.number().min(0), exercisePrice: z.coerce.number(), stakeholderId: z.string(), }); @@ -85,7 +85,7 @@ export const VestingDetails = (props: VestingDetailsProps) => {