feat: prompt user to create subscription if inactive

This commit is contained in:
Henry
2025-09-02 13:12:43 +01:00
parent a7c68db90e
commit 5f4678ab4e
9 changed files with 162 additions and 38 deletions

View File

@@ -11,6 +11,7 @@ import { env } from "next-runtime-env";
import type { dbClient } from "@kan/db/client";
import * as memberRepo from "@kan/db/repository/member.repo";
import * as userRepo from "@kan/db/repository/user.repo";
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
import * as schema from "@kan/db/schema";
import { cloudMailerClient, sendEmail } from "@kan/email";
import { createStripeClient } from "@kan/stripe";
@@ -176,6 +177,25 @@ export const initAuth = (db: dbClient) => {
process.env.STRIPE_PRO_PLAN_YEARLY_PRICE_ID!,
},
],
authorizeReference: async (data) => {
const workspace = await workspaceRepo.getByPublicId(
db,
data.referenceId,
);
if (!workspace) {
return Promise.resolve(false);
}
const isUserInWorkspace =
await workspaceRepo.isUserInWorkspace(
db,
data.user.id,
workspace.id,
);
return isUserInWorkspace;
},
},
}),
]

View File

@@ -1,7 +1,7 @@
CREATE TABLE IF NOT EXISTS "subscription" (
"id" bigserial PRIMARY KEY NOT NULL,
"plan" varchar(255) NOT NULL,
"referenceId" uuid,
"referenceId" varchar(12) NOT NULL,
"stripeCustomerId" varchar(255),
"stripeSubscriptionId" varchar(255),
"status" varchar(255) NOT NULL,
@@ -17,7 +17,7 @@ CREATE TABLE IF NOT EXISTS "subscription" (
--> statement-breakpoint
ALTER TABLE "subscription" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "subscription" ADD CONSTRAINT "subscription_referenceId_user_id_fk" FOREIGN KEY ("referenceId") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "subscription" ADD CONSTRAINT "subscription_referenceId_workspace_publicId_fk" FOREIGN KEY ("referenceId") REFERENCES "public"."workspace"("publicId") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;

View File

@@ -1,5 +1,5 @@
{
"id": "35e9d75a-9dad-4f25-8471-a94132fa12e1",
"id": "d16ab16a-b4af-4d34-abb9-e663f4e63307",
"prevId": "5d713202-07aa-46e3-abc2-83d0eb6d0858",
"version": "7",
"dialect": "postgresql",
@@ -2339,9 +2339,9 @@
},
"referenceId": {
"name": "referenceId",
"type": "uuid",
"type": "varchar(12)",
"primaryKey": false,
"notNull": false
"notNull": true
},
"stripeCustomerId": {
"name": "stripeCustomerId",
@@ -2414,17 +2414,17 @@
},
"indexes": {},
"foreignKeys": {
"subscription_referenceId_user_id_fk": {
"name": "subscription_referenceId_user_id_fk",
"subscription_referenceId_workspace_publicId_fk": {
"name": "subscription_referenceId_workspace_publicId_fk",
"tableFrom": "subscription",
"tableTo": "user",
"tableTo": "workspace",
"columnsFrom": [
"referenceId"
],
"columnsTo": [
"id"
"publicId"
],
"onDelete": "set null",
"onDelete": "no action",
"onUpdate": "no action"
}
},

View File

@@ -68,8 +68,8 @@
{
"idx": 9,
"version": "7",
"when": 1756757589852,
"tag": "20250901201309_concerned_doctor_octopus",
"when": 1756803246096,
"tag": "20250902085406_AddSubscriptions",
"breakpoints": true
}
]

View File

@@ -121,6 +121,16 @@ export const getByPublicIdWithMembers = (
},
},
},
subscriptions: {
columns: {
id: true,
plan: true,
status: true,
seats: true,
periodStart: true,
periodEnd: true,
},
},
},
where: and(
eq(workspaces.publicId, workspacePublicId),

View File

@@ -5,18 +5,17 @@ import {
integer,
pgTable,
timestamp,
uuid,
varchar,
} from "drizzle-orm/pg-core";
import { users } from "./users";
import { workspaces } from "./workspaces";
export const subscription = pgTable("subscription", {
id: bigserial("id", { mode: "number" }).primaryKey(),
plan: varchar("plan", { length: 255 }).notNull(),
referenceId: uuid("referenceId").references(() => users.id, {
onDelete: "set null",
}),
referenceId: varchar("referenceId", { length: 12 })
.notNull()
.references(() => workspaces.publicId),
stripeCustomerId: varchar("stripeCustomerId", { length: 255 }),
stripeSubscriptionId: varchar("stripeSubscriptionId", { length: 255 }),
status: varchar("status", { length: 255 }).notNull(),
@@ -31,8 +30,8 @@ export const subscription = pgTable("subscription", {
}).enableRLS();
export const subscriptionsRelations = relations(subscription, ({ one }) => ({
user: one(users, {
workspace: one(workspaces, {
fields: [subscription.referenceId],
references: [users.id],
references: [workspaces.publicId],
}),
}));

View File

@@ -11,6 +11,7 @@ import {
} from "drizzle-orm/pg-core";
import { boards } from "./boards";
import { subscription } from "./subscriptions";
import { users } from "./users";
export const memberRoles = ["admin", "member", "guest"] as const;
@@ -60,6 +61,7 @@ export const workspaceRelations = relations(workspaces, ({ one, many }) => ({
}),
members: many(workspaceMembers),
boards: many(boards),
subscriptions: many(subscription),
}));
export const workspaceMembers = pgTable("workspace_members", {