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 | 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'
import { arcadeRooms } from './arcade-rooms'
/**
* Historical record of all users who have ever been in a room
* This table is append-only and tracks the complete history of room membership
*/
export const roomMemberHistory = sqliteTable('room_member_history', {
id: text('id')
.primaryKey()
.$defaultFn(() => createId()),
roomId: text('room_id')
.notNull()
.references(() => arcadeRooms.id, { onDelete: 'cascade' }),
userId: text('user_id').notNull(),
displayName: text('display_name', { length: 50 }).notNull(),
// First time this user joined the room
firstJoinedAt: integer('first_joined_at', { mode: 'timestamp' })
.notNull()
.$defaultFn(() => new Date()),
// Last time we saw this user in the room
lastSeenAt: integer('last_seen_at', { mode: 'timestamp' })
.notNull()
.$defaultFn(() => new Date()),
// Track what happened to this membership
// 'active' - currently in room
// 'left' - voluntarily left
// 'kicked' - kicked by host
// 'banned' - banned by host
lastAction: text('last_action', {
enum: ['active', 'left', 'kicked', 'banned'],
})
.notNull()
.default('active'),
// When the last action occurred
lastActionAt: integer('last_action_at', { mode: 'timestamp' })
.notNull()
.$defaultFn(() => new Date()),
})
export type RoomMemberHistory = typeof roomMemberHistory.$inferSelect
export type NewRoomMemberHistory = typeof roomMemberHistory.$inferInsert
|