From fc8af865fcbfeb6d2e5ba9041b65ba09aa6f2ff6 Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:48:56 +1300 Subject: [PATCH 1/7] chore: refactor createCheckout to provide client secret if user session is missing --- api/controller/stripeController.ts | 111 +++++++++-------------------- 1 file changed, 33 insertions(+), 78 deletions(-) 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); } From c2610ae756442daa91015ce768feae703a1de783 Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:49:25 +1300 Subject: [PATCH 2/7] I fucking hate drizzle sometimes --- api/schemas/relations.ts | 264 ++++++++++---------- api/schemas/schema.ts | 511 ++++++++++++++++++--------------------- 2 files changed, 362 insertions(+), 413 deletions(-) diff --git a/api/schemas/relations.ts b/api/schemas/relations.ts index da1bf79..2e20f6b 100644 --- a/api/schemas/relations.ts +++ b/api/schemas/relations.ts @@ -2,8 +2,9 @@ import { relations } from "drizzle-orm/relations"; import { adminUsers, tickets, - oauthClients, - oauthSessions, + answers, + answersPeopleTicketLinks, + userTickets, purchasableMemberships, adminPermissions, adminRoles, @@ -19,7 +20,6 @@ import { upPermissions, upRoles, upUsers, - answers, events, eventGalleries, execs, @@ -28,9 +28,7 @@ import { peoples, previousTeams, questions, - socials, somePhotos, - userTickets, values, adminPermissionsRoleLinks, adminUsersRolesLinks, @@ -42,21 +40,22 @@ import { strapiReleaseActionsReleaseLinks, upPermissionsRoleLinks, upUsersRoleLinks, - answersUserTicketIdLinks, answersQuestionIdLinks, questionsTicketIdLinks, ticketsEventIdLinks, userTicketsPeopleIdLinks, userTicketsTicketIdLinks, + oauthClients, + oauthSessions, apps, roles, totpUsers, tenants, - sessionAccessTokenSigningKeys, userLastActive, + sessionAccessTokenSigningKeys, emailverificationVerifiedEmails, - userMetadata, rolePermissions, + userMetadata, tenantConfigs, tenantFirstFactors, tenantRequiredSecondaryFactors, @@ -66,12 +65,12 @@ import { appIdToUserId, useridMapping, oauthM2MTokens, - keyValue, - emailpasswordUsers, - emailpasswordPswdResetTokens, thirdpartyUserToTenant, jwtSigningKeys, passwordlessUsers, + keyValue, + emailpasswordUsers, + emailpasswordPswdResetTokens, passwordlessUserToTenant, dashboardUsers, dashboardUserSessions, @@ -116,6 +115,12 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ purchasableMemberships_updatedById: many(purchasableMemberships, { relationName: "purchasableMemberships_updatedById_adminUsers_id", }), + userTickets_createdById: many(userTickets, { + relationName: "userTickets_createdById_adminUsers_id", + }), + userTickets_updatedById: many(userTickets, { + relationName: "userTickets_updatedById_adminUsers_id", + }), adminUser_createdById: one(adminUsers, { fields: [adminUsers.createdById], references: [adminUsers.id], @@ -276,24 +281,12 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ 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", }), - userTickets_createdById: many(userTickets, { - relationName: "userTickets_createdById_adminUsers_id", - }), - userTickets_updatedById: many(userTickets, { - relationName: "userTickets_updatedById_adminUsers_id", - }), values_createdById: many(values, { relationName: "values_createdById_adminUsers_id", }), @@ -303,26 +296,51 @@ 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], +export const answersPeopleTicketLinksRelations = relations( + answersPeopleTicketLinks, + ({ one }) => ({ + answer: one(answers, { + fields: [answersPeopleTicketLinks.answerId], + references: [answers.id], + }), + userTicket: one(userTickets, { + fields: [answersPeopleTicketLinks.userTicketId], + references: [userTickets.id], }), - oauthLogoutChallenges: many(oauthLogoutChallenges), }) ); +export const answersRelations = relations(answers, ({ one, many }) => ({ + answersPeopleTicketLinks: many(answersPeopleTicketLinks), + adminUser_createdById: one(adminUsers, { + fields: [answers.createdById], + references: [adminUsers.id], + relationName: "answers_createdById_adminUsers_id", + }), + adminUser_updatedById: one(adminUsers, { + fields: [answers.updatedById], + references: [adminUsers.id], + relationName: "answers_updatedById_adminUsers_id", + }), + answersQuestionIdLinks: many(answersQuestionIdLinks), +})); + +export const userTicketsRelations = relations(userTickets, ({ one, many }) => ({ + answersPeopleTicketLinks: many(answersPeopleTicketLinks), + adminUser_createdById: one(adminUsers, { + fields: [userTickets.createdById], + references: [adminUsers.id], + relationName: "userTickets_createdById_adminUsers_id", + }), + adminUser_updatedById: one(adminUsers, { + fields: [userTickets.updatedById], + references: [adminUsers.id], + relationName: "userTickets_updatedById_adminUsers_id", + }), + userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), + userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), +})); + export const purchasableMembershipsRelations = relations( purchasableMemberships, ({ one }) => ({ @@ -578,21 +596,6 @@ export const upUsersRelations = relations(upUsers, ({ one, many }) => ({ upUsersRoleLinks: many(upUsersRoleLinks), })); -export const answersRelations = relations(answers, ({ one, many }) => ({ - adminUser_createdById: one(adminUsers, { - fields: [answers.createdById], - references: [adminUsers.id], - relationName: "answers_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [answers.updatedById], - references: [adminUsers.id], - relationName: "answers_updatedById_adminUsers_id", - }), - answersPeopleIdLinks: many(answersUserTicketIdLinks), - answersQuestionIdLinks: many(answersQuestionIdLinks), -})); - export const eventsRelations = relations(events, ({ one, many }) => ({ adminUser_createdById: one(adminUsers, { fields: [events.createdById], @@ -658,7 +661,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 +673,6 @@ export const peoplesRelations = relations(peoples, ({ one, many }) => ({ references: [adminUsers.id], relationName: "peoples_updatedById_adminUsers_id", }), - answersPeopleIdLinks: many(answersUserTicketIdLinks), userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), })); @@ -702,19 +704,6 @@ export const questionsRelations = relations(questions, ({ one, many }) => ({ questionsTicketIdLinks: many(questionsTicketIdLinks), })); -export const socialsRelations = relations(socials, ({ one }) => ({ - adminUser_createdById: one(adminUsers, { - fields: [socials.createdById], - references: [adminUsers.id], - relationName: "socials_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [socials.updatedById], - references: [adminUsers.id], - relationName: "socials_updatedById_adminUsers_id", - }), -})); - export const somePhotosRelations = relations(somePhotos, ({ one }) => ({ adminUser_createdById: one(adminUsers, { fields: [somePhotos.createdById], @@ -728,21 +717,6 @@ export const somePhotosRelations = relations(somePhotos, ({ one }) => ({ }), })); -export const userTicketsRelations = relations(userTickets, ({ one, many }) => ({ - adminUser_createdById: one(adminUsers, { - fields: [userTickets.createdById], - references: [adminUsers.id], - relationName: "userTickets_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [userTickets.updatedById], - references: [adminUsers.id], - relationName: "userTickets_updatedById_adminUsers_id", - }), - userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), - userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), -})); - export const valuesRelations = relations(values, ({ one }) => ({ adminUser_createdById: one(adminUsers, { fields: [values.createdById], @@ -895,20 +869,6 @@ export const upUsersRoleLinksRelations = relations( }), }) ); -// update realtion -export const answersPeopleIdLinksRelations = relations( - answersUserTicketIdLinks, - ({ one }) => ({ - answer: one(answers, { - fields: [answersUserTicketIdLinks.answerId], - references: [answers.id], - }), - people: one(userTickets, { - fields: [answersUserTicketIdLinks.userTicketId], - references: [userTickets.id], - }), - }) -); export const answersQuestionIdLinksRelations = relations( answersQuestionIdLinks, @@ -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,12 +972,12 @@ 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), jwtSigningKeys: many(jwtSigningKeys), + appIdToUserIds: many(appIdToUserId), dashboardUsers: many(dashboardUsers), oauthClients: many(oauthClients), })); @@ -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 }) => ({ @@ -1052,13 +1032,6 @@ export const emailverificationVerifiedEmailsRelations = relations( }) ); -export const userMetadataRelations = relations(userMetadata, ({ one }) => ({ - app: one(apps, { - fields: [userMetadata.appId], - references: [apps.appId], - }), -})); - export const rolePermissionsRelations = relations( rolePermissions, ({ one }) => ({ @@ -1069,6 +1042,13 @@ export const rolePermissionsRelations = relations( }) ); +export const userMetadataRelations = relations(userMetadata, ({ one }) => ({ + app: one(apps, { + fields: [userMetadata.appId], + references: [apps.appId], + }), +})); + export const tenantFirstFactorsRelations = relations( tenantFirstFactors, ({ one }) => ({ @@ -1141,6 +1121,7 @@ export const appIdToUserIdRelations = relations( appIdToUserId, ({ one, many }) => ({ useridMappings: many(useridMapping), + passwordlessUsers: many(passwordlessUsers), appIdToUserId: one(appIdToUserId, { fields: [appIdToUserId.appId], references: [appIdToUserId.appId], @@ -1155,7 +1136,6 @@ export const appIdToUserIdRelations = relations( }), emailpasswordUsers: many(emailpasswordUsers), emailpasswordPswdResetTokens: many(emailpasswordPswdResetTokens), - passwordlessUsers: many(passwordlessUsers), thirdpartyUsers: many(thirdpartyUsers), allAuthRecipeUsers_appId: many(allAuthRecipeUsers, { relationName: "allAuthRecipeUsers_appId_appIdToUserId_appId", @@ -1170,33 +1150,6 @@ export const oauthM2MTokensRelations = relations(oauthM2MTokens, ({ one }) => ({ }), })); -export const keyValueRelations = relations(keyValue, ({ one }) => ({ - tenant: one(tenants, { - fields: [keyValue.appId], - references: [tenants.appId], - }), -})); - -export const emailpasswordUsersRelations = relations( - emailpasswordUsers, - ({ one }) => ({ - appIdToUserId: one(appIdToUserId, { - fields: [emailpasswordUsers.appId], - references: [appIdToUserId.appId], - }), - }) -); - -export const emailpasswordPswdResetTokensRelations = relations( - emailpasswordPswdResetTokens, - ({ one }) => ({ - appIdToUserId: one(appIdToUserId, { - fields: [emailpasswordPswdResetTokens.appId], - references: [appIdToUserId.appId], - }), - }) -); - export const thirdpartyUserToTenantRelations = relations( thirdpartyUserToTenant, ({ one }) => ({ @@ -1224,6 +1177,33 @@ export const passwordlessUsersRelations = relations( }) ); +export const keyValueRelations = relations(keyValue, ({ one }) => ({ + tenant: one(tenants, { + fields: [keyValue.appId], + references: [tenants.appId], + }), +})); + +export const emailpasswordUsersRelations = relations( + emailpasswordUsers, + ({ one }) => ({ + appIdToUserId: one(appIdToUserId, { + fields: [emailpasswordUsers.appId], + references: [appIdToUserId.appId], + }), + }) +); + +export const emailpasswordPswdResetTokensRelations = relations( + emailpasswordPswdResetTokens, + ({ one }) => ({ + appIdToUserId: one(appIdToUserId, { + fields: [emailpasswordPswdResetTokens.appId], + references: [appIdToUserId.appId], + }), + }) +); + export const passwordlessUserToTenantRelations = relations( passwordlessUserToTenant, ({ one }) => ({ diff --git a/api/schemas/schema.ts b/api/schemas/schema.ts index 1c3ac56..ad87311 100644 --- a/api/schemas/schema.ts +++ b/api/schemas/schema.ts @@ -9,12 +9,12 @@ import { integer, text, timestamp, - bigint, - unique, json, jsonb, - date, + unique, doublePrecision, + bigint, + date, primaryKey, char, } from "drizzle-orm/pg-core"; @@ -65,52 +65,6 @@ export const tickets = 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 strapiMigrations = pgTable("strapi_migrations", { id: serial("id").primaryKey().notNull(), name: varchar("name", { length: 255 }), @@ -142,6 +96,39 @@ export const strapiWebhooks = pgTable("strapi_webhooks", { enabled: boolean("enabled"), }); +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(() => userTickets.id, { + onDelete: "cascade", + }), + answerOrder: doublePrecision("answer_order"), + }, + (table) => { + return { + fk: index("answers_people_ticket_links_fk").using( + "btree", + table.answerId + ), + invFk: index("answers_people_ticket_links_inv_fk").using( + "btree", + table.userTicketId + ), + orderInvFk: index("answers_people_ticket_links_order_inv_fk").using( + "btree", + table.answerOrder + ), + answersPeopleTicketLinksUnique: unique( + "answers_people_ticket_links_unique" + ).on(table.answerId, table.userTicketId), + }; + } +); + export const purchasableMemberships = pgTable( "purchasable_memberships", { @@ -177,6 +164,49 @@ export const purchasableMemberships = 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 userTickets = pgTable( + "user_tickets", + { + id: serial("id").primaryKey().notNull(), + peopleTicketCode: varchar("people_ticket_code", { 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", + }), + name: varchar("name", { length: 255 }), + email: varchar("email", { length: 255 }), + phoneNumber: varchar("phone_number", { length: 255 }), + attendance: boolean("attendance"), + paid: boolean("paid"), + }, + (table) => { + return { + createdByIdFk: index("user_tickets_created_by_id_fk").using( + "btree", + table.createdById + ), + updatedByIdFk: index("user_tickets_updated_by_id_fk").using( + "btree", + table.updatedById + ), + }; + } +); + export const adminUsers = pgTable( "admin_users", { @@ -987,36 +1017,6 @@ export const questions = pgTable( } ); -export const socials = pgTable( - "socials", - { - id: serial("id").primaryKey().notNull(), - type: varchar("type", { length: 255 }), - link: varchar("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("socials_created_by_id_fk").using( - "btree", - table.createdById - ), - updatedByIdFk: index("socials_updated_by_id_fk").using( - "btree", - table.updatedById - ), - }; - } -); - export const somePhotos = pgTable( "some_photos", { @@ -1047,40 +1047,6 @@ export const somePhotos = pgTable( } ); -export const userTickets = pgTable( - "user_tickets", - { - id: serial("id").primaryKey().notNull(), - name: varchar("name", { length: 255 }), - email: varchar("email", { length: 255 }), - phoneNumber: varchar("phone_number", { length: 255 }), - peopleTicketCode: varchar("people_ticket_code", { length: 255 }), - attendance: boolean("attendance"), - paid: boolean("paid"), - 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("user_tickets_created_by_id_fk").using( - "btree", - table.createdById - ), - updatedByIdFk: index("user_tickets_updated_by_id_fk").using( - "btree", - table.updatedById - ), - }; - } -); - export const values = pgTable( "values", { @@ -1429,40 +1395,6 @@ export const upUsersRoleLinks = pgTable( } ); -// THIS NEEDS TO BE CHANMGED -export const answersUserTicketIdLinks = pgTable( - "answers_user_ticket_id_links", - { - id: serial("id").primaryKey().notNull(), - answerId: integer("answer_id").references(() => answers.id, { - onDelete: "cascade", - }), - userTicketId: integer("user_ticket_id").references(() => peoples.id, { - onDelete: "cascade", - }), - answerOrder: doublePrecision("answer_order"), - }, - (table) => { - return { - fk: index("answers_user_ticket_id_links_fk").using( - "btree", - table.answerId - ), - invFk: index("answers_user_ticket_id_links_inv_fk").using( - "btree", - table.userTicketId - ), - orderInvFk: index("answers_user_ticket_id_links_order_inv_fk").using( - "btree", - table.answerOrder - ), - answersUserTicketIdLinksUnique: unique( - "answers_user_ticket_id_links_unique" - ).on(table.answerId, table.userTicketId), - }; - } -); - export const answersQuestionIdLinks = pgTable( "answers_question_id_links", { @@ -1556,7 +1488,7 @@ export const ticketsEventIdLinks = pgTable( }; } ); -// update this + export const userTicketsPeopleIdLinks = pgTable( "user_tickets_people_id_links", { @@ -1623,6 +1555,43 @@ export const userTicketsTicketIdLinks = pgTable( } ); +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,30 +1654,6 @@ export const tenants = pgTable( } ); -export const sessionAccessTokenSigningKeys = pgTable( - "session_access_token_signing_keys", - { - appId: varchar("app_id", { length: 64 }) - .default("public") - .notNull() - .references(() => apps.appId, { onDelete: "cascade" }), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - createdAtTime: bigint("created_at_time", { mode: "number" }).notNull(), - value: text("value"), - }, - (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", - }), - }; - } -); - export const userLastActive = pgTable( "user_last_active", { @@ -1736,43 +1681,46 @@ export const userLastActive = pgTable( } ); -export const emailverificationVerifiedEmails = pgTable( - "emailverification_verified_emails", +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(), - email: varchar("email", { length: 256 }).notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + createdAtTime: bigint("created_at_time", { mode: "number" }).notNull(), + value: text("value"), }, (table) => { return { - appIdIdx: index().using("btree", table.appId), - emailverificationVerifiedEmailsPkey: primaryKey({ - columns: [table.appId, table.userId, table.email], - name: "emailverification_verified_emails_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", }), }; } ); -export const userMetadata = pgTable( - "user_metadata", +export const emailverificationVerifiedEmails = pgTable( + "emailverification_verified_emails", { appId: varchar("app_id", { length: 64 }) .default("public") .notNull() .references(() => apps.appId, { onDelete: "cascade" }), userId: varchar("user_id", { length: 128 }).notNull(), - userMetadata: text("user_metadata").notNull(), + email: varchar("email", { length: 256 }).notNull(), }, (table) => { return { appIdIdx: index().using("btree", table.appId), - userMetadataPkey: primaryKey({ - columns: [table.appId, table.userId], - name: "user_metadata_pkey", + emailverificationVerifiedEmailsPkey: primaryKey({ + columns: [table.appId, table.userId, table.email], + name: "emailverification_verified_emails_pkey", }), }; } @@ -1810,6 +1758,27 @@ export const rolePermissions = pgTable( } ); +export const userMetadata = pgTable( + "user_metadata", + { + appId: varchar("app_id", { length: 64 }) + .default("public") + .notNull() + .references(() => apps.appId, { onDelete: "cascade" }), + userId: varchar("user_id", { length: 128 }).notNull(), + userMetadata: text("user_metadata").notNull(), + }, + (table) => { + return { + appIdIdx: index().using("btree", table.appId), + userMetadataPkey: primaryKey({ + columns: [table.appId, table.userId], + name: "user_metadata_pkey", + }), + }; + } +); + export const tenantFirstFactors = pgTable( "tenant_first_factors", { @@ -2018,6 +1987,91 @@ export const oauthM2MTokens = pgTable( } ); +export const thirdpartyUserToTenant = pgTable( + "thirdparty_user_to_tenant", + { + appId: varchar("app_id", { length: 64 }).default("public").notNull(), + tenantId: varchar("tenant_id", { length: 64 }).default("public").notNull(), + userId: char("user_id", { length: 36 }).notNull(), + thirdPartyId: varchar("third_party_id", { length: 28 }).notNull(), + thirdPartyUserId: varchar("third_party_user_id", { length: 256 }).notNull(), + }, + (table) => { + return { + thirdpartyUserToTenantUserIdFkey: foreignKey({ + columns: [table.appId, table.tenantId, table.userId], + foreignColumns: [ + allAuthRecipeUsers.appId, + allAuthRecipeUsers.tenantId, + allAuthRecipeUsers.userId, + ], + name: "thirdparty_user_to_tenant_user_id_fkey", + }).onDelete("cascade"), + thirdpartyUserToTenantPkey: primaryKey({ + columns: [table.appId, table.tenantId, table.userId], + name: "thirdparty_user_to_tenant_pkey", + }), + thirdpartyUserToTenantThirdPartyUserIdKey: unique( + "thirdparty_user_to_tenant_third_party_user_id_key" + ).on( + table.appId, + table.tenantId, + table.thirdPartyId, + table.thirdPartyUserId + ), + }; + } +); + +export const jwtSigningKeys = pgTable( + "jwt_signing_keys", + { + appId: varchar("app_id", { length: 64 }) + .default("public") + .notNull() + .references(() => apps.appId, { onDelete: "cascade" }), + keyId: varchar("key_id", { length: 255 }).notNull(), + keyString: text("key_string").notNull(), + algorithm: varchar("algorithm", { length: 10 }).notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + createdAt: bigint("created_at", { mode: "number" }), + }, + (table) => { + return { + appIdIdx: index().using("btree", table.appId), + jwtSigningKeysPkey: primaryKey({ + columns: [table.appId, table.keyId], + name: "jwt_signing_keys_pkey", + }), + }; + } +); + +export const passwordlessUsers = pgTable( + "passwordless_users", + { + appId: varchar("app_id", { length: 64 }).default("public").notNull(), + userId: char("user_id", { length: 36 }).notNull(), + email: varchar("email", { length: 256 }), + phoneNumber: varchar("phone_number", { length: 256 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + timeJoined: bigint("time_joined", { mode: "number" }).notNull(), + }, + (table) => { + return { + passwordlessUsersUserIdFkey: foreignKey({ + columns: [table.appId, table.userId], + foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], + name: "passwordless_users_user_id_fkey", + }).onDelete("cascade"), + passwordlessUsersPkey: primaryKey({ + columns: [table.appId, table.userId], + name: "passwordless_users_pkey", + }), + }; + } +); + export const keyValue = pgTable( "key_value", { @@ -2148,91 +2202,6 @@ export const emailpasswordPswdResetTokens = pgTable( } ); -export const thirdpartyUserToTenant = pgTable( - "thirdparty_user_to_tenant", - { - appId: varchar("app_id", { length: 64 }).default("public").notNull(), - tenantId: varchar("tenant_id", { length: 64 }).default("public").notNull(), - userId: char("user_id", { length: 36 }).notNull(), - thirdPartyId: varchar("third_party_id", { length: 28 }).notNull(), - thirdPartyUserId: varchar("third_party_user_id", { length: 256 }).notNull(), - }, - (table) => { - return { - thirdpartyUserToTenantUserIdFkey: foreignKey({ - columns: [table.appId, table.tenantId, table.userId], - foreignColumns: [ - allAuthRecipeUsers.appId, - allAuthRecipeUsers.tenantId, - allAuthRecipeUsers.userId, - ], - name: "thirdparty_user_to_tenant_user_id_fkey", - }).onDelete("cascade"), - thirdpartyUserToTenantPkey: primaryKey({ - columns: [table.appId, table.tenantId, table.userId], - name: "thirdparty_user_to_tenant_pkey", - }), - thirdpartyUserToTenantThirdPartyUserIdKey: unique( - "thirdparty_user_to_tenant_third_party_user_id_key" - ).on( - table.appId, - table.tenantId, - table.thirdPartyId, - table.thirdPartyUserId - ), - }; - } -); - -export const jwtSigningKeys = pgTable( - "jwt_signing_keys", - { - appId: varchar("app_id", { length: 64 }) - .default("public") - .notNull() - .references(() => apps.appId, { onDelete: "cascade" }), - keyId: varchar("key_id", { length: 255 }).notNull(), - keyString: text("key_string").notNull(), - algorithm: varchar("algorithm", { length: 10 }).notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - createdAt: bigint("created_at", { mode: "number" }), - }, - (table) => { - return { - appIdIdx: index().using("btree", table.appId), - jwtSigningKeysPkey: primaryKey({ - columns: [table.appId, table.keyId], - name: "jwt_signing_keys_pkey", - }), - }; - } -); - -export const passwordlessUsers = pgTable( - "passwordless_users", - { - appId: varchar("app_id", { length: 64 }).default("public").notNull(), - userId: char("user_id", { length: 36 }).notNull(), - email: varchar("email", { length: 256 }), - phoneNumber: varchar("phone_number", { length: 256 }), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - timeJoined: bigint("time_joined", { mode: "number" }).notNull(), - }, - (table) => { - return { - passwordlessUsersUserIdFkey: foreignKey({ - columns: [table.appId, table.userId], - foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], - name: "passwordless_users_user_id_fkey", - }).onDelete("cascade"), - passwordlessUsersPkey: primaryKey({ - columns: [table.appId, table.userId], - name: "passwordless_users_pkey", - }), - }; - } -); - export const passwordlessUserToTenant = pgTable( "passwordless_user_to_tenant", { From 7d344438f73c0bd3f86978a09612aea8f52d4eff Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:50:24 +1300 Subject: [PATCH 3/7] chore: add exec role to supertokens --- api/supertokens/supertokens.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/supertokens/supertokens.ts b/api/supertokens/supertokens.ts index 6dcb4a9..04d80a8 100644 --- a/api/supertokens/supertokens.ts +++ b/api/supertokens/supertokens.ts @@ -179,11 +179,18 @@ export async function createRoles() { "read", "write", ]); + const execRole = await UserRoles.createNewRoleOrAddPermissions("exec", [ + "read", + "write", + ]); const userRole = await UserRoles.createNewRoleOrAddPermissions("user", []); if (userRole.createdNewRole === false) { // The role already exists } + if (execRole.createdNewRole === false) { + // The role already exists + } if (adminRole.createdNewRole === false) { // The role already exists } From 456ec25c37350f590c4535671fc0a8d657cfe62b Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:51:18 +1300 Subject: [PATCH 4/7] chore: refactor routes order in index.ts --- api/index.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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); From 4d487de65bb661a1d88f57619209160eabe9ea67 Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:03:52 +1300 Subject: [PATCH 5/7] chore: delete unused sampleEvents file --- api/db/sampleEvents.ts | 82 ------------------------------------------ 1 file changed, 82 deletions(-) delete mode 100644 api/db/sampleEvents.ts diff --git a/api/db/sampleEvents.ts b/api/db/sampleEvents.ts deleted file mode 100644 index a06480f..0000000 --- a/api/db/sampleEvents.ts +++ /dev/null @@ -1,82 +0,0 @@ -const events = [ - { - _id: "1", - title: "Live Concert: Wireless Beats", - imageUrl: "/images/concert.jpg", - description: - "Experience an immersive listening journey with our live concert event. Featuring state-of-the-art Bluetooth technology, high-quality AAC audio, and interactive experiences to connect with your favorite music like never before.", - organizer: "Apple", - category: "Music", - price: 89.99, - seatsAvailable: 1000, - rating: 4.5, - numReviews: 12, - }, - { - _id: "2", - title: "Tech Talk: iPhone 11 Pro Innovations", - imageUrl: "/images/techtalk.jpg", - description: - "Join us for a deep dive into the iPhone 11 Pro. Discover the transformative triple-camera system and significant leaps in battery life and performance.", - organizer: "Apple", - category: "Technology", - price: 599.99, - seatsAvailable: 500, - rating: 4.0, - numReviews: 8, - }, - { - _id: "3", - title: "Photography Workshop: Canon EOS 80D", - imageUrl: "/images/workshop.jpg", - description: - "Explore the Canon EOS 80D with hands-on guidance in our workshop. Learn about its versatile imaging specs, robust focusing systems, and intuitive design from industry experts.", - organizer: "Cannon", - category: "Photography", - price: 929.99, - seatsAvailable: 15, - rating: 3, - numReviews: 12, - }, - { - _id: "4", - title: "Gaming Marathon: Playstation 4 Pro Showdown", - imageUrl: "/images/gaming.jpg", - description: - "The ultimate gaming marathon is here. Join us for non-stop PlayStation action, featuring HD movies, music, and the best games on the market.", - organizer: "Sony", - category: "Gaming", - price: 399.99, - seatsAvailable: 200, - rating: 5, - numReviews: 12, - }, - { - _id: "5", - title: "Esports Tournament: Ultimate Gaming Challenge", - imageUrl: "/images/esports.jpg", - description: - "Get ready for the Logitech LIGHTSYNC Esports Tournament. Customize your play with programmable buttons and experience gaming like never before.", - organizer: "Logitech", - category: "Gaming", - price: 49.99, - seatsAvailable: 100, - rating: 3.5, - numReviews: 10, - }, - { - _id: "6", - title: "Smart Home Seminar: Amazon Echo Dot Masterclass", - imageUrl: "/images/smarthome.jpg", - description: - "Meet Echo Dot in our smart home seminar. Discover compact design and how it fits into your smart home ecosystem, offering hands-free help in any room.", - organizer: "Amazon", - category: "Technology", - price: 29.99, - seatsAvailable: 0, // Could indicate sold out or not available - rating: 4, - numReviews: 12, - }, -]; - -export default events; From 62f9957d977f0e0b6b3bf125715c0c326588d3c5 Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:08:35 +1300 Subject: [PATCH 6/7] chore: fix drizzle malfunctioning (please dont' malfunction anymore drizzle) --- api/.gitignore | 2 + api/drizzle-schema.config.ts | 5 +- api/drizzle.config.ts | 2 +- api/package.json | 2 +- api/schemas/relations.ts | 282 ++++++++-------- api/schemas/schema.ts | 616 +++++++++++++++++------------------ 6 files changed, 454 insertions(+), 455 deletions(-) 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/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/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 2e20f6b..8e70447 100644 --- a/api/schemas/relations.ts +++ b/api/schemas/relations.ts @@ -1,11 +1,6 @@ import { relations } from "drizzle-orm/relations"; import { adminUsers, - tickets, - answers, - answersPeopleTicketLinks, - userTickets, - purchasableMemberships, adminPermissions, adminRoles, strapiApiTokens, @@ -20,6 +15,7 @@ import { upPermissions, upRoles, upUsers, + answers, events, eventGalleries, execs, @@ -27,8 +23,11 @@ import { partners, peoples, previousTeams, + purchasableMemberships, questions, somePhotos, + tickets, + userTickets, values, adminPermissionsRoleLinks, adminUsersRolesLinks, @@ -40,6 +39,7 @@ import { strapiReleaseActionsReleaseLinks, upPermissionsRoleLinks, upUsersRoleLinks, + answersPeopleTicketLinks, answersQuestionIdLinks, questionsTicketIdLinks, ticketsEventIdLinks, @@ -54,8 +54,8 @@ import { userLastActive, sessionAccessTokenSigningKeys, emailverificationVerifiedEmails, - rolePermissions, userMetadata, + rolePermissions, tenantConfigs, tenantFirstFactors, tenantRequiredSecondaryFactors, @@ -65,12 +65,12 @@ import { appIdToUserId, useridMapping, oauthM2MTokens, + keyValue, + emailpasswordPswdResetTokens, + emailpasswordUsers, thirdpartyUserToTenant, jwtSigningKeys, passwordlessUsers, - keyValue, - emailpasswordUsers, - emailpasswordPswdResetTokens, passwordlessUserToTenant, dashboardUsers, dashboardUserSessions, @@ -86,41 +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", - }), - userTickets_createdById: many(userTickets, { - relationName: "userTickets_createdById_adminUsers_id", - }), - userTickets_updatedById: many(userTickets, { - relationName: "userTickets_updatedById_adminUsers_id", - }), adminUser_createdById: one(adminUsers, { fields: [adminUsers.createdById], references: [adminUsers.id], @@ -275,6 +241,12 @@ 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", }), @@ -287,6 +259,18 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ 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", + }), + userTickets_updatedById: many(userTickets, { + relationName: "userTickets_updatedById_adminUsers_id", + }), values_createdById: many(values, { relationName: "values_createdById_adminUsers_id", }), @@ -296,67 +280,6 @@ export const adminUsersRelations = relations(adminUsers, ({ one, many }) => ({ adminUsersRolesLinks: many(adminUsersRolesLinks), })); -export const answersPeopleTicketLinksRelations = relations( - answersPeopleTicketLinks, - ({ one }) => ({ - answer: one(answers, { - fields: [answersPeopleTicketLinks.answerId], - references: [answers.id], - }), - userTicket: one(userTickets, { - fields: [answersPeopleTicketLinks.userTicketId], - references: [userTickets.id], - }), - }) -); - -export const answersRelations = relations(answers, ({ one, many }) => ({ - answersPeopleTicketLinks: many(answersPeopleTicketLinks), - adminUser_createdById: one(adminUsers, { - fields: [answers.createdById], - references: [adminUsers.id], - relationName: "answers_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [answers.updatedById], - references: [adminUsers.id], - relationName: "answers_updatedById_adminUsers_id", - }), - answersQuestionIdLinks: many(answersQuestionIdLinks), -})); - -export const userTicketsRelations = relations(userTickets, ({ one, many }) => ({ - answersPeopleTicketLinks: many(answersPeopleTicketLinks), - adminUser_createdById: one(adminUsers, { - fields: [userTickets.createdById], - references: [adminUsers.id], - relationName: "userTickets_createdById_adminUsers_id", - }), - adminUser_updatedById: one(adminUsers, { - fields: [userTickets.updatedById], - references: [adminUsers.id], - relationName: "userTickets_updatedById_adminUsers_id", - }), - userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), - userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), -})); - -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 }) => ({ @@ -596,6 +519,21 @@ export const upUsersRelations = relations(upUsers, ({ one, many }) => ({ upUsersRoleLinks: many(upUsersRoleLinks), })); +export const answersRelations = relations(answers, ({ one, many }) => ({ + adminUser_createdById: one(adminUsers, { + fields: [answers.createdById], + references: [adminUsers.id], + relationName: "answers_createdById_adminUsers_id", + }), + adminUser_updatedById: one(adminUsers, { + fields: [answers.updatedById], + references: [adminUsers.id], + relationName: "answers_updatedById_adminUsers_id", + }), + answersPeopleTicketLinks: many(answersPeopleTicketLinks), + answersQuestionIdLinks: many(answersQuestionIdLinks), +})); + export const eventsRelations = relations(events, ({ one, many }) => ({ adminUser_createdById: one(adminUsers, { fields: [events.createdById], @@ -689,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], @@ -717,6 +671,38 @@ export const somePhotosRelations = relations(somePhotos, ({ one }) => ({ }), })); +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 userTicketsRelations = relations(userTickets, ({ one, many }) => ({ + adminUser_createdById: one(adminUsers, { + fields: [userTickets.createdById], + references: [adminUsers.id], + relationName: "userTickets_createdById_adminUsers_id", + }), + adminUser_updatedById: one(adminUsers, { + fields: [userTickets.updatedById], + references: [adminUsers.id], + relationName: "userTickets_updatedById_adminUsers_id", + }), + answersPeopleTicketLinks: many(answersPeopleTicketLinks), + userTicketsPeopleIdLinks: many(userTicketsPeopleIdLinks), + userTicketsTicketIdLinks: many(userTicketsTicketIdLinks), +})); + export const valuesRelations = relations(values, ({ one }) => ({ adminUser_createdById: one(adminUsers, { fields: [values.createdById], @@ -870,6 +856,20 @@ export const upUsersRoleLinksRelations = relations( }) ); +export const answersPeopleTicketLinksRelations = relations( + answersPeopleTicketLinks, + ({ one }) => ({ + answer: one(answers, { + fields: [answersPeopleTicketLinks.answerId], + references: [answers.id], + }), + userTicket: one(userTickets, { + fields: [answersPeopleTicketLinks.userTicketId], + references: [userTickets.id], + }), + }) +); + export const answersQuestionIdLinksRelations = relations( answersQuestionIdLinks, ({ one }) => ({ @@ -976,8 +976,8 @@ export const appsRelations = relations(apps, ({ many }) => ({ sessionAccessTokenSigningKeys: many(sessionAccessTokenSigningKeys), emailverificationVerifiedEmails: many(emailverificationVerifiedEmails), userMetadata: many(userMetadata), - jwtSigningKeys: many(jwtSigningKeys), appIdToUserIds: many(appIdToUserId), + jwtSigningKeys: many(jwtSigningKeys), dashboardUsers: many(dashboardUsers), oauthClients: many(oauthClients), })); @@ -1032,6 +1032,13 @@ export const emailverificationVerifiedEmailsRelations = relations( }) ); +export const userMetadataRelations = relations(userMetadata, ({ one }) => ({ + app: one(apps, { + fields: [userMetadata.appId], + references: [apps.appId], + }), +})); + export const rolePermissionsRelations = relations( rolePermissions, ({ one }) => ({ @@ -1042,13 +1049,6 @@ export const rolePermissionsRelations = relations( }) ); -export const userMetadataRelations = relations(userMetadata, ({ one }) => ({ - app: one(apps, { - fields: [userMetadata.appId], - references: [apps.appId], - }), -})); - export const tenantFirstFactorsRelations = relations( tenantFirstFactors, ({ one }) => ({ @@ -1121,7 +1121,6 @@ export const appIdToUserIdRelations = relations( appIdToUserId, ({ one, many }) => ({ useridMappings: many(useridMapping), - passwordlessUsers: many(passwordlessUsers), appIdToUserId: one(appIdToUserId, { fields: [appIdToUserId.appId], references: [appIdToUserId.appId], @@ -1134,8 +1133,9 @@ 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, { relationName: "allAuthRecipeUsers_appId_appIdToUserId_appId", @@ -1150,40 +1150,23 @@ export const oauthM2MTokensRelations = relations(oauthM2MTokens, ({ one }) => ({ }), })); -export const thirdpartyUserToTenantRelations = relations( - thirdpartyUserToTenant, - ({ one }) => ({ - allAuthRecipeUser: one(allAuthRecipeUsers, { - fields: [thirdpartyUserToTenant.appId], - references: [allAuthRecipeUsers.appId], - }), - }) -); - -export const jwtSigningKeysRelations = relations(jwtSigningKeys, ({ one }) => ({ - app: one(apps, { - fields: [jwtSigningKeys.appId], - references: [apps.appId], +export const keyValueRelations = relations(keyValue, ({ one }) => ({ + tenant: one(tenants, { + fields: [keyValue.appId], + references: [tenants.appId], }), })); -export const passwordlessUsersRelations = relations( - passwordlessUsers, +export const emailpasswordPswdResetTokensRelations = relations( + emailpasswordPswdResetTokens, ({ one }) => ({ appIdToUserId: one(appIdToUserId, { - fields: [passwordlessUsers.appId], + fields: [emailpasswordPswdResetTokens.appId], references: [appIdToUserId.appId], }), }) ); -export const keyValueRelations = relations(keyValue, ({ one }) => ({ - tenant: one(tenants, { - fields: [keyValue.appId], - references: [tenants.appId], - }), -})); - export const emailpasswordUsersRelations = relations( emailpasswordUsers, ({ one }) => ({ @@ -1194,11 +1177,28 @@ export const emailpasswordUsersRelations = relations( }) ); -export const emailpasswordPswdResetTokensRelations = relations( - emailpasswordPswdResetTokens, +export const thirdpartyUserToTenantRelations = relations( + thirdpartyUserToTenant, + ({ one }) => ({ + allAuthRecipeUser: one(allAuthRecipeUsers, { + fields: [thirdpartyUserToTenant.appId], + references: [allAuthRecipeUsers.appId], + }), + }) +); + +export const jwtSigningKeysRelations = relations(jwtSigningKeys, ({ one }) => ({ + app: one(apps, { + fields: [jwtSigningKeys.appId], + references: [apps.appId], + }), +})); + +export const passwordlessUsersRelations = relations( + passwordlessUsers, ({ one }) => ({ appIdToUserId: one(appIdToUserId, { - fields: [emailpasswordPswdResetTokens.appId], + fields: [passwordlessUsers.appId], references: [appIdToUserId.appId], }), }) diff --git a/api/schemas/schema.ts b/api/schemas/schema.ts index ad87311..d42bd92 100644 --- a/api/schemas/schema.ts +++ b/api/schemas/schema.ts @@ -1,70 +1,25 @@ import { pgTable, - index, - foreignKey, serial, varchar, - numeric, - boolean, - integer, - text, timestamp, json, + text, jsonb, - unique, - doublePrecision, + boolean, + index, + foreignKey, + integer, bigint, + numeric, + unique, date, + doublePrecision, primaryKey, char, } 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 strapiMigrations = pgTable("strapi_migrations", { id: serial("id").primaryKey().notNull(), name: varchar("name", { length: 255 }), @@ -96,117 +51,6 @@ export const strapiWebhooks = pgTable("strapi_webhooks", { enabled: boolean("enabled"), }); -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(() => userTickets.id, { - onDelete: "cascade", - }), - answerOrder: doublePrecision("answer_order"), - }, - (table) => { - return { - fk: index("answers_people_ticket_links_fk").using( - "btree", - table.answerId - ), - invFk: index("answers_people_ticket_links_inv_fk").using( - "btree", - table.userTicketId - ), - orderInvFk: index("answers_people_ticket_links_order_inv_fk").using( - "btree", - table.answerOrder - ), - answersPeopleTicketLinksUnique: unique( - "answers_people_ticket_links_unique" - ).on(table.answerId, table.userTicketId), - }; - } -); - -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 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 userTickets = pgTable( - "user_tickets", - { - id: serial("id").primaryKey().notNull(), - peopleTicketCode: varchar("people_ticket_code", { 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", - }), - name: varchar("name", { length: 255 }), - email: varchar("email", { length: 255 }), - phoneNumber: varchar("phone_number", { length: 255 }), - attendance: boolean("attendance"), - paid: boolean("paid"), - }, - (table) => { - return { - createdByIdFk: index("user_tickets_created_by_id_fk").using( - "btree", - table.createdById - ), - updatedByIdFk: index("user_tickets_updated_by_id_fk").using( - "btree", - table.updatedById - ), - }; - } -); - export const adminUsers = pgTable( "admin_users", { @@ -987,6 +831,41 @@ export const previousTeams = pgTable( } ); +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"), + 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" }), + 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("purchasable_memberships_created_by_id_fk").using( + "btree", + table.createdById + ), + updatedByIdFk: index("purchasable_memberships_updated_by_id_fk").using( + "btree", + table.updatedById + ), + }; + } +); + export const questions = pgTable( "questions", { @@ -1047,12 +926,27 @@ export const somePhotos = pgTable( } ); -export const values = pgTable( - "values", +export const tickets = pgTable( + "tickets", { id: serial("id").primaryKey().notNull(), - title: varchar("title", { length: 255 }), - description: text("description"), + 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" }), @@ -1065,11 +959,11 @@ export const values = pgTable( }, (table) => { return { - createdByIdFk: index("values_created_by_id_fk").using( + createdByIdFk: index("tickets_created_by_id_fk").using( "btree", table.createdById ), - updatedByIdFk: index("values_updated_by_id_fk").using( + updatedByIdFk: index("tickets_updated_by_id_fk").using( "btree", table.updatedById ), @@ -1077,18 +971,82 @@ export const values = pgTable( } ); -export const adminPermissionsRoleLinks = pgTable( - "admin_permissions_role_links", +export const userTickets = pgTable( + "user_tickets", { id: serial("id").primaryKey().notNull(), - permissionId: integer("permission_id").references( - () => adminPermissions.id, - { onDelete: "cascade" } - ), - roleId: integer("role_id").references(() => adminRoles.id, { - onDelete: "cascade", + name: varchar("name", { length: 255 }), + email: varchar("email", { length: 255 }), + phoneNumber: varchar("phone_number", { length: 255 }), + peopleTicketCode: varchar("people_ticket_code", { length: 255 }), + attendance: boolean("attendance"), + paid: boolean("paid"), + 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", }), - permissionOrder: doublePrecision("permission_order"), + updatedById: integer("updated_by_id").references(() => adminUsers.id, { + onDelete: "set null", + }), + }, + (table) => { + return { + createdByIdFk: index("user_tickets_created_by_id_fk").using( + "btree", + table.createdById + ), + updatedByIdFk: index("user_tickets_updated_by_id_fk").using( + "btree", + table.updatedById + ), + }; + } +); + +export const values = pgTable( + "values", + { + id: serial("id").primaryKey().notNull(), + title: varchar("title", { 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", + }), + }, + (table) => { + return { + createdByIdFk: index("values_created_by_id_fk").using( + "btree", + table.createdById + ), + updatedByIdFk: index("values_updated_by_id_fk").using( + "btree", + table.updatedById + ), + }; + } +); + +export const adminPermissionsRoleLinks = pgTable( + "admin_permissions_role_links", + { + id: serial("id").primaryKey().notNull(), + permissionId: integer("permission_id").references( + () => adminPermissions.id, + { onDelete: "cascade" } + ), + roleId: integer("role_id").references(() => adminRoles.id, { + onDelete: "cascade", + }), + permissionOrder: doublePrecision("permission_order"), }, (table) => { return { @@ -1395,6 +1353,39 @@ export const upUsersRoleLinks = pgTable( } ); +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(() => userTickets.id, { + onDelete: "cascade", + }), + answerOrder: doublePrecision("answer_order"), + }, + (table) => { + return { + fk: index("answers_people_ticket_links_fk").using( + "btree", + table.answerId + ), + invFk: index("answers_people_ticket_links_inv_fk").using( + "btree", + table.userTicketId + ), + orderInvFk: index("answers_people_ticket_links_order_inv_fk").using( + "btree", + table.answerOrder + ), + answersPeopleTicketLinksUnique: unique( + "answers_people_ticket_links_unique" + ).on(table.answerId, table.userTicketId), + }; + } +); + export const answersQuestionIdLinks = pgTable( "answers_question_id_links", { @@ -1555,6 +1546,15 @@ 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", { @@ -1726,6 +1726,27 @@ export const emailverificationVerifiedEmails = pgTable( } ); +export const userMetadata = pgTable( + "user_metadata", + { + appId: varchar("app_id", { length: 64 }) + .default("public") + .notNull() + .references(() => apps.appId, { onDelete: "cascade" }), + userId: varchar("user_id", { length: 128 }).notNull(), + userMetadata: text("user_metadata").notNull(), + }, + (table) => { + return { + appIdIdx: index().using("btree", table.appId), + userMetadataPkey: primaryKey({ + columns: [table.appId, table.userId], + name: "user_metadata_pkey", + }), + }; + } +); + export const rolePermissions = pgTable( "role_permissions", { @@ -1758,27 +1779,6 @@ export const rolePermissions = pgTable( } ); -export const userMetadata = pgTable( - "user_metadata", - { - appId: varchar("app_id", { length: 64 }) - .default("public") - .notNull() - .references(() => apps.appId, { onDelete: "cascade" }), - userId: varchar("user_id", { length: 128 }).notNull(), - userMetadata: text("user_metadata").notNull(), - }, - (table) => { - return { - appIdIdx: index().using("btree", table.appId), - userMetadataPkey: primaryKey({ - columns: [table.appId, table.userId], - name: "user_metadata_pkey", - }), - }; - } -); - export const tenantFirstFactors = pgTable( "tenant_first_factors", { @@ -1987,91 +1987,6 @@ export const oauthM2MTokens = pgTable( } ); -export const thirdpartyUserToTenant = pgTable( - "thirdparty_user_to_tenant", - { - appId: varchar("app_id", { length: 64 }).default("public").notNull(), - tenantId: varchar("tenant_id", { length: 64 }).default("public").notNull(), - userId: char("user_id", { length: 36 }).notNull(), - thirdPartyId: varchar("third_party_id", { length: 28 }).notNull(), - thirdPartyUserId: varchar("third_party_user_id", { length: 256 }).notNull(), - }, - (table) => { - return { - thirdpartyUserToTenantUserIdFkey: foreignKey({ - columns: [table.appId, table.tenantId, table.userId], - foreignColumns: [ - allAuthRecipeUsers.appId, - allAuthRecipeUsers.tenantId, - allAuthRecipeUsers.userId, - ], - name: "thirdparty_user_to_tenant_user_id_fkey", - }).onDelete("cascade"), - thirdpartyUserToTenantPkey: primaryKey({ - columns: [table.appId, table.tenantId, table.userId], - name: "thirdparty_user_to_tenant_pkey", - }), - thirdpartyUserToTenantThirdPartyUserIdKey: unique( - "thirdparty_user_to_tenant_third_party_user_id_key" - ).on( - table.appId, - table.tenantId, - table.thirdPartyId, - table.thirdPartyUserId - ), - }; - } -); - -export const jwtSigningKeys = pgTable( - "jwt_signing_keys", - { - appId: varchar("app_id", { length: 64 }) - .default("public") - .notNull() - .references(() => apps.appId, { onDelete: "cascade" }), - keyId: varchar("key_id", { length: 255 }).notNull(), - keyString: text("key_string").notNull(), - algorithm: varchar("algorithm", { length: 10 }).notNull(), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - createdAt: bigint("created_at", { mode: "number" }), - }, - (table) => { - return { - appIdIdx: index().using("btree", table.appId), - jwtSigningKeysPkey: primaryKey({ - columns: [table.appId, table.keyId], - name: "jwt_signing_keys_pkey", - }), - }; - } -); - -export const passwordlessUsers = pgTable( - "passwordless_users", - { - appId: varchar("app_id", { length: 64 }).default("public").notNull(), - userId: char("user_id", { length: 36 }).notNull(), - email: varchar("email", { length: 256 }), - phoneNumber: varchar("phone_number", { length: 256 }), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - timeJoined: bigint("time_joined", { mode: "number" }).notNull(), - }, - (table) => { - return { - passwordlessUsersUserIdFkey: foreignKey({ - columns: [table.appId, table.userId], - foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], - name: "passwordless_users_user_id_fkey", - }).onDelete("cascade"), - passwordlessUsersPkey: primaryKey({ - columns: [table.appId, table.userId], - name: "passwordless_users_pkey", - }), - }; - } -); - export const keyValue = pgTable( "key_value", { @@ -2139,6 +2054,44 @@ export const appIdToUserId = pgTable( } ); +export const emailpasswordPswdResetTokens = pgTable( + "emailpassword_pswd_reset_tokens", + { + appId: varchar("app_id", { length: 64 }).default("public").notNull(), + userId: char("user_id", { length: 36 }).notNull(), + token: varchar("token", { length: 128 }).notNull(), + email: varchar("email", { length: 256 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + tokenExpiry: bigint("token_expiry", { mode: "number" }).notNull(), + }, + (table) => { + return { + emailpasswordPasswordResetTokenExpiryIdx: index( + "emailpassword_password_reset_token_expiry_index" + ).using("btree", table.tokenExpiry), + userIdIdx: index("emailpassword_pswd_reset_tokens_user_id_index").using( + "btree", + table.appId, + table.userId + ), + emailpasswordPswdResetTokensUserIdFkey: foreignKey({ + columns: [table.appId, table.userId], + foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], + name: "emailpassword_pswd_reset_tokens_user_id_fkey", + }) + .onUpdate("cascade") + .onDelete("cascade"), + emailpasswordPswdResetTokensPkey: primaryKey({ + columns: [table.appId, table.userId, table.token], + name: "emailpassword_pswd_reset_tokens_pkey", + }), + emailpasswordPswdResetTokensTokenKey: unique( + "emailpassword_pswd_reset_tokens_token_key" + ).on(table.token), + }; + } +); + export const emailpasswordUsers = pgTable( "emailpassword_users", { @@ -2164,40 +2117,87 @@ export const emailpasswordUsers = pgTable( } ); -export const emailpasswordPswdResetTokens = pgTable( - "emailpassword_pswd_reset_tokens", +export const thirdpartyUserToTenant = pgTable( + "thirdparty_user_to_tenant", { appId: varchar("app_id", { length: 64 }).default("public").notNull(), + tenantId: varchar("tenant_id", { length: 64 }).default("public").notNull(), userId: char("user_id", { length: 36 }).notNull(), - token: varchar("token", { length: 128 }).notNull(), - email: varchar("email", { length: 256 }), - // You can use { mode: "bigint" } if numbers are exceeding js number limitations - tokenExpiry: bigint("token_expiry", { mode: "number" }).notNull(), + thirdPartyId: varchar("third_party_id", { length: 28 }).notNull(), + thirdPartyUserId: varchar("third_party_user_id", { length: 256 }).notNull(), }, (table) => { return { - emailpasswordPasswordResetTokenExpiryIdx: index( - "emailpassword_password_reset_token_expiry_index" - ).using("btree", table.tokenExpiry), - userIdIdx: index("emailpassword_pswd_reset_tokens_user_id_index").using( - "btree", + thirdpartyUserToTenantUserIdFkey: foreignKey({ + columns: [table.appId, table.tenantId, table.userId], + foreignColumns: [ + allAuthRecipeUsers.appId, + allAuthRecipeUsers.tenantId, + allAuthRecipeUsers.userId, + ], + name: "thirdparty_user_to_tenant_user_id_fkey", + }).onDelete("cascade"), + thirdpartyUserToTenantPkey: primaryKey({ + columns: [table.appId, table.tenantId, table.userId], + name: "thirdparty_user_to_tenant_pkey", + }), + thirdpartyUserToTenantThirdPartyUserIdKey: unique( + "thirdparty_user_to_tenant_third_party_user_id_key" + ).on( table.appId, - table.userId + table.tenantId, + table.thirdPartyId, + table.thirdPartyUserId ), - emailpasswordPswdResetTokensUserIdFkey: foreignKey({ + }; + } +); + +export const jwtSigningKeys = pgTable( + "jwt_signing_keys", + { + appId: varchar("app_id", { length: 64 }) + .default("public") + .notNull() + .references(() => apps.appId, { onDelete: "cascade" }), + keyId: varchar("key_id", { length: 255 }).notNull(), + keyString: text("key_string").notNull(), + algorithm: varchar("algorithm", { length: 10 }).notNull(), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + createdAt: bigint("created_at", { mode: "number" }), + }, + (table) => { + return { + appIdIdx: index().using("btree", table.appId), + jwtSigningKeysPkey: primaryKey({ + columns: [table.appId, table.keyId], + name: "jwt_signing_keys_pkey", + }), + }; + } +); + +export const passwordlessUsers = pgTable( + "passwordless_users", + { + appId: varchar("app_id", { length: 64 }).default("public").notNull(), + userId: char("user_id", { length: 36 }).notNull(), + email: varchar("email", { length: 256 }), + phoneNumber: varchar("phone_number", { length: 256 }), + // You can use { mode: "bigint" } if numbers are exceeding js number limitations + timeJoined: bigint("time_joined", { mode: "number" }).notNull(), + }, + (table) => { + return { + passwordlessUsersUserIdFkey: foreignKey({ columns: [table.appId, table.userId], foreignColumns: [appIdToUserId.appId, appIdToUserId.userId], - name: "emailpassword_pswd_reset_tokens_user_id_fkey", - }) - .onUpdate("cascade") - .onDelete("cascade"), - emailpasswordPswdResetTokensPkey: primaryKey({ - columns: [table.appId, table.userId, table.token], - name: "emailpassword_pswd_reset_tokens_pkey", + name: "passwordless_users_user_id_fkey", + }).onDelete("cascade"), + passwordlessUsersPkey: primaryKey({ + columns: [table.appId, table.userId], + name: "passwordless_users_pkey", }), - emailpasswordPswdResetTokensTokenKey: unique( - "emailpassword_pswd_reset_tokens_token_key" - ).on(table.token), }; } ); From 0cceeeeb6f526a0b2cc265eac3db714267f6b6c2 Mon Sep 17 00:00:00 2001 From: Ratchet7x5 <36789694+Ratchet7x5@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:13:34 +1300 Subject: [PATCH 7/7] Revert "chore: delete unused sampleEvents file" This reverts commit 4d487de65bb661a1d88f57619209160eabe9ea67. --- api/db/sampleEvents.ts | 82 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 api/db/sampleEvents.ts diff --git a/api/db/sampleEvents.ts b/api/db/sampleEvents.ts new file mode 100644 index 0000000..a06480f --- /dev/null +++ b/api/db/sampleEvents.ts @@ -0,0 +1,82 @@ +const events = [ + { + _id: "1", + title: "Live Concert: Wireless Beats", + imageUrl: "/images/concert.jpg", + description: + "Experience an immersive listening journey with our live concert event. Featuring state-of-the-art Bluetooth technology, high-quality AAC audio, and interactive experiences to connect with your favorite music like never before.", + organizer: "Apple", + category: "Music", + price: 89.99, + seatsAvailable: 1000, + rating: 4.5, + numReviews: 12, + }, + { + _id: "2", + title: "Tech Talk: iPhone 11 Pro Innovations", + imageUrl: "/images/techtalk.jpg", + description: + "Join us for a deep dive into the iPhone 11 Pro. Discover the transformative triple-camera system and significant leaps in battery life and performance.", + organizer: "Apple", + category: "Technology", + price: 599.99, + seatsAvailable: 500, + rating: 4.0, + numReviews: 8, + }, + { + _id: "3", + title: "Photography Workshop: Canon EOS 80D", + imageUrl: "/images/workshop.jpg", + description: + "Explore the Canon EOS 80D with hands-on guidance in our workshop. Learn about its versatile imaging specs, robust focusing systems, and intuitive design from industry experts.", + organizer: "Cannon", + category: "Photography", + price: 929.99, + seatsAvailable: 15, + rating: 3, + numReviews: 12, + }, + { + _id: "4", + title: "Gaming Marathon: Playstation 4 Pro Showdown", + imageUrl: "/images/gaming.jpg", + description: + "The ultimate gaming marathon is here. Join us for non-stop PlayStation action, featuring HD movies, music, and the best games on the market.", + organizer: "Sony", + category: "Gaming", + price: 399.99, + seatsAvailable: 200, + rating: 5, + numReviews: 12, + }, + { + _id: "5", + title: "Esports Tournament: Ultimate Gaming Challenge", + imageUrl: "/images/esports.jpg", + description: + "Get ready for the Logitech LIGHTSYNC Esports Tournament. Customize your play with programmable buttons and experience gaming like never before.", + organizer: "Logitech", + category: "Gaming", + price: 49.99, + seatsAvailable: 100, + rating: 3.5, + numReviews: 10, + }, + { + _id: "6", + title: "Smart Home Seminar: Amazon Echo Dot Masterclass", + imageUrl: "/images/smarthome.jpg", + description: + "Meet Echo Dot in our smart home seminar. Discover compact design and how it fits into your smart home ecosystem, offering hands-free help in any room.", + organizer: "Amazon", + category: "Technology", + price: 29.99, + seatsAvailable: 0, // Could indicate sold out or not available + rating: 4, + numReviews: 12, + }, +]; + +export default events;