All files / web/src/db/schema arcade-rooms.ts

100% Statements 53/53
100% Branches 3/3
100% Functions 0/0
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 542x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
import { createId } from '@paralleldrive/cuid2'
import { integer, sqliteTable, text } from 'drizzle-orm/sqlite-core'
 
export const arcadeRooms = sqliteTable('arcade_rooms', {
  id: text('id')
    .primaryKey()
    .$defaultFn(() => createId()),
 
  // Room identity
  code: text('code', { length: 6 }).notNull().unique(), // e.g., "ABC123"
  name: text('name', { length: 50 }), // Optional: auto-generates from code and game if null
 
  // Creator info
  createdBy: text('created_by').notNull(), // User/guest ID
  creatorName: text('creator_name', { length: 50 }).notNull(),
  createdAt: integer('created_at', { mode: 'timestamp' })
    .notNull()
    .$defaultFn(() => new Date()),
 
  // Lifecycle
  lastActivity: integer('last_activity', { mode: 'timestamp' })
    .notNull()
    .$defaultFn(() => new Date()),
  ttlMinutes: integer('ttl_minutes').notNull().default(60), // Time to live
 
  // Access control
  accessMode: text('access_mode', {
    enum: ['open', 'locked', 'retired', 'password', 'restricted', 'approval-only'],
  })
    .notNull()
    .default('open'),
  password: text('password', { length: 255 }), // Hashed password for password-protected rooms
  displayPassword: text('display_password', { length: 100 }), // Plain text password for display to room owner
 
  // Game configuration (nullable to support game selection in room)
  // Accepts any string - validation happens at runtime against validator registry
  gameName: text('game_name'),
  gameConfig: text('game_config', { mode: 'json' }), // Game-specific settings (nullable when no game selected)
 
  // Current state
  status: text('status', {
    enum: ['lobby', 'playing', 'finished'],
  })
    .notNull()
    .default('lobby'),
  currentSessionId: text('current_session_id'), // FK to arcade_sessions (nullable)
 
  // Metadata
  totalGamesPlayed: integer('total_games_played').notNull().default(0),
})
 
export type ArcadeRoom = typeof arcadeRooms.$inferSelect
export type NewArcadeRoom = typeof arcadeRooms.$inferInsert