Files
promo_steakhouse/src/db/schema.ts
T
lukas 0ffbad2855
CI / build-and-test (push) Failing after 50s
wip
2026-08-25 12:04:06 +02:00

104 lines
4.1 KiB
TypeScript

import { sql } from 'drizzle-orm'
import { boolean, integer, pgTable, serial, text, timestamp, unique } from 'drizzle-orm/pg-core'
export const restaurantTables = pgTable('restaurant_tables', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
seats: integer('seats').notNull(),
})
export const reservations = pgTable(
'reservations',
{
id: serial('id').primaryKey(),
tableId: integer('table_id')
.notNull()
.references(() => restaurantTables.id, { onDelete: 'cascade' }),
customerName: text('customer_name').notNull(),
customerEmail: text('customer_email').notNull(),
partySize: integer('party_size').notNull(),
reservationTime: timestamp('reservation_time', { withTimezone: true }).notNull(),
// Captured from the reservation-duration setting at booking time, so a later
// change to that setting doesn't retroactively change how long past bookings
// are considered to occupy their table.
durationMinutes: integer('duration_minutes').notNull().default(90),
cancelToken: text('cancel_token')
.notNull()
.unique()
.default(sql`gen_random_uuid()`),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
},
(table) => [unique().on(table.tableId, table.reservationTime)],
)
// Single-row table of restaurant-wide booking rules, editable by admins.
export const restaurantSettings = pgTable('restaurant_settings', {
id: serial('id').primaryKey(),
reservationIntervalMinutes: integer('reservation_interval_minutes').notNull().default(15),
reservationDurationMinutes: integer('reservation_duration_minutes').notNull().default(90),
minLeadTimeMinutes: integer('min_lead_time_minutes').notNull().default(60),
maxLeadTimeDays: integer('max_lead_time_days').notNull().default(60),
})
// Better Auth's standard schema (staff accounts) — see https://www.better-auth.com/docs/concepts/database
// `role`/`banned`/`banReason`/`banExpires` and `session.impersonatedBy` are added by the `admin` plugin.
export const user = pgTable('user', {
id: text('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: boolean('email_verified').notNull(),
image: text('image'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
role: text('role'),
banned: boolean('banned'),
banReason: text('ban_reason'),
banExpires: timestamp('ban_expires'),
})
export const session = pgTable('session', {
id: text('id').primaryKey(),
expiresAt: timestamp('expires_at').notNull(),
token: text('token').notNull().unique(),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
ipAddress: text('ip_address'),
userAgent: text('user_agent'),
userId: text('user_id')
.notNull()
.references(() => user.id, { onDelete: 'cascade' }),
impersonatedBy: text('impersonated_by'),
})
export const account = pgTable('account', {
id: text('id').primaryKey(),
accountId: text('account_id').notNull(),
providerId: text('provider_id').notNull(),
userId: text('user_id')
.notNull()
.references(() => user.id, { onDelete: 'cascade' }),
accessToken: text('access_token'),
refreshToken: text('refresh_token'),
idToken: text('id_token'),
accessTokenExpiresAt: timestamp('access_token_expires_at'),
refreshTokenExpiresAt: timestamp('refresh_token_expires_at'),
scope: text('scope'),
password: text('password'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
})
export const verification = pgTable('verification', {
id: text('id').primaryKey(),
identifier: text('identifier').notNull(),
value: text('value').notNull(),
expiresAt: timestamp('expires_at').notNull(),
createdAt: timestamp('created_at'),
updatedAt: timestamp('updated_at'),
})
export type RestaurantTable = typeof restaurantTables.$inferSelect
export type Reservation = typeof reservations.$inferSelect
export type NewReservation = typeof reservations.$inferInsert
export type RestaurantSettings = typeof restaurantSettings.$inferSelect