import { adminGetAllLegacyTenantSummaries } from "@toolctrl/db/accounts.server"; import { adminDeleteLegacyApiKeyLogsByIds, countLegacyApiKeyLogs, deleteTenantLegacyApiKeyLogsByIds, getLegacyApiKeyLogAdminDetails, groupLegacyApiKeyLogs, tenantLegacyApiKeyLogScope, type LegacyApiKeyLogOrderByInput, type LegacyApiKeyLogWhereInput, } from "@toolctrl/db/api-keys.server"; import { Prisma } from "@toolctrl/db/prisma-browser"; import { Params } from "react-router"; import { FilterablePropertyDto } from "~/application/dtos/data/FilterablePropertyDto"; import { getFiltersFromCurrentUrl, getPaginationFromCurrentUrl } from "~/utils/helpers/RowPaginationHelper"; import { getTenantIdOrNull } from "~/utils/services/.server/urlService"; import { ApiCallSummaryDto } from "../dtos/ApiCallSummaryDto"; import ApiKeyLogUtils from "../utils/ApiKeyLogUtils"; import { ApiKeyLogDto } from "../dtos/ApiKeyLogDto"; import { PaginationDto } from "~/application/dtos/data/PaginationDto"; async function getSummary({ request, params }: { request: Request; params: Params }) { const { filterableProperties, whereFilters, allTenants } = await getFilters({ request, params }); const searchParams = new URL(request.url).searchParams; let groupBy = ApiKeyLogUtils.getGroupByValues(searchParams); let items: ApiCallSummaryDto[] = []; if (groupBy.length > 0) { try { const data = await groupLegacyApiKeyLogs({ by: groupBy, where: whereFilters, }); items = data.map((x) => x as ApiCallSummaryDto); } catch { throw Error("Invalid group by: " + groupBy.join(", ")); } } return { items, allTenants, filterableProperties }; } async function getDetails({ request, params }: { request: Request; params: Params }): Promise<{ items: ApiKeyLogDto[]; filterableProperties: FilterablePropertyDto[]; pagination: PaginationDto; }> { const { filterableProperties, whereFilters } = await getFilters({ request, params }); const urlSearchParams = new URL(request.url).searchParams; const pagination = getPaginationFromCurrentUrl(urlSearchParams); const orderBy: LegacyApiKeyLogOrderByInput | LegacyApiKeyLogOrderByInput[] = !pagination.sortedBy.length ? { createdAt: "desc" } : pagination.sortedBy.map((x) => ({ [x.name]: x.direction, })); const items = await getLegacyApiKeyLogAdminDetails({ take: pagination.pageSize, skip: pagination.pageSize * (pagination.page - 1), where: whereFilters, includeTenant: !whereFilters.tenantId, orderBy, }); const totalItems = await countLegacyApiKeyLogs(whereFilters); return { items: items as ApiKeyLogDto[], filterableProperties, pagination: { page: pagination.page, pageSize: pagination.pageSize, totalItems, totalPages: Math.ceil(totalItems / pagination.pageSize), }, }; } async function getGroupBys() { const allMethods = [ { name: "GET", value: "GET" }, { name: "POST", value: "POST" }, { name: "PUT", value: "PUT" }, { name: "PATCH", value: "PATCH" }, { name: "DELETE", value: "DELETE" }, ]; return { allMethods, }; } async function getFilterableProperties(tenantId: string | null) { const { allMethods } = await getGroupBys(); const filterableProperties: FilterablePropertyDto[] = [ { name: "method", title: "models.apiKeyLog.method", options: allMethods }, { name: "endpoint", title: "models.apiKeyLog.endpoint", }, { name: "params", title: "models.apiKeyLog.params", }, { name: "status", title: "models.apiKeyLog.status", }, { name: "apiKeyId", title: "models.apiKey.object", }, ]; let allTenants: { id: string; name: string; slug: string }[] = []; if (tenantId === null) { allTenants = await adminGetAllLegacyTenantSummaries(); filterableProperties.unshift({ name: "tenantId", title: "models.tenant.object", options: [ { value: "null", name: "{null}" }, ...allTenants.map((item) => { return { value: item.id, name: item.name, }; }), ], }); } return { filterableProperties, allTenants }; } async function getFilters({ request, params }: { request: Request; params: Params }) { const tenantId = await getTenantIdOrNull({ request, params }); const { filterableProperties, allTenants } = await getFilterableProperties(tenantId); const filters = getFiltersFromCurrentUrl(request, filterableProperties); const q = filters.query || ""; const AND_filters: Prisma.ApiKeyLogWhereInput[] = []; filterableProperties.forEach((filter) => { const value = filters.properties.find((f) => f.name === filter.name)?.value; if (value) { let formattedValue = filter.name === "status" ? Number(value) : value; AND_filters.push({ [filter.name]: value === "null" ? null : formattedValue, }); } }); const OR_filters: Prisma.ApiKeyLogWhereInput[] = []; if (q) { OR_filters.push( { ip: { contains: q, mode: "insensitive" } }, { endpoint: { contains: q, mode: "insensitive" } }, { method: { contains: q, mode: "insensitive" } }, { params: { contains: q, mode: "insensitive" } }, { error: { contains: q, mode: "insensitive" } } ); } const whereFilters: LegacyApiKeyLogWhereInput = {}; if (OR_filters.length > 0) { whereFilters.OR = OR_filters; } if (AND_filters.length > 0) { whereFilters.AND = AND_filters; } if (tenantId) { const existingAndFilters = Array.isArray(whereFilters.AND) ? whereFilters.AND : whereFilters.AND ? [whereFilters.AND] : []; whereFilters.AND = [...existingAndFilters, tenantLegacyApiKeyLogScope(tenantId)]; } return { filterableProperties, whereFilters, allTenants }; } async function adminDeleteMany(ids: string[]) { return await adminDeleteLegacyApiKeyLogsByIds(ids); } async function deleteManyForTenant(ids: string[], tenantId: string | null) { return await deleteTenantLegacyApiKeyLogsByIds({ ids, tenantId }); } export default { getSummary, getDetails, adminDeleteMany, deleteManyForTenant, };