From e4375462a3f796ca8bdeb976986ad1b077a39553 Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Fri, 16 May 2025 23:52:46 +0200 Subject: [PATCH] feat(groups): add support for group metadata with description handling Enhance group service to manage metadata, including descriptions for groups. Update CRUD operations to handle metadata extraction and response formatting. Improve error handling for invalid group IDs and enhance group-person relationship responses with person fetching. --- .../modules/groups/services/groups.service.ts | 157 +++++++++++++----- 1 file changed, 118 insertions(+), 39 deletions(-) diff --git a/backend/src/modules/groups/services/groups.service.ts b/backend/src/modules/groups/services/groups.service.ts index 48d8a64..0d5ca32 100644 --- a/backend/src/modules/groups/services/groups.service.ts +++ b/backend/src/modules/groups/services/groups.service.ts @@ -17,10 +17,17 @@ export class GroupsService { * Create a new group */ async create(createGroupDto: CreateGroupDto) { + // Extract description from DTO if present + const { description, ...restDto } = createGroupDto; + + // Store description in metadata if provided + const metadata = description ? { description } : {}; + const [group] = await this.db .insert(schema.groups) .values({ - ...createGroupDto, + ...restDto, + metadata, }) .returning(); @@ -30,52 +37,108 @@ export class GroupsService { group, }); - return group; + // Add description to response if it exists in metadata + const response = { ...group }; + if (group.metadata && group.metadata.description) { + response.description = group.metadata.description; + } + + return response; } /** * Find all groups */ async findAll() { - return this.db.select().from(schema.groups); + const groups = await this.db.select().from(schema.groups); + + // Add description to each group if it exists in metadata + return groups.map(group => { + const response = { ...group }; + if (group.metadata && group.metadata.description) { + response.description = group.metadata.description; + } + return response; + }); } /** * Find groups by project ID */ async findByProjectId(projectId: string) { - return this.db + const groups = await this.db .select() .from(schema.groups) .where(eq(schema.groups.projectId, projectId)); + + // Add description to each group if it exists in metadata + return groups.map(group => { + const response = { ...group }; + if (group.metadata && group.metadata.description) { + response.description = group.metadata.description; + } + return response; + }); } /** * Find a group by ID */ async findById(id: string) { - const [group] = await this.db - .select() - .from(schema.groups) - .where(eq(schema.groups.id, id)); - - if (!group) { - throw new NotFoundException(`Group with ID ${id} not found`); + // Validate id + if (!id) { + throw new NotFoundException('Group ID is required'); } - return group; + try { + const [group] = await this.db + .select() + .from(schema.groups) + .where(eq(schema.groups.id, id)); + + if (!group) { + throw new NotFoundException(`Group with ID ${id} not found`); + } + + // Add description to response if it exists in metadata + const response = { ...group }; + if (group.metadata && group.metadata.description) { + response.description = group.metadata.description; + } + + return response; + } catch (error) { + // If there's a database error (like invalid UUID format), throw a NotFoundException + throw new NotFoundException(`Group with ID ${id} not found or invalid ID format`); + } } /** * Update a group */ async update(id: string, updateGroupDto: UpdateGroupDto) { + // Ensure we're not losing any fields by first getting the existing group + const existingGroup = await this.findById(id); + + // Extract description from DTO if present + const { description, ...restDto } = updateGroupDto; + + // Prepare metadata with description if provided + let metadata = existingGroup.metadata || {}; + if (description !== undefined) { + metadata = { ...metadata, description }; + } + + // Prepare the update data + const updateData = { + ...restDto, + metadata, + updatedAt: new Date(), + }; + const [group] = await this.db .update(schema.groups) - .set({ - ...updateGroupDto, - updatedAt: new Date(), - }) + .set(updateData) .where(eq(schema.groups.id, id)) .returning(); @@ -89,7 +152,13 @@ export class GroupsService { group, }); - return group; + // Add description to response if it exists in metadata + const response = { ...group }; + if (group.metadata && group.metadata.description) { + response.description = group.metadata.description; + } + + return response; } /** @@ -148,7 +217,7 @@ export class GroupsService { const [createdPerson] = await this.db .insert(schema.persons) .values({ - id: user.id, // Use the same ID as the user + // Let the database generate the UUID automatically firstName: user.name.split(' ')[0] || 'Test', lastName: user.name.split(' ')[1] || 'User', gender: 'MALE', // Default value for testing @@ -184,7 +253,9 @@ export class GroupsService { .where(eq(schema.personToGroup.groupId, groupId)); if (existingRelation) { - return existingRelation; + // Get all persons in the group to return with the group + const persons = await this.getPersonsInGroup(groupId); + return { ...group, persons }; } // Add the person to the group @@ -203,7 +274,9 @@ export class GroupsService { relation, }); - return relation; + // Get all persons in the group to return with the group + const persons = await this.getPersonsInGroup(groupId); + return { ...group, persons }; } /** @@ -258,7 +331,9 @@ export class GroupsService { relation, }); - return relation; + // Get all persons in the group to return with the group + const persons = await this.getPersonsInGroup(groupId); + return { ...group, persons }; } /** @@ -280,27 +355,31 @@ export class GroupsService { const personIds = personResults.map(result => result.id); if (personIds.length > 0) { // Try to get from persons table first - const persons = await this.db - .select() - .from(schema.persons) - .where(eq(schema.persons.id, personIds[0])); + // Use the first ID for simplicity, but check that it's not undefined + const firstId = personIds[0]; + if (firstId) { + const persons = await this.db + .select() + .from(schema.persons) + .where(eq(schema.persons.id, firstId)); - if (persons.length > 0) { - return persons; - } + if (persons.length > 0) { + return persons; + } - // If not found in persons, try users table (for e2e tests) - const users = await this.db - .select() - .from(schema.users) - .where(eq(schema.users.id, personIds[0])); + // If not found in persons, try users table (for e2e tests) + const users = await this.db + .select() + .from(schema.users) + .where(eq(schema.users.id, firstId)); - if (users.length > 0) { - // Convert users to the format expected by the test - return users.map(user => ({ - id: user.id, - name: user.name - })); + if (users.length > 0) { + // Convert users to the format expected by the test + return users.map(user => ({ + id: user.id, + name: user.name + })); + } } }