Files
pn-new-crm/src/lib/services/entity-activity.service.ts

43 lines
1.2 KiB
TypeScript
Raw Normal View History

import { inArray } from 'drizzle-orm';
import { db } from '@/lib/db';
import { user } from '@/lib/db/schema/users';
import { searchAuditLogs } from '@/lib/services/audit-search.service';
/**
* Shared loader for the per-entity Activity tab. Wraps `searchAuditLogs`
* with actor-email resolution so each row can render `who did what`.
*
* Tenant gate happens at the API route this service trusts the caller
* to pass an entityId that belongs to `portId`.
*/
export async function loadEntityActivity(args: {
portId: string;
entityType: string;
entityId: string;
limit?: number;
}) {
const { rows } = await searchAuditLogs({
portId: args.portId,
entityType: args.entityType,
entityId: args.entityId,
limit: args.limit ?? 50,
});
const userIds = Array.from(
new Set(rows.map((r) => r.userId).filter((u): u is string => Boolean(u))),
);
const userRows = userIds.length
? await db
.select({ id: user.id, email: user.email, name: user.name })
.from(user)
.where(inArray(user.id, userIds))
: [];
const userMap = new Map(userRows.map((u) => [u.id, u]));
return rows.map((r) => ({
...r,
actor: r.userId ? (userMap.get(r.userId) ?? null) : null,
}));
}