feat: add WebSocket module for real-time functionalities

- Implemented `WebSocketsGateway` for handling Socket.IO connections, events, and rooms.
- Added `WebSocketsService` to act as a facade for emitting WebSocket events (projects, groups, notifications).
- Registered `WebSocketsModule` and integrated it into `AppModule`.
- Enabled real-time updates in `ProjectsService` and `GroupsService` with relevant WebSocket events (create, update, delete, collaborator/group actions).
This commit is contained in:
2025-05-16 16:42:15 +02:00
parent ad6ef4c907
commit 2697c7ebdd
6 changed files with 345 additions and 20 deletions

View File

@@ -4,10 +4,14 @@ import { DRIZZLE } from '../../../database/database.module';
import * as schema from '../../../database/schema';
import { CreateProjectDto } from '../dto/create-project.dto';
import { UpdateProjectDto } from '../dto/update-project.dto';
import { WebSocketsService } from '../../websockets/websockets.service';
@Injectable()
export class ProjectsService {
constructor(@Inject(DRIZZLE) private readonly db: any) {}
constructor(
@Inject(DRIZZLE) private readonly db: any,
private readonly websocketsService: WebSocketsService,
) {}
/**
* Create a new project
@@ -17,6 +21,13 @@ export class ProjectsService {
.insert(schema.projects)
.values(createProjectDto)
.returning();
// Emit project created event
this.websocketsService.emitProjectUpdated(project.id, {
action: 'created',
project,
});
return project;
}
@@ -70,6 +81,12 @@ export class ProjectsService {
throw new NotFoundException(`Project with ID ${id} not found`);
}
// Emit project updated event
this.websocketsService.emitProjectUpdated(project.id, {
action: 'updated',
project,
});
return project;
}
@@ -86,6 +103,12 @@ export class ProjectsService {
throw new NotFoundException(`Project with ID ${id} not found`);
}
// Emit project deleted event
this.websocketsService.emitProjectUpdated(project.id, {
action: 'deleted',
project,
});
return project;
}
@@ -127,7 +150,7 @@ export class ProjectsService {
*/
async addCollaborator(projectId: string, userId: string) {
// Check if the project exists
await this.findById(projectId);
const project = await this.findById(projectId);
// Check if the user exists
const [user] = await this.db
@@ -163,6 +186,21 @@ export class ProjectsService {
})
.returning();
// Emit collaborator added event
this.websocketsService.emitCollaboratorAdded(projectId, {
project,
user,
collaboration,
});
// Emit notification to the user
this.websocketsService.emitNotification(userId, {
type: 'project_invitation',
message: `You have been added as a collaborator to the project "${project.name}"`,
projectId,
projectName: project.name,
});
return collaboration;
}