Speed up calendar response time by removing agent data from calendar response

This commit is contained in:
Karl Ludwig Weise
2026-07-22 12:30:28 +02:00
parent 6259edf8d0
commit 0eae50ca21
4 changed files with 42 additions and 39 deletions
@@ -186,9 +186,6 @@ describe("ScheduleService", () => {
channelId: "channel1",
agent: {
id: "agent1",
name: "Test Agent",
description: "Test Description",
logo: null,
},
},
];
@@ -241,7 +238,6 @@ describe("ScheduleService", () => {
expect(actualSlot.duration).toBe(60); // 60-minute slots
expect(actualSlot.availableAgents).toHaveLength(1);
expect(actualSlot.availableAgents[0].id).toBe("agent1");
expect(actualSlot.availableAgents[0].name).toBe("Test Agent");
});
});
+6 -4
View File
@@ -29,11 +29,13 @@ const scheduleRequestSchema = z.object({
export type ScheduleRequest = z.infer<typeof scheduleRequestSchema>;
export type CalendarAgent = Pick<SelectAgent, "id">;
export interface TimeSlot {
from: string; // UTC ISO timestamp
to: string; // UTC ISO timestamp
duration: number; // minutes
availableAgents: SelectAgent[];
availableAgents: CalendarAgent[];
}
export interface AppointmentWithKeyShare extends SelectAppointment {
@@ -201,7 +203,7 @@ export class ScheduleService {
let channelAgents = await db
.select({
channelId: tenantSchema.channelAgent.channelId,
agent: tenantSchema.agent,
agent: { id: tenantSchema.agent.id },
})
.from(tenantSchema.channelAgent)
.innerJoin(
@@ -266,7 +268,7 @@ export class ScheduleService {
slotTemplates: { slotTemplate: SelectSlotTemplate; channelId: string }[];
appointments: SelectAppointment[];
absences: SelectAgentAbsence[];
channelAgents: { channelId: string; agent: SelectAgent }[];
channelAgents: { channelId: string; agent: CalendarAgent }[];
staffKeyShares: Record<string, string>;
timeZone: string;
}): Promise<DaySchedule[]> {
@@ -357,7 +359,7 @@ export class ScheduleService {
date: Date;
slotTemplates: SelectSlotTemplate[];
appointments: SelectAppointment[];
agents: SelectAgent[];
agents: CalendarAgent[];
absences: SelectAgentAbsence[];
timeZone: string;
}): TimeSlot[] {
+2 -3
View File
@@ -1,5 +1,4 @@
import type { SelectAgent } from "$lib/server/db/tenant-schema";
import type { DaySchedule } from "$lib/server/services/schedule-service";
import type { CalendarAgent, DaySchedule } from "$lib/server/services/schedule-service";
export type AppointmentStatus = "available" | "booked" | "reserved";
export type TAppointmentFilter = "all" | AppointmentStatus;
@@ -33,5 +32,5 @@ export type TCalendarSlot = {
color: string | null;
column: number;
channelId: string;
availableAgents?: SelectAgent[];
availableAgents?: CalendarAgent[];
};
@@ -2,9 +2,10 @@
import { m } from "$i18n/messages";
import { Button } from "$lib/components/ui/button";
import { Text } from "$lib/components/ui/typography";
import type { SelectAgent } from "$lib/server/db/tenant-schema";
import type { TAddAppointment } from "./types";
import type { CalendarAgent } from "$lib/server/services/schedule-service";
import { agents as agentsStore } from "$lib/stores/agents";
import UnknownItemIcon from "@lucide/svelte/icons/user-star";
import type { TAddAppointment } from "./types";
let {
newAppointment,
@@ -12,9 +13,11 @@
proceed,
}: {
newAppointment: TAddAppointment;
availableAgents: SelectAgent[];
availableAgents: CalendarAgent[];
proceed: (data: TAddAppointment) => void;
} = $props();
let agents = $derived($agentsStore.agents);
</script>
<div class="flex flex-col gap-2">
@@ -23,31 +26,34 @@
</Text>
<ul class="flex w-full flex-col gap-2">
{#each availableAgents as agent (agent.id)}
<li>
<Button
variant="outline"
class="flex h-auto w-full cursor-pointer items-center gap-4 px-2 py-1.5 text-left"
onclick={() => proceed({ ...newAppointment, agentId: agent.id })}
>
{#if agent.image}
<img
src={agent.image}
alt={agent.name}
class="size-8 rounded-full border object-cover object-center"
loading="lazy"
/>
{:else}
<UnknownItemIcon
class="bg-muted text-muted-foreground size-15 rounded-full border stroke-1 p-1"
/>
{/if}
<div class="flex grow flex-col gap-1">
<Text style="md" class="font-medium">
{agent.name}
</Text>
</div>
</Button>
</li>
{@const agentItem = agents.find((it) => it.id === agent.id)}
{#if agentItem}
<li>
<Button
variant="outline"
class="flex h-auto w-full cursor-pointer items-center gap-4 px-2 py-1.5 text-left"
onclick={() => proceed({ ...newAppointment, agentId: agent.id })}
>
{#if agentItem.image}
<img
src={agentItem.image}
alt={agentItem.name}
class="size-8 rounded-full border object-cover object-center"
loading="lazy"
/>
{:else}
<UnknownItemIcon
class="bg-muted text-muted-foreground size-15 rounded-full border stroke-1 p-1"
/>
{/if}
<div class="flex grow flex-col gap-1">
<Text style="md" class="font-medium">
{agentItem.name}
</Text>
</div>
</Button>
</li>
{/if}
{/each}
</ul>
</div>