core/apps/webapp/app/routes/api.v1.logs.activity.tsx
2025-07-17 13:10:29 +05:30

136 lines
3.2 KiB
TypeScript

import { type LoaderFunctionArgs, json } from "@remix-run/node";
import { prisma } from "~/db.server";
import { requireUserId } from "~/services/session.server";
export async function loader({ request }: LoaderFunctionArgs) {
const userId = await requireUserId(request);
const url = new URL(request.url);
const page = parseInt(url.searchParams.get("page") || "1");
const limit = parseInt(url.searchParams.get("limit") || "20");
const source = url.searchParams.get("source");
const status = url.searchParams.get("status");
const skip = (page - 1) * limit;
const user = await prisma.user.findUnique({
where: { id: userId },
include: { Workspace: true },
});
if (!user?.Workspace) {
throw new Response("Workspace not found", { status: 404 });
}
// Build where clause for filtering - only items with activityId
const whereClause: any = {
workspaceId: user.Workspace.id,
activityId: {
not: null,
},
};
if (status) {
whereClause.status = status;
}
// If source filter is provided, we need to filter by integration source
if (source) {
whereClause.activity = {
integrationAccount: {
integrationDefinition: {
slug: source,
},
},
};
}
const [logs, totalCount] = await Promise.all([
prisma.ingestionQueue.findMany({
where: whereClause,
include: {
activity: {
include: {
integrationAccount: {
include: {
integrationDefinition: {
select: {
name: true,
slug: true,
},
},
},
},
},
},
},
orderBy: {
createdAt: "desc",
},
skip,
take: limit,
}),
prisma.ingestionQueue.count({
where: whereClause,
}),
]);
// Get available sources for filtering (only those with activities)
const availableSources = await prisma.integrationDefinitionV2.findMany({
where: {
IntegrationAccount: {
some: {
workspaceId: user.Workspace.id,
Activity: {
some: {
IngestionQueue: {
some: {
activityId: {
not: null,
},
},
},
},
},
},
},
},
select: {
name: true,
slug: true,
},
});
// Format the response
const formattedLogs = logs.map((log) => ({
id: log.id,
source:
log.activity?.integrationAccount?.integrationDefinition?.name ||
(log.data as any)?.source ||
"Unknown",
ingestText:
log.activity?.text ||
(log.data as any)?.episodeBody ||
(log.data as any)?.text ||
"No content",
time: log.createdAt,
processedAt: log.processedAt,
status: log.status,
error: log.error,
episodeUUID: (log.output as any)?.episodeUuid,
sourceURL: log.activity?.sourceURL,
integrationSlug:
log.activity?.integrationAccount?.integrationDefinition?.slug,
activityId: log.activityId,
data: log.data,
}));
return json({
logs: formattedLogs,
totalCount,
page,
limit,
hasMore: skip + logs.length < totalCount,
availableSources,
});
}