import { pgTable, text, timestamp, numeric, boolean, primaryKey } from 'drizzle-orm/pg-core'; import { relations } from 'drizzle-orm'; import { createId } from '@paralleldrive/cuid2'; import type { AdapterAccountType } from '@auth/core/adapters'; export const users = pgTable('user', { id: text('id') .primaryKey() .$defaultFn(() => createId()), name: text('name'), email: text('email').unique(), emailVerified: timestamp('emailVerified', { mode: 'date' }), image: text('image'), password: text('password'), username: text('username').unique() }); export const accounts = pgTable( 'account', { userId: text('userId') .notNull() .references(() => users.id, { onDelete: 'cascade' }), type: text('type').$type().notNull(), provider: text('provider').notNull(), providerAccountId: text('providerAccountId').notNull(), refresh_token: text('refresh_token'), access_token: text('access_token'), expires_at: numeric('expires_at'), token_type: text('token_type'), scope: text('scope'), id_token: text('id_token'), session_state: text('session_state') }, (account) => ({ compoundKey: primaryKey({ columns: [account.provider, account.providerAccountId] }) }) ); export const sessions = pgTable('session', { sessionToken: text('sessionToken').primaryKey(), userId: text('userId') .notNull() .references(() => users.id, { onDelete: 'cascade' }), expires: timestamp('expires', { mode: 'date' }).notNull() }); export const verificationTokens = pgTable( 'verificationToken', { identifier: text('identifier').notNull(), token: text('token').notNull(), expires: timestamp('expires', { mode: 'date' }).notNull() }, (verificationToken) => ({ compositePk: primaryKey({ columns: [verificationToken.identifier, verificationToken.token] }) }) ); export const wishlists = pgTable('wishlists', { id: text('id').primaryKey().$defaultFn(() => createId()), userId: text('user_id').references(() => users.id, { onDelete: 'set null' }), title: text('title').notNull(), description: text('description'), ownerToken: text('owner_token').notNull().unique(), publicToken: text('public_token').notNull().unique(), isFavorite: boolean('is_favorite').default(false).notNull(), color: text('color'), endDate: timestamp('end_date', { mode: 'date' }), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at').defaultNow().notNull() }); export const wishlistsRelations = relations(wishlists, ({ one, many }) => ({ user: one(users, { fields: [wishlists.userId], references: [users.id] }), items: many(items), savedBy: many(savedWishlists) })); export const items = pgTable('items', { id: text('id').primaryKey().$defaultFn(() => createId()), wishlistId: text('wishlist_id') .notNull() .references(() => wishlists.id, { onDelete: 'cascade' }), title: text('title').notNull(), description: text('description'), link: text('link'), imageUrl: text('image_url'), price: numeric('price', { precision: 10, scale: 2 }), currency: text('currency').default('DKK'), color: text('color'), order: numeric('order').notNull().default('0'), isReserved: boolean('is_reserved').default(false).notNull(), createdAt: timestamp('created_at').defaultNow().notNull(), updatedAt: timestamp('updated_at').defaultNow().notNull() }); export const itemsRelations = relations(items, ({ one, many }) => ({ wishlist: one(wishlists, { fields: [items.wishlistId], references: [wishlists.id] }), reservations: many(reservations) })); export const reservations = pgTable('reservations', { id: text('id').primaryKey().$defaultFn(() => createId()), itemId: text('item_id') .notNull() .references(() => items.id, { onDelete: 'cascade' }), reserverName: text('reserver_name'), createdAt: timestamp('created_at').defaultNow().notNull() }); export const reservationsRelations = relations(reservations, ({ one }) => ({ item: one(items, { fields: [reservations.itemId], references: [items.id] }) })); export const savedWishlists = pgTable('saved_wishlists', { id: text('id').primaryKey().$defaultFn(() => createId()), userId: text('user_id') .notNull() .references(() => users.id, { onDelete: 'cascade' }), wishlistId: text('wishlist_id') .notNull() .references(() => wishlists.id, { onDelete: 'cascade' }), ownerToken: text('owner_token'), // Stores the owner token if user has edit access (claimed via edit link) isFavorite: boolean('is_favorite').default(false).notNull(), createdAt: timestamp('created_at').defaultNow().notNull() }); export const savedWishlistsRelations = relations(savedWishlists, ({ one }) => ({ user: one(users, { fields: [savedWishlists.userId], references: [users.id] }), wishlist: one(wishlists, { fields: [savedWishlists.wishlistId], references: [wishlists.id] }) })); export const usersRelations = relations(users, ({ many }) => ({ wishlists: many(wishlists), savedWishlists: many(savedWishlists) })); export type User = typeof users.$inferSelect; export type NewUser = typeof users.$inferInsert; export type Wishlist = typeof wishlists.$inferSelect; export type NewWishlist = typeof wishlists.$inferInsert; export type Item = typeof items.$inferSelect; export type NewItem = typeof items.$inferInsert; export type Reservation = typeof reservations.$inferSelect; export type NewReservation = typeof reservations.$inferInsert; export type SavedWishlist = typeof savedWishlists.$inferSelect; export type NewSavedWishlist = typeof savedWishlists.$inferInsert;