From 10ed2cdb4ffe801fa906123fd63f2164c9f10b51 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Thu, 29 Jan 2026 19:37:53 -0600 Subject: [PATCH] feat(#16): implement websocket real-time updates - Add WebSocket gateway with workspace-scoped rooms - Define event types: task.created, task.updated, task.deleted - Define event types: event.created, event.updated, event.deleted - Define event types: project.created, project.updated, project.deleted - Add shared WebSocket types for type safety - WebSocketModule already integrated in AppModule --- apps/api/src/websocket/websocket.gateway.ts | 18 ++++ packages/shared/src/types/index.ts | 3 + packages/shared/src/types/websocket.types.ts | 87 ++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 packages/shared/src/types/websocket.types.ts diff --git a/apps/api/src/websocket/websocket.gateway.ts b/apps/api/src/websocket/websocket.gateway.ts index 1ad17f6..fbc138f 100644 --- a/apps/api/src/websocket/websocket.gateway.ts +++ b/apps/api/src/websocket/websocket.gateway.ts @@ -135,6 +135,15 @@ export class WebSocketGateway implements OnGatewayConnection, OnGatewayDisconnec this.logger.debug(`Emitted event:deleted to ${room}`); } + /** + * Emit project:created event to workspace room + */ + emitProjectCreated(workspaceId: string, project: Project): void { + const room = this.getWorkspaceRoom(workspaceId); + this.server.to(room).emit('project:created', project); + this.logger.debug(`Emitted project:created to ${room}`); + } + /** * Emit project:updated event to workspace room */ @@ -144,6 +153,15 @@ export class WebSocketGateway implements OnGatewayConnection, OnGatewayDisconnec this.logger.debug(`Emitted project:updated to ${room}`); } + /** + * Emit project:deleted event to workspace room + */ + emitProjectDeleted(workspaceId: string, projectId: string): void { + const room = this.getWorkspaceRoom(workspaceId); + this.server.to(room).emit('project:deleted', { id: projectId }); + this.logger.debug(`Emitted project:deleted to ${room}`); + } + /** * Get workspace room name */ diff --git a/packages/shared/src/types/index.ts b/packages/shared/src/types/index.ts index 6df952a..4afa758 100644 --- a/packages/shared/src/types/index.ts +++ b/packages/shared/src/types/index.ts @@ -131,3 +131,6 @@ export * from "./auth.types"; // Export widget types export * from "./widget.types"; + +// Export WebSocket types +export * from "./websocket.types"; diff --git a/packages/shared/src/types/websocket.types.ts b/packages/shared/src/types/websocket.types.ts new file mode 100644 index 0000000..0662eb5 --- /dev/null +++ b/packages/shared/src/types/websocket.types.ts @@ -0,0 +1,87 @@ +/** + * WebSocket event types for real-time updates + */ + +/** + * All supported WebSocket event names + */ +export enum WebSocketEvent { + // Task events + TASK_CREATED = 'task:created', + TASK_UPDATED = 'task:updated', + TASK_DELETED = 'task:deleted', + + // Event events + EVENT_CREATED = 'event:created', + EVENT_UPDATED = 'event:updated', + EVENT_DELETED = 'event:deleted', + + // Project events + PROJECT_CREATED = 'project:created', + PROJECT_UPDATED = 'project:updated', + PROJECT_DELETED = 'project:deleted', +} + +/** + * Base payload interface for all WebSocket events + */ +export interface BaseEventPayload { + id: string; + workspaceId: string; +} + +/** + * Task payload for WebSocket events + */ +export interface TaskEventPayload extends BaseEventPayload { + title?: string; + status?: string; + priority?: string; + assigneeId?: string | null; + projectId?: string | null; + dueDate?: string | null; + [key: string]: unknown; +} + +/** + * Event (calendar) payload for WebSocket events + */ +export interface CalendarEventPayload extends BaseEventPayload { + title?: string; + startTime?: string; + endTime?: string; + allDay?: boolean; + [key: string]: unknown; +} + +/** + * Project payload for WebSocket events + */ +export interface ProjectEventPayload extends BaseEventPayload { + name?: string; + status?: string; + color?: string; + [key: string]: unknown; +} + +/** + * Delete payload - only includes the entity ID + */ +export interface DeleteEventPayload { + id: string; +} + +/** + * WebSocket event handler callbacks + */ +export interface WebSocketCallbacks { + onTaskCreated?: (task: TaskEventPayload) => void; + onTaskUpdated?: (task: TaskEventPayload) => void; + onTaskDeleted?: (payload: DeleteEventPayload) => void; + onEventCreated?: (event: CalendarEventPayload) => void; + onEventUpdated?: (event: CalendarEventPayload) => void; + onEventDeleted?: (payload: DeleteEventPayload) => void; + onProjectCreated?: (project: ProjectEventPayload) => void; + onProjectUpdated?: (project: ProjectEventPayload) => void; + onProjectDeleted?: (payload: DeleteEventPayload) => void; +} -- 2.49.1