@@ -128,6 +128,65 @@ const router = new Hono()
128128 }
129129 } ,
130130 )
131+ /**
132+ * Delete a chat room and all its associated data
133+ *
134+ * This endpoint allows a room member to delete the entire chat room.
135+ * It will:
136+ * 1. Verify the requesting user is a member of the room
137+ * 2. Delete the room (which cascades to messages and memberships due to foreign key constraints)
138+ * 3. Broadcast a DeleteRoom event to all room members
139+ *
140+ * @route DELETE /rooms/:room
141+ * @param room - The ID of the room to delete
142+ * @returns {Object } Success status
143+ * @throws {HTTPException } 404 - If room not found or user is not a member
144+ * @throws {HTTPException } 500 - If room deletion fails
145+ */
146+ . delete (
147+ "/rooms/:room" ,
148+ zValidator ( "param" , z . object ( { room : z . string ( ) } ) ) ,
149+ zValidator ( "header" , z . object ( { Authorization : z . string ( ) } ) ) ,
150+ async ( c ) => {
151+ const userId = await getUserID ( c ) ;
152+ const { room : roomId } = c . req . valid ( "param" ) ;
153+
154+ // Verify user is a member of the room to prevent unauthorized deletion
155+ const membership = await prisma . belongs . findUnique ( {
156+ where : { userId_roomId : { userId, roomId } } ,
157+ select : { roomId : true } ,
158+ } ) ;
159+
160+ if ( ! membership ) {
161+ throw new HTTPException ( 404 , { message : "Room not found or access denied" } ) ;
162+ }
163+
164+ // Get all room members before deletion so we can notify them
165+ const roomMembers = await prisma . belongs . findMany ( {
166+ where : { roomId } ,
167+ select : { userId : true } ,
168+ } ) ;
169+ const memberIds = roomMembers . map ( ( member ) => member . userId ) ;
170+
171+ try {
172+ // Delete the room - this will cascade to messages and memberships
173+ await prisma . room . delete ( {
174+ where : { id : roomId } ,
175+ } ) ;
176+
177+ // Notify all room members that the room was deleted
178+ broadcast ( memberIds , {
179+ event : "DeleteRoom" ,
180+ data : devalue ( { roomId } ) ,
181+ } ) ;
182+
183+ return c . json ( { ok : true } , 200 ) ;
184+ } catch ( err ) {
185+ console . error ( "Failed to delete room:" , err ) ;
186+ throw new HTTPException ( 500 , { message : "Failed to delete room" } ) ;
187+ }
188+ } ,
189+ )
131190 // ## room preview
132191 . get ( "/rooms/preview" , zValidator ( "header" , z . object ( { Authorization : z . string ( ) } ) ) , async ( c ) => {
133192 const requester = await getUserID ( c ) ;
@@ -540,6 +599,12 @@ type BroadcastEvents =
540599 id : string ;
541600 } > ;
542601 }
602+ | {
603+ event : "DeleteRoom" ;
604+ data : Devalue < {
605+ roomId : string ;
606+ } > ;
607+ }
543608 | {
544609 event : "Ping" ;
545610 data : "" ;
0 commit comments