fix: replace isLocked with accessMode and add bcryptjs

- Updated all test files to use accessMode instead of isLocked field
- Fixed room-manager tests to reflect new access control schema
- Installed bcryptjs dependency for password hashing
- All access mode TypeScript compilation errors resolved

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-10-13 19:44:14 -05:00
parent 6ff21c4f1d
commit a74b96bb6f
4 changed files with 6796 additions and 12492 deletions

View File

@ -65,7 +65,7 @@ describe('Arcade Rooms API', () => {
expect(room.createdBy).toBe(testGuestId1)
expect(room.gameName).toBe('matching')
expect(room.status).toBe('lobby')
expect(room.isLocked).toBe(false)
expect(room.accessMode).toBe('open')
expect(room.ttlMinutes).toBe(60)
expect(room.code).toMatch(/^[A-Z0-9]{6}$/)
})
@ -180,11 +180,11 @@ describe('Arcade Rooms API', () => {
it('locks room', async () => {
const [updated] = await db
.update(schema.arcadeRooms)
.set({ isLocked: true })
.set({ accessMode: 'locked' })
.where(eq(schema.arcadeRooms.id, testRoomId))
.returning()
expect(updated.isLocked).toBe(true)
expect(updated.accessMode).toBe('locked')
})
it('updates room status', async () => {
@ -442,14 +442,14 @@ describe('Arcade Rooms API', () => {
// Lock one room
await db
.update(schema.arcadeRooms)
.set({ isLocked: true })
.set({ accessMode: 'locked' })
.where(eq(schema.arcadeRooms.id, testRoomId))
const unlockedRooms = await db.query.arcadeRooms.findMany({
where: eq(schema.arcadeRooms.isLocked, false),
const openRooms = await db.query.arcadeRooms.findMany({
where: eq(schema.arcadeRooms.accessMode, 'open'),
})
expect(unlockedRooms.every((r) => !r.isLocked)).toBe(true)
expect(openRooms.every((r) => r.accessMode === 'open')).toBe(true)
})
})
})

View File

@ -33,7 +33,8 @@ vi.mock('@/db', () => ({
code: 'code',
name: 'name',
gameName: 'gameName',
isLocked: 'isLocked',
accessMode: 'accessMode',
password: 'password',
status: 'status',
lastActivity: 'lastActivity',
},
@ -59,7 +60,8 @@ describe('Room Manager', () => {
createdAt: new Date(),
lastActivity: new Date(),
ttlMinutes: 60,
isLocked: false,
accessMode: 'open',
password: null,
gameName: 'matching',
gameConfig: { difficulty: 6 },
status: 'lobby',
@ -245,7 +247,7 @@ describe('Room Manager', () => {
describe('updateRoom', () => {
it('updates room and returns updated data', async () => {
const updates = { name: 'Updated Room', isLocked: true }
const updates = { name: 'Updated Room', status: 'playing' as const }
const mockUpdate = {
set: vi.fn().mockReturnThis(),
@ -257,7 +259,7 @@ describe('Room Manager', () => {
const room = await updateRoom('room-123', updates)
expect(room?.name).toBe('Updated Room')
expect(room?.isLocked).toBe(true)
expect(room?.status).toBe('playing')
expect(db.update).toHaveBeenCalled()
})
@ -328,12 +330,12 @@ describe('Room Manager', () => {
expect(db.query.arcadeRooms.findMany).toHaveBeenCalled()
})
it('excludes locked rooms', async () => {
it('only includes open and password-protected rooms', async () => {
vi.mocked(db.query.arcadeRooms.findMany).mockResolvedValue(activeRooms)
await listActiveRooms()
// Verify the where clause excludes locked rooms
// Verify the where clause filters by accessMode
const call = vi.mocked(db.query.arcadeRooms.findMany).mock.calls[0][0]
expect(call).toBeDefined()
})

View File

@ -19,7 +19,6 @@ export interface CreateRoomOptions {
export interface UpdateRoomOptions {
name?: string
isLocked?: boolean
status?: 'lobby' | 'playing' | 'finished'
currentSessionId?: string | null
totalGamesPlayed?: number
@ -56,7 +55,7 @@ export async function createRoom(options: CreateRoomOptions): Promise<schema.Arc
createdAt: now,
lastActivity: now,
ttlMinutes: options.ttlMinutes || 60,
isLocked: false,
accessMode: 'open', // Default to open access
gameName: options.gameName,
gameConfig: options.gameConfig as any,
status: 'lobby',
@ -134,6 +133,7 @@ export async function deleteRoom(roomId: string): Promise<void> {
/**
* List active rooms
* Returns rooms ordered by most recently active
* Only returns openly accessible rooms (accessMode: 'open' or 'password')
*/
export async function listActiveRooms(gameName?: GameName): Promise<schema.ArcadeRoom[]> {
const whereConditions = []
@ -143,9 +143,10 @@ export async function listActiveRooms(gameName?: GameName): Promise<schema.Arcad
whereConditions.push(eq(schema.arcadeRooms.gameName, gameName))
}
// Only return non-locked rooms in lobby or playing status
// Only return accessible rooms in lobby or playing status
// Exclude locked, retired, restricted, and approval-only rooms
whereConditions.push(
eq(schema.arcadeRooms.isLocked, false),
or(eq(schema.arcadeRooms.accessMode, 'open'), eq(schema.arcadeRooms.accessMode, 'password')),
or(eq(schema.arcadeRooms.status, 'lobby'), eq(schema.arcadeRooms.status, 'playing'))
)

File diff suppressed because it is too large Load Diff