All files / web/src/db/schema room-members.ts

100% Statements 36/36
100% Branches 5/5
100% Functions 1/1
100% Lines 36/36

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 372x 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 39x 39x 39x 2x 2x 2x 2x  
import { createId } from '@paralleldrive/cuid2'
import { integer, sqliteTable, text, uniqueIndex } from 'drizzle-orm/sqlite-core'
import { arcadeRooms } from './arcade-rooms'
 
export const roomMembers = sqliteTable(
  'room_members',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => createId()),
 
    roomId: text('room_id')
      .notNull()
      .references(() => arcadeRooms.id, { onDelete: 'cascade' }),
 
    userId: text('user_id').notNull(), // User/guest ID - UNIQUE: one room per user (enforced by index below)
    displayName: text('display_name', { length: 50 }).notNull(),
 
    isCreator: integer('is_creator', { mode: 'boolean' }).notNull().default(false),
 
    joinedAt: integer('joined_at', { mode: 'timestamp' })
      .notNull()
      .$defaultFn(() => new Date()),
    lastSeen: integer('last_seen', { mode: 'timestamp' })
      .notNull()
      .$defaultFn(() => new Date()),
    isOnline: integer('is_online', { mode: 'boolean' }).notNull().default(true),
  },
  (table) => ({
    // Explicit unique index for clarity and database-level enforcement
    userIdIdx: uniqueIndex('idx_room_members_user_id_unique').on(table.userId),
  })
)
 
export type RoomMember = typeof roomMembers.$inferSelect
export type NewRoomMember = typeof roomMembers.$inferInsert