|
1 | | -import { createLogger } from '@sim/logger' |
2 | | -import { getErrorMessage } from '@sim/utils/errors' |
3 | | -import { type NextRequest, NextResponse } from 'next/server' |
4 | 1 | import { listAuditLogsContract } from '@/lib/api/contracts/audit-logs' |
5 | | -import { getValidationErrorMessage, parseRequest } from '@/lib/api/server' |
6 | | -import { getSession } from '@/lib/auth' |
7 | | -import { withRouteHandler } from '@/lib/core/utils/with-route-handler' |
8 | | -import { validateEnterpriseAuditAccess } from '@/app/api/v1/audit-logs/auth' |
9 | | -import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' |
10 | 2 | import { |
11 | | - buildFilterConditions, |
12 | | - buildOrgScopeCondition, |
13 | | - getOrgWorkspaceIds, |
14 | | - queryAuditLogs, |
15 | | -} from '@/app/api/v1/audit-logs/query' |
16 | | - |
17 | | -const logger = createLogger('AuditLogsAPI') |
| 3 | + defineInternalJsonRoute, |
| 4 | + internalPlainOrchestrationErrorPolicy, |
| 5 | + internalRateLimits, |
| 6 | + internalSessionAuth, |
| 7 | +} from '@/lib/api/server/routes' |
| 8 | +import { listAuditLogs } from '@/lib/audit-logs/application/list-audit-logs' |
| 9 | +import { auditLogOperations } from '@/lib/audit-logs/application/operations' |
| 10 | +import { formatAuditLogEntry } from '@/app/api/v1/audit-logs/format' |
18 | 11 |
|
19 | 12 | export const dynamic = 'force-dynamic' |
20 | 13 |
|
21 | | -export const GET = withRouteHandler(async (request: NextRequest) => { |
22 | | - try { |
23 | | - const session = await getSession() |
24 | | - if (!session?.user?.id) { |
25 | | - return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) |
26 | | - } |
27 | | - |
28 | | - const parsed = await parseRequest( |
29 | | - listAuditLogsContract, |
30 | | - request, |
31 | | - {}, |
32 | | - { |
33 | | - validationErrorResponse: (error) => |
34 | | - NextResponse.json( |
35 | | - { error: getValidationErrorMessage(error, 'Invalid query parameters') }, |
36 | | - { status: 400 } |
37 | | - ), |
38 | | - } |
39 | | - ) |
40 | | - if (!parsed.success) return parsed.response |
41 | | - |
42 | | - const authResult = await validateEnterpriseAuditAccess( |
43 | | - session.user.id, |
44 | | - parsed.data.query.organizationId |
45 | | - ) |
46 | | - if (!authResult.success) { |
47 | | - return authResult.response |
48 | | - } |
49 | | - |
50 | | - const { organizationId, orgMemberIds } = authResult.context |
51 | | - |
52 | | - const { |
53 | | - organizationId: _targetOrganizationId, |
54 | | - search, |
55 | | - action, |
56 | | - resourceType, |
57 | | - actorId, |
58 | | - startDate, |
59 | | - endDate, |
60 | | - includeDeparted, |
61 | | - limit, |
62 | | - cursor, |
63 | | - } = parsed.data.query |
64 | | - |
65 | | - const orgWorkspaceIds = await getOrgWorkspaceIds(organizationId) |
66 | | - const scopeCondition = buildOrgScopeCondition({ |
67 | | - organizationId, |
68 | | - orgWorkspaceIds, |
69 | | - orgMemberIds, |
70 | | - includeDeparted, |
71 | | - }) |
72 | | - const filterConditions = buildFilterConditions({ |
73 | | - action, |
74 | | - resourceType, |
75 | | - actorId, |
76 | | - search, |
77 | | - startDate, |
78 | | - endDate, |
79 | | - }) |
80 | | - |
81 | | - const { data, nextCursor } = await queryAuditLogs( |
82 | | - [scopeCondition, ...filterConditions], |
83 | | - limit, |
84 | | - cursor |
85 | | - ) |
86 | | - |
87 | | - return NextResponse.json({ |
88 | | - success: true, |
89 | | - data: data.map(formatAuditLogEntry), |
90 | | - nextCursor, |
91 | | - }) |
92 | | - } catch (error: unknown) { |
93 | | - const message = getErrorMessage(error, 'Unknown error') |
94 | | - logger.error('Audit logs fetch error', { error: message }) |
95 | | - return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) |
96 | | - } |
| 14 | +export const GET = defineInternalJsonRoute({ |
| 15 | + contract: listAuditLogsContract, |
| 16 | + auth: internalSessionAuth, |
| 17 | + operation: auditLogOperations.list, |
| 18 | + rateLimit: internalRateLimits.none({ |
| 19 | + reason: 'Existing authenticated audit-log settings read has no request-rate policy', |
| 20 | + }), |
| 21 | + errorPolicy: internalPlainOrchestrationErrorPolicy, |
| 22 | + mapInput: ({ query }) => ({ |
| 23 | + organizationId: query.organizationId, |
| 24 | + includeDeparted: query.includeDeparted, |
| 25 | + filters: { |
| 26 | + search: query.search, |
| 27 | + action: query.action, |
| 28 | + resourceType: query.resourceType, |
| 29 | + actorId: query.actorId, |
| 30 | + startDate: query.startDate, |
| 31 | + endDate: query.endDate, |
| 32 | + }, |
| 33 | + limit: query.limit, |
| 34 | + cursor: query.cursor, |
| 35 | + }), |
| 36 | + useCase: listAuditLogs, |
| 37 | + present: ({ data, nextCursor }) => ({ |
| 38 | + success: true, |
| 39 | + data: data.map(formatAuditLogEntry), |
| 40 | + nextCursor, |
| 41 | + }), |
97 | 42 | }) |
0 commit comments