Initial commit v1.1
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
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)])
|
||||
Reference in New Issue
Block a user