add subscription upgrade plan
Build & Push / Pipeline Tests (push) Failing after 2m0s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 53s
Test / API Unit Tests (push) Successful in 1m8s
Test / Homepage Unit Tests (push) Successful in 48s
Test / Carplace Unit Tests (push) Successful in 42s
Test / Admin Unit Tests (push) Successful in 41s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Failing after 1m7s
Build & Push / Pipeline Tests (push) Failing after 2m0s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 53s
Test / API Unit Tests (push) Successful in 1m8s
Test / Homepage Unit Tests (push) Successful in 48s
Test / Carplace Unit Tests (push) Successful in 42s
Test / Admin Unit Tests (push) Successful in 41s
Test / Dashboard Unit Tests (push) Successful in 43s
Test / API Integration Tests (push) Failing after 1m7s
This commit is contained in:
+179
@@ -0,0 +1,179 @@
|
||||
CREATE TYPE "SubscriptionUpgradeRequestType" AS ENUM (
|
||||
'IMMEDIATE_PRORATED',
|
||||
'AT_RENEWAL',
|
||||
'TERM_RESET'
|
||||
);
|
||||
|
||||
CREATE TYPE "SubscriptionUpgradeRequestStatus" AS ENUM (
|
||||
'DRAFT',
|
||||
'QUOTED',
|
||||
'PAYMENT_PENDING',
|
||||
'PAYMENT_REVIEW',
|
||||
'CORRECTION_REQUIRED',
|
||||
'APPROVED',
|
||||
'ACTIVATED',
|
||||
'SCHEDULED',
|
||||
'REJECTED',
|
||||
'EXPIRED',
|
||||
'CANCELLED',
|
||||
'ACTIVATION_FAILED',
|
||||
'SUPERSEDED'
|
||||
);
|
||||
|
||||
CREATE TABLE "subscription_upgrade_requests" (
|
||||
"id" TEXT NOT NULL,
|
||||
"companyId" TEXT NOT NULL,
|
||||
"subscriptionId" TEXT NOT NULL,
|
||||
"requestType" "SubscriptionUpgradeRequestType" NOT NULL,
|
||||
"fromPlan" "Plan" NOT NULL,
|
||||
"fromBillingPeriod" "BillingPeriod" NOT NULL,
|
||||
"toPlan" "Plan" NOT NULL,
|
||||
"toBillingPeriod" "BillingPeriod" NOT NULL,
|
||||
"status" "SubscriptionUpgradeRequestStatus" NOT NULL DEFAULT 'DRAFT',
|
||||
"requestedByEmployeeId" TEXT NOT NULL,
|
||||
"requestedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"effectiveAt" TIMESTAMP(3),
|
||||
"scheduledFor" TIMESTAMP(3),
|
||||
"quoteId" TEXT,
|
||||
"companyLanguageSnapshot" TEXT NOT NULL DEFAULT 'en',
|
||||
"billingTimezoneSnapshot" TEXT NOT NULL DEFAULT 'Africa/Casablanca',
|
||||
"acceptedTermsVersion" TEXT,
|
||||
"acceptedAt" TIMESTAMP(3),
|
||||
"cancelledAt" TIMESTAMP(3),
|
||||
"cancelledByEmployeeId" TEXT,
|
||||
"cancellationReason" TEXT,
|
||||
"expiresAt" TIMESTAMP(3),
|
||||
"billingInvoiceId" TEXT,
|
||||
"approvedPaymentAttemptId" TEXT,
|
||||
"approvedByAdminId" TEXT,
|
||||
"approvedAt" TIMESTAMP(3),
|
||||
"activationKey" TEXT,
|
||||
"activatedAt" TIMESTAMP(3),
|
||||
"rejectionReason" TEXT,
|
||||
"correctionReason" TEXT,
|
||||
"version" INTEGER NOT NULL DEFAULT 1,
|
||||
"metadata" JSONB NOT NULL DEFAULT '{}',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "subscription_upgrade_requests_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "subscription_upgrade_quotes" (
|
||||
"id" TEXT NOT NULL,
|
||||
"upgradeRequestId" TEXT NOT NULL,
|
||||
"currency" TEXT NOT NULL DEFAULT 'MAD',
|
||||
"currentEligibleNetTermPrice" INTEGER NOT NULL,
|
||||
"targetNetTermPrice" INTEGER NOT NULL,
|
||||
"termStart" TIMESTAMP(3) NOT NULL,
|
||||
"renewalDate" TIMESTAMP(3) NOT NULL,
|
||||
"pricingEffectiveAt" TIMESTAMP(3) NOT NULL,
|
||||
"termDays" INTEGER NOT NULL,
|
||||
"remainingDays" INTEGER NOT NULL,
|
||||
"prorationNumerator" INTEGER NOT NULL,
|
||||
"prorationDenominator" INTEGER NOT NULL,
|
||||
"currentCredit" INTEGER NOT NULL,
|
||||
"targetRemainingValue" INTEGER NOT NULL,
|
||||
"discountAmount" INTEGER NOT NULL DEFAULT 0,
|
||||
"taxAmount" INTEGER NOT NULL DEFAULT 0,
|
||||
"feeAmount" INTEGER NOT NULL DEFAULT 0,
|
||||
"subtotalAmount" INTEGER NOT NULL,
|
||||
"totalAmount" INTEGER NOT NULL,
|
||||
"calculationVersion" TEXT NOT NULL,
|
||||
"inputSnapshot" JSONB NOT NULL DEFAULT '{}',
|
||||
"integrityHash" TEXT NOT NULL,
|
||||
"expiresAt" TIMESTAMP(3) NOT NULL,
|
||||
"expiredAt" TIMESTAMP(3),
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "subscription_upgrade_quotes_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "subscription_plan_history" (
|
||||
"id" TEXT NOT NULL,
|
||||
"subscriptionId" TEXT NOT NULL,
|
||||
"companyId" TEXT NOT NULL,
|
||||
"previousPlan" "Plan" NOT NULL,
|
||||
"previousBillingPeriod" "BillingPeriod" NOT NULL,
|
||||
"newPlan" "Plan" NOT NULL,
|
||||
"newBillingPeriod" "BillingPeriod" NOT NULL,
|
||||
"changeType" TEXT NOT NULL,
|
||||
"sourceUpgradeRequestId" TEXT,
|
||||
"approvedPaymentAttemptId" TEXT,
|
||||
"effectiveAt" TIMESTAMP(3) NOT NULL,
|
||||
"previousTermStart" TIMESTAMP(3),
|
||||
"previousTermEnd" TIMESTAMP(3),
|
||||
"newTermStart" TIMESTAMP(3),
|
||||
"newTermEnd" TIMESTAMP(3),
|
||||
"actorType" TEXT NOT NULL,
|
||||
"actorId" TEXT,
|
||||
"approvingAdminId" TEXT,
|
||||
"entitlementSnapshot" JSONB NOT NULL DEFAULT '{}',
|
||||
"auditCorrelationId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "subscription_plan_history_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "subscription_upgrade_requests_quoteId_key" ON "subscription_upgrade_requests"("quoteId");
|
||||
CREATE UNIQUE INDEX "subscription_upgrade_requests_billingInvoiceId_key" ON "subscription_upgrade_requests"("billingInvoiceId");
|
||||
CREATE UNIQUE INDEX "subscription_upgrade_requests_activationKey_key" ON "subscription_upgrade_requests"("activationKey");
|
||||
CREATE UNIQUE INDEX "subscription_plan_history_sourceUpgradeRequestId_key" ON "subscription_plan_history"("sourceUpgradeRequestId");
|
||||
CREATE INDEX "subscription_upgrade_requests_companyId_status_idx" ON "subscription_upgrade_requests"("companyId", "status");
|
||||
CREATE INDEX "subscription_upgrade_requests_subscriptionId_status_idx" ON "subscription_upgrade_requests"("subscriptionId", "status");
|
||||
CREATE INDEX "subscription_upgrade_requests_expiresAt_idx" ON "subscription_upgrade_requests"("expiresAt");
|
||||
CREATE INDEX "subscription_upgrade_requests_scheduledFor_idx" ON "subscription_upgrade_requests"("scheduledFor");
|
||||
CREATE INDEX "subscription_upgrade_quotes_upgradeRequestId_idx" ON "subscription_upgrade_quotes"("upgradeRequestId");
|
||||
CREATE INDEX "subscription_upgrade_quotes_expiresAt_idx" ON "subscription_upgrade_quotes"("expiresAt");
|
||||
CREATE INDEX "subscription_plan_history_subscriptionId_idx" ON "subscription_plan_history"("subscriptionId");
|
||||
CREATE INDEX "subscription_plan_history_companyId_idx" ON "subscription_plan_history"("companyId");
|
||||
CREATE INDEX "subscription_plan_history_changeType_idx" ON "subscription_plan_history"("changeType");
|
||||
|
||||
CREATE UNIQUE INDEX "subscription_upgrade_requests_one_non_terminal_per_subscription"
|
||||
ON "subscription_upgrade_requests"("subscriptionId")
|
||||
WHERE "status" IN (
|
||||
'DRAFT',
|
||||
'QUOTED',
|
||||
'PAYMENT_PENDING',
|
||||
'PAYMENT_REVIEW',
|
||||
'CORRECTION_REQUIRED',
|
||||
'APPROVED',
|
||||
'SCHEDULED',
|
||||
'ACTIVATION_FAILED'
|
||||
);
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_companyId_fkey"
|
||||
FOREIGN KEY ("companyId") REFERENCES "companies"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_subscriptionId_fkey"
|
||||
FOREIGN KEY ("subscriptionId") REFERENCES "subscriptions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_requestedByEmployeeId_fkey"
|
||||
FOREIGN KEY ("requestedByEmployeeId") REFERENCES "employees"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_quoteId_fkey"
|
||||
FOREIGN KEY ("quoteId") REFERENCES "subscription_upgrade_quotes"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_billingInvoiceId_fkey"
|
||||
FOREIGN KEY ("billingInvoiceId") REFERENCES "billing_invoices"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_requests"
|
||||
ADD CONSTRAINT "subscription_upgrade_requests_approvedByAdminId_fkey"
|
||||
FOREIGN KEY ("approvedByAdminId") REFERENCES "admin_users"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_upgrade_quotes"
|
||||
ADD CONSTRAINT "subscription_upgrade_quotes_upgradeRequestId_fkey"
|
||||
FOREIGN KEY ("upgradeRequestId") REFERENCES "subscription_upgrade_requests"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_plan_history"
|
||||
ADD CONSTRAINT "subscription_plan_history_subscriptionId_fkey"
|
||||
FOREIGN KEY ("subscriptionId") REFERENCES "subscriptions"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
ALTER TABLE "subscription_plan_history"
|
||||
ADD CONSTRAINT "subscription_plan_history_companyId_fkey"
|
||||
FOREIGN KEY ("companyId") REFERENCES "companies"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -45,6 +45,28 @@ enum SubscriptionStatus {
|
||||
UNPAID
|
||||
}
|
||||
|
||||
enum SubscriptionUpgradeRequestType {
|
||||
IMMEDIATE_PRORATED
|
||||
AT_RENEWAL
|
||||
TERM_RESET
|
||||
}
|
||||
|
||||
enum SubscriptionUpgradeRequestStatus {
|
||||
DRAFT
|
||||
QUOTED
|
||||
PAYMENT_PENDING
|
||||
PAYMENT_REVIEW
|
||||
CORRECTION_REQUIRED
|
||||
APPROVED
|
||||
ACTIVATED
|
||||
SCHEDULED
|
||||
REJECTED
|
||||
EXPIRED
|
||||
CANCELLED
|
||||
ACTIVATION_FAILED
|
||||
SUPERSEDED
|
||||
}
|
||||
|
||||
enum InvoiceStatus {
|
||||
PENDING
|
||||
PAID
|
||||
@@ -618,6 +640,8 @@ model Company {
|
||||
subscriptionPaymentRef String?
|
||||
|
||||
subscription Subscription?
|
||||
subscriptionUpgradeRequests SubscriptionUpgradeRequest[]
|
||||
subscriptionPlanHistory SubscriptionPlanHistory[]
|
||||
billingAccounts BillingAccount[]
|
||||
billingInvoices BillingInvoice[]
|
||||
brand BrandSettings?
|
||||
@@ -692,6 +716,8 @@ model Subscription {
|
||||
billingInvoices BillingInvoice[]
|
||||
collectionsCases CollectionsCase[]
|
||||
events SubscriptionEvent[]
|
||||
upgradeRequests SubscriptionUpgradeRequest[]
|
||||
planHistory SubscriptionPlanHistory[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -853,6 +879,7 @@ model BillingInvoice {
|
||||
subscriptionId String?
|
||||
subscription Subscription? @relation(fields: [subscriptionId], references: [id])
|
||||
legacySubscriptionInvoice SubscriptionInvoice?
|
||||
subscriptionUpgradeRequest SubscriptionUpgradeRequest?
|
||||
invoiceNumber String? @unique
|
||||
invoiceSequence Int? @unique
|
||||
invoiceType BillingInvoiceType
|
||||
@@ -907,6 +934,122 @@ model BillingInvoice {
|
||||
@@map("billing_invoices")
|
||||
}
|
||||
|
||||
model SubscriptionUpgradeRequest {
|
||||
id String @id @default(cuid())
|
||||
companyId String
|
||||
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
|
||||
subscriptionId String
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
requestType SubscriptionUpgradeRequestType
|
||||
fromPlan Plan
|
||||
fromBillingPeriod BillingPeriod
|
||||
toPlan Plan
|
||||
toBillingPeriod BillingPeriod
|
||||
status SubscriptionUpgradeRequestStatus @default(DRAFT)
|
||||
requestedByEmployeeId String
|
||||
requestedByEmployee Employee @relation("SubscriptionUpgradeRequester", fields: [requestedByEmployeeId], references: [id])
|
||||
requestedAt DateTime @default(now())
|
||||
effectiveAt DateTime?
|
||||
scheduledFor DateTime?
|
||||
quoteId String? @unique
|
||||
quote SubscriptionUpgradeQuote? @relation("ActiveSubscriptionUpgradeQuote", fields: [quoteId], references: [id])
|
||||
quotes SubscriptionUpgradeQuote[] @relation("SubscriptionUpgradeQuotes")
|
||||
companyLanguageSnapshot String @default("en")
|
||||
billingTimezoneSnapshot String @default("Africa/Casablanca")
|
||||
acceptedTermsVersion String?
|
||||
acceptedAt DateTime?
|
||||
cancelledAt DateTime?
|
||||
cancelledByEmployeeId String?
|
||||
cancellationReason String?
|
||||
expiresAt DateTime?
|
||||
billingInvoiceId String? @unique
|
||||
billingInvoice BillingInvoice? @relation(fields: [billingInvoiceId], references: [id])
|
||||
approvedPaymentAttemptId String?
|
||||
approvedByAdminId String?
|
||||
approvedByAdmin AdminUser? @relation("SubscriptionUpgradeApprover", fields: [approvedByAdminId], references: [id], onDelete: SetNull)
|
||||
approvedAt DateTime?
|
||||
activationKey String? @unique
|
||||
activatedAt DateTime?
|
||||
rejectionReason String?
|
||||
correctionReason String?
|
||||
version Int @default(1)
|
||||
metadata Json @default("{}")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@index([companyId, status])
|
||||
@@index([subscriptionId, status])
|
||||
@@index([expiresAt])
|
||||
@@index([scheduledFor])
|
||||
@@map("subscription_upgrade_requests")
|
||||
}
|
||||
|
||||
model SubscriptionUpgradeQuote {
|
||||
id String @id @default(cuid())
|
||||
upgradeRequestId String
|
||||
upgradeRequest SubscriptionUpgradeRequest @relation("SubscriptionUpgradeQuotes", fields: [upgradeRequestId], references: [id], onDelete: Cascade)
|
||||
activeForUpgradeRequest SubscriptionUpgradeRequest? @relation("ActiveSubscriptionUpgradeQuote")
|
||||
currency String @default("MAD")
|
||||
currentEligibleNetTermPrice Int
|
||||
targetNetTermPrice Int
|
||||
termStart DateTime
|
||||
renewalDate DateTime
|
||||
pricingEffectiveAt DateTime
|
||||
termDays Int
|
||||
remainingDays Int
|
||||
prorationNumerator Int
|
||||
prorationDenominator Int
|
||||
currentCredit Int
|
||||
targetRemainingValue Int
|
||||
discountAmount Int @default(0)
|
||||
taxAmount Int @default(0)
|
||||
feeAmount Int @default(0)
|
||||
subtotalAmount Int
|
||||
totalAmount Int
|
||||
calculationVersion String
|
||||
inputSnapshot Json @default("{}")
|
||||
integrityHash String
|
||||
expiresAt DateTime
|
||||
expiredAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([upgradeRequestId])
|
||||
@@index([expiresAt])
|
||||
@@map("subscription_upgrade_quotes")
|
||||
}
|
||||
|
||||
model SubscriptionPlanHistory {
|
||||
id String @id @default(cuid())
|
||||
subscriptionId String
|
||||
subscription Subscription @relation(fields: [subscriptionId], references: [id], onDelete: Cascade)
|
||||
companyId String
|
||||
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
|
||||
previousPlan Plan
|
||||
previousBillingPeriod BillingPeriod
|
||||
newPlan Plan
|
||||
newBillingPeriod BillingPeriod
|
||||
changeType String
|
||||
sourceUpgradeRequestId String?
|
||||
approvedPaymentAttemptId String?
|
||||
effectiveAt DateTime
|
||||
previousTermStart DateTime?
|
||||
previousTermEnd DateTime?
|
||||
newTermStart DateTime?
|
||||
newTermEnd DateTime?
|
||||
actorType String
|
||||
actorId String?
|
||||
approvingAdminId String?
|
||||
entitlementSnapshot Json @default("{}")
|
||||
auditCorrelationId String
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([sourceUpgradeRequestId])
|
||||
@@index([subscriptionId])
|
||||
@@index([companyId])
|
||||
@@index([changeType])
|
||||
@@map("subscription_plan_history")
|
||||
}
|
||||
|
||||
model BillingInvoiceLineItem {
|
||||
id String @id @default(cuid())
|
||||
invoiceId String
|
||||
@@ -1365,6 +1508,7 @@ model Employee {
|
||||
billingContacts BillingContact[]
|
||||
manualPaymentSubmissions ManualPaymentSubmission[]
|
||||
manualPaymentDocuments ManualPaymentDocument[]
|
||||
subscriptionUpgradeRequests SubscriptionUpgradeRequest[] @relation("SubscriptionUpgradeRequester")
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -2290,6 +2434,7 @@ model AdminUser {
|
||||
ownedBillingAccounts BillingAccount[] @relation("BillingAccountCollectionsOwner")
|
||||
confirmedManualPayments BillingPaymentAttempt[] @relation("ManualPaymentConfirmingAdmin")
|
||||
reviewedManualSubmissions ManualPaymentSubmission[] @relation("ManualPaymentReviewingAdmin")
|
||||
approvedSubscriptionUpgrades SubscriptionUpgradeRequest[] @relation("SubscriptionUpgradeApprover")
|
||||
ownedCollectionsCases CollectionsCase[] @relation("CollectionsCaseOwner")
|
||||
assignedCollectionsTasks CollectionsCallTask[] @relation("CollectionsTaskAssignee")
|
||||
completedCollectionsTasks CollectionsCallTask[] @relation("CollectionsTaskCompleter")
|
||||
|
||||
Reference in New Issue
Block a user