feat: set workspace url when creating a new workspace (#172)

* feat: add migration to remove not null constraint from referenceId on subscriptions

* feat(cloud): write worspace slug availability checks to db

* feat: add migration to add cascade set null to referenceId on subscription

* feat: update workspace and subscripton schema

* feat: add createWorkspaceSlugCheck repo func

* feat: set workspace url on creation

* chore: update translations

* refactor: various tweaks and fixes

* feat: add pro bolt to pricing notice

* feat: toggle pro subscription

* fix: hide pro subscription notice for self hosters

* feat: add pro upgrade message on members page

* feat: hide pro upgrade notice on small viewports

* feat: update workspace url placeholder
This commit is contained in:
Henry
2025-09-11 20:32:02 +01:00
committed by GitHub
parent 4f7fa1a228
commit 2f88366418
31 changed files with 8942 additions and 385 deletions

View File

@@ -1,7 +1,7 @@
import { eq } from "drizzle-orm";
import type { dbClient } from "@kan/db/client";
import { slugs } from "@kan/db/schema";
import { slugChecks, slugs } from "@kan/db/schema";
export const getWorkspaceSlug = (db: dbClient, slug: string) => {
return db.query.slugs.findFirst({
@@ -12,3 +12,20 @@ export const getWorkspaceSlug = (db: dbClient, slug: string) => {
where: eq(slugs.slug, slug),
});
};
export const createWorkspaceSlugCheck = (
db: dbClient,
input: {
slug: string;
userId: string;
available: boolean;
reserved: boolean;
},
) => {
return db.insert(slugChecks).values({
slug: input.slug,
available: input.available,
reserved: input.reserved,
createdBy: input.userId,
});
};

View File

@@ -13,9 +13,10 @@ import { workspaces } from "./workspaces";
export const subscription = pgTable("subscription", {
id: bigserial("id", { mode: "number" }).primaryKey(),
plan: varchar("plan", { length: 255 }).notNull(),
referenceId: varchar("referenceId", { length: 12 })
.notNull()
.references(() => workspaces.publicId),
referenceId: varchar("referenceId", { length: 12 }).references(
() => workspaces.publicId,
{ onDelete: "set null" },
),
stripeCustomerId: varchar("stripeCustomerId", { length: 255 }),
stripeSubscriptionId: varchar("stripeSubscriptionId", { length: 255 }),
status: varchar("status", { length: 255 }).notNull(),

View File

@@ -2,6 +2,7 @@ import { relations } from "drizzle-orm";
import {
bigint,
bigserial,
boolean,
pgEnum,
pgTable,
text,
@@ -103,3 +104,17 @@ export const slugs = pgTable("workspace_slugs", {
slug: varchar("slug", { length: 255 }).notNull().unique(),
type: slugTypeEnum("type").notNull(),
});
export const slugChecks = pgTable("workspace_slug_checks", {
id: bigserial("id", { mode: "number" }).primaryKey(),
slug: varchar("slug", { length: 255 }).notNull(),
available: boolean("available").notNull(),
reserved: boolean("reserved").notNull(),
workspaceId: bigint("workspaceId", { mode: "number" }).references(
() => workspaces.id,
),
createdBy: uuid("createdBy").references(() => users.id, {
onDelete: "set null",
}),
createdAt: timestamp("createdAt").defaultNow().notNull(),
}).enableRLS();