Files
2026-03-18 13:34:41 +01:00

111 lines
5.3 KiB
TypeScript

import {
pgTable, pgEnum, text, boolean, integer,
numeric, timestamp, date, unique,
uuid,
} from 'drizzle-orm/pg-core'
import { sql } from 'drizzle-orm'
// ── better-auth managed tables ────────────────────────────────
export const user = pgTable('user', {
id: text('id').primaryKey(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
emailVerified: boolean('email_verified').notNull().default(false),
image: text('image'),
createdAt: timestamp('created_at').notNull(),
updatedAt: timestamp('updated_at').notNull(),
// App-specific additional field
handicapIndex: numeric('handicap_index', { precision: 4, scale: 1 }),
})
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' }),
})
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'),
})
// ── App tables ────────────────────────────────────────────────
export const courses = pgTable('courses', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
name: text('name').notNull(),
par: integer('par').notNull(),
createdBy: text('created_by').notNull().references(() => user.id, { onDelete: 'set null' }),
createdAt: timestamp('created_at').notNull().defaultNow(),
})
export const tees = pgTable('tees', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
courseId: uuid('course_id').notNull().references(() => courses.id, { onDelete: 'cascade' }),
name: text('name').notNull(),
color: text('color').notNull().default('#888888'),
courseRating: numeric('course_rating', { precision: 4, scale: 1 }).notNull(),
slopeRating: integer('slope_rating').notNull(),
createdAt: timestamp('created_at').notNull().defaultNow(),
})
export const holes = pgTable('holes', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
courseId: uuid('course_id').notNull().references(() => courses.id, { onDelete: 'cascade' }),
holeNumber: integer('hole_number').notNull(),
par: integer('par').notNull(),
strokeIndex: integer('stroke_index').notNull(),
}, (t) => [unique().on(t.courseId, t.holeNumber)])
export const roundStatusEnum = pgEnum('round_status', ['lobby', 'active', 'completed'])
export const rounds = pgTable('rounds', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
courseId: uuid('course_id').notNull().references(() => courses.id),
teeId: uuid('tee_id').notNull().references(() => tees.id),
name: text('name'),
date: date('date').notNull().default(sql`current_date`),
holesCount: integer('holes_count').notNull(),
status: roundStatusEnum('status').notNull().default('lobby'),
createdBy: text('created_by').notNull().references(() => user.id),
createdAt: timestamp('created_at').notNull().defaultNow(),
})
export const roundPlayers = pgTable('round_players', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
roundId: uuid('round_id').notNull().references(() => rounds.id, { onDelete: 'cascade' }),
userId: text('user_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
role: text('role').notNull().default('player'),
handicapIndex: numeric('handicap_index', { precision: 4, scale: 1 }),
courseHandicap: integer('course_handicap'),
joinedAt: timestamp('joined_at').notNull().defaultNow(),
}, (t) => [unique().on(t.roundId, t.userId)])
export const roundInvites = pgTable('round_invites', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
roundId: uuid('round_id').notNull().references(() => rounds.id, { onDelete: 'cascade' }),
email: text('email').notNull(),
invitedBy: text('invited_by').notNull().references(() => user.id),
acceptedAt: timestamp('accepted_at'),
expiresAt: timestamp('expires_at').notNull().default(sql`now() + interval '7 days'`),
createdAt: timestamp('created_at').notNull().defaultNow(),
})
export const scores = pgTable('scores', {
id: uuid('id').primaryKey().default(sql`gen_random_uuid()`),
roundId: uuid('round_id').notNull().references(() => rounds.id, { onDelete: 'cascade' }),
holeId: uuid('hole_id').notNull().references(() => holes.id, { onDelete: 'cascade' }),
playerId: text('player_id').notNull().references(() => user.id, { onDelete: 'cascade' }),
strokes: integer('strokes').notNull(),
updatedBy: text('updated_by').notNull().references(() => user.id),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
}, (t) => [unique().on(t.roundId, t.holeId, t.playerId)])