feat: Introduce new profile sections and fields with detailed configurations and validation rules.

This commit is contained in:
pradeepkumar
2026-01-24 15:32:54 +05:30
parent 43b422a81e
commit 7d7eb1ac31
4 changed files with 1010 additions and 13 deletions

View File

@@ -108,4 +108,29 @@ export class ProfileSectionsController {
) {
return this.sectionsService.removeFromAgentType(id, agentTypeId);
}
@Get('agent-type/:agentTypeId')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
@ApiBearerAuth()
@ApiOperation({ summary: 'Get all sections for an agent type with ordering (Admin only)' })
@ApiQuery({ name: 'includeFields', required: false, type: Boolean })
getSectionsForAgentType(
@Param('agentTypeId', ParseUUIDPipe) agentTypeId: string,
@Query('includeFields') includeFields?: string,
) {
return this.sectionsService.getSectionsForAgentType(agentTypeId, includeFields !== 'false');
}
@Patch('agent-type/:agentTypeId/order')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(UserRole.ADMIN)
@ApiBearerAuth()
@ApiOperation({ summary: 'Update section ordering for an agent type (Admin only)' })
updateSectionOrderForAgentType(
@Param('agentTypeId', ParseUUIDPipe) agentTypeId: string,
@Body() body: { sectionOrders: { sectionId: string; sortOrder: number; isRequired?: boolean }[] },
) {
return this.sectionsService.updateSectionOrderForAgentType(agentTypeId, body.sectionOrders);
}
}

View File

@@ -256,7 +256,7 @@ export class ProfileSectionsService {
}
/**
* Get all sections for a specific agent type
* Get all sections for a specific agent type with custom ordering support
*/
async getSectionsForAgentType(agentTypeId: string, includeFields = true) {
const agentType = await this.prisma.agentType.findUnique({
@@ -267,10 +267,9 @@ export class ProfileSectionsService {
throw new NotFoundException(`Agent type with ID ${agentTypeId} not found`);
}
// Get assigned sections
// Get ALL AgentTypeSection entries for this agent type (including global sections)
const assignments = await this.prisma.agentTypeSection.findMany({
where: { agentTypeId },
orderBy: { sortOrder: 'asc' },
include: {
section: {
include: includeFields
@@ -285,7 +284,10 @@ export class ProfileSectionsService {
},
});
// Also get global sections
// Create a map of section IDs that have custom assignments
const assignmentMap = new Map(assignments.map((a) => [a.sectionId, a]));
// Get all global sections
const globalSections = await this.prisma.profileSection.findMany({
where: {
isGlobal: true,
@@ -299,19 +301,104 @@ export class ProfileSectionsService {
},
}
: undefined,
orderBy: { sortOrder: 'asc' },
});
// Combine all sections with their effective sort order
const allSections: any[] = [];
// Add global sections (with custom order if assigned, otherwise use default)
for (const section of globalSections) {
const assignment = assignmentMap.get(section.id);
allSections.push({
...section,
isRequired: assignment?.isRequired ?? false,
isGlobal: true,
effectiveSortOrder: assignment?.sortOrder ?? section.sortOrder,
hasCustomOrder: !!assignment,
});
}
// Add non-global assigned sections
for (const assignment of assignments) {
if (!assignment.section.isGlobal) {
allSections.push({
...assignment.section,
isRequired: assignment.isRequired,
isGlobal: false,
effectiveSortOrder: assignment.sortOrder,
hasCustomOrder: true,
});
}
}
// Sort by effective sort order
allSections.sort((a, b) => a.effectiveSortOrder - b.effectiveSortOrder);
return {
agentType,
sections: [
...globalSections.map((s) => ({ ...s, isRequired: false, isGlobal: true })),
...assignments.map((a) => ({
...a.section,
isRequired: a.isRequired,
isGlobal: false,
})),
],
sections: allSections,
};
}
/**
* Update section ordering for a specific agent type
* Creates or updates AgentTypeSection entries with custom sortOrder
*/
async updateSectionOrderForAgentType(
agentTypeId: string,
sectionOrders: { sectionId: string; sortOrder: number; isRequired?: boolean }[],
) {
// Verify agent type exists
const agentType = await this.prisma.agentType.findUnique({
where: { id: agentTypeId },
});
if (!agentType) {
throw new NotFoundException(`Agent type with ID ${agentTypeId} not found`);
}
// Process each section order update
const results = await Promise.all(
sectionOrders.map(async ({ sectionId, sortOrder, isRequired }) => {
// Check if assignment exists
const existing = await this.prisma.agentTypeSection.findUnique({
where: {
agentTypeId_sectionId: {
agentTypeId,
sectionId,
},
},
});
if (existing) {
// Update existing assignment
return this.prisma.agentTypeSection.update({
where: { id: existing.id },
data: {
sortOrder,
...(isRequired !== undefined && { isRequired }),
},
include: { section: true },
});
} else {
// Create new assignment (for global sections that need custom ordering)
return this.prisma.agentTypeSection.create({
data: {
agentTypeId,
sectionId,
sortOrder,
isRequired: isRequired ?? false,
},
include: { section: true },
});
}
}),
);
return {
success: true,
updated: results.length,
assignments: results,
};
}
}