mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-11 18:38:27 +00:00
fix: logs api should with both API and access keys
This commit is contained in:
parent
169a2713d2
commit
b912080815
@ -47,7 +47,7 @@ export function useLogs({ endpoint, source, status, type }: UseLogsOptions) {
|
|||||||
(pageNum: number) => {
|
(pageNum: number) => {
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
params.set("page", pageNum.toString());
|
params.set("page", pageNum.toString());
|
||||||
params.set("limit", "5");
|
params.set("limit", "50");
|
||||||
if (source) params.set("source", source);
|
if (source) params.set("source", source);
|
||||||
if (status) params.set("status", status);
|
if (status) params.set("status", status);
|
||||||
if (type) params.set("type", type);
|
if (type) params.set("type", type);
|
||||||
|
|||||||
@ -1,150 +1,157 @@
|
|||||||
import { type LoaderFunctionArgs, json } from "@remix-run/node";
|
import { type LoaderFunctionArgs, json } from "@remix-run/node";
|
||||||
|
import { z } from "zod";
|
||||||
import { prisma } from "~/db.server";
|
import { prisma } from "~/db.server";
|
||||||
import { requireUserId } from "~/services/session.server";
|
import { createHybridLoaderApiRoute } from "~/services/routeBuilders/apiBuilder.server";
|
||||||
|
|
||||||
/**
|
// Schema for logs search parameters
|
||||||
* Optimizations:
|
const LogsSearchParams = z.object({
|
||||||
* - Use `findMany` with `select` instead of `include` to fetch only required fields.
|
page: z.string().optional(),
|
||||||
* - Use `count` with the same where clause, but only after fetching logs (to avoid unnecessary count if no logs).
|
limit: z.string().optional(),
|
||||||
* - Use a single query for availableSources with minimal fields.
|
source: z.string().optional(),
|
||||||
* - Avoid unnecessary object spreading and type casting.
|
status: z.string().optional(),
|
||||||
* - Minimize nested object traversal in mapping.
|
type: z.string().optional(),
|
||||||
*/
|
});
|
||||||
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");
|
export const loader = createHybridLoaderApiRoute(
|
||||||
const limit = parseInt(url.searchParams.get("limit") || "100");
|
{
|
||||||
const source = url.searchParams.get("source");
|
allowJWT: true,
|
||||||
const status = url.searchParams.get("status");
|
searchParams: LogsSearchParams,
|
||||||
const type = url.searchParams.get("type");
|
corsStrategy: "all",
|
||||||
const skip = (page - 1) * limit;
|
findResource: async () => 1,
|
||||||
|
},
|
||||||
|
async ({ authentication, searchParams }) => {
|
||||||
|
const page = parseInt(searchParams.page || "1");
|
||||||
|
const limit = parseInt(searchParams.limit || "100");
|
||||||
|
const source = searchParams.source;
|
||||||
|
const status = searchParams.status;
|
||||||
|
const type = searchParams.type;
|
||||||
|
const skip = (page - 1) * limit;
|
||||||
|
|
||||||
// Get user and workspace in one query
|
// Get user and workspace in one query
|
||||||
const user = await prisma.user.findUnique({
|
const user = await prisma.user.findUnique({
|
||||||
where: { id: userId },
|
where: { id: authentication.userId },
|
||||||
select: { Workspace: { select: { id: true } } },
|
select: { Workspace: { select: { id: true } } },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user?.Workspace) {
|
if (!user?.Workspace) {
|
||||||
throw new Response("Workspace not found", { status: 404 });
|
throw new Response("Workspace not found", { status: 404 });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build where clause for filtering
|
// Build where clause for filtering
|
||||||
const whereClause: any = {
|
const whereClause: any = {
|
||||||
workspaceId: user.Workspace.id,
|
workspaceId: user.Workspace.id,
|
||||||
};
|
|
||||||
|
|
||||||
if (status) {
|
|
||||||
whereClause.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type) {
|
|
||||||
whereClause.data = {
|
|
||||||
path: ["type"],
|
|
||||||
equals: type,
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// If source filter is provided, filter by integration source
|
if (status) {
|
||||||
if (source) {
|
whereClause.status = status;
|
||||||
whereClause.activity = {
|
}
|
||||||
integrationAccount: {
|
|
||||||
integrationDefinition: {
|
if (type) {
|
||||||
slug: source,
|
whereClause.data = {
|
||||||
|
path: ["type"],
|
||||||
|
equals: type,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// If source filter is provided, filter by integration source
|
||||||
|
if (source) {
|
||||||
|
whereClause.activity = {
|
||||||
|
integrationAccount: {
|
||||||
|
integrationDefinition: {
|
||||||
|
slug: source,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Use select to fetch only required fields for logs
|
// Use select to fetch only required fields for logs
|
||||||
const [logs, totalCount, availableSources] = await Promise.all([
|
const [logs, totalCount, availableSources] = await Promise.all([
|
||||||
prisma.ingestionQueue.findMany({
|
prisma.ingestionQueue.findMany({
|
||||||
where: whereClause,
|
where: whereClause,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
createdAt: true,
|
createdAt: true,
|
||||||
processedAt: true,
|
processedAt: true,
|
||||||
status: true,
|
status: true,
|
||||||
error: true,
|
error: true,
|
||||||
type: true,
|
type: true,
|
||||||
output: true,
|
output: true,
|
||||||
data: true,
|
data: true,
|
||||||
activity: {
|
activity: {
|
||||||
select: {
|
select: {
|
||||||
text: true,
|
text: true,
|
||||||
sourceURL: true,
|
sourceURL: true,
|
||||||
integrationAccount: {
|
integrationAccount: {
|
||||||
select: {
|
select: {
|
||||||
integrationDefinition: {
|
integrationDefinition: {
|
||||||
select: {
|
select: {
|
||||||
name: true,
|
name: true,
|
||||||
slug: true,
|
slug: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
orderBy: {
|
||||||
orderBy: {
|
createdAt: "desc",
|
||||||
createdAt: "desc",
|
},
|
||||||
},
|
skip,
|
||||||
skip,
|
take: limit,
|
||||||
take: limit,
|
}),
|
||||||
}),
|
|
||||||
|
|
||||||
prisma.ingestionQueue.count({
|
prisma.ingestionQueue.count({
|
||||||
where: whereClause,
|
where: whereClause,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
prisma.integrationDefinitionV2.findMany({
|
prisma.integrationDefinitionV2.findMany({
|
||||||
where: {
|
where: {
|
||||||
IntegrationAccount: {
|
IntegrationAccount: {
|
||||||
some: {
|
some: {
|
||||||
workspaceId: user.Workspace.id,
|
workspaceId: user.Workspace.id,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
select: {
|
||||||
select: {
|
name: true,
|
||||||
name: true,
|
slug: true,
|
||||||
slug: true,
|
},
|
||||||
},
|
}),
|
||||||
}),
|
]);
|
||||||
]);
|
|
||||||
|
|
||||||
// Format the response
|
// Format the response
|
||||||
const formattedLogs = logs.map((log) => {
|
const formattedLogs = logs.map((log) => {
|
||||||
const integrationDef =
|
const integrationDef =
|
||||||
log.activity?.integrationAccount?.integrationDefinition;
|
log.activity?.integrationAccount?.integrationDefinition;
|
||||||
const logData = log.data as any;
|
const logData = log.data as any;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: log.id,
|
id: log.id,
|
||||||
source: integrationDef?.name || logData?.source || "Unknown",
|
source: integrationDef?.name || logData?.source || "Unknown",
|
||||||
ingestText:
|
ingestText:
|
||||||
log.activity?.text ||
|
log.activity?.text ||
|
||||||
logData?.episodeBody ||
|
logData?.episodeBody ||
|
||||||
logData?.text ||
|
logData?.text ||
|
||||||
"No content",
|
"No content",
|
||||||
time: log.createdAt,
|
time: log.createdAt,
|
||||||
processedAt: log.processedAt,
|
processedAt: log.processedAt,
|
||||||
episodeUUID: (log.output as any)?.episodeUuid,
|
episodeUUID: (log.output as any)?.episodeUuid,
|
||||||
status: log.status,
|
status: log.status,
|
||||||
error: log.error,
|
error: log.error,
|
||||||
sourceURL: log.activity?.sourceURL,
|
sourceURL: log.activity?.sourceURL,
|
||||||
integrationSlug: integrationDef?.slug,
|
integrationSlug: integrationDef?.slug,
|
||||||
data: log.data,
|
data: log.data,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
return json({
|
return json({
|
||||||
logs: formattedLogs,
|
logs: formattedLogs,
|
||||||
totalCount,
|
totalCount,
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
hasMore: skip + logs.length < totalCount,
|
hasMore: skip + logs.length < totalCount,
|
||||||
availableSources,
|
availableSources,
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user