Messenger/packages/backend/src/modules/rooms/rooms.repository.ts
Заид Омар Медхат | Zaid Omar Medhat e7f37be62c simple chat init
2026-07-10 15:32:34 +05:00

103 lines
3.1 KiB
TypeScript

import type { Kysely, Selectable } from 'kysely';
import type { Database, RoomsTable } from '../../db/schema';
export type RoomRow = Selectable<RoomsTable>;
export interface RoomMemberWithUser {
user_id: string;
role: string;
joined_at: Date;
username: string;
display_name: string;
avatar_ref: string | null;
}
export interface RoomsRepository {
createWithOwner(name: string, ownerId: string): Promise<RoomRow>;
findById(id: string): Promise<RoomRow | undefined>;
listForUser(userId: string): Promise<RoomRow[]>;
isMember(roomId: string, userId: string): Promise<boolean>;
getRole(roomId: string, userId: string): Promise<string | undefined>;
addMember(roomId: string, userId: string, role: string): Promise<void>;
removeMember(roomId: string, userId: string): Promise<void>;
listMembers(roomId: string): Promise<RoomMemberWithUser[]>;
}
export const createRoomsRepository = (db: Kysely<Database>): RoomsRepository => ({
createWithOwner: (name, ownerId) =>
db.transaction().execute(async (trx) => {
const room = await trx
.insertInto('rooms')
.values({ name, created_by: ownerId })
.returningAll()
.executeTakeFirstOrThrow();
await trx
.insertInto('room_members')
.values({ room_id: room.id, user_id: ownerId, role: 'owner' })
.execute();
return room;
}),
findById: (id) => db.selectFrom('rooms').selectAll().where('id', '=', id).executeTakeFirst(),
listForUser: (userId) =>
db
.selectFrom('rooms')
.innerJoin('room_members', 'room_members.room_id', 'rooms.id')
.where('room_members.user_id', '=', userId)
.selectAll('rooms')
.orderBy('rooms.created_at', 'desc')
.execute(),
isMember: async (roomId, userId) => {
const row = await db
.selectFrom('room_members')
.select('user_id')
.where('room_id', '=', roomId)
.where('user_id', '=', userId)
.executeTakeFirst();
return row !== undefined;
},
getRole: async (roomId, userId) => {
const row = await db
.selectFrom('room_members')
.select('role')
.where('room_id', '=', roomId)
.where('user_id', '=', userId)
.executeTakeFirst();
return row?.role;
},
addMember: async (roomId, userId, role) => {
await db
.insertInto('room_members')
.values({ room_id: roomId, user_id: userId, role })
.onConflict((oc) => oc.columns(['room_id', 'user_id']).doNothing())
.execute();
},
removeMember: async (roomId, userId) => {
await db
.deleteFrom('room_members')
.where('room_id', '=', roomId)
.where('user_id', '=', userId)
.execute();
},
listMembers: (roomId) =>
db
.selectFrom('room_members')
.innerJoin('users', 'users.id', 'room_members.user_id')
.where('room_members.room_id', '=', roomId)
.select([
'room_members.user_id as user_id',
'room_members.role as role',
'room_members.joined_at as joined_at',
'users.username as username',
'users.display_name as display_name',
'users.avatar_ref as avatar_ref',
])
.orderBy('room_members.joined_at', 'asc')
.execute(),
});