perf(api): eliminate N+1 queries, add query guards and missing indexes
- Notification fan-out: replace sequential for loops with Promise.all (allocation-effects, notification-broadcast, create-notification) - Public holiday batch: group resources by location combo, resolve holidays once per group, replace per-holiday delete/findFirst/create with 3 batched queries (~18K → ~5 queries) - Add take guards to unbounded findMany calls (resource-analytics: 5000, resource-marketplace: 2000, resource-capacity: 1000, chargeability-report: 2000) - auto-staffing: add select with only needed fields + take: 5000 - schema.prisma: add 5 missing indexes (ManagementLevel.groupId, Blueprint.isActive/target, Comment.parentId, Vacation.requestedById, Resource.managementLevelGroupId) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -117,27 +117,28 @@ async function persistImmediateBroadcast(
|
||||
data: buildBroadcastCreateData(senderId, input),
|
||||
});
|
||||
|
||||
const notificationIds: BroadcastRecipientNotification[] = [];
|
||||
for (const recipientUserId of recipientIds) {
|
||||
const notificationId = await createNotification({
|
||||
db,
|
||||
userId: recipientUserId,
|
||||
type: `BROADCAST_${input.category}`,
|
||||
title: input.title,
|
||||
body: input.body,
|
||||
link: input.link,
|
||||
category: input.category,
|
||||
priority: input.priority,
|
||||
channel: input.channel,
|
||||
sourceId: broadcast.id,
|
||||
senderId,
|
||||
taskStatus: isTask ? "OPEN" : undefined,
|
||||
taskAction: input.taskAction,
|
||||
dueDate: input.dueDate,
|
||||
emit: false,
|
||||
});
|
||||
notificationIds.push({ id: notificationId, userId: recipientUserId });
|
||||
}
|
||||
const created = await Promise.all(
|
||||
recipientIds.map((recipientUserId) =>
|
||||
createNotification({
|
||||
db,
|
||||
userId: recipientUserId,
|
||||
type: `BROADCAST_${input.category}`,
|
||||
title: input.title,
|
||||
body: input.body,
|
||||
link: input.link,
|
||||
category: input.category,
|
||||
priority: input.priority,
|
||||
channel: input.channel,
|
||||
sourceId: broadcast.id,
|
||||
senderId,
|
||||
taskStatus: isTask ? "OPEN" : undefined,
|
||||
taskAction: input.taskAction,
|
||||
dueDate: input.dueDate,
|
||||
emit: false,
|
||||
}),
|
||||
),
|
||||
);
|
||||
const notificationIds: BroadcastRecipientNotification[] = created.map((id, i) => ({ id, userId: recipientIds[i]! }));
|
||||
|
||||
const updatedBroadcast = await db.notificationBroadcast.update({
|
||||
where: { id: broadcast.id },
|
||||
|
||||
Reference in New Issue
Block a user