diff --git a/api/.gitignore b/api/.gitignore index 600825c..f223f30 100644 --- a/api/.gitignore +++ b/api/.gitignore @@ -46,6 +46,8 @@ jspm_packages/ #Migrations db/migrations/ db/migrations/meta/ +schemas/migrations/ +schemas/migrations/meta/ # Snowpack dependency directory (https://snowpack.dev/) web_modules/ diff --git a/api/controller/stripeController.ts b/api/controller/stripeController.ts index a1776ff..bc33597 100644 --- a/api/controller/stripeController.ts +++ b/api/controller/stripeController.ts @@ -17,19 +17,17 @@ const endpointSecret: string = process.env.STRIPE_WEBHOOK_ENDPOINT as string; export const createCheckout = asyncHandler( async (req: Request, res: Response) => { const { priceId } = req.body; - const session = req.session!; - - // console.log(session.getUserId()); - let email; + if (session) { const user = await getUser(session.getUserId()); email = user?.emails[0]; + } else { + // set to undefined so user manually fills out their email + email = undefined; } - //prefill user email if they are logged in - // if priceId is undefined, send a 404 back. if (priceId == undefined || priceId == "") { return res @@ -54,85 +52,42 @@ export const createCheckout = asyncHandler( reserveTicket(priceId); } } else if (isEventTicket === "n") { - if (!email) { - return res.send({ - error: - "There are no tickets available for this event. Please come back later to see if more tickets become available.", - }); - } + // do nothing } // epoch time in seconds, 30mins timeout let session_expiry = Math.floor(new Date().getTime() / 1000 + 30 * 60); - // Set customer email if they are logged in or don't if they aren't - try { - if (email) { - const session = await stripe.checkout.sessions.create({ - //do not change anything below - ui_mode: "embedded", - // Figure out some way to see if user is logged in, and if so then auto enter email pls - customer_email: `${email}`, - // invoice_creation: { - // enabled: true, - // }, - expires_at: session_expiry, - line_items: [ - { - // Provide the exact Price ID (pr_1234) of the product on sale - price: priceId, - quantity: 1, - }, - ], - mode: "payment", - payment_method_types: ["card"], - currency: "NZD", - return_url: `${process.env.DOMAIN_FRONTEND}/return?session_id={CHECKOUT_SESSION_ID}`, - allow_promotion_codes: true, - - //changeable below: - // use metadata property - metadata: { - priceId: `${priceId}`, - isEventTicket: `${isEventTicket}`, + const session = await stripe.checkout.sessions.create({ + //do not change anything below + ui_mode: "embedded", + customer_email: email, + // invoice_creation: { + // enabled: true, + // }, + expires_at: session_expiry, + line_items: [ + { + // Provide the exact Price ID (pr_1234) of the product on sale + price: priceId, + quantity: 1, }, - }); - - res.send({ clientSecret: session.client_secret }); - } else { - const session = await stripe.checkout.sessions.create({ - //do not change anything below - ui_mode: "embedded", - // Figure out some way to see if user is logged in, and if so then auto enter email pls - // customer_email: `${email}`, - // invoice_creation: { - // enabled: true, - // }, - expires_at: session_expiry, - line_items: [ - { - // Provide the exact Price ID (pr_1234) of the product on sale - price: priceId, - quantity: 1, - }, - ], - mode: "payment", - payment_method_types: ["card"], - currency: "NZD", - return_url: `${process.env.DOMAIN_FRONTEND}/return?session_id={CHECKOUT_SESSION_ID}`, - allow_promotion_codes: true, - - //changeable below: - // use metadata property - metadata: { - priceId: `${priceId}`, - isEventTicket: `${isEventTicket}`, - }, - }); - - res.send({ clientSecret: session.client_secret }); - } + ], + mode: "payment", + payment_method_types: ["card"], + currency: "NZD", + return_url: `${process.env.DOMAIN_FRONTEND}/return?session_id={CHECKOUT_SESSION_ID}`, + allow_promotion_codes: true, + + //changeable below: + metadata: { + priceId: `${priceId}`, + isEventTicket: `${isEventTicket}`, + }, + }); + + res.send({ clientSecret: session.client_secret }); } catch (error) { res.send({ error }).status(404); } diff --git a/api/drizzle-schema.config.ts b/api/drizzle-schema.config.ts index 5b04a03..d29bd1a 100644 --- a/api/drizzle-schema.config.ts +++ b/api/drizzle-schema.config.ts @@ -4,14 +4,11 @@ import { defineConfig } from "drizzle-kit"; export default defineConfig({ schema: "./schemas/*", - out: "./schemas", + out: "./schemas/migrations", dialect: "postgresql", dbCredentials: { url: process.env.DATABASE_URL!, }, - introspect: { - casing: "preserve", - }, verbose: true, strict: true, }); diff --git a/api/drizzle.config.ts b/api/drizzle.config.ts index d30fcbc..d29bd1a 100644 --- a/api/drizzle.config.ts +++ b/api/drizzle.config.ts @@ -4,7 +4,7 @@ import { defineConfig } from "drizzle-kit"; export default defineConfig({ schema: "./schemas/*", - out: "./db/migrations", + out: "./schemas/migrations", dialect: "postgresql", dbCredentials: { url: process.env.DATABASE_URL!, diff --git a/api/index.ts b/api/index.ts index 0345b34..96aefc0 100644 --- a/api/index.ts +++ b/api/index.ts @@ -84,11 +84,8 @@ app.use( // Routes app.use("/api/user", userRoutes); - -//StripeJS -app.use("/api/stripe", stripeRoutes); - app.use("/api/event", eventRoutes); +app.use("/api/stripe", stripeRoutes); // The custom handlers in /middleware need to be below Routes app.use(notFound); diff --git a/api/package.json b/api/package.json index 51653f7..789dda0 100644 --- a/api/package.json +++ b/api/package.json @@ -16,7 +16,7 @@ "db:seed": "node -r esbuild-register ./scripts/seed.ts", "db": "yarn db:generate && yarn db:migrate", "db:visualise": "drizzle-kit studio", - "db:pull": " drizzle-kit introspect --config=drizzle-schema.config.ts", + "db:pull": " drizzle-kit introspect --config=drizzle.config.ts", "db:all": "yarn db:generate && yarn db:migrate && yarn db:seed && yarn drizzle-kit studio --config=drizzle.config.ts", "generate-types": "quicktype ../api/types/types.ts -o ../web/src/types/backend-types.ts --just-types", "watch-types": "nodemon -e ts -x \"yarn generate-types\"" diff --git a/api/schemas/relations.ts b/api/schemas/relations.ts index da1bf79..8e70447 100644 --- a/api/schemas/relations.ts +++ b/api/schemas/relations.ts @@ -1,10 +1,6 @@ import { relations } from "drizzle-orm/relations"; import { adminUsers, - tickets, - oauthClients, - oauthSessions, - purchasableMemberships, adminPermissions, adminRoles, strapiApiTokens, @@ -27,9 +23,10 @@ import { partners, peoples, previousTeams, + purchasableMemberships, questions, - socials, somePhotos, + tickets, userTickets, values, adminPermissionsRoleLinks, @@ -42,18 +39,20 @@ import { strapiReleaseActionsReleaseLinks, upPermissionsRoleLinks, upUsersRoleLinks, - answersUserTicketIdLinks, + answersPeopleTicketLinks, answersQuestionIdLinks, questionsTicketIdLinks, ticketsEventIdLinks, userTicketsPeopleIdLinks, userTicketsTicketIdLinks, + oauthClients, + oauthSessions, apps, roles, totpUsers, tenants, - sessionAccessTokenSigningKeys, userLastActive, + sessionAccessTokenSigningKeys, emailverificationVerifiedEmails, userMetadata, rolePermissions, @@ -67,8 +66,8 @@ import { useridMapping, oauthM2MTokens, keyValue, - emailpasswordUsers, emailpasswordPswdResetTokens, + emailpasswordUsers, thirdpartyUserToTenant, jwtSigningKeys, passwordlessUsers, @@ -87,35 +86,7 @@ import { tenantThirdpartyProviderClients, } from "./schema"; -export const ticketsRelations = relations(tickets, ({ one, many }) => ({ - adminUser_createdById: one(adminUsers, { - fields: [tickets.createdById], - references: [adminUsers.id], - relationName: "tickets_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [tickets.updatedById], - references: [adminUsers.id], - relationName: "tickets_updatedById_adminUsers_id", - }), - questionsTicketIdLinks: many(questionsTicketIdLinks), - ticketsEventIdLinks: many(ticketsEventIdLinks), - userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), -})); - export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ - tickets_createdById: many(tickets, { - relationName: "tickets_createdById_adminUsers_id", - }), - tickets_updatedById: many(tickets, { - relationName: "tickets_updatedById_adminUsers_id", - }), - purchasableMemberships_createdById: many(purchasableMemberships, { - relationName: "purchasableMemberships_createdById_adminUsers_id", - }), - purchasableMemberships_updatedById: many(purchasableMemberships, { - relationName: "purchasableMemberships_updatedById_adminUsers_id", - }), adminUser_createdById: one(adminUsers, { fields: [adminUsers.createdById], references: [adminUsers.id], @@ -270,24 +241,30 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ previousTeams_updatedById: many(previousTeams, { relationName: "previousTeams_updatedById_adminUsers_id", }), + purchasableMemberships_createdById: many(purchasableMemberships, { + relationName: "purchasableMemberships_createdById_adminUsers_id", + }), + purchasableMemberships_updatedById: many(purchasableMemberships, { + relationName: "purchasableMemberships_updatedById_adminUsers_id", + }), questions_createdById: many(questions, { relationName: "questions_createdById_adminUsers_id", }), questions_updatedById: many(questions, { relationName: "questions_updatedById_adminUsers_id", }), - socials_createdById: many(socials, { - relationName: "socials_createdById_adminUsers_id", - }), - socials_updatedById: many(socials, { - relationName: "socials_updatedById_adminUsers_id", - }), somePhotos_createdById: many(somePhotos, { relationName: "somePhotos_createdById_adminUsers_id", }), somePhotos_updatedById: many(somePhotos, { relationName: "somePhotos_updatedById_adminUsers_id", }), + tickets_createdById: many(tickets, { + relationName: "tickets_createdById_adminUsers_id", + }), + tickets_updatedById: many(tickets, { + relationName: "tickets_updatedById_adminUsers_id", + }), userTickets_createdById: many(userTickets, { relationName: "userTickets_createdById_adminUsers_id", }), @@ -303,42 +280,6 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ adminUsersRolesLinks: many(adminUsersRolesLinks), })); -export const oauthSessionsRelations = relations(oauthSessions, ({ one }) => ({ - oauthClient: one(oauthClients, { - fields: [oauthSessions.appId], - references: [oauthClients.appId], - }), -})); - -export const oauthClientsRelations = relations( - oauthClients, - ({ one, many }) => ({ - oauthSessions: many(oauthSessions), - oauthM2MTokens: many(oauthM2MTokens), - app: one(apps, { - fields: [oauthClients.appId], - references: [apps.appId], - }), - oauthLogoutChallenges: many(oauthLogoutChallenges), - }) -); - -export const purchasableMembershipsRelations = relations( - purchasableMemberships, - ({ one }) => ({ - adminUser_createdById: one(adminUsers, { - fields: [purchasableMemberships.createdById], - references: [adminUsers.id], - relationName: "purchasableMemberships_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [purchasableMemberships.updatedById], - references: [adminUsers.id], - relationName: "purchasableMemberships_updatedById_adminUsers_id", - }), - }) -); - export const adminPermissionsRelations = relations( adminPermissions, ({ one, many }) => ({ @@ -589,7 +530,7 @@ export const answersRelations = relations(answers, ({ one, many }) => ({ references: [adminUsers.id], relationName: "answers_updatedById_adminUsers_id", }), - answersPeopleIdLinks: many(answersUserTicketIdLinks), + answersPeopleTicketLinks: many(answersPeopleTicketLinks), answersQuestionIdLinks: many(answersQuestionIdLinks), })); @@ -658,7 +599,7 @@ export const partnersRelations = relations(partners, ({ one }) => ({ relationName: "partners_updatedById_adminUsers_id", }), })); -// update this + export const peoplesRelations = relations(peoples, ({ one, many }) => ({ adminUser_createdById: one(adminUsers, { fields: [peoples.createdById], @@ -670,7 +611,6 @@ export const peoplesRelations = relations(peoples, ({ one, many }) => ({ references: [adminUsers.id], relationName: "peoples_updatedById_adminUsers_id", }), - answersPeopleIdLinks: many(answersUserTicketIdLinks), userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), })); @@ -687,6 +627,22 @@ export const previousTeamsRelations = relations(previousTeams, ({ one }) => ({ }), })); +export const purchasableMembershipsRelations = relations( + purchasableMemberships, + ({ one }) => ({ + adminUser_createdById: one(adminUsers, { + fields: [purchasableMemberships.createdById], + references: [adminUsers.id], + relationName: "purchasableMemberships_createdById_adminUsers_id", + }), + adminUser_updatedById: one(adminUsers, { + fields: [purchasableMemberships.updatedById], + references: [adminUsers.id], + relationName: "purchasableMemberships_updatedById_adminUsers_id", + }), + }) +); + export const questionsRelations = relations(questions, ({ one, many }) => ({ adminUser_createdById: one(adminUsers, { fields: [questions.createdById], @@ -702,30 +658,33 @@ export const questionsRelations = relations(questions, ({ one, many }) => ({ questionsTicketIdLinks: many(questionsTicketIdLinks), })); -export const socialsRelations = relations(socials, ({ one }) => ({ +export const somePhotosRelations = relations(somePhotos, ({ one }) => ({ adminUser_createdById: one(adminUsers, { - fields: [socials.createdById], + fields: [somePhotos.createdById], references: [adminUsers.id], - relationName: "socials_createdById_adminUsers_id", + relationName: "somePhotos_createdById_adminUsers_id", }), adminUser_updatedById: one(adminUsers, { - fields: [socials.updatedById], + fields: [somePhotos.updatedById], references: [adminUsers.id], - relationName: "socials_updatedById_adminUsers_id", + relationName: "somePhotos_updatedById_adminUsers_id", }), })); -export const somePhotosRelations = relations(somePhotos, ({ one }) => ({ +export const ticketsRelations = relations(tickets, ({ one, many }) => ({ adminUser_createdById: one(adminUsers, { - fields: [somePhotos.createdById], + fields: [tickets.createdById], references: [adminUsers.id], - relationName: "somePhotos_createdById_adminUsers_id", + relationName: "tickets_createdById_adminUsers_id", }), adminUser_updatedById: one(adminUsers, { - fields: [somePhotos.updatedById], + fields: [tickets.updatedById], references: [adminUsers.id], - relationName: "somePhotos_updatedById_adminUsers_id", + relationName: "tickets_updatedById_adminUsers_id", }), + questionsTicketIdLinks: many(questionsTicketIdLinks), + ticketsEventIdLinks: many(ticketsEventIdLinks), + userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), })); export const userTicketsRelations = relations(userTickets, ({ one, many }) => ({ @@ -739,6 +698,7 @@ export const userTicketsRelations = relations(userTickets, ({ one, many }) => ({ references: [adminUsers.id], relationName: "userTickets_updatedById_adminUsers_id", }), + answersPeopleTicketLinks: many(answersPeopleTicketLinks), userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), })); @@ -895,16 +855,16 @@ export const upUsersRoleLinksRelations = relations( }), }) ); -// update realtion -export const answersPeopleIdLinksRelations = relations( - answersUserTicketIdLinks, + +export const answersPeopleTicketLinksRelations = relations( + answersPeopleTicketLinks, ({ one }) => ({ answer: one(answers, { - fields: [answersUserTicketIdLinks.answerId], + fields: [answersPeopleTicketLinks.answerId], references: [answers.id], }), - people: one(userTickets, { - fields: [answersUserTicketIdLinks.userTicketId], + userTicket: one(userTickets, { + fields: [answersPeopleTicketLinks.userTicketId], references: [userTickets.id], }), }) @@ -980,6 +940,26 @@ export const userTicketsTicketIdLinksRelations = relations( }) ); +export const oauthSessionsRelations = relations(oauthSessions, ({ one }) => ({ + oauthClient: one(oauthClients, { + fields: [oauthSessions.appId], + references: [oauthClients.appId], + }), +})); + +export const oauthClientsRelations = relations( + oauthClients, + ({ one, many }) => ({ + oauthSessions: many(oauthSessions), + oauthM2MTokens: many(oauthM2MTokens), + app: one(apps, { + fields: [oauthClients.appId], + references: [apps.appId], + }), + oauthLogoutChallenges: many(oauthLogoutChallenges), + }) +); + export const rolesRelations = relations(roles, ({ one, many }) => ({ app: one(apps, { fields: [roles.appId], @@ -992,8 +972,8 @@ export const appsRelations = relations(apps, ({ many }) => ({ roles: many(roles), totpUsers: many(totpUsers), tenants: many(tenants), - sessionAccessTokenSigningKeys: many(sessionAccessTokenSigningKeys), userLastActives: many(userLastActive), + sessionAccessTokenSigningKeys: many(sessionAccessTokenSigningKeys), emailverificationVerifiedEmails: many(emailverificationVerifiedEmails), userMetadata: many(userMetadata), appIdToUserIds: many(appIdToUserId), @@ -1025,6 +1005,13 @@ export const tenantsRelations = relations(tenants, ({ one, many }) => ({ sessionInfos: many(sessionInfo), })); +export const userLastActiveRelations = relations(userLastActive, ({ one }) => ({ + app: one(apps, { + fields: [userLastActive.appId], + references: [apps.appId], + }), +})); + export const sessionAccessTokenSigningKeysRelations = relations( sessionAccessTokenSigningKeys, ({ one }) => ({ @@ -1035,13 +1022,6 @@ export const sessionAccessTokenSigningKeysRelations = relations( }) ); -export const userLastActiveRelations = relations(userLastActive, ({ one }) => ({ - app: one(apps, { - fields: [userLastActive.appId], - references: [apps.appId], - }), -})); - export const emailverificationVerifiedEmailsRelations = relations( emailverificationVerifiedEmails, ({ one }) => ({ @@ -1153,8 +1133,8 @@ export const appIdToUserIdRelations = relations( fields: [appIdToUserId.appId], references: [apps.appId], }), - emailpasswordUsers: many(emailpasswordUsers), emailpasswordPswdResetTokens: many(emailpasswordPswdResetTokens), + emailpasswordUsers: many(emailpasswordUsers), passwordlessUsers: many(passwordlessUsers), thirdpartyUsers: many(thirdpartyUsers), allAuthRecipeUsers_appId: many(allAuthRecipeUsers, { @@ -1177,21 +1157,21 @@ export const keyValueRelations = relations(keyValue, ({ one }) => ({ }), })); -export const emailpasswordUsersRelations = relations( - emailpasswordUsers, +export const emailpasswordPswdResetTokensRelations = relations( + emailpasswordPswdResetTokens, ({ one }) => ({ appIdToUserId: one(appIdToUserId, { - fields: [emailpasswordUsers.appId], + fields: [emailpasswordPswdResetTokens.appId], references: [appIdToUserId.appId], }), }) ); -export const emailpasswordPswdResetTokensRelations = relations( - emailpasswordPswdResetTokens, +export const emailpasswordUsersRelations = relations( + emailpasswordUsers, ({ one }) => ({ appIdToUserId: one(appIdToUserId, { - fields: [emailpasswordPswdResetTokens.appId], + fields: [emailpasswordUsers.appId], references: [appIdToUserId.appId], }), }) diff --git a/api/schemas/schema.ts b/api/schemas/schema.ts index 1c3ac56..d42bd92 100644 --- a/api/schemas/schema.ts +++ b/api/schemas/schema.ts @@ -1,18 +1,18 @@ import { pgTable, - index, - foreignKey, serial, varchar, - numeric, + timestamp, + json, + text, + jsonb, boolean, + index, + foreignKey, integer, - text, - timestamp, bigint, + numeric, unique, - json, - jsonb, date, doublePrecision, primaryKey, @@ -20,97 +20,6 @@ import { } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; -export const tickets = pgTable( - "tickets", - { - id: serial("id").primaryKey().notNull(), - name: varchar("name", { length: 255 }), - discountCode: varchar("discount_code", { length: 255 }), - discountPrice: numeric("discount_price", { precision: 10, scale: 2 }), - price: numeric("price", { precision: 10, scale: 2 }), - isMemberOnly: boolean("is_member_only"), - isDouble: boolean("is_double"), - maxNumberTickets: integer("max_number_tickets"), - numberTicketsLeft: integer("number_tickets_left"), - ticketDescription: text("ticket_description"), - startDateTicketSales: timestamp("start_date_ticket_sales", { - precision: 6, - mode: "string", - }), - isTicketLive: boolean("is_ticket_live"), - ticketLinkBypass: boolean("ticket_link_bypass"), - bypassTicketLink: varchar("bypass_ticket_link", { length: 255 }), - createdAt: timestamp("created_at", { precision: 6, mode: "string" }), - updatedAt: timestamp("updated_at", { precision: 6, mode: "string" }), - publishedAt: timestamp("published_at", { precision: 6, mode: "string" }), - createdById: integer("created_by_id").references(() => adminUsers.id, { - onDelete: "set null", - }), - updatedById: integer("updated_by_id").references(() => adminUsers.id, { - onDelete: "set null", - }), - stripeLink: varchar("stripe_link", { length: 255 }), - }, - (table) => { - return { - createdByIdFk: index("tickets_created_by_id_fk").using( - "btree", - table.createdById - ), - updatedByIdFk: index("tickets_updated_by_id_fk").using( - "btree", - table.updatedById - ), - }; - } -); - -export const apps = pgTable("apps", { - appId: varchar("app_id", { length: 64 }) - .default("public") - .primaryKey() - .notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - createdAtTime: bigint("created_at_time", { mode: "number" }), -}); - -export const oauthSessions = pgTable( - "oauth_sessions", - { - gid: varchar("gid", { length: 255 }).primaryKey().notNull(), - appId: varchar("app_id", { length: 64 }).default("public"), - clientId: varchar("client_id", { length: 255 }).notNull(), - sessionHandle: varchar("session_handle", { length: 128 }), - externalRefreshToken: varchar("external_refresh_token", { length: 255 }), - internalRefreshToken: varchar("internal_refresh_token", { length: 255 }), - jti: text("jti").notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - exp: bigint("exp", { mode: "number" }).notNull(), - }, - (table) => { - return { - oauthSessionExpIdx: index("oauth_session_exp_index").using( - "btree", - table.exp - ), - oauthSessionExternalRefreshTokenIdx: index( - "oauth_session_external_refresh_token_index" - ).using("btree", table.appId, table.externalRefreshToken), - oauthSessionsClientIdFkey: foreignKey({ - columns: [table.appId, table.clientId], - foreignColumns: [oauthClients.appId, oauthClients.clientId], - name: "oauth_sessions_client_id_fkey", - }).onDelete("cascade"), - oauthSessionsExternalRefreshTokenKey: unique( - "oauth_sessions_external_refresh_token_key" - ).on(table.externalRefreshToken), - oauthSessionsInternalRefreshTokenKey: unique( - "oauth_sessions_internal_refresh_token_key" - ).on(table.internalRefreshToken), - }; - } -); - export const strapiMigrations = pgTable("strapi_migrations", { id: serial("id").primaryKey().notNull(), name: varchar("name", { length: 255 }), @@ -142,41 +51,6 @@ export const strapiWebhooks = pgTable("strapi_webhooks", { enabled: boolean("enabled"), }); -export const purchasableMemberships = pgTable( - "purchasable_memberships", - { - id: serial("id").primaryKey().notNull(), - title: varchar("title", { length: 255 }), - expiry: timestamp("expiry", { precision: 6, mode: "string" }), - price: numeric("price", { precision: 10, scale: 2 }), - stripeLink: varchar("stripe_link", { length: 255 }), - description: text("description"), - createdAt: timestamp("created_at", { precision: 6, mode: "string" }), - updatedAt: timestamp("updated_at", { precision: 6, mode: "string" }), - publishedAt: timestamp("published_at", { precision: 6, mode: "string" }), - createdById: integer("created_by_id").references(() => adminUsers.id, { - onDelete: "set null", - }), - updatedById: integer("updated_by_id").references(() => adminUsers.id, { - onDelete: "set null", - }), - membershipLinkBypass: boolean("membership_link_bypass"), - bypassMembershipLink: varchar("bypass_membership_link", { length: 255 }), - }, - (table) => { - return { - createdByIdFk: index("purchasable_memberships_created_by_id_fk").using( - "btree", - table.createdById - ), - updatedByIdFk: index("purchasable_memberships_updated_by_id_fk").using( - "btree", - table.updatedById - ), - }; - } -); - export const adminUsers = pgTable( "admin_users", { @@ -957,12 +831,17 @@ export const previousTeams = pgTable( } ); -export const questions = pgTable( - "questions", +export const purchasableMemberships = pgTable( + "purchasable_memberships", { id: serial("id").primaryKey().notNull(), - question: varchar("question", { length: 255 }), - checkForMemberEmail: boolean("check_for_member_email"), + title: varchar("title", { length: 255 }), + expiry: timestamp("expiry", { precision: 6, mode: "string" }), + price: numeric("price", { precision: 10, scale: 2 }), + stripeLink: varchar("stripe_link", { length: 255 }), + description: text("description"), + membershipLinkBypass: boolean("membership_link_bypass"), + bypassMembershipLink: varchar("bypass_membership_link", { length: 255 }), createdAt: timestamp("created_at", { precision: 6, mode: "string" }), updatedAt: timestamp("updated_at", { precision: 6, mode: "string" }), publishedAt: timestamp("published_at", { precision: 6, mode: "string" }), @@ -975,11 +854,11 @@ export const questions = pgTable( }, (table) => { return { - createdByIdFk: index("questions_created_by_id_fk").using( + createdByIdFk: index("purchasable_memberships_created_by_id_fk").using( "btree", table.createdById ), - updatedByIdFk: index("questions_updated_by_id_fk").using( + updatedByIdFk: index("purchasable_memberships_updated_by_id_fk").using( "btree", table.updatedById ), @@ -987,12 +866,12 @@ export const questions = pgTable( } ); -export const socials = pgTable( - "socials", +export const questions = pgTable( + "questions", { id: serial("id").primaryKey().notNull(), - type: varchar("type", { length: 255 }), - link: varchar("link", { length: 255 }), + question: varchar("question", { length: 255 }), + checkForMemberEmail: boolean("check_for_member_email"), createdAt: timestamp("created_at", { precision: 6, mode: "string" }), updatedAt: timestamp("updated_at", { precision: 6, mode: "string" }), publishedAt: timestamp("published_at", { precision: 6, mode: "string" }), @@ -1005,11 +884,11 @@ export const socials = pgTable( }, (table) => { return { - createdByIdFk: index("socials_created_by_id_fk").using( + createdByIdFk: index("questions_created_by_id_fk").using( "btree", table.createdById ), - updatedByIdFk: index("socials_updated_by_id_fk").using( + updatedByIdFk: index("questions_updated_by_id_fk").using( "btree", table.updatedById ), @@ -1047,6 +926,51 @@ export const somePhotos = pgTable( } ); +export const tickets = pgTable( + "tickets", + { + id: serial("id").primaryKey().notNull(), + name: varchar("name", { length: 255 }), + discountCode: varchar("discount_code", { length: 255 }), + discountPrice: numeric("discount_price", { precision: 10, scale: 2 }), + price: numeric("price", { precision: 10, scale: 2 }), + isMemberOnly: boolean("is_member_only"), + isDouble: boolean("is_double"), + maxNumberTickets: integer("max_number_tickets"), + numberTicketsLeft: integer("number_tickets_left"), + ticketDescription: text("ticket_description"), + startDateTicketSales: timestamp("start_date_ticket_sales", { + precision: 6, + mode: "string", + }), + isTicketLive: boolean("is_ticket_live"), + ticketLinkBypass: boolean("ticket_link_bypass"), + bypassTicketLink: varchar("bypass_ticket_link", { length: 255 }), + stripeLink: varchar("stripe_link", { length: 255 }), + createdAt: timestamp("created_at", { precision: 6, mode: "string" }), + updatedAt: timestamp("updated_at", { precision: 6, mode: "string" }), + publishedAt: timestamp("published_at", { precision: 6, mode: "string" }), + createdById: integer("created_by_id").references(() => adminUsers.id, { + onDelete: "set null", + }), + updatedById: integer("updated_by_id").references(() => adminUsers.id, { + onDelete: "set null", + }), + }, + (table) => { + return { + createdByIdFk: index("tickets_created_by_id_fk").using( + "btree", + table.createdById + ), + updatedByIdFk: index("tickets_updated_by_id_fk").using( + "btree", + table.updatedById + ), + }; + } +); + export const userTickets = pgTable( "user_tickets", { @@ -1429,35 +1353,34 @@ export const upUsersRoleLinks = pgTable( } ); -// THIS NEEDS TO BE CHANMGED -export const answersUserTicketIdLinks = pgTable( - "answers_user_ticket_id_links", +export const answersPeopleTicketLinks = pgTable( + "answers_people_ticket_links", { id: serial("id").primaryKey().notNull(), answerId: integer("answer_id").references(() => answers.id, { onDelete: "cascade", }), - userTicketId: integer("user_ticket_id").references(() => peoples.id, { + userTicketId: integer("user_ticket_id").references(() => userTickets.id, { onDelete: "cascade", }), answerOrder: doublePrecision("answer_order"), }, (table) => { return { - fk: index("answers_user_ticket_id_links_fk").using( + fk: index("answers_people_ticket_links_fk").using( "btree", table.answerId ), - invFk: index("answers_user_ticket_id_links_inv_fk").using( + invFk: index("answers_people_ticket_links_inv_fk").using( "btree", table.userTicketId ), - orderInvFk: index("answers_user_ticket_id_links_order_inv_fk").using( + orderInvFk: index("answers_people_ticket_links_order_inv_fk").using( "btree", table.answerOrder ), - answersUserTicketIdLinksUnique: unique( - "answers_user_ticket_id_links_unique" + answersPeopleTicketLinksUnique: unique( + "answers_people_ticket_links_unique" ).on(table.answerId, table.userTicketId), }; } @@ -1556,7 +1479,7 @@ export const ticketsEventIdLinks = pgTable( }; } ); -// update this + export const userTicketsPeopleIdLinks = pgTable( "user_tickets_people_id_links", { @@ -1623,6 +1546,52 @@ export const userTicketsTicketIdLinks = pgTable( } ); +export const apps = pgTable("apps", { + appId: varchar("app_id", { length: 64 }) + .default("public") + .primaryKey() + .notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + createdAtTime: bigint("created_at_time", { mode: "number" }), +}); + +export const oauthSessions = pgTable( + "oauth_sessions", + { + gid: varchar("gid", { length: 255 }).primaryKey().notNull(), + appId: varchar("app_id", { length: 64 }).default("public"), + clientId: varchar("client_id", { length: 255 }).notNull(), + sessionHandle: varchar("session_handle", { length: 128 }), + externalRefreshToken: varchar("external_refresh_token", { length: 255 }), + internalRefreshToken: varchar("internal_refresh_token", { length: 255 }), + jti: text("jti").notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + exp: bigint("exp", { mode: "number" }).notNull(), + }, + (table) => { + return { + oauthSessionExpIdx: index("oauth_session_exp_index").using( + "btree", + table.exp + ), + oauthSessionExternalRefreshTokenIdx: index( + "oauth_session_external_refresh_token_index" + ).using("btree", table.appId, table.externalRefreshToken), + oauthSessionsClientIdFkey: foreignKey({ + columns: [table.appId, table.clientId], + foreignColumns: [oauthClients.appId, oauthClients.clientId], + name: "oauth_sessions_client_id_fkey", + }).onDelete("cascade"), + oauthSessionsExternalRefreshTokenKey: unique( + "oauth_sessions_external_refresh_token_key" + ).on(table.externalRefreshToken), + oauthSessionsInternalRefreshTokenKey: unique( + "oauth_sessions_internal_refresh_token_key" + ).on(table.internalRefreshToken), + }; + } +); + export const roles = pgTable( "roles", { @@ -1685,52 +1654,52 @@ export const tenants = pgTable( } ); -export const sessionAccessTokenSigningKeys = pgTable( - "session_access_token_signing_keys", +export const userLastActive = pgTable( + "user_last_active", { appId: varchar("app_id", { length: 64 }) .default("public") .notNull() .references(() => apps.appId, { onDelete: "cascade" }), + userId: varchar("user_id", { length: 128 }).notNull(), // You can use { mode: "bigint" } if numbers are exceeding js number limitations - createdAtTime: bigint("created_at_time", { mode: "number" }).notNull(), - value: text("value"), + lastActiveTime: bigint("last_active_time", { mode: "number" }), }, (table) => { return { - accessTokenSigningKeysAppIdIdx: index( - "access_token_signing_keys_app_id_index" - ).using("btree", table.appId), - sessionAccessTokenSigningKeysPkey: primaryKey({ - columns: [table.appId, table.createdAtTime], - name: "session_access_token_signing_keys_pkey", + appIdIdx: index().using("btree", table.appId), + lastActiveTimeIdx: index("user_last_active_last_active_time_index").using( + "btree", + table.lastActiveTime, + table.appId + ), + userLastActivePkey: primaryKey({ + columns: [table.appId, table.userId], + name: "user_last_active_pkey", }), }; } ); -export const userLastActive = pgTable( - "user_last_active", +export const sessionAccessTokenSigningKeys = pgTable( + "session_access_token_signing_keys", { appId: varchar("app_id", { length: 64 }) .default("public") .notNull() .references(() => apps.appId, { onDelete: "cascade" }), - userId: varchar("user_id", { length: 128 }).notNull(), // You can use { mode: "bigint" } if numbers are exceeding js number limitations - lastActiveTime: bigint("last_active_time", { mode: "number" }), + createdAtTime: bigint("created_at_time", { mode: "number" }).notNull(), + value: text("value"), }, (table) => { return { - appIdIdx: index().using("btree", table.appId), - lastActiveTimeIdx: index("user_last_active_last_active_time_index").using( - "btree", - table.lastActiveTime, - table.appId - ), - userLastActivePkey: primaryKey({ - columns: [table.appId, table.userId], - name: "user_last_active_pkey", + accessTokenSigningKeysAppIdIdx: index( + "access_token_signing_keys_app_id_index" + ).using("btree", table.appId), + sessionAccessTokenSigningKeysPkey: primaryKey({ + columns: [table.appId, table.createdAtTime], + name: "session_access_token_signing_keys_pkey", }), }; } @@ -2085,31 +2054,6 @@ export const appIdToUserId = pgTable( } ); -export const emailpasswordUsers = pgTable( - "emailpassword_users", - { - appId: varchar("app_id", { length: 64 }).default("public").notNull(), - userId: char("user_id", { length: 36 }).notNull(), - email: varchar("email", { length: 256 }).notNull(), - passwordHash: varchar("password_hash", { length: 256 }).notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - timeJoined: bigint("time_joined", { mode: "number" }).notNull(), - }, - (table) => { - return { - emailpasswordUsersUserIdFkey: foreignKey({ - columns: [table.appId, table.userId], - foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], - name: "emailpassword_users_user_id_fkey", - }).onDelete("cascade"), - emailpasswordUsersPkey: primaryKey({ - columns: [table.appId, table.userId], - name: "emailpassword_users_pkey", - }), - }; - } -); - export const emailpasswordPswdResetTokens = pgTable( "emailpassword_pswd_reset_tokens", { @@ -2148,6 +2092,31 @@ export const emailpasswordPswdResetTokens = pgTable( } ); +export const emailpasswordUsers = pgTable( + "emailpassword_users", + { + appId: varchar("app_id", { length: 64 }).default("public").notNull(), + userId: char("user_id", { length: 36 }).notNull(), + email: varchar("email", { length: 256 }).notNull(), + passwordHash: varchar("password_hash", { length: 256 }).notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + timeJoined: bigint("time_joined", { mode: "number" }).notNull(), + }, + (table) => { + return { + emailpasswordUsersUserIdFkey: foreignKey({ + columns: [table.appId, table.userId], + foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], + name: "emailpassword_users_user_id_fkey", + }).onDelete("cascade"), + emailpasswordUsersPkey: primaryKey({ + columns: [table.appId, table.userId], + name: "emailpassword_users_pkey", + }), + }; + } +); + export const thirdpartyUserToTenant = pgTable( "thirdparty_user_to_tenant", { diff --git a/api/supertokens/supertokens.ts b/api/supertokens/supertokens.ts index 2795c72..6f6ae99 100644 --- a/api/supertokens/supertokens.ts +++ b/api/supertokens/supertokens.ts @@ -179,12 +179,19 @@ export async function createRoles() { "read", "write", ]); + const execRole = await UserRoles.createNewRoleOrAddPermissions("exec", [ + "read", + "write", + ]); const userRole = await UserRoles.createNewRoleOrAddPermissions("user", []); const execRole = await UserRoles.createNewRoleOrAddPermissions("exec", []); if (userRole.createdNewRole === false) { // The role already exists } + if (execRole.createdNewRole === false) { + // The role already exists + } if (adminRole.createdNewRole === false) { // The role already exists }