diff --git a/shared/archives/orgModels_old.ts b/shared/archives/orgModels_old.ts index 9663443f1..56532a3d5 100644 --- a/shared/archives/orgModels_old.ts +++ b/shared/archives/orgModels_old.ts @@ -2,7 +2,6 @@ import { z } from "zod"; import { OrgConfigSchema } from "../models/orgModels/orgConfig.js"; -import { APIVersion } from "../models/apiVersionEnum.js"; export const MinOrgSchema = z.object({ id: z.string(), diff --git a/shared/db/productsTable.ts b/shared/db/productsTable.ts deleted file mode 100644 index 6530eeac6..000000000 --- a/shared/db/productsTable.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { - boolean, - foreignKey, - jsonb, - numeric, - pgTable, - text, -} from "drizzle-orm/pg-core"; -import { sqlNow } from "./utils.js"; -import { relations } from "drizzle-orm"; -import { organizations } from "../models/orgModels/orgTable.js"; -import { entitlements } from "../models/productModels/entModels/entTable.js"; -import { prices } from "./pricesTable.js"; - -export const products = pgTable( - "products", - { - internal_id: text("internal_id").primaryKey().notNull(), - created_at: numeric("created_at").notNull().default(sqlNow), - name: text(), - org_id: text("org_id"), - env: text(), - is_add_on: boolean("is_add_on"), - processor: jsonb(), - is_default: boolean("is_default").default(false), - id: text(), - group: text().default(""), - version: numeric().default("1"), - }, - (table) => [ - foreignKey({ - columns: [table.org_id], - foreignColumns: [organizations.id], - name: "products_org_id_fkey", - }).onDelete("cascade"), - ], -); - -export const productsRelations = relations(products, ({ one, many }) => ({ - org: one(organizations, { - fields: [products.org_id], - references: [organizations.id], - }), - entitlements: many(entitlements), - prices: many(prices), -})); diff --git a/shared/db/schema.ts b/shared/db/schema.ts index 4fb6845c5..3181a81b9 100644 --- a/shared/db/schema.ts +++ b/shared/db/schema.ts @@ -1,37 +1,45 @@ +/* TABLES */ import { organizations } from "../models/orgModels/orgTable.js"; import { chatResults } from "../models/chatResultModels/chatResultTable.js"; -import { entitlements } from "../models/productModels/entModels/entTable.js"; import { features } from "../models/featureModels/featureTable.js"; +// Product Tables +import { products } from "../models/productModels/productTable.js"; +import { prices } from "../models/productModels/priceModels/priceTable.js"; +import { entitlements } from "../models/productModels/entModels/entTable.js"; + +// Others import { apiKeys } from "./apiKeysTable.js"; import { customers } from "./cusTable.js"; -import { prices } from "./pricesTable.js"; -import { products } from "./productsTable.js"; -// import * as relations from "./relations.js"; - -// Relations +/* RELATIONS */ import { organizationsRelations } from "../models/orgModels/orgRelations.js"; import { apiKeysRelations } from "./relations.js"; -import { entitlementsRelations } from "../models/productModels/entModels/entRelations.js"; import { featureRelations } from "../models/featureModels/featureRelations.js"; +// Product Relations +import { entitlementsRelations } from "../models/productModels/entModels/entRelations.js"; +import { priceRelations } from "../models/productModels/priceModels/priceRelations.js"; +import { productRelations } from "../models/productModels/productRelations.js"; + const relations = { organizationsRelations, apiKeysRelations, entitlementsRelations, featureRelations, + priceRelations, + productRelations, }; export const schemas = { apiKeys, - customers, - chatResults, - prices, organizations, + chatResults, entitlements, features, products, + prices, + customers, ...relations, }; diff --git a/shared/index.ts b/shared/index.ts index 38afee708..6e0c26382 100644 --- a/shared/index.ts +++ b/shared/index.ts @@ -1,6 +1,10 @@ // Schemas export * from "./db/schema.js"; +// Gen Models +export * from "./models/genModels/genEnums.js"; +export * from "./models/genModels/genModels.js"; + // 1. Org Models export * from "./models/orgModels/orgTable.js"; export * from "./models/orgModels/orgConfig.js"; @@ -14,13 +18,37 @@ export * from "./models/featureModels/featureConfig/creditConfig.js"; // 3. Entitlement Models export * from "./models/productModels/entModels/entTable.js"; +export * from "./models/productModels/entModels/entModels.js"; +export * from "./models/productModels/entModels/entEnums.js"; -// 3. Chat Result Models +// 4. Free Trial Models +export * from "./models/productModels/freeTrialModels/freeTrialEnums.js"; +export * from "./models/productModels/freeTrialModels/freeTrialModels.js"; + +// 4. Price Models +export * from "./models/productModels/priceModels/priceEnums.js"; +export * from "./models/productModels/priceModels/priceConfig/fixedPriceConfig.js"; +export * from "./models/productModels/priceModels/priceConfig/usagePriceConfig.js"; +export * from "./models/productModels/priceModels/priceTable.js"; +export * from "./models/productModels/priceModels/priceModels.js"; + +// 5. Product Models +export * from "./models/productModels/productEnums.js"; +export * from "./models/productModels/productTable.js"; +export * from "./models/productModels/productModels.js"; +export * from "./models/productModels/productRelations.js"; + +// 6. Product V2 Models +export * from "./models/productV2Models/productV2Models.js"; +export * from "./models/productV2Models/productResponseModels.js"; +export * from "./models/productV2Models/productItemModels/productItemModels.js"; +export * from "./models/productV2Models/productItemModels/prodItemResponseModels.js"; + +// 4. Chat Result Models export * from "./models/chatResultModels/chatResultTable.js"; export * from "./models/chatResultModels/chatResultFeature.js"; // Gen Models -export * from "./models/genModels.js"; // Dev Models export * from "./models/devModels/apiKeyModels.js"; @@ -42,26 +70,16 @@ export * from "./models/cusModels/cusResponseModels.js"; // Entity Models export * from "./models/cusModels/entityModels/entityModels.js"; - export * from "./models/migrationModels/migrationModels.js"; // Product Models -export * from "./models/productModels/productModels.js"; -export * from "./models/productModels/entitlementModels.js"; -export * from "./models/productModels/priceModels.js"; -export * from "./models/productModels/usagePriceModels.js"; -export * from "./models/productModels/fixedPriceModels.js"; -export * from "./models/productModels/freeTrialModels.js"; +export * from "./models/productModels/freeTrialModels/freeTrialModels.js"; export * from "./models/rewardModels/rewardModels.js"; export * from "./models/rewardModels/rewardProgramModels.js"; export * from "./models/rewardModels/referralModels/referralModels.js"; export * from "./models/subModels/subModels.js"; -export * from "./models/productModels/productItemModels.js"; -export * from "./models/productModels/productV2Models.js"; -export * from "./models/productModels/productResponseModels.js"; -export * from "./models/apiVersionEnum.js"; - -export * from "./models/productModels/productItemModels/prodItemResponseModels.js"; +export * from "./models/productV2Models/productV2Models.js"; +export * from "./models/productV2Models/productResponseModels.js"; export * from "./models/cusModels/fullCusModel.js"; export * from "./models/cusModels/entityModels/entityResModels.js"; diff --git a/shared/models/apiVersionEnum.ts b/shared/models/apiVersionEnum.ts deleted file mode 100644 index 23300497a..000000000 --- a/shared/models/apiVersionEnum.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum APIVersion { - v1 = 1, - v1_1 = 1.1, - v1_2 = 1.2, -} diff --git a/shared/models/checkModels/checkPreviewModels.ts b/shared/models/checkModels/checkPreviewModels.ts index d93f3666d..1bb6ce876 100644 --- a/shared/models/checkModels/checkPreviewModels.ts +++ b/shared/models/checkModels/checkPreviewModels.ts @@ -1,6 +1,6 @@ -import { UsageModel } from "../productModels/productItemModels.js"; -import { Infinite } from "../productModels/productItemModels.js"; -import { ProductResponse } from "../productModels/productResponseModels.js"; +import { UsageModel } from "../productV2Models/productItemModels/productItemModels.js"; +import { Infinite } from "../productModels/productEnums.js"; +import { ProductResponse } from "../productV2Models/productResponseModels.js"; export enum AttachScenario { // AlreadyAttached = "already_attached", diff --git a/shared/models/cusModels/cusEntModels/cusEntitlementModels.ts b/shared/models/cusModels/cusEntModels/cusEntitlementModels.ts index 6271a5309..76b5a7b52 100644 --- a/shared/models/cusModels/cusEntModels/cusEntitlementModels.ts +++ b/shared/models/cusModels/cusEntModels/cusEntitlementModels.ts @@ -2,7 +2,7 @@ import { z } from "zod"; import { EntitlementSchema, EntitlementWithFeatureSchema, -} from "../../productModels/entitlementModels.js"; +} from "../../productModels/entModels/entModels.js"; import { FeatureSchema } from "../../featureModels/featureModels.js"; export const EntityBalanceSchema = z.object({ diff --git a/shared/models/cusModels/cusModels.ts b/shared/models/cusModels/cusModels.ts index 00f8f36b7..9006762e4 100644 --- a/shared/models/cusModels/cusModels.ts +++ b/shared/models/cusModels/cusModels.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { AppEnv } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; export const CustomerSchema = z.object({ id: z.string().nullish(), // given by user diff --git a/shared/models/cusModels/cusPriceModels/cusPriceModels.ts b/shared/models/cusModels/cusPriceModels/cusPriceModels.ts index b13bc27c4..d71b66de5 100644 --- a/shared/models/cusModels/cusPriceModels/cusPriceModels.ts +++ b/shared/models/cusModels/cusPriceModels/cusPriceModels.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { PriceSchema } from "../../productModels/priceModels.js"; +import { PriceSchema } from "../../productModels/priceModels/priceModels.js"; export const CustomerPriceSchema = z.object({ id: z.string(), diff --git a/shared/models/cusModels/cusPriceModels/pricesInputModel.ts b/shared/models/cusModels/cusPriceModels/pricesInputModel.ts index e2668bf92..7e4c889f1 100644 --- a/shared/models/cusModels/cusPriceModels/pricesInputModel.ts +++ b/shared/models/cusModels/cusPriceModels/pricesInputModel.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { FixedPriceConfigSchema } from "../../productModels/fixedPriceModels.js"; -import { UsagePriceConfigSchema } from "../../productModels/usagePriceModels.js"; +import { FixedPriceConfigSchema } from "../../productModels/priceModels/priceConfig/fixedPriceConfig.js"; +import { UsagePriceConfigSchema } from "../../productModels/priceModels/priceConfig/usagePriceConfig.js"; export const PriceOptionsSchema = z.object({ quantity: z.number().optional(), // for usage in-advance @@ -12,7 +12,7 @@ export const PricesInputSchema = z.array( id: z.string(), options: PriceOptionsSchema, config: FixedPriceConfigSchema.or(UsagePriceConfigSchema), - }) + }), ); export type PricesInput = z.infer; diff --git a/shared/models/cusModels/cusProductModels.ts b/shared/models/cusModels/cusProductModels.ts index f1ce7e553..d21730184 100644 --- a/shared/models/cusModels/cusProductModels.ts +++ b/shared/models/cusModels/cusProductModels.ts @@ -1,13 +1,13 @@ import { z } from "zod"; -import { ProcessorType } from "../genModels.js"; +import { ProcessorType } from "../genModels/genEnums.js"; import { ProductSchema } from "../productModels/productModels.js"; import { CustomerPriceSchema } from "./cusPriceModels/cusPriceModels.js"; -import { PriceSchema } from "../productModels/priceModels.js"; +import { PriceSchema } from "../productModels/priceModels/priceModels.js"; import { CustomerEntitlementSchema } from "./cusEntModels/cusEntitlementModels.js"; -import { EntitlementSchema } from "../productModels/entitlementModels.js"; +import { EntitlementSchema } from "../productModels/entModels/entModels.js"; import { FeatureSchema } from "../featureModels/featureModels.js"; import { CustomerSchema } from "./cusModels.js"; -import { FreeTrialSchema } from "../productModels/freeTrialModels.js"; +import { FreeTrialSchema } from "../productModels/freeTrialModels/freeTrialModels.js"; export const FeatureOptionsSchema = z.object({ internal_feature_id: z.string().optional(), @@ -93,7 +93,7 @@ export const FullCusProductSchema = CusProductSchema.extend({ customer_prices: z.array( CustomerPriceSchema.extend({ price: PriceSchema, - }) + }), ), customer_entitlements: z.array( @@ -101,7 +101,7 @@ export const FullCusProductSchema = CusProductSchema.extend({ entitlement: EntitlementSchema.extend({ feature: FeatureSchema, }), - }) + }), ), customer: CustomerSchema, diff --git a/shared/models/cusModels/cusResponseModels.ts b/shared/models/cusModels/cusResponseModels.ts index c43ecd4af..b6eb3ce0f 100644 --- a/shared/models/cusModels/cusResponseModels.ts +++ b/shared/models/cusModels/cusResponseModels.ts @@ -1,6 +1,7 @@ import { z } from "zod"; import { CusProductStatus } from "./cusProductModels.js"; -import { AppEnv, EntInterval } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; +import { EntInterval } from "../productModels/entModels/entEnums.js"; import { InvoiceResponseSchema } from "./invoiceModels/invoiceResponseModels.js"; import { RewardResponseSchema } from "../rewardModels/rewardResponseModels.js"; @@ -48,7 +49,7 @@ export const CusEntResponseV2Schema = z.object({ usage: z.number().nullish(), included_usage: z.number().nullish(), next_reset_at: z.number().nullish(), - }) + }), ) .nullish(), }); diff --git a/shared/models/cusModels/entityModels/entityResModels.ts b/shared/models/cusModels/entityModels/entityResModels.ts index 10e74d75c..a35da6128 100644 --- a/shared/models/cusModels/entityModels/entityResModels.ts +++ b/shared/models/cusModels/entityModels/entityResModels.ts @@ -1,4 +1,4 @@ -import { AppEnv } from "../../genModels.js"; +import { AppEnv } from "../../genModels/genEnums.js"; import { CusProductResponseSchema, CusEntResponseV2Schema, diff --git a/shared/models/devModels/apiKeyModels.ts b/shared/models/devModels/apiKeyModels.ts index 42889f71a..02edc0dc9 100644 --- a/shared/models/devModels/apiKeyModels.ts +++ b/shared/models/devModels/apiKeyModels.ts @@ -1,4 +1,4 @@ -import { AppEnv } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; export type ApiKey = { id: string; diff --git a/shared/models/featureModels/featureModels.ts b/shared/models/featureModels/featureModels.ts index 940f40f4d..ca0dcf6eb 100644 --- a/shared/models/featureModels/featureModels.ts +++ b/shared/models/featureModels/featureModels.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { AppEnv } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; import { FeatureType } from "./featureEnums.js"; export const FeatureSchema = z.object({ diff --git a/shared/models/featureModels/featureTable.ts b/shared/models/featureModels/featureTable.ts index b8d70bc56..1d15ba80a 100644 --- a/shared/models/featureModels/featureTable.ts +++ b/shared/models/featureModels/featureTable.ts @@ -13,10 +13,11 @@ import { MeteredConfig } from "./featureConfig/meteredConfig.js"; import { CreditSystemConfig } from "./featureConfig/creditConfig.js"; import { collatePgColumn } from "../../db/utils.js"; -interface FeatureDisplay { +type FeatureDisplay = { singular: string; plural: string; -} +}; + export const features = pgTable( "features", { diff --git a/shared/models/genModels.ts b/shared/models/genModels/genEnums.ts similarity index 56% rename from shared/models/genModels.ts rename to shared/models/genModels/genEnums.ts index fe867289d..59d4bfe89 100644 --- a/shared/models/genModels.ts +++ b/shared/models/genModels/genEnums.ts @@ -1,3 +1,14 @@ +export enum APIVersion { + v1 = 1, + v1_1 = 1.1, + v1_2 = 1.2, +} + +export enum AppEnv { + Sandbox = "sandbox", + Live = "live", +} + export enum Duration { Minute = "minute", Hour = "hour", @@ -8,23 +19,6 @@ export enum Duration { Lifetime = "lifetime", } -export enum EntInterval { - Lifetime = "lifetime", - Minute = "minute", - Hour = "hour", - Day = "day", - Week = "week", - Month = "month", - Quarter = "quarter", - SemiAnnual = "semi_annual", - Year = "year" -} - -export enum AppEnv { - Sandbox = "sandbox", - Live = "live", -} - export enum ProcessorType { Stripe = "stripe", } diff --git a/shared/models/genModels/genModels.ts b/shared/models/genModels/genModels.ts new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/shared/models/genModels/genModels.ts @@ -0,0 +1 @@ + diff --git a/shared/models/migrationModels/migrationModels.ts b/shared/models/migrationModels/migrationModels.ts index a8d27b958..46b93c4f9 100644 --- a/shared/models/migrationModels/migrationModels.ts +++ b/shared/models/migrationModels/migrationModels.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { AppEnv } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; export enum MigrationJobStep { // Pending = "pending", diff --git a/shared/models/productModels/entModels/entEnums.ts b/shared/models/productModels/entModels/entEnums.ts new file mode 100644 index 000000000..4eaa9fc9c --- /dev/null +++ b/shared/models/productModels/entModels/entEnums.ts @@ -0,0 +1,11 @@ +export enum EntInterval { + Lifetime = "lifetime", + Minute = "minute", + Hour = "hour", + Day = "day", + Week = "week", + Month = "month", + Quarter = "quarter", + SemiAnnual = "semi_annual", + Year = "year", +} diff --git a/shared/models/productModels/entitlementModels.ts b/shared/models/productModels/entModels/entModels.ts similarity index 63% rename from shared/models/productModels/entitlementModels.ts rename to shared/models/productModels/entModels/entModels.ts index 7cce539a3..9354279f7 100644 --- a/shared/models/productModels/entitlementModels.ts +++ b/shared/models/productModels/entModels/entModels.ts @@ -1,8 +1,6 @@ import { z } from "zod"; -import { FeatureSchema } from "../featureModels/featureModels.js"; -import { FeatureType } from "../featureModels/featureEnums.js"; -import { EntInterval } from "../genModels.js"; -import { UsagePriceConfigSchema } from "./usagePriceModels.js"; +import { FeatureSchema } from "../../featureModels/featureModels.js"; +import { EntInterval } from "./entEnums.js"; export enum AllowanceType { Fixed = "fixed", @@ -12,21 +10,22 @@ export enum AllowanceType { export const EntitlementSchema = z.object({ // Required fields - no .optional() - id: z.string().optional(), - org_id: z.string().optional(), - created_at: z.number().optional(), - is_custom: z.boolean().default(false).optional(), - internal_product_id: z.string().optional(), + id: z.string(), + created_at: z.number(), + internal_feature_id: z.string(), + internal_product_id: z.string(), + is_custom: z.boolean().default(false), - // Part of create entitlement - internal_feature_id: z.string().optional(), - feature_id: z.string().optional(), allowance_type: z.nativeEnum(AllowanceType).optional().nullable(), allowance: z.number().nullish(), interval: z.nativeEnum(EntInterval).optional().nullable(), carry_from_previous: z.boolean().default(false).optional(), entity_feature_id: z.string().nullish(), + + // Part of create entitlement + org_id: z.string().optional(), + feature_id: z.string().optional(), }); export const CreateEntitlementSchema = z.object({ @@ -40,18 +39,6 @@ export const CreateEntitlementSchema = z.object({ entity_feature_id: z.string().nullish(), }); -export const PublicEntitlementSchema = z.object({ - feature: z.object({ - id: z.string(), - type: z.nativeEnum(FeatureType), - name: z.string(), - }), - allowance_type: z.nativeEnum(AllowanceType).nullish(), - allowance: z.number().nullish(), - interval: z.nativeEnum(EntInterval).nullish(), - price: UsagePriceConfigSchema.nullish(), -}); - export type CreateEntitlement = z.infer; export type Entitlement = z.infer; diff --git a/shared/models/productModels/entModels/entRelations.ts b/shared/models/productModels/entModels/entRelations.ts index 377286cae..41076f4a3 100644 --- a/shared/models/productModels/entModels/entRelations.ts +++ b/shared/models/productModels/entModels/entRelations.ts @@ -2,10 +2,15 @@ import { relations } from "drizzle-orm"; import { features } from "../../featureModels/featureTable.js"; import { entitlements } from "./entTable.js"; +import { products } from "../productTable.js"; export const entitlementsRelations = relations(entitlements, ({ one }) => ({ feature: one(features, { fields: [entitlements.internal_feature_id], references: [features.internal_id], }), + product: one(products, { + fields: [entitlements.internal_product_id], + references: [products.internal_id], + }), })); diff --git a/shared/models/productModels/entModels/entTable.ts b/shared/models/productModels/entModels/entTable.ts index 4b2332249..c92fe453e 100644 --- a/shared/models/productModels/entModels/entTable.ts +++ b/shared/models/productModels/entModels/entTable.ts @@ -5,28 +5,32 @@ import { foreignKey, unique, text, - integer, } from "drizzle-orm/pg-core"; import { features } from "../../featureModels/featureTable.js"; -import { products } from "../../../db/productsTable.js"; +import { products } from "../productTable.js"; import { createInsertSchema } from "drizzle-zod"; +import { sql } from "drizzle-orm"; export const entitlements = pgTable( "entitlements", { - internal_feature_id: text("internal_feature_id"), - org_id: text("org_id"), - internal_product_id: text("internal_product_id"), - allowance_type: text("allowance_type"), + id: text().primaryKey().notNull(), + created_at: numeric({ mode: "number" }).notNull(), + internal_feature_id: text().notNull(), + internal_product_id: text().notNull(), + is_custom: boolean().default(false), + + allowance_type: text(), allowance: numeric({ mode: "number" }), interval: text(), - id: text().primaryKey().notNull(), - feature_id: text("feature_id"), - is_custom: boolean("is_custom").default(false), + carry_from_previous: boolean("carry_from_previous").default(false), - entity_feature_id: text("entity_feature_id"), - created_at: numeric("created_at", { mode: "number" }).notNull(), + entity_feature_id: text("entity_feature_id").default(sql`null`), + + // Optional fields + org_id: text("org_id"), + feature_id: text("feature_id"), }, (table) => [ foreignKey({ diff --git a/shared/models/productModels/freeTrialModels/freeTrialEnums.ts b/shared/models/productModels/freeTrialModels/freeTrialEnums.ts new file mode 100644 index 000000000..b6b2be995 --- /dev/null +++ b/shared/models/productModels/freeTrialModels/freeTrialEnums.ts @@ -0,0 +1,5 @@ +export enum FreeTrialDuration { + Day = "day", + Month = "month", + Year = "year", +} diff --git a/shared/models/productModels/freeTrialModels.ts b/shared/models/productModels/freeTrialModels/freeTrialModels.ts similarity index 89% rename from shared/models/productModels/freeTrialModels.ts rename to shared/models/productModels/freeTrialModels/freeTrialModels.ts index 4071b0450..94d705456 100644 --- a/shared/models/productModels/freeTrialModels.ts +++ b/shared/models/productModels/freeTrialModels/freeTrialModels.ts @@ -1,11 +1,5 @@ import { z } from "zod"; - -export enum FreeTrialDuration { - Day = "day", - // Week = "week", - Month = "month", - Year = "year", -} +import { FreeTrialDuration } from "./freeTrialEnums.js"; export const FreeTrialSchema = z.object({ id: z.string(), diff --git a/shared/models/productModels/fixedPriceModels.ts b/shared/models/productModels/priceModels/priceConfig/fixedPriceConfig.ts similarity index 66% rename from shared/models/productModels/fixedPriceModels.ts rename to shared/models/productModels/priceModels/priceConfig/fixedPriceConfig.ts index 624bb2fe4..8123b1536 100644 --- a/shared/models/productModels/fixedPriceModels.ts +++ b/shared/models/productModels/priceModels/priceConfig/fixedPriceConfig.ts @@ -1,12 +1,5 @@ import { z } from "zod"; - -export enum BillingInterval { - OneOff = "one_off", - Month = "month", - Quarter = "quarter", - SemiAnnual = "semi_annual", - Year = "year", -} +import { BillingInterval } from "../priceEnums.js"; export const FixedPriceConfigSchema = z.object({ type: z.string(), diff --git a/shared/models/productModels/usagePriceModels.ts b/shared/models/productModels/priceModels/priceConfig/usagePriceConfig.ts similarity index 72% rename from shared/models/productModels/usagePriceModels.ts rename to shared/models/productModels/priceModels/priceConfig/usagePriceConfig.ts index 1b39534e0..14c56ecbb 100644 --- a/shared/models/productModels/usagePriceModels.ts +++ b/shared/models/productModels/priceModels/priceConfig/usagePriceConfig.ts @@ -1,23 +1,15 @@ import { z } from "zod"; -import { BillingInterval } from "./fixedPriceModels.js"; -import { TierInfinite } from "./productItemModels.js"; +import { Infinite } from "../../productEnums.js"; +import { BillingInterval } from "../priceEnums.js"; export enum BillWhen { - // Deprecated InAdvance = "in_advance", - - // Latest StartOfPeriod = "start_of_period", EndOfPeriod = "end_of_period", - - // Seat based - // Licensed = "on_usage", - BelowThreshold = "below_threshold", } export const UsageTierSchema = z.object({ - // from: z.number(), - to: z.number().or(z.literal(TierInfinite)), + to: z.number().or(z.literal(Infinite)), amount: z.number(), }); @@ -26,10 +18,8 @@ export const UsagePriceConfigSchema = z.object({ bill_when: z.nativeEnum(BillWhen), billing_units: z.number().nullish(), - // entitlement_id: z.string().nullish(), internal_feature_id: z.string(), feature_id: z.string(), - usage_tiers: z.array(UsageTierSchema), interval: z.nativeEnum(BillingInterval).optional(), diff --git a/shared/models/productModels/priceModels/priceEnums.ts b/shared/models/productModels/priceModels/priceEnums.ts new file mode 100644 index 000000000..26a5c048a --- /dev/null +++ b/shared/models/productModels/priceModels/priceEnums.ts @@ -0,0 +1,7 @@ +export enum BillingInterval { + OneOff = "one_off", + Month = "month", + Quarter = "quarter", + SemiAnnual = "semi_annual", + Year = "year", +} diff --git a/shared/models/productModels/priceModels.ts b/shared/models/productModels/priceModels/priceModels.ts similarity index 87% rename from shared/models/productModels/priceModels.ts rename to shared/models/productModels/priceModels/priceModels.ts index 645376290..8957dbb6b 100644 --- a/shared/models/productModels/priceModels.ts +++ b/shared/models/productModels/priceModels/priceModels.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { UsagePriceConfigSchema } from "./usagePriceModels.js"; -import { FixedPriceConfigSchema } from "./fixedPriceModels.js"; +import { UsagePriceConfigSchema } from "./priceConfig/usagePriceConfig.js"; +import { FixedPriceConfigSchema } from "./priceConfig/fixedPriceConfig.js"; export enum PriceType { Fixed = "fixed", diff --git a/shared/models/productModels/priceModels/priceRelations.ts b/shared/models/productModels/priceModels/priceRelations.ts new file mode 100644 index 000000000..a4e04b89c --- /dev/null +++ b/shared/models/productModels/priceModels/priceRelations.ts @@ -0,0 +1,10 @@ +import { relations } from "drizzle-orm"; +import { prices } from "./priceTable.js"; +import { products } from "../productTable.js"; + +export const priceRelations = relations(prices, ({ one }) => ({ + product: one(products, { + fields: [prices.internal_product_id], + references: [products.internal_id], + }), +})); diff --git a/shared/db/pricesTable.ts b/shared/models/productModels/priceModels/priceTable.ts similarity index 62% rename from shared/db/pricesTable.ts rename to shared/models/productModels/priceModels/priceTable.ts index efb24a871..82d7da31f 100644 --- a/shared/db/pricesTable.ts +++ b/shared/models/productModels/priceModels/priceTable.ts @@ -7,16 +7,18 @@ import { jsonb, text, } from "drizzle-orm/pg-core"; -import { entitlements } from "../models/productModels/entModels/entTable.js"; -import { products } from "./productsTable.js"; +import { entitlements } from "../entModels/entTable.js"; +import { products } from "../productTable.js"; +import { FixedPriceConfig } from "./priceConfig/fixedPriceConfig.js"; +import { UsagePriceConfig } from "./priceConfig/usagePriceConfig.js"; export const prices = pgTable( "prices", { - created_at: numeric("created_at").notNull(), - config: jsonb(), - org_id: text("org_id"), - internal_product_id: text("internal_product_id"), + created_at: numeric({ mode: "number" }).notNull(), + config: jsonb().$type(), + org_id: text("org_id").notNull(), + internal_product_id: text("internal_product_id").notNull(), id: text().primaryKey().notNull(), name: text(), billing_type: text("billing_type"), diff --git a/shared/models/productModels/productEnums.ts b/shared/models/productModels/productEnums.ts new file mode 100644 index 000000000..31ebe9c34 --- /dev/null +++ b/shared/models/productModels/productEnums.ts @@ -0,0 +1 @@ +export const Infinite = "inf"; diff --git a/shared/models/productModels/productItemModels/checkProdItemModels.ts b/shared/models/productModels/productItemModels/checkProdItemModels.ts deleted file mode 100644 index b39beacef..000000000 --- a/shared/models/productModels/productItemModels/checkProdItemModels.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { z } from "zod"; -import { UsageModel } from "../productItemModels.js"; - -export const CheckProdItemSchema = z.object({ - feature_id: z.string().nullish(), - feature_name: z.string().nullish(), - usage_model: z.nativeEnum(UsageModel).nullish(), - - description: z.string(), - price: z.number().nullish(), - - billing_units: z.number().nullish(), -}); - -export type CheckProdItem = z.infer; diff --git a/shared/models/productModels/productModels.ts b/shared/models/productModels/productModels.ts index 76b44b80a..8f4e924b1 100644 --- a/shared/models/productModels/productModels.ts +++ b/shared/models/productModels/productModels.ts @@ -1,11 +1,8 @@ import { z } from "zod"; -import { PriceSchema } from "./priceModels.js"; -import { - EntitlementSchema, - PublicEntitlementSchema, -} from "./entitlementModels.js"; +import { PriceSchema } from "./priceModels/priceModels.js"; +import { EntitlementSchema } from "./entModels/entModels.js"; import { FeatureSchema } from "../featureModels/featureModels.js"; -import { FreeTrialSchema } from "./freeTrialModels.js"; +import { FreeTrialSchema } from "./freeTrialModels/freeTrialModels.js"; export const ProductSchema = z.object({ id: z.string(), @@ -72,22 +69,8 @@ export const FullProductSchema = ProductSchema.extend({ free_trial: FreeTrialSchema.optional(), }); -export const PublicProductSchema = z.object({ - id: z.string(), - name: z.string(), - is_add_on: z.boolean(), - is_default: z.boolean(), - group: z.string(), - free_trial: FreeTrialSchema.nullish(), - entitlements: z.array(PublicEntitlementSchema), - fixed_prices: z.array(PriceSchema), - usage_prices: z.array(PriceSchema), -}); - export type Product = z.infer; export type FrontendProduct = z.infer; export type FullProduct = z.infer; export type CreateProduct = z.infer; -export type PublicProduct = z.infer; - export type UpdateProduct = z.infer; diff --git a/shared/models/productModels/productRelations.ts b/shared/models/productModels/productRelations.ts new file mode 100644 index 000000000..992999d35 --- /dev/null +++ b/shared/models/productModels/productRelations.ts @@ -0,0 +1,9 @@ +import { relations } from "drizzle-orm"; +import { entitlements } from "./entModels/entTable.js"; +import { prices } from "./priceModels/priceTable.js"; +import { products } from "./productTable.js"; + +export const productRelations = relations(products, ({ many }) => ({ + entitlements: many(entitlements), + prices: many(prices), +})); diff --git a/shared/models/productModels/productTable.ts b/shared/models/productModels/productTable.ts new file mode 100644 index 000000000..5f886dabf --- /dev/null +++ b/shared/models/productModels/productTable.ts @@ -0,0 +1,44 @@ +import { + boolean, + foreignKey, + jsonb, + numeric, + pgTable, + text, +} from "drizzle-orm/pg-core"; +import { sql } from "drizzle-orm"; +import { organizations } from "../orgModels/orgTable.js"; +import { collatePgColumn, sqlNow } from "../../db/utils.js"; + +type ProductProcessor = { + type: string; + id: string; +}; + +export const products = pgTable( + "products", + { + internal_id: text("internal_id").primaryKey().notNull(), + id: text().notNull(), + name: text(), + org_id: text("org_id").notNull(), + created_at: numeric({ mode: "number" }).notNull().default(sqlNow), + env: text().notNull(), + is_add_on: boolean("is_add_on").notNull().default(false), + is_default: boolean("is_default").notNull().default(false), + group: text().default(""), + version: numeric({ mode: "number" }).notNull().default(1), + processor: jsonb() + .$type() + .default(sql`null`), + }, + (table) => [ + foreignKey({ + columns: [table.org_id], + foreignColumns: [organizations.id], + name: "products_org_id_fkey", + }).onDelete("cascade"), + ], +); + +collatePgColumn(products.internal_id, "C"); diff --git a/shared/models/productV2Models/productItemModels/checkProdItemModels.ts b/shared/models/productV2Models/productItemModels/checkProdItemModels.ts new file mode 100644 index 000000000..4dcbac377 --- /dev/null +++ b/shared/models/productV2Models/productItemModels/checkProdItemModels.ts @@ -0,0 +1,15 @@ +// import { z } from "zod"; +// import { UsageModel } from "../productItemModels.js"; + +// export const CheckProdItemSchema = z.object({ +// feature_id: z.string().nullish(), +// feature_name: z.string().nullish(), +// usage_model: z.nativeEnum(UsageModel).nullish(), + +// description: z.string(), +// price: z.number().nullish(), + +// billing_units: z.number().nullish(), +// }); + +// export type CheckProdItem = z.infer; diff --git a/shared/models/productModels/productItemModels/prodItemResponseModels.ts b/shared/models/productV2Models/productItemModels/prodItemResponseModels.ts similarity index 91% rename from shared/models/productModels/productItemModels/prodItemResponseModels.ts rename to shared/models/productV2Models/productItemModels/prodItemResponseModels.ts index c525fd305..a2acbd23a 100644 --- a/shared/models/productModels/productItemModels/prodItemResponseModels.ts +++ b/shared/models/productV2Models/productItemModels/prodItemResponseModels.ts @@ -1,12 +1,12 @@ import { z } from "zod"; import { - Infinite, PriceTierSchema, ProductItemFeatureType, ProductItemInterval, ProductItemType, UsageModel, -} from "../productItemModels.js"; +} from "./productItemModels.js"; +import { Infinite } from "../../productModels/productEnums.js"; export const ProductItemResponseSchema = z.object({ // Feature stuff diff --git a/shared/models/productModels/productItemModels.ts b/shared/models/productV2Models/productItemModels/productItemModels.ts similarity index 96% rename from shared/models/productModels/productItemModels.ts rename to shared/models/productV2Models/productItemModels/productItemModels.ts index 271460d41..d22e28387 100644 --- a/shared/models/productModels/productItemModels.ts +++ b/shared/models/productV2Models/productItemModels/productItemModels.ts @@ -1,7 +1,7 @@ import { z } from "zod"; +import { Infinite } from "../../productModels/productEnums.js"; export const TierInfinite = "inf"; -export const Infinite = "inf"; export enum ProductItemInterval { // None = "none", diff --git a/shared/models/productModels/productResponseModels.ts b/shared/models/productV2Models/productResponseModels.ts similarity index 69% rename from shared/models/productModels/productResponseModels.ts rename to shared/models/productV2Models/productResponseModels.ts index e48bc3028..b60ec0ce4 100644 --- a/shared/models/productModels/productResponseModels.ts +++ b/shared/models/productV2Models/productResponseModels.ts @@ -1,12 +1,9 @@ import { z } from "zod"; -import { AppEnv } from "../genModels.js"; -import { ProductItemSchema } from "./productItemModels.js"; -import { FreeTrialResponseSchema, FreeTrialSchema } from "./freeTrialModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; +import { FreeTrialResponseSchema } from "../productModels/freeTrialModels/freeTrialModels.js"; import { ProductItemResponseSchema } from "./productItemModels/prodItemResponseModels.js"; export const ProductResponseSchema = z.object({ - // internal_id: z.string(), - // autumn_id: z.string(), id: z.string(), name: z.string().nullable(), group: z.string().nullable(), diff --git a/shared/models/productModels/productV2Models.ts b/shared/models/productV2Models/productV2Models.ts similarity index 70% rename from shared/models/productModels/productV2Models.ts rename to shared/models/productV2Models/productV2Models.ts index cf1af473a..cce595136 100644 --- a/shared/models/productModels/productV2Models.ts +++ b/shared/models/productV2Models/productV2Models.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { ProductItemSchema } from "./productItemModels.js"; -import { FreeTrialSchema } from "./freeTrialModels.js"; +import { FreeTrialSchema } from "../productModels/freeTrialModels/freeTrialModels.js"; +import { ProductItemSchema } from "./productItemModels/productItemModels.js"; export const ProductV2Schema = z.object({ internal_id: z.string().nullish(), diff --git a/shared/models/subModels/subModels.ts b/shared/models/subModels/subModels.ts index 9e527fbbd..5558363a2 100644 --- a/shared/models/subModels/subModels.ts +++ b/shared/models/subModels/subModels.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { AppEnv } from "../genModels.js"; +import { AppEnv } from "../genModels/genEnums.js"; export const SubscriptionSchema = z.object({ id: z.string(), diff --git a/shared/models/userModels.ts b/shared/models/userModels.ts deleted file mode 100644 index c646cd7c7..000000000 --- a/shared/models/userModels.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface User { - id: string; - email: string; -}