feat(subscriptions): added polar as payment provider for subscriptions

* feature(dashboard): add polar / subscription

* wip(payments): manage subscription

* wip(payments): add free product, faq and some other improvements

* fix(root): change node to bundler in tsconfig

* wip(payments): display current subscription

* feat(dashboard): schedule project for deletion

* wip(payments): support custom products/subscriptions

* wip(payments): fix polar scripts

* wip(payments): add json package to dockerfiles
This commit is contained in:
Carl-Gerhard Lindesvärd
2025-02-26 11:24:00 +01:00
committed by GitHub
parent 86bf9dd064
commit 168ebc3430
105 changed files with 3395 additions and 463 deletions

View File

@@ -0,0 +1,11 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "subscriptionCreatedByUserId" TEXT,
ADD COLUMN "subscriptionCustomerId" TEXT,
ADD COLUMN "subscriptionEndsAt" TIMESTAMP(3),
ADD COLUMN "subscriptionId" TEXT,
ADD COLUMN "subscriptionPriceId" TEXT,
ADD COLUMN "subscriptionProductId" TEXT,
ADD COLUMN "subscriptionStatus" TEXT;
-- AddForeignKey
ALTER TABLE "organizations" ADD CONSTRAINT "organizations_subscriptionCreatedByUserId_fkey" FOREIGN KEY ("subscriptionCreatedByUserId") REFERENCES "users"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "eventsCount" INTEGER NOT NULL DEFAULT 0;

View File

@@ -0,0 +1,10 @@
/*
Warnings:
- You are about to drop the column `eventsCount` on the `organizations` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "organizations" DROP COLUMN "eventsCount",
ADD COLUMN "subscriptionPeriodEventsCount" INTEGER NOT NULL DEFAULT 0,
ADD COLUMN "subscriptionStartsAt" TIMESTAMP(3);

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "subscriptionPeriodLimit" INTEGER NOT NULL DEFAULT 0;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "subscriptionInterval" TEXT;

View File

@@ -0,0 +1,9 @@
/*
Warnings:
- You are about to drop the column `subscriptionPeriodLimit` on the `organizations` table. All the data in the column will be lost.
*/
-- AlterTable
ALTER TABLE "organizations" DROP COLUMN "subscriptionPeriodLimit",
ADD COLUMN "subscriptionPeriodEventsLimit" INTEGER NOT NULL DEFAULT 0;

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "subscriptionPeriodEventsCountExceededAt" TIMESTAMP(3);

View File

@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "subscriptionCanceledAt" TIMESTAMP(3);

View File

@@ -0,0 +1,5 @@
-- AlterTable
ALTER TABLE "organizations" ADD COLUMN "deleteAt" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "projects" ADD COLUMN "deleteAt" TIMESTAMP(3);

View File

@@ -0,0 +1,41 @@
-- DropForeignKey
ALTER TABLE "clients" DROP CONSTRAINT "clients_projectId_fkey";
-- DropForeignKey
ALTER TABLE "dashboards" DROP CONSTRAINT "dashboards_projectId_fkey";
-- DropForeignKey
ALTER TABLE "event_meta" DROP CONSTRAINT "event_meta_projectId_fkey";
-- DropForeignKey
ALTER TABLE "notification_rules" DROP CONSTRAINT "notification_rules_projectId_fkey";
-- DropForeignKey
ALTER TABLE "notifications" DROP CONSTRAINT "notifications_projectId_fkey";
-- DropForeignKey
ALTER TABLE "references" DROP CONSTRAINT "references_projectId_fkey";
-- DropForeignKey
ALTER TABLE "shares" DROP CONSTRAINT "shares_projectId_fkey";
-- AddForeignKey
ALTER TABLE "clients" ADD CONSTRAINT "clients_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "dashboards" ADD CONSTRAINT "dashboards_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "shares" ADD CONSTRAINT "shares_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "event_meta" ADD CONSTRAINT "event_meta_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "references" ADD CONSTRAINT "references_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "notification_rules" ADD CONSTRAINT "notification_rules_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "notifications" ADD CONSTRAINT "notifications_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,5 @@
-- DropForeignKey
ALTER TABLE "reports" DROP CONSTRAINT "reports_projectId_fkey";
-- AddForeignKey
ALTER TABLE "reports" ADD CONSTRAINT "reports_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "projects"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -36,9 +36,7 @@ model Organization {
projects Project[]
members Member[]
createdByUserId String?
createdBy User? @relation(fields: [createdByUserId], references: [id])
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
createdBy User? @relation(name: "organizationCreatedBy", fields: [createdByUserId], references: [id])
ProjectAccess ProjectAccess[]
Client Client[]
Dashboard Dashboard[]
@@ -46,6 +44,29 @@ model Organization {
integrations Integration[]
invites Invite[]
// Subscription
subscriptionId String?
subscriptionCustomerId String?
subscriptionPriceId String?
subscriptionProductId String?
/// [IPrismaSubscriptionStatus]
subscriptionStatus String?
subscriptionStartsAt DateTime?
subscriptionEndsAt DateTime?
subscriptionCanceledAt DateTime?
subscriptionCreatedByUserId String?
subscriptionCreatedBy User? @relation(name: "subscriptionCreatedBy", fields: [subscriptionCreatedByUserId], references: [id])
subscriptionPeriodEventsCount Int @default(0)
subscriptionPeriodEventsCountExceededAt DateTime?
subscriptionPeriodEventsLimit Int @default(0)
subscriptionInterval String?
// When deleteAt > now(), the organization will be deleted
deleteAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@map("organizations")
}
@@ -54,7 +75,8 @@ model User {
email String @unique
firstName String?
lastName String?
createdOrganizations Organization[]
createdOrganizations Organization[] @relation("organizationCreatedBy")
subscriptions Organization[] @relation("subscriptionCreatedBy")
membership Member[]
sentInvites Member[] @relation("invitedBy")
createdAt DateTime @default(now())
@@ -157,6 +179,9 @@ model Project {
notificationRules NotificationRule[]
notifications Notification[]
// When deleteAt > now(), the project will be deleted
deleteAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@ -204,7 +229,7 @@ model Client {
secret String?
type ClientType @default(write)
projectId String?
project Project? @relation(fields: [projectId], references: [id])
project Project? @relation(fields: [projectId], references: [id], onDelete: Cascade)
organization Organization @relation(fields: [organizationId], references: [id])
organizationId String
@@ -240,7 +265,7 @@ model Dashboard {
organization Organization @relation(fields: [organizationId], references: [id])
organizationId String
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
reports Report[]
createdAt DateTime @default(now())
@@ -269,7 +294,7 @@ model Report {
unit String?
metric Metric @default(sum)
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
previous Boolean @default(false)
criteria String?
funnelGroup String?
@@ -287,7 +312,7 @@ model Report {
model ShareOverview {
id String @unique
projectId String @unique
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
organization Organization @relation(fields: [organizationId], references: [id])
organizationId String
public Boolean @default(false)
@@ -305,7 +330,7 @@ model EventMeta {
color String?
icon String?
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@ -320,7 +345,7 @@ model Reference {
description String?
date DateTime @default(now())
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@@ -338,7 +363,7 @@ model NotificationRule {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
name String
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
integrations Integration[]
sendToApp Boolean @default(false)
sendToEmail Boolean @default(false)
@@ -355,7 +380,7 @@ model NotificationRule {
model Notification {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
projectId String
project Project @relation(fields: [projectId], references: [id])
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
title String
message String
isReadAt DateTime?