From 9201f9230e6f9c18aae9d7a93cc7c3553bb11bfe Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Tue, 22 Apr 2025 04:21:43 +0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/src/db/schema/deployment.ts | 13 +++++++------ apps/api/src/db/schema/project.ts | 18 ++++++++++-------- apps/api/src/db/schema/team-members.ts | 18 ++++++------------ apps/api/src/db/schema/team.ts | 3 ++- apps/api/src/db/schema/utils.ts | 23 +++++++++++++++++++++-- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/apps/api/src/db/schema/deployment.ts b/apps/api/src/db/schema/deployment.ts index a932f554..4de7f72e 100644 --- a/apps/api/src/db/schema/deployment.ts +++ b/apps/api/src/db/schema/deployment.ts @@ -9,6 +9,7 @@ import { createInsertSchema, createSelectSchema, createUpdateSchema, + cuid, timestamps } from './utils' @@ -16,7 +17,7 @@ export const deployments = pgTable( 'deployments', { // namespace/projectName@hash - id: text('id').primaryKey(), + id: text().primaryKey(), ...timestamps, hash: text().notNull(), @@ -28,11 +29,11 @@ export const deployments = pgTable( description: text().notNull().default(''), readme: text().notNull().default(''), - userId: text() + userId: cuid() .notNull() .references(() => users.id), - teamId: text().references(() => teams.id), - projectId: text() + teamId: cuid().references(() => teams.id), + projectId: cuid() .notNull() .references(() => projects.id, { onDelete: 'cascade' @@ -52,8 +53,8 @@ export const deployments = pgTable( // Backend API URL _url: text().notNull(), - pricingPlans: jsonb().$type(), - coupons: jsonb().$type() + pricingPlans: jsonb().$type().notNull(), + coupons: jsonb().$type().notNull().default([]) }, (table) => [ index('deployment_userId_idx').on(table.userId), diff --git a/apps/api/src/db/schema/project.ts b/apps/api/src/db/schema/project.ts index 3a4ef0e1..12ee697a 100644 --- a/apps/api/src/db/schema/project.ts +++ b/apps/api/src/db/schema/project.ts @@ -18,6 +18,8 @@ import { createInsertSchema, createSelectSchema, createUpdateSchema, + cuid, + stripeId, timestamps } from './utils' @@ -25,22 +27,22 @@ export const projects = pgTable( 'projects', { // namespace/projectName - id: text('id').primaryKey(), + id: text().primaryKey(), ...timestamps, name: text().notNull(), alias: text(), - userId: text() + userId: cuid() .notNull() .references(() => users.id), - teamId: text().notNull(), + teamId: cuid().notNull(), // Most recently published Deployment if one exists - lastPublishedDeploymentId: text(), + lastPublishedDeploymentId: cuid(), // Most recent Deployment if one exists - lastDeploymentId: text(), + lastDeploymentId: cuid(), applicationFeePercent: integer().notNull().default(20), @@ -59,8 +61,8 @@ export const projects = pgTable( _webhooks: jsonb().$type().default([]), // Stripe products corresponding to the stripe plans across deployments - stripeBaseProduct: text(), - stripeRequestProduct: text(), + stripeBaseProduct: stripeId(), + stripeRequestProduct: stripeId(), // [metricSlug: string]: string stripeMetricProducts: jsonb().$type>().default({}), @@ -85,7 +87,7 @@ export const projects = pgTable( // the stripeID utility. // TODO: is it wise to share this between dev and prod? // TODO: is it okay for this to be public? - _stripeAccount: text() + _stripeAccount: stripeId() }, (table) => [ index('project_userId_idx').on(table.userId), diff --git a/apps/api/src/db/schema/team-members.ts b/apps/api/src/db/schema/team-members.ts index 3a86ef16..6e04212a 100644 --- a/apps/api/src/db/schema/team-members.ts +++ b/apps/api/src/db/schema/team-members.ts @@ -1,33 +1,27 @@ import { relations } from 'drizzle-orm' -import { - index, - pgTable, - primaryKey, - text, - uniqueIndex -} from 'drizzle-orm/pg-core' +import { index, pgTable, primaryKey } from 'drizzle-orm/pg-core' import { teams } from './team' import { users } from './user' -import { teamMemberRoleEnum, timestamps } from './utils' +import { cuid, teamMemberRoleEnum, timestamps } from './utils' export const teamMembers = pgTable( 'team_members', { ...timestamps, - userId: text() + userId: cuid() .notNull() .references(() => users.id, { onDelete: 'cascade' }), - teamId: text() + teamId: cuid() .notNull() .references(() => teams.id, { onDelete: 'cascade' }), role: teamMemberRoleEnum().default('user').notNull() }, (table) => [ primaryKey({ columns: [table.userId, table.teamId] }), - uniqueIndex('team_member_user_idx').on(table.userId), - uniqueIndex('team_member_team_idx').on(table.teamId), + index('team_member_user_idx').on(table.userId), + index('team_member_team_idx').on(table.teamId), index('team_member_createdAt_idx').on(table.createdAt), index('team_member_updatedAt_idx').on(table.updatedAt) ] diff --git a/apps/api/src/db/schema/team.ts b/apps/api/src/db/schema/team.ts index 8e85a1a2..850f274e 100644 --- a/apps/api/src/db/schema/team.ts +++ b/apps/api/src/db/schema/team.ts @@ -7,6 +7,7 @@ import { createInsertSchema, createSelectSchema, createUpdateSchema, + cuid, id, timestamps } from './utils' @@ -20,7 +21,7 @@ export const teams = pgTable( slug: text().notNull().unique(), name: text().notNull(), - ownerId: text('owner').notNull() + ownerId: cuid().notNull() }, (table) => [ uniqueIndex('team_slug_idx').on(table.slug), diff --git a/apps/api/src/db/schema/utils.ts b/apps/api/src/db/schema/utils.ts index da01fc32..6388b19a 100644 --- a/apps/api/src/db/schema/utils.ts +++ b/apps/api/src/db/schema/utils.ts @@ -1,10 +1,29 @@ import { createId } from '@paralleldrive/cuid2' -import { sql } from 'drizzle-orm' -import { pgEnum, text, timestamp } from 'drizzle-orm/pg-core' +import { sql, type Writable } from 'drizzle-orm' +import { + pgEnum, + type PgVarcharBuilderInitial, + type PgVarcharConfig, + text, + timestamp, + varchar +} from 'drizzle-orm/pg-core' import { createSchemaFactory } from 'drizzle-zod' export const id = text('id').primaryKey().$defaultFn(createId) +export function cuid>( + config?: PgVarcharConfig, never> +): PgVarcharBuilderInitial<'', Writable, 24> { + return varchar({ length: 24, ...config }) +} + +export function stripeId>( + config?: PgVarcharConfig, never> +): PgVarcharBuilderInitial<'', Writable, 255> { + return varchar({ length: 255, ...config }) +} + export const timestamps = { createdAt: timestamp('createdAt').notNull().defaultNow(), updatedAt: timestamp('updatedAt')