Subscription, Payment and User.plan

This commit is contained in:
2026-01-28 18:16:32 +00:00
parent 0fffbfeb1f
commit c8cb99c86a
4 changed files with 1232 additions and 1 deletions

View File

@@ -0,0 +1,30 @@
CREATE TABLE "Payment" (
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "Payment_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
"subscriptionId" integer NOT NULL,
"stripePaymentIntentId" varchar(255),
"amount" integer NOT NULL,
"currency" varchar(3) DEFAULT 'gbp' NOT NULL,
"status" varchar(32) NOT NULL,
"createdAt" timestamp DEFAULT now()
);
--> statement-breakpoint
CREATE TABLE "Subscription" (
"id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "Subscription_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
"userId" integer NOT NULL,
"stripeCustomerId" varchar(255),
"stripeSubscriptionId" varchar(255),
"stripeSubscriptionItemId" varchar(255),
"stripePriceId" varchar(255),
"status" varchar(32) DEFAULT 'incomplete' NOT NULL,
"currentPeriodStart" timestamp,
"currentPeriodEnd" timestamp,
"cancelAtPeriodEnd" boolean DEFAULT false NOT NULL,
"trialEnd" timestamp,
"quantity" integer DEFAULT 1 NOT NULL,
"createdAt" timestamp DEFAULT now(),
"updatedAt" timestamp DEFAULT now()
);
--> statement-breakpoint
ALTER TABLE "User" ADD COLUMN "plan" varchar(32) DEFAULT 'free' NOT NULL;--> statement-breakpoint
ALTER TABLE "Payment" ADD CONSTRAINT "Payment_subscriptionId_Subscription_id_fk" FOREIGN KEY ("subscriptionId") REFERENCES "public"."Subscription"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_userId_User_id_fk" FOREIGN KEY ("userId") REFERENCES "public"."User"("id") ON DELETE no action ON UPDATE no action;

File diff suppressed because it is too large Load Diff

View File

@@ -183,6 +183,13 @@
"when": 1769549697892, "when": 1769549697892,
"tag": "0025_sharp_quicksilver", "tag": "0025_sharp_quicksilver",
"breakpoints": true "breakpoints": true
},
{
"idx": 26,
"version": "7",
"when": 1769615487574,
"tag": "0026_stale_shocker",
"breakpoints": true
} }
] ]
} }

View File

@@ -1,4 +1,4 @@
import { integer, json, pgTable, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core"; import { boolean, integer, json, pgTable, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
import { createInsertSchema, createSelectSchema } from "drizzle-zod"; import { createInsertSchema, createSelectSchema } from "drizzle-zod";
import type { z } from "zod"; import type { z } from "zod";
import { import {
@@ -59,6 +59,7 @@ export const User = pgTable("User", {
passwordHash: varchar({ length: 255 }).notNull(), passwordHash: varchar({ length: 255 }).notNull(),
avatarURL: varchar({ length: 512 }), avatarURL: varchar({ length: 512 }),
iconPreference: varchar({ length: 10 }).notNull().default("pixel").$type<IconStyle>(), iconPreference: varchar({ length: 10 }).notNull().default("pixel").$type<IconStyle>(),
plan: varchar({ length: 32 }).notNull().default("free"),
createdAt: timestamp({ withTimezone: false }).defaultNow(), createdAt: timestamp({ withTimezone: false }).defaultNow(),
updatedAt: timestamp({ withTimezone: false }).defaultNow(), updatedAt: timestamp({ withTimezone: false }).defaultNow(),
}); });
@@ -295,3 +296,50 @@ export type TimerState = {
timestamps: string[]; timestamps: string[];
endedAt: string | null; endedAt: string | null;
} | null; } | null;
// Subscription table - tracks user subscriptions
export const Subscription = pgTable("Subscription", {
id: integer().primaryKey().generatedAlwaysAsIdentity(),
userId: integer()
.notNull()
.references(() => User.id),
stripeCustomerId: varchar({ length: 255 }),
stripeSubscriptionId: varchar({ length: 255 }),
stripeSubscriptionItemId: varchar({ length: 255 }),
stripePriceId: varchar({ length: 255 }),
status: varchar({ length: 32 }).notNull().default("incomplete"),
currentPeriodStart: timestamp({ withTimezone: false }),
currentPeriodEnd: timestamp({ withTimezone: false }),
cancelAtPeriodEnd: boolean().notNull().default(false),
trialEnd: timestamp({ withTimezone: false }),
quantity: integer().notNull().default(1),
createdAt: timestamp({ withTimezone: false }).defaultNow(),
updatedAt: timestamp({ withTimezone: false }).defaultNow(),
});
// Payment history table
export const Payment = pgTable("Payment", {
id: integer().primaryKey().generatedAlwaysAsIdentity(),
subscriptionId: integer()
.notNull()
.references(() => Subscription.id),
stripePaymentIntentId: varchar({ length: 255 }),
amount: integer().notNull(),
currency: varchar({ length: 3 }).notNull().default("gbp"),
status: varchar({ length: 32 }).notNull(),
createdAt: timestamp({ withTimezone: false }).defaultNow(),
});
// Zod schemas for Subscription and Payment
export const SubscriptionSelectSchema = createSelectSchema(Subscription);
export const SubscriptionInsertSchema = createInsertSchema(Subscription);
export const PaymentSelectSchema = createSelectSchema(Payment);
export const PaymentInsertSchema = createInsertSchema(Payment);
// Types for Subscription and Payment
export type SubscriptionRecord = z.infer<typeof SubscriptionSelectSchema>;
export type SubscriptionInsert = z.infer<typeof SubscriptionInsertSchema>;
export type PaymentRecord = z.infer<typeof PaymentSelectSchema>;
export type PaymentInsert = z.infer<typeof PaymentInsertSchema>;