From c5d8d174aa310bc73fade6aa37241437d4f36c99 Mon Sep 17 00:00:00 2001 From: Hendrik Belitz Date: Wed, 28 Jan 2026 17:23:46 +0100 Subject: [PATCH] Optionally set staff channel associations when creating or updating a channel. --- .../__tests__/channel-service.test.ts | 4 +++ src/lib/server/services/channel-service.ts | 36 +++++++++++++++++-- .../api/tenants/[id]/channels/+server.ts | 7 ++++ .../[id]/channels/[channelId]/+server.ts | 6 ++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/lib/server/services/__tests__/channel-service.test.ts b/src/lib/server/services/__tests__/channel-service.test.ts index db6f909..01ae201 100644 --- a/src/lib/server/services/__tests__/channel-service.test.ts +++ b/src/lib/server/services/__tests__/channel-service.test.ts @@ -175,6 +175,7 @@ describe("ChannelService", () => { duration: 30, }, ], + staffIds: [], }; const result = await service.createChannel(request); @@ -188,6 +189,7 @@ describe("ChannelService", () => { names: { en: "" }, agentIds: [], slotTemplates: [], + staffIds: [], }; await expect(service.createChannel(request)).rejects.toThrow(ValidationError); @@ -205,6 +207,7 @@ describe("ChannelService", () => { duration: 30, }, ], + staffIds: [], }; await expect(service.createChannel(request)).rejects.toThrow(ValidationError); @@ -217,6 +220,7 @@ describe("ChannelService", () => { names: { en: "Test Channel" }, agentIds: [], slotTemplates: [], + staffIds: [], }; await expect(service.createChannel(request)).rejects.toThrow("Transaction failed"); diff --git a/src/lib/server/services/channel-service.ts b/src/lib/server/services/channel-service.ts index bf35731..2e8bc72 100644 --- a/src/lib/server/services/channel-service.ts +++ b/src/lib/server/services/channel-service.ts @@ -36,7 +36,8 @@ const channelCreationSchema = z.object({ descriptions: z.partialRecord(z.enum(supportedLocales), z.string().min(1)).optional(), isPublic: z.boolean().optional(), requiresConfirmation: z.boolean().optional(), - agentIds: z.array(z.string().uuid()).optional().default([]), + agentIds: z.array(z.uuid()).optional().default([]), + staffIds: z.array(z.uuid()).optional().default([]), slotTemplates: z.array(slotTemplateSchema).optional().default([]), }); @@ -47,7 +48,8 @@ const channelUpdateSchema = z.object({ isPublic: z.boolean().optional(), pause: z.boolean().optional(), requiresConfirmation: z.boolean().optional(), - agentIds: z.array(z.string().uuid()).optional(), + agentIds: z.array(z.uuid()).optional(), + staffIds: z.array(z.uuid()).optional(), slotTemplates: z .array( slotTemplateSchema.extend({ @@ -198,6 +200,16 @@ export class ChannelService { agents.push(...existingAgents); } + // 4. Link staff to the channel + if (request.staffIds && request.staffIds.length > 0) { + for (const staffId of request.staffIds) { + await tx.insert(tenantSchema.channelStaff).values({ + channelId: channel.id, + staffId: staffId, + }); + } + } + return { ...channel, agents, @@ -355,7 +367,25 @@ export class ChannelService { ); } - // 3. Handle slot template relationships + // 3. Handle staff relationships + if (updateData.staffIds !== undefined) { + // Remove all existing staff assignments + await tx + .delete(tenantSchema.channelStaff) + .where(eq(tenantSchema.channelStaff.channelId, channelId)); + + // Add new staff assignments + if (updateData.staffIds.length > 0) { + for (const staffId of updateData.staffIds) { + await tx.insert(tenantSchema.channelStaff).values({ + channelId: channelId, + staffId: staffId, + }); + } + } + } + + // 4. Handle slot template relationships let slotTemplates: SelectSlotTemplate[] = []; if (updateData.slotTemplates !== undefined) { // Get existing slot template IDs for this channel diff --git a/src/routes/api/tenants/[id]/channels/+server.ts b/src/routes/api/tenants/[id]/channels/+server.ts index de82a0d..dc87e19 100644 --- a/src/routes/api/tenants/[id]/channels/+server.ts +++ b/src/routes/api/tenants/[id]/channels/+server.ts @@ -62,6 +62,12 @@ registerOpenAPIRoute("/tenants/{id}/channels", "POST", { description: "IDs of agents to assign to this channel", example: ["01234567-89ab-cdef-0123-456789abcdef"], }, + staffIds: { + type: "array", + items: { type: "string", format: "uuid" }, + description: "IDs of staff members to assign to this channel", + example: ["12345678-90ab-cdef-0123-456789abcdef"], + }, slotTemplates: { type: "array", items: { @@ -312,6 +318,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => { requestedBy: locals.user?.id, channelNames: body.names, languages: body.languages, + staffIds: body.staffIds, }); const channelService = await ChannelService.forTenant(tenantId); diff --git a/src/routes/api/tenants/[id]/channels/[channelId]/+server.ts b/src/routes/api/tenants/[id]/channels/[channelId]/+server.ts index 9de0de3..2477d31 100644 --- a/src/routes/api/tenants/[id]/channels/[channelId]/+server.ts +++ b/src/routes/api/tenants/[id]/channels/[channelId]/+server.ts @@ -188,6 +188,12 @@ registerOpenAPIRoute("/tenants/{id}/channels/{channelId}", "PUT", { description: "IDs of agents to assign to this channel", example: ["01234567-89ab-cdef-0123-456789abcdef"], }, + staffIds: { + type: "array", + items: { type: "string", format: "uuid" }, + description: "IDs of staff members to assign to this channel", + example: ["12345678-90ab-cdef-0123-456789abcdef"], + }, slotTemplates: { type: "array", items: {