Feat/s3 storage #2

Closed
maaz519 wants to merge 30 commits from feat/s3-storage into main
Showing only changes of commit 3e66c7a5db - Show all commits
@@ -208,28 +208,41 @@ export class MessageService {
membersBy.set(p.threadId, [...(membersBy.get(p.threadId) ?? []), name]);
}
const summaries = await Promise.all(
threads.map(async (t) => {
const last = await this.prisma.iiosInteraction.findFirst({
where: { threadId: t.id },
orderBy: { occurredAt: 'desc' },
include: { parts: { where: { kind: 'TEXT' }, take: 1 } },
});
const members = membersBy.get(t.id) ?? [];
return {
threadId: t.id,
subject: t.subject,
membership: (t.metadata as { membership?: string } | null)?.membership,
metadata: (t.metadata as Record<string, unknown> | null) ?? null,
participants: members,
participantCount: members.length,
unread: unreadBy.get(t.id) ?? 0,
muted: mutedBy.get(t.id) ?? false,
lastMessage: last?.parts[0]?.bodyText ?? undefined,
lastAt: last?.occurredAt,
};
}),
);
// Latest message per thread in ONE query (Postgres DISTINCT ON) instead of one findFirst
// per thread — a caller with many threads no longer fans out N parallel queries and
// exhausts the connection pool.
const lastRows =
threads.length === 0
? []
: await this.prisma.$queryRaw<Array<{ threadId: string; occurredAt: Date; lastMessage: string | null }>>(Prisma.sql`
SELECT DISTINCT ON (i."threadId")
i."threadId" AS "threadId",
i."occurredAt" AS "occurredAt",
(SELECT p."bodyText" FROM "IiosMessagePart" p
WHERE p."interactionId" = i.id AND p.kind::text = 'TEXT'
ORDER BY p."partIndex" ASC LIMIT 1) AS "lastMessage"
FROM "IiosInteraction" i
WHERE i."threadId" IN (${Prisma.join(threads.map((t) => t.id))})
ORDER BY i."threadId", i."occurredAt" DESC
`);
const lastBy = new Map(lastRows.map((r) => [r.threadId, r]));
const summaries = threads.map((t) => {
const last = lastBy.get(t.id);
const members = membersBy.get(t.id) ?? [];
return {
threadId: t.id,
subject: t.subject,
membership: (t.metadata as { membership?: string } | null)?.membership,
metadata: (t.metadata as Record<string, unknown> | null) ?? null,
participants: members,
participantCount: members.length,
unread: unreadBy.get(t.id) ?? 0,
muted: mutedBy.get(t.id) ?? false,
lastMessage: last?.lastMessage ?? undefined,
lastAt: last?.occurredAt,
};
});
return summaries.sort((a, b) => (b.lastAt?.getTime() ?? 0) - (a.lastAt?.getTime() ?? 0));
}