@@ -12,39 +12,70 @@ import {
1212import { persistWorkflowOperation } from '@/socket/database/operations'
1313import type { AuthenticatedSocket } from '@/socket/middleware/auth'
1414import { checkRolePermission } from '@/socket/middleware/permissions'
15- import type { IRoomManager } from '@/socket/rooms'
15+ import type { IRoomManager , UserSession } from '@/socket/rooms'
1616import { WorkflowOperationSchema } from '@/socket/validation/schemas'
1717
1818const logger = createLogger ( 'OperationsHandlers' )
1919
2020export function setupOperationsHandlers ( socket : AuthenticatedSocket , roomManager : IRoomManager ) {
2121 socket . on ( 'workflow-operation' , async ( data ) => {
22- const workflowId = await roomManager . getWorkflowIdForSocket ( socket . id )
23- const session = await roomManager . getUserSession ( socket . id )
22+ const emitOperationError = (
23+ forbidden : { type : string ; message : string ; operation ?: string ; target ?: string } ,
24+ failed ?: { error : string ; retryable ?: boolean }
25+ ) => {
26+ socket . emit ( 'operation-forbidden' , forbidden )
27+ if ( failed && data ?. operationId ) {
28+ socket . emit ( 'operation-failed' , { operationId : data . operationId , ...failed } )
29+ }
30+ }
31+
32+ if ( ! roomManager . isReady ( ) ) {
33+ emitOperationError (
34+ { type : 'ROOM_MANAGER_UNAVAILABLE' , message : 'Realtime unavailable' } ,
35+ { error : 'Realtime unavailable' , retryable : true }
36+ )
37+ return
38+ }
39+
40+ let workflowId : string | null = null
41+ let session : UserSession | null = null
42+
43+ try {
44+ workflowId = await roomManager . getWorkflowIdForSocket ( socket . id )
45+ session = await roomManager . getUserSession ( socket . id )
46+ } catch ( error ) {
47+ logger . error ( 'Error loading session for workflow operation:' , error )
48+ emitOperationError (
49+ { type : 'ROOM_MANAGER_UNAVAILABLE' , message : 'Realtime unavailable' } ,
50+ { error : 'Realtime unavailable' , retryable : true }
51+ )
52+ return
53+ }
2454
2555 if ( ! workflowId || ! session ) {
26- socket . emit ( 'operation-forbidden' , {
27- type : 'SESSION_ERROR' ,
28- message : 'Session expired, please rejoin workflow' ,
29- } )
30- if ( data ?. operationId ) {
31- socket . emit ( 'operation-failed' , { operationId : data . operationId , error : 'Session expired' } )
32- }
56+ emitOperationError (
57+ { type : 'SESSION_ERROR' , message : 'Session expired, please rejoin workflow' } ,
58+ { error : 'Session expired' }
59+ )
3360 return
3461 }
3562
36- const hasRoom = await roomManager . hasWorkflowRoom ( workflowId )
63+ let hasRoom = false
64+ try {
65+ hasRoom = await roomManager . hasWorkflowRoom ( workflowId )
66+ } catch ( error ) {
67+ logger . error ( 'Error checking workflow room:' , error )
68+ emitOperationError (
69+ { type : 'ROOM_MANAGER_UNAVAILABLE' , message : 'Realtime unavailable' } ,
70+ { error : 'Realtime unavailable' , retryable : true }
71+ )
72+ return
73+ }
3774 if ( ! hasRoom ) {
38- socket . emit ( 'operation-forbidden' , {
39- type : 'ROOM_NOT_FOUND' ,
40- message : 'Workflow room not found' ,
41- } )
42- if ( data ?. operationId ) {
43- socket . emit ( 'operation-failed' , {
44- operationId : data . operationId ,
45- error : 'Workflow room not found' ,
46- } )
47- }
75+ emitOperationError (
76+ { type : 'ROOM_NOT_FOUND' , message : 'Workflow room not found' } ,
77+ { error : 'Workflow room not found' }
78+ )
4879 return
4980 }
5081
@@ -77,15 +108,15 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
77108 // Check permissions from cached role for all other operations
78109 if ( ! userPresence ) {
79110 logger . warn ( `User presence not found for socket ${ socket . id } ` )
80- socket . emit ( 'operation-forbidden' , {
81- type : 'SESSION_ERROR' ,
82- message : 'User session not found ',
83- operation ,
84- target ,
85- } )
86- if ( operationId ) {
87- socket . emit ( 'operation-failed' , { operationId , error : 'User session not found' } )
88- }
111+ emitOperationError (
112+ {
113+ type : 'SESSION_ERROR ',
114+ message : 'User session not found' ,
115+ operation ,
116+ target ,
117+ } ,
118+ { error : 'User session not found' }
119+ )
89120 return
90121 }
91122
@@ -97,7 +128,7 @@ export function setupOperationsHandlers(socket: AuthenticatedSocket, roomManager
97128 logger . warn (
98129 `User ${ session . userId } (role: ${ userPresence . role } ) forbidden from ${ operation } on ${ target } `
99130 )
100- socket . emit ( 'operation-forbidden' , {
131+ emitOperationError ( {
101132 type : 'INSUFFICIENT_PERMISSIONS' ,
102133 message : `${ permissionCheck . reason } on '${ target } '` ,
103134 operation,
0 commit comments