diff --git a/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/__tests__/route.test.ts b/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/__tests__/route.test.ts index b67add64ca..9dd8bbd70f 100644 --- a/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/__tests__/route.test.ts +++ b/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/__tests__/route.test.ts @@ -14,19 +14,23 @@ vi.mock('@/lib/auth', () => ({ vi.mock('@pagespace/db', () => ({ db: {} })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, security: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); -vi.mock('@pagespace/lib/permissions', () => ({ - canUserEditPage: vi.fn().mockResolvedValue(true), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn().mockResolvedValue(true), })); -vi.mock('@pagespace/lib/integrations', () => ({ +vi.mock('@pagespace/lib/integrations/repositories/grant-repository', () => ({ getGrantById: mockGetGrantById, updateGrant: vi.fn(), deleteGrant: mockDeleteGrant, @@ -34,7 +38,7 @@ vi.mock('@pagespace/lib/integrations', () => ({ import { DELETE } from '../route'; import { authenticateRequestWithOptions } from '@/lib/auth'; -import { auditRequest } from '@pagespace/lib/server'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; const mockUserId = 'user_123'; const mockAgentId = 'agent-1'; diff --git a/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/route.ts b/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/route.ts index ca50f113a2..6526dd5179 100644 --- a/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/route.ts +++ b/apps/web/src/app/api/agents/[agentId]/integrations/[grantId]/route.ts @@ -2,9 +2,10 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { canUserEditPage } from '@pagespace/lib/permissions'; -import { getGrantById, updateGrant, deleteGrant } from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { getGrantById, updateGrant, deleteGrant } from '@pagespace/lib/integrations/repositories/grant-repository'; const AUTH_OPTIONS_WRITE = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/agents/[agentId]/integrations/__tests__/route.test.ts b/apps/web/src/app/api/agents/[agentId]/integrations/__tests__/route.test.ts index 3f533f7fef..c5b795869a 100644 --- a/apps/web/src/app/api/agents/[agentId]/integrations/__tests__/route.test.ts +++ b/apps/web/src/app/api/agents/[agentId]/integrations/__tests__/route.test.ts @@ -13,32 +13,38 @@ vi.mock('@/lib/auth', () => ({ vi.mock('@pagespace/db', () => ({ db: {} })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, security: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); -vi.mock('@pagespace/lib/permissions', () => ({ - canUserEditPage: vi.fn().mockResolvedValue(true), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn().mockResolvedValue(true), })); vi.mock('@pagespace/lib/services/drive-service', () => ({ getDriveAccess: vi.fn(), })); -vi.mock('@pagespace/lib/integrations', () => ({ +vi.mock('@pagespace/lib/integrations/repositories/grant-repository', () => ({ listGrantsByAgent: mockListGrantsByAgent, createGrant: vi.fn(), - getConnectionById: vi.fn(), findGrant: vi.fn(), })); +vi.mock('@pagespace/lib/integrations/repositories/connection-repository', () => ({ + getConnectionById: vi.fn(), +})); import { GET } from '../route'; import { authenticateRequestWithOptions } from '@/lib/auth'; -import { auditRequest } from '@pagespace/lib/server'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; const mockUserId = 'user_123'; const mockAgentId = 'agent-1'; diff --git a/apps/web/src/app/api/agents/[agentId]/integrations/route.ts b/apps/web/src/app/api/agents/[agentId]/integrations/route.ts index bbce942194..df297f8911 100644 --- a/apps/web/src/app/api/agents/[agentId]/integrations/route.ts +++ b/apps/web/src/app/api/agents/[agentId]/integrations/route.ts @@ -2,15 +2,12 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { canUserEditPage } from '@pagespace/lib/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import { getDriveAccess } from '@pagespace/lib/services/drive-service'; -import { - listGrantsByAgent, - createGrant, - getConnectionById, - findGrant, -} from '@pagespace/lib/integrations'; +import { listGrantsByAgent, createGrant, findGrant } from '@pagespace/lib/integrations/repositories/grant-repository'; +import { getConnectionById } from '@pagespace/lib/integrations/repositories/connection-repository'; const AUTH_OPTIONS_READ = { allow: ['session'] as const }; const AUTH_OPTIONS_WRITE = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/ai/abort/__tests__/route.test.ts b/apps/web/src/app/api/ai/abort/__tests__/route.test.ts index 64938c19f0..eb9908a9c6 100644 --- a/apps/web/src/app/api/ai/abort/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/abort/__tests__/route.test.ts @@ -22,30 +22,29 @@ vi.mock('@/lib/ai/core/stream-abort-registry', () => ({ })); // Mock logger (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); -// Mock rate limit (boundary) - note: checkRateLimit is exported from @pagespace/lib/auth -vi.mock('@pagespace/lib/auth', async () => { - const actual = await vi.importActual('@pagespace/lib/auth'); - return { - ...actual, - checkRateLimit: vi.fn(), - }; -}); +vi.mock('@pagespace/lib/auth/rate-limit-utils', () => ({ + checkRateLimit: vi.fn(), +})); import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { abortStream } from '@/lib/ai/core/stream-abort-registry'; -import { loggers } from '@pagespace/lib/server'; -import { checkRateLimit } from '@pagespace/lib/auth'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { checkRateLimit } from '@pagespace/lib/auth/rate-limit-utils'; // Test fixtures const mockUserId = 'user-123'; diff --git a/apps/web/src/app/api/ai/abort/route.ts b/apps/web/src/app/api/ai/abort/route.ts index bac7e883f9..33263e16d4 100644 --- a/apps/web/src/app/api/ai/abort/route.ts +++ b/apps/web/src/app/api/ai/abort/route.ts @@ -1,8 +1,9 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { abortStream } from '@/lib/ai/core/stream-abort-registry'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { checkRateLimit } from '@pagespace/lib/auth'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { checkRateLimit } from '@pagespace/lib/auth/rate-limit-utils'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/ai/chat/__tests__/mcp-scope.test.ts b/apps/web/src/app/api/ai/chat/__tests__/mcp-scope.test.ts index 18cf304e7e..50947e94f6 100644 --- a/apps/web/src/app/api/ai/chat/__tests__/mcp-scope.test.ts +++ b/apps/web/src/app/api/ai/chat/__tests__/mcp-scope.test.ts @@ -19,10 +19,14 @@ vi.mock('@/lib/auth', () => ({ checkMCPPageScope: vi.fn().mockResolvedValue(null), })); -vi.mock('@pagespace/lib/server', () => ({ - canUserViewPage: vi.fn().mockResolvedValue(true), - canUserEditPage: vi.fn().mockResolvedValue(true), - getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@test.com', actorDisplayName: 'Test' }), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserViewPage: vi.fn().mockResolvedValue(true), + canUserEditPage: vi.fn().mockResolvedValue(true), +})); +vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ + getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@test.com', actorDisplayName: 'Test' }), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ loggers: { ai: { info: vi.fn(), @@ -39,7 +43,10 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, - auditRequest: vi.fn(), + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); vi.mock('@pagespace/db', () => ({ diff --git a/apps/web/src/app/api/ai/chat/messages/[messageId]/__tests__/route.test.ts b/apps/web/src/app/api/ai/chat/messages/[messageId]/__tests__/route.test.ts index a6db6bfe65..977cf15641 100644 --- a/apps/web/src/app/api/ai/chat/messages/[messageId]/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/chat/messages/[messageId]/__tests__/route.test.ts @@ -28,12 +28,18 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn() }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock logging mask (boundary) @@ -64,7 +70,8 @@ import { chatMessageRepository } from '@/lib/repositories/chat-message-repositor import { getActorInfo, logMessageActivity } from '@pagespace/lib/monitoring/activity-logger'; import { db } from '@pagespace/db'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserEditPage, loggers } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions' +import { loggers } from '@pagespace/lib/logging/logger-config'; // Type for page lookup mock (matches Drizzle schema) type PageType = 'DOCUMENT' | 'FOLDER' | 'CHANNEL' | 'AI_CHAT' | 'CANVAS' | 'FILE' | 'SHEET' | 'TASK_LIST' | 'CODE'; diff --git a/apps/web/src/app/api/ai/chat/messages/[messageId]/route.ts b/apps/web/src/app/api/ai/chat/messages/[messageId]/route.ts index b8592a0c7a..52fcd2fc94 100644 --- a/apps/web/src/app/api/ai/chat/messages/[messageId]/route.ts +++ b/apps/web/src/app/api/ai/chat/messages/[messageId]/route.ts @@ -1,6 +1,8 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserEditPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import { chatMessageRepository, diff --git a/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/__tests__/route.test.ts b/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/__tests__/route.test.ts index 34c6222661..4e3916d315 100644 --- a/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/__tests__/route.test.ts @@ -34,9 +34,11 @@ vi.mock('@/lib/repositories/global-conversation-repository', () => ({ })); // Mock permissions -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), @@ -44,7 +46,11 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock websocket broadcasts @@ -66,7 +72,7 @@ vi.mock('@/lib/logging/mask', () => ({ import { previewAiUndo, executeAiUndo, type AiUndoPreview } from '@/services/api'; import { authenticateRequestWithOptions, checkMCPPageScope } from '@/lib/auth'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; const mockAuth = vi.mocked(authenticateRequestWithOptions); const mockCheckMCPPageScope = vi.mocked(checkMCPPageScope); diff --git a/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/route.ts b/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/route.ts index 6610ad8a84..158c79e727 100644 --- a/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/route.ts +++ b/apps/web/src/app/api/ai/chat/messages/[messageId]/undo/route.ts @@ -1,7 +1,9 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope, type AuthResult } from '@/lib/auth'; -import { canUserEditPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { previewAiUndo, executeAiUndo, type AiUndoPreview } from '@/services/api'; diff --git a/apps/web/src/app/api/ai/chat/messages/__tests__/mcp-scope.test.ts b/apps/web/src/app/api/ai/chat/messages/__tests__/mcp-scope.test.ts index 31b8bfdc01..cb0e18b649 100644 --- a/apps/web/src/app/api/ai/chat/messages/__tests__/mcp-scope.test.ts +++ b/apps/web/src/app/api/ai/chat/messages/__tests__/mcp-scope.test.ts @@ -26,12 +26,18 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserViewPage: vi.fn().mockResolvedValue(true), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserViewPage: vi.fn().mockResolvedValue(true), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn() }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock message converter (boundary) @@ -44,7 +50,7 @@ vi.mock('@/lib/ai/core', () => ({ })); import { authenticateRequestWithOptions, checkMCPPageScope } from '@/lib/auth'; -import { canUserViewPage } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; import { chatMessageRepository } from '@/lib/repositories/chat-message-repository'; // ============================================================================ diff --git a/apps/web/src/app/api/ai/chat/messages/__tests__/route.test.ts b/apps/web/src/app/api/ai/chat/messages/__tests__/route.test.ts index 2313d44331..8ca57d28a5 100644 --- a/apps/web/src/app/api/ai/chat/messages/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/chat/messages/__tests__/route.test.ts @@ -26,12 +26,18 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserViewPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserViewPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn() }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock message converter (boundary) @@ -45,7 +51,8 @@ vi.mock('@/lib/ai/core', () => ({ import { chatMessageRepository } from '@/lib/repositories/chat-message-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { canUserViewPage, loggers } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions' +import { loggers } from '@pagespace/lib/logging/logger-config'; import { convertDbMessageToUIMessage } from '@/lib/ai/core'; // Test fixtures diff --git a/apps/web/src/app/api/ai/chat/messages/route.ts b/apps/web/src/app/api/ai/chat/messages/route.ts index ba3fff1729..aa8f052647 100644 --- a/apps/web/src/app/api/ai/chat/messages/route.ts +++ b/apps/web/src/app/api/ai/chat/messages/route.ts @@ -1,7 +1,9 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; import { convertDbMessageToUIMessage } from '@/lib/ai/core'; -import { loggers, auditRequest, canUserViewPage } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; import { chatMessageRepository } from '@/lib/repositories/chat-message-repository'; // Auth options: GET is read-only operation diff --git a/apps/web/src/app/api/ai/chat/route.ts b/apps/web/src/app/api/ai/chat/route.ts index b5f6f74ee3..491776c797 100644 --- a/apps/web/src/app/api/ai/chat/route.ts +++ b/apps/web/src/app/api/ai/chat/route.ts @@ -21,7 +21,8 @@ import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from ' const AUTH_OPTIONS_READ = { allow: ['session', 'mcp'] as const, requireCSRF: false }; const AUTH_OPTIONS_WRITE = { allow: ['session', 'mcp'] as const, requireCSRF: true }; -import { canUserViewPage, canUserEditPage, getActorInfo } from '@pagespace/lib/server'; +import { canUserViewPage, canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; import { createAIProvider, updateUserProviderSettings, @@ -60,7 +61,8 @@ import { } from '@/lib/ai/core'; import { db, users, chatMessages, pages, drives, eq, and } from '@pagespace/db'; import { createId } from '@paralleldrive/cuid2'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import { trackFeature } from '@pagespace/lib/monitoring/activity-tracker'; import { AIMonitoring } from '@pagespace/lib/monitoring/ai-monitoring'; diff --git a/apps/web/src/app/api/ai/global/[id]/__tests__/route.test.ts b/apps/web/src/app/api/ai/global/[id]/__tests__/route.test.ts index da1c11e005..52f8cfd23d 100644 --- a/apps/web/src/app/api/ai/global/[id]/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/global/[id]/__tests__/route.test.ts @@ -26,20 +26,24 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/__tests__/route.test.ts b/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/__tests__/route.test.ts index efec6099a7..9062807875 100644 --- a/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/__tests__/route.test.ts @@ -32,15 +32,19 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock logging mask (boundary) @@ -58,7 +62,7 @@ vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { getActorInfo, logMessageActivity } from '@pagespace/lib/monitoring/activity-logger'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/route.ts b/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/route.ts index 78431c98c3..873e3add62 100644 --- a/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/route.ts +++ b/apps/web/src/app/api/ai/global/[id]/messages/[messageId]/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { processMessageContentUpdate } from '@/lib/repositories/chat-message-repository'; diff --git a/apps/web/src/app/api/ai/global/[id]/messages/route.ts b/apps/web/src/app/api/ai/global/[id]/messages/route.ts index 4818962d6f..7caa557307 100644 --- a/apps/web/src/app/api/ai/global/[id]/messages/route.ts +++ b/apps/web/src/app/api/ai/global/[id]/messages/route.ts @@ -39,7 +39,8 @@ import { import { db, conversations, messages, drives, eq, and, desc, gt, lt } from '@pagespace/db'; import { createId } from '@paralleldrive/cuid2'; import { getMCPBridge } from '@/lib/mcp'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import type { MCPTool } from '@/types/mcp'; import { AIMonitoring } from '@pagespace/lib/monitoring/ai-monitoring'; diff --git a/apps/web/src/app/api/ai/global/[id]/route.ts b/apps/web/src/app/api/ai/global/[id]/route.ts index c15bbf923e..cfe4a0b362 100644 --- a/apps/web/src/app/api/ai/global/[id]/route.ts +++ b/apps/web/src/app/api/ai/global/[id]/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; const AUTH_OPTIONS_READ = { allow: ['session'] as const, requireCSRF: false }; diff --git a/apps/web/src/app/api/ai/global/[id]/usage/__tests__/route.test.ts b/apps/web/src/app/api/ai/global/[id]/usage/__tests__/route.test.ts index ef8e4a3443..a33fe429b8 100644 --- a/apps/web/src/app/api/ai/global/[id]/usage/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/global/[id]/usage/__tests__/route.test.ts @@ -27,15 +27,19 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock AI monitoring (boundary) @@ -48,7 +52,7 @@ import { calculateUsageSummary as mockedCalculateUsageSummary, } from '@/lib/repositories/global-conversation-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { getContextWindow } from '@pagespace/lib/monitoring/ai-monitoring'; // Test fixtures diff --git a/apps/web/src/app/api/ai/global/[id]/usage/route.ts b/apps/web/src/app/api/ai/global/[id]/usage/route.ts index 1de72e1bb6..391be75834 100644 --- a/apps/web/src/app/api/ai/global/[id]/usage/route.ts +++ b/apps/web/src/app/api/ai/global/[id]/usage/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { getContextWindow } from '@pagespace/lib/monitoring/ai-monitoring'; import { globalConversationRepository, diff --git a/apps/web/src/app/api/ai/global/__tests__/route.test.ts b/apps/web/src/app/api/ai/global/__tests__/route.test.ts index ee6cb6db2c..5856d31467 100644 --- a/apps/web/src/app/api/ai/global/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/global/__tests__/route.test.ts @@ -25,20 +25,24 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/global/active/__tests__/route.test.ts b/apps/web/src/app/api/ai/global/active/__tests__/route.test.ts index 010279180d..00d7a036d9 100644 --- a/apps/web/src/app/api/ai/global/active/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/global/active/__tests__/route.test.ts @@ -24,20 +24,24 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/global/active/route.ts b/apps/web/src/app/api/ai/global/active/route.ts index 04af954bd5..c4df9b1dc0 100644 --- a/apps/web/src/app/api/ai/global/active/route.ts +++ b/apps/web/src/app/api/ai/global/active/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: false }; diff --git a/apps/web/src/app/api/ai/global/route.ts b/apps/web/src/app/api/ai/global/route.ts index 3af8652c71..de15c2ea84 100644 --- a/apps/web/src/app/api/ai/global/route.ts +++ b/apps/web/src/app/api/ai/global/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { globalConversationRepository } from '@/lib/repositories/global-conversation-repository'; import { parseBoundedIntParam } from '@/lib/utils/query-params'; diff --git a/apps/web/src/app/api/ai/lmstudio/models/__tests__/route.test.ts b/apps/web/src/app/api/ai/lmstudio/models/__tests__/route.test.ts index e60fba9912..76d6451099 100644 --- a/apps/web/src/app/api/ai/lmstudio/models/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/lmstudio/models/__tests__/route.test.ts @@ -4,8 +4,8 @@ import { GET } from '../route'; import type { SessionAuthResult, AuthError } from '@/lib/auth'; // Mock dependencies -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn(), @@ -13,6 +13,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/auth', () => ({ @@ -24,11 +26,11 @@ vi.mock('@/lib/ai/core', () => ({ getUserLMStudioSettings: vi.fn(), })); -vi.mock('@pagespace/lib/security', () => ({ +vi.mock('@pagespace/lib/security/url-validator', () => ({ validateLocalProviderURL: vi.fn().mockResolvedValue({ valid: true, resolvedIPs: ['127.0.0.1'] }), })); -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { authenticateSessionRequest, isAuthError } from '@/lib/auth'; import { getUserLMStudioSettings } from '@/lib/ai/core'; diff --git a/apps/web/src/app/api/ai/lmstudio/models/route.ts b/apps/web/src/app/api/ai/lmstudio/models/route.ts index 2092c0d822..581f4b9a3c 100644 --- a/apps/web/src/app/api/ai/lmstudio/models/route.ts +++ b/apps/web/src/app/api/ai/lmstudio/models/route.ts @@ -1,8 +1,8 @@ import { NextResponse } from 'next/server'; import { authenticateSessionRequest, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { getUserLMStudioSettings } from '@/lib/ai/core'; -import { validateLocalProviderURL } from '@pagespace/lib/security'; +import { validateLocalProviderURL } from '@pagespace/lib/security/url-validator'; /** * GET /api/ai/lmstudio/models diff --git a/apps/web/src/app/api/ai/ollama/models/__tests__/route.test.ts b/apps/web/src/app/api/ai/ollama/models/__tests__/route.test.ts index 0a96e0a02f..76cd7825db 100644 --- a/apps/web/src/app/api/ai/ollama/models/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/ollama/models/__tests__/route.test.ts @@ -4,8 +4,8 @@ import { GET } from '../route'; import type { SessionAuthResult, AuthError } from '@/lib/auth'; // Mock dependencies -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn(), @@ -13,6 +13,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/auth', () => ({ @@ -24,11 +26,11 @@ vi.mock('@/lib/ai/core', () => ({ getUserOllamaSettings: vi.fn(), })); -vi.mock('@pagespace/lib/security', () => ({ +vi.mock('@pagespace/lib/security/url-validator', () => ({ validateLocalProviderURL: vi.fn().mockResolvedValue({ valid: true, resolvedIPs: ['127.0.0.1'] }), })); -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { authenticateSessionRequest, isAuthError } from '@/lib/auth'; import { getUserOllamaSettings } from '@/lib/ai/core'; diff --git a/apps/web/src/app/api/ai/ollama/models/route.ts b/apps/web/src/app/api/ai/ollama/models/route.ts index 46fc79a27e..43a0e6dc3c 100644 --- a/apps/web/src/app/api/ai/ollama/models/route.ts +++ b/apps/web/src/app/api/ai/ollama/models/route.ts @@ -1,8 +1,8 @@ import { NextResponse } from 'next/server'; import { authenticateSessionRequest, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { getUserOllamaSettings } from '@/lib/ai/core'; -import { validateLocalProviderURL } from '@pagespace/lib/security'; +import { validateLocalProviderURL } from '@pagespace/lib/security/url-validator'; /** * GET /api/ai/ollama/models diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/config/__tests__/route.test.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/config/__tests__/route.test.ts index c068be1829..4bdabc4ee4 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/config/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/config/__tests__/route.test.ts @@ -26,15 +26,21 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock websocket broadcast (boundary) @@ -84,7 +90,7 @@ vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ import { pageAgentRepository } from '@/lib/repositories/page-agent-repository'; import { authenticateRequestWithOptions, isAuthError, checkMCPDriveScope } from '@/lib/auth'; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import { broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; import { applyPageMutation } from '@/services/api/page-mutation-service'; diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/config/route.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/config/route.ts index 10dc431933..4bdfe1b7b2 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/config/route.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/config/route.ts @@ -2,10 +2,11 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPDriveScope } from '@/lib/auth'; const AUTH_OPTIONS = { allow: ['session', 'mcp'] as const, requireCSRF: true }; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import { broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; import { pageSpaceTools } from '@/lib/ai/core'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { pageAgentRepository, type AgentConfigUpdate } from '@/lib/repositories/page-agent-repository'; import { getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; import { applyPageMutation, PageRevisionMismatchError } from '@/services/api/page-mutation-service'; diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/__tests__/route.test.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/__tests__/route.test.ts index 566439fc89..5ed3d57021 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/__tests__/route.test.ts @@ -30,20 +30,27 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); import { conversationRepository } from '@/lib/repositories/conversation-repository'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserEditPage, loggers } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions' +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/[messageId]/route.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/[messageId]/route.ts index 01f7c387a7..dd4af8b956 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/[messageId]/route.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/[messageId]/route.ts @@ -1,6 +1,8 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserEditPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { maskIdentifier } from '@/lib/logging/mask'; import { chatMessageRepository, diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/route.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/route.ts index 3c50f313c9..f42ab39583 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/route.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/messages/route.ts @@ -1,7 +1,9 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; import { db, chatMessages, pages, eq, and, desc, sql } from '@pagespace/db'; -import { canUserViewPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { convertDbMessageToUIMessage } from '@/lib/ai/core'; import { parseBoundedIntParam } from '@/lib/utils/query-params'; diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/route.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/route.ts index b6d6c56f5b..ab257ae4c0 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/route.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/[conversationId]/route.ts @@ -1,6 +1,8 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserEditPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { conversationRepository } from '@/lib/repositories/conversation-repository'; // Auth options: PATCH and DELETE are write operations requiring CSRF protection diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/__tests__/route.test.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/__tests__/route.test.ts index 0bb280f311..2f7fa1157c 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/__tests__/route.test.ts @@ -43,15 +43,21 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserViewPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserViewPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock ID generation @@ -62,7 +68,8 @@ vi.mock('@paralleldrive/cuid2', () => ({ import { conversationRepository } from '@/lib/repositories/conversation-repository'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserViewPage, loggers } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions' +import { loggers } from '@pagespace/lib/logging/logger-config'; // Test fixtures const mockUserId = 'user_123'; diff --git a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/route.ts b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/route.ts index fe0a4e6986..6e1ebb7db3 100644 --- a/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/route.ts +++ b/apps/web/src/app/api/ai/page-agents/[agentId]/conversations/route.ts @@ -1,7 +1,9 @@ import { NextResponse } from 'next/server'; import { createId } from '@paralleldrive/cuid2'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserViewPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { conversationRepository, extractPreviewText, diff --git a/apps/web/src/app/api/ai/page-agents/consult/route.ts b/apps/web/src/app/api/ai/page-agents/consult/route.ts index 6efa388b2e..7982a1fa78 100644 --- a/apps/web/src/app/api/ai/page-agents/consult/route.ts +++ b/apps/web/src/app/api/ai/page-agents/consult/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from 'next/server'; import { convertToModelMessages, generateText, stepCountIs, hasToolCall } from 'ai'; import { finishTool, FINISH_TOOL_NAME } from '@/lib/ai/tools/finish-tool'; import { authenticateRequestWithOptions, isAuthError, checkMCPPageScope } from '@/lib/auth'; -import { canUserViewPage } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; import { AIMonitoring } from '@pagespace/lib/monitoring/ai-monitoring'; const AUTH_OPTIONS = { allow: ['session', 'mcp'] as const, requireCSRF: true }; @@ -16,7 +16,8 @@ import { type ToolExecutionContext, } from '@/lib/ai/core'; import { db, pages, drives, eq, chatMessages } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; /** * Format tool execution results into human-readable text diff --git a/apps/web/src/app/api/ai/page-agents/create/__tests__/route.test.ts b/apps/web/src/app/api/ai/page-agents/create/__tests__/route.test.ts index 7a2f610510..ebc3b3b012 100644 --- a/apps/web/src/app/api/ai/page-agents/create/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/page-agents/create/__tests__/route.test.ts @@ -28,15 +28,21 @@ vi.mock('@/lib/auth', () => ({ })); // Mock permissions (boundary) -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock websocket broadcast (boundary) @@ -63,7 +69,7 @@ vi.mock('@/lib/ai/core', () => ({ import { pageAgentRepository } from '@/lib/repositories/page-agent-repository'; import { authenticateRequestWithOptions, isAuthError, checkMCPDriveScope } from '@/lib/auth'; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import { broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; // Test fixtures diff --git a/apps/web/src/app/api/ai/page-agents/create/route.ts b/apps/web/src/app/api/ai/page-agents/create/route.ts index 24106a1a26..e022f2b8e0 100644 --- a/apps/web/src/app/api/ai/page-agents/create/route.ts +++ b/apps/web/src/app/api/ai/page-agents/create/route.ts @@ -2,10 +2,11 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError, checkMCPDriveScope } from '@/lib/auth'; const AUTH_OPTIONS = { allow: ['session', 'mcp'] as const, requireCSRF: true }; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import { broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; import { pageSpaceTools } from '@/lib/ai/core'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { pageAgentRepository, type AgentData } from '@/lib/repositories/page-agent-repository'; /** diff --git a/apps/web/src/app/api/ai/page-agents/multi-drive/route.ts b/apps/web/src/app/api/ai/page-agents/multi-drive/route.ts index 01c2805939..522d98e110 100644 --- a/apps/web/src/app/api/ai/page-agents/multi-drive/route.ts +++ b/apps/web/src/app/api/ai/page-agents/multi-drive/route.ts @@ -3,7 +3,9 @@ import { authenticateRequestWithOptions, isAuthError, getAllowedDriveIds } from const AUTH_OPTIONS = { allow: ['session', 'mcp'] as const }; import { db, pages, drives, eq, and } from '@pagespace/db'; -import { getUserDriveAccess, canUserViewPage, loggers, auditRequest } from '@pagespace/lib/server'; +import { getUserDriveAccess, canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; interface AgentSummary { id: string; diff --git a/apps/web/src/app/api/ai/settings/__tests__/route.test.ts b/apps/web/src/app/api/ai/settings/__tests__/route.test.ts index 9c0995d209..6cd073eaa4 100644 --- a/apps/web/src/app/api/ai/settings/__tests__/route.test.ts +++ b/apps/web/src/app/api/ai/settings/__tests__/route.test.ts @@ -25,8 +25,8 @@ vi.mock('@/lib/auth', () => ({ })); // Mock logging (boundary) -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), error: vi.fn(), @@ -34,7 +34,11 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, - auditRequest: vi.fn(), + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ + auditRequest: vi.fn(), })); // Mock AI provider settings functions (boundary) @@ -79,7 +83,7 @@ vi.mock('@/lib/subscription/rate-limit-middleware', () => ({ import { aiSettingsRepository } from '@/lib/repositories/ai-settings-repository'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { getDefaultPageSpaceSettings, getUserOpenRouterSettings, diff --git a/apps/web/src/app/api/ai/settings/route.ts b/apps/web/src/app/api/ai/settings/route.ts index 3cd3eca03f..34551d411b 100644 --- a/apps/web/src/app/api/ai/settings/route.ts +++ b/apps/web/src/app/api/ai/settings/route.ts @@ -1,6 +1,7 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { getUserOpenRouterSettings, createOpenRouterSettings, @@ -37,7 +38,7 @@ import { import { ONPREM_ALLOWED_PROVIDERS } from '@/lib/ai/core/ai-providers-config'; import { aiSettingsRepository } from '@/lib/repositories/ai-settings-repository'; import { requiresProSubscription } from '@/lib/subscription/rate-limit-middleware'; -import { isOnPrem } from '@pagespace/lib'; +import { isOnPrem } from '@pagespace/lib/deployment-mode'; function isProviderBlocked(provider: string): boolean { return isOnPrem() && !ONPREM_ALLOWED_PROVIDERS.has(provider); diff --git a/apps/web/src/app/api/integrations/connections/[connectionId]/grants/route.ts b/apps/web/src/app/api/integrations/connections/[connectionId]/grants/route.ts index f677e3dbb1..603c7460bb 100644 --- a/apps/web/src/app/api/integrations/connections/[connectionId]/grants/route.ts +++ b/apps/web/src/app/api/integrations/connections/[connectionId]/grants/route.ts @@ -1,8 +1,10 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { getConnectionById, listGrantsByConnection } from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { getConnectionById } from '@pagespace/lib/integrations/repositories/connection-repository'; +import { listGrantsByConnection } from '@pagespace/lib/integrations/repositories/grant-repository'; import { getDriveAccess } from '@pagespace/lib/services/drive-service'; const AUTH_OPTIONS = { allow: ['session'] as const }; diff --git a/apps/web/src/app/api/integrations/google-calendar/calendars/route.ts b/apps/web/src/app/api/integrations/google-calendar/calendars/route.ts index b5e2b3bf56..54fb7f491c 100644 --- a/apps/web/src/app/api/integrations/google-calendar/calendars/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/calendars/route.ts @@ -1,7 +1,8 @@ import { NextResponse } from 'next/server'; import { isOnPrem } from '@pagespace/lib'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { getValidAccessToken } from '@/lib/integrations/google-calendar/token-refresh'; import { listCalendars } from '@/lib/integrations/google-calendar/api-client'; diff --git a/apps/web/src/app/api/integrations/google-calendar/callback/__tests__/route.test.ts b/apps/web/src/app/api/integrations/google-calendar/callback/__tests__/route.test.ts index cd6c1ce96b..680f13650d 100644 --- a/apps/web/src/app/api/integrations/google-calendar/callback/__tests__/route.test.ts +++ b/apps/web/src/app/api/integrations/google-calendar/callback/__tests__/route.test.ts @@ -31,17 +31,17 @@ vi.mock('@pagespace/db', () => ({ googleCalendarConnections: { userId: 'userId' }, })); -vi.mock('@pagespace/lib', () => ({ - isOnPrem: () => false, +vi.mock('@pagespace/lib/deployment-mode', () => ({ + isOnPrem: vi.fn().mockReturnValue(false), +})); +vi.mock('@pagespace/lib/encryption', () => ({ encrypt: vi.fn().mockResolvedValue('encrypted'), +})); +vi.mock('@pagespace/lib/auth/secure-compare', () => ({ secureCompare: (a: string, b: string) => a === b, })); -vi.mock('@pagespace/lib/server', async () => { - const { maskEmail } = await vi.importActual( - '@pagespace/lib/audit/mask-email' - ); - return { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ loggers: { auth: { error: vi.fn(), @@ -50,10 +50,12 @@ vi.mock('@pagespace/lib/server', async () => { debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/audit/audit-log', () => ({ auditRequest: vi.fn(), - maskEmail, - }; -}); +})); vi.mock('@/lib/integrations/google-calendar/return-url', () => ({ GOOGLE_CALENDAR_DEFAULT_RETURN_PATH: '/settings', @@ -61,7 +63,7 @@ vi.mock('@/lib/integrations/google-calendar/return-url', () => ({ })); import { GET } from '../route'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; const SECRET = 'test-oauth-state-secret'; diff --git a/apps/web/src/app/api/integrations/google-calendar/callback/route.ts b/apps/web/src/app/api/integrations/google-calendar/callback/route.ts index 38db5ec570..2c83824a51 100644 --- a/apps/web/src/app/api/integrations/google-calendar/callback/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/callback/route.ts @@ -1,10 +1,13 @@ import { NextResponse } from 'next/server'; import { db, googleCalendarConnections } from '@pagespace/db'; -import { loggers, auditRequest, maskEmail } from '@pagespace/lib/server'; -import { encrypt, isOnPrem } from '@pagespace/lib'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { maskEmail } from '@pagespace/lib/audit/mask-email'; +import { encrypt } from '@pagespace/lib/encryption'; +import { isOnPrem } from '@pagespace/lib/deployment-mode'; import { OAuth2Client } from 'google-auth-library'; import crypto from 'crypto'; -import { secureCompare } from '@pagespace/lib'; +import { secureCompare } from '@pagespace/lib/auth/secure-compare'; import { GOOGLE_CALENDAR_DEFAULT_RETURN_PATH, normalizeGoogleCalendarReturnPath, diff --git a/apps/web/src/app/api/integrations/google-calendar/connect/route.ts b/apps/web/src/app/api/integrations/google-calendar/connect/route.ts index df14707eb4..5c5681b089 100644 --- a/apps/web/src/app/api/integrations/google-calendar/connect/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/connect/route.ts @@ -1,8 +1,9 @@ import { z } from 'zod/v4'; import { db, users, eq } from '@pagespace/db'; -import { isOnPrem } from '@pagespace/lib'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { checkDistributedRateLimit, DISTRIBUTED_RATE_LIMITS } from '@pagespace/lib/security'; +import { isOnPrem } from '@pagespace/lib/deployment-mode'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { checkDistributedRateLimit, DISTRIBUTED_RATE_LIMITS } from '@pagespace/lib/security/distributed-rate-limit'; import { authenticateRequestWithOptions, isAuthError, getClientIP } from '@/lib/auth'; import crypto from 'crypto'; import { normalizeGoogleCalendarReturnPath } from '@/lib/integrations/google-calendar/return-url'; diff --git a/apps/web/src/app/api/integrations/google-calendar/disconnect/route.ts b/apps/web/src/app/api/integrations/google-calendar/disconnect/route.ts index ce776b43e0..de75ccfc27 100644 --- a/apps/web/src/app/api/integrations/google-calendar/disconnect/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/disconnect/route.ts @@ -1,8 +1,10 @@ import { NextResponse } from 'next/server'; import { db, googleCalendarConnections, eq } from '@pagespace/db'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { decrypt, isOnPrem } from '@pagespace/lib'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { decrypt } from '@pagespace/lib/encryption'; +import { isOnPrem } from '@pagespace/lib/deployment-mode'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; import { unregisterWebhookChannels } from '@/lib/integrations/google-calendar/sync-service'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/integrations/google-calendar/settings/route.ts b/apps/web/src/app/api/integrations/google-calendar/settings/route.ts index 42c611d3de..a119e117f0 100644 --- a/apps/web/src/app/api/integrations/google-calendar/settings/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/settings/route.ts @@ -3,7 +3,8 @@ import { z } from 'zod/v4'; import { db, googleCalendarConnections, calendarEvents, eq, and, count } from '@pagespace/db'; import { isOnPrem } from '@pagespace/lib'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; const AUTH_OPTIONS_READ = { allow: ['session'] as const, requireCSRF: false }; const AUTH_OPTIONS_WRITE = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/integrations/google-calendar/status/route.ts b/apps/web/src/app/api/integrations/google-calendar/status/route.ts index d1c60028fb..33fa0cc98f 100644 --- a/apps/web/src/app/api/integrations/google-calendar/status/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/status/route.ts @@ -2,7 +2,8 @@ import { NextResponse } from 'next/server'; import { db, googleCalendarConnections, calendarEvents, eq, and, count } from '@pagespace/db'; import { isOnPrem } from '@pagespace/lib'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: false }; diff --git a/apps/web/src/app/api/integrations/google-calendar/sync/route.ts b/apps/web/src/app/api/integrations/google-calendar/sync/route.ts index f1133b6946..78aadc7dc8 100644 --- a/apps/web/src/app/api/integrations/google-calendar/sync/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/sync/route.ts @@ -1,8 +1,9 @@ import { NextResponse } from 'next/server'; import { isOnPrem } from '@pagespace/lib'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { checkDistributedRateLimit, DISTRIBUTED_RATE_LIMITS } from '@pagespace/lib/security'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { checkDistributedRateLimit, DISTRIBUTED_RATE_LIMITS } from '@pagespace/lib/security/distributed-rate-limit'; import { syncGoogleCalendar } from '@/lib/integrations/google-calendar/sync-service'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/integrations/google-calendar/webhook/__tests__/route.test.ts b/apps/web/src/app/api/integrations/google-calendar/webhook/__tests__/route.test.ts index c4bfe77130..146be5eb03 100644 --- a/apps/web/src/app/api/integrations/google-calendar/webhook/__tests__/route.test.ts +++ b/apps/web/src/app/api/integrations/google-calendar/webhook/__tests__/route.test.ts @@ -9,14 +9,16 @@ vi.mock('@/lib/integrations/google-calendar/sync-service', () => ({ })); // Mock loggers -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); // Mock next/server after() - it executes the callback synchronously in tests diff --git a/apps/web/src/app/api/integrations/google-calendar/webhook/route.ts b/apps/web/src/app/api/integrations/google-calendar/webhook/route.ts index 1ce1f42ff5..fae79dd6fd 100644 --- a/apps/web/src/app/api/integrations/google-calendar/webhook/route.ts +++ b/apps/web/src/app/api/integrations/google-calendar/webhook/route.ts @@ -1,6 +1,6 @@ import { NextResponse, after } from 'next/server'; -import { isOnPrem } from '@pagespace/lib'; -import { loggers } from '@pagespace/lib/server'; +import { isOnPrem } from '@pagespace/lib/deployment-mode'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { syncGoogleCalendar } from '@/lib/integrations/google-calendar/sync-service'; import { validateWebhookAuth } from '@/lib/integrations/google-calendar/webhook-auth'; diff --git a/apps/web/src/app/api/integrations/providers/[providerId]/route.ts b/apps/web/src/app/api/integrations/providers/[providerId]/route.ts index bb1277acd9..cd15a4ea66 100644 --- a/apps/web/src/app/api/integrations/providers/[providerId]/route.ts +++ b/apps/web/src/app/api/integrations/providers/[providerId]/route.ts @@ -2,13 +2,9 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError, verifyAdminAuth } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { - getProviderById, - updateProvider, - deleteProvider, - countProviderConnections, -} from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { getProviderById, updateProvider, deleteProvider, countProviderConnections } from '@pagespace/lib/integrations/repositories/provider-repository'; const AUTH_OPTIONS_READ = { allow: ['session'] as const }; const AUTH_OPTIONS_WRITE = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/integrations/providers/available/route.ts b/apps/web/src/app/api/integrations/providers/available/route.ts index 187ac4ad11..03b2560f95 100644 --- a/apps/web/src/app/api/integrations/providers/available/route.ts +++ b/apps/web/src/app/api/integrations/providers/available/route.ts @@ -1,8 +1,10 @@ import { NextResponse } from 'next/server'; import { authenticateRequestWithOptions, isAuthError } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { builtinProviderList, listEnabledProviders } from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { builtinProviderList } from '@pagespace/lib/integrations/providers'; +import { listEnabledProviders } from '@pagespace/lib/integrations/repositories/provider-repository'; const AUTH_OPTIONS = { allow: ['session'] as const }; diff --git a/apps/web/src/app/api/integrations/providers/import-openapi/route.ts b/apps/web/src/app/api/integrations/providers/import-openapi/route.ts index ffb38b5274..15a84e0590 100644 --- a/apps/web/src/app/api/integrations/providers/import-openapi/route.ts +++ b/apps/web/src/app/api/integrations/providers/import-openapi/route.ts @@ -1,8 +1,9 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError, verifyAdminAuth } from '@/lib/auth'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { importOpenAPISpec } from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { importOpenAPISpec } from '@pagespace/lib/integrations/converter/openapi'; const AUTH_OPTIONS = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/app/api/integrations/providers/install/route.ts b/apps/web/src/app/api/integrations/providers/install/route.ts index 6d8048e5c3..fdc5955b01 100644 --- a/apps/web/src/app/api/integrations/providers/install/route.ts +++ b/apps/web/src/app/api/integrations/providers/install/route.ts @@ -2,12 +2,10 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { verifyAdminAuth, isAdminAuthError } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { - getBuiltinProvider, - getProviderBySlug, - createProvider, -} from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { getBuiltinProvider } from '@pagespace/lib/integrations/providers'; +import { getProviderBySlug, createProvider } from '@pagespace/lib/integrations/repositories/provider-repository'; const installSchema = z.object({ builtinId: z.string().min(1), diff --git a/apps/web/src/app/api/integrations/providers/route.ts b/apps/web/src/app/api/integrations/providers/route.ts index b973535759..52fc1ddbae 100644 --- a/apps/web/src/app/api/integrations/providers/route.ts +++ b/apps/web/src/app/api/integrations/providers/route.ts @@ -2,8 +2,10 @@ import { NextResponse } from 'next/server'; import { z } from 'zod'; import { authenticateRequestWithOptions, isAuthError, verifyAdminAuth } from '@/lib/auth'; import { db } from '@pagespace/db'; -import { loggers, auditRequest } from '@pagespace/lib/server'; -import { listEnabledProviders, createProvider, seedBuiltinProviders, refreshBuiltinProviders, builtinProviderList } from '@pagespace/lib/integrations'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { auditRequest } from '@pagespace/lib/audit/audit-log'; +import { listEnabledProviders, createProvider, seedBuiltinProviders, refreshBuiltinProviders } from '@pagespace/lib/integrations/repositories/provider-repository'; +import { builtinProviderList } from '@pagespace/lib/integrations/providers'; const AUTH_OPTIONS_READ = { allow: ['session'] as const }; const AUTH_OPTIONS_WRITE = { allow: ['session'] as const, requireCSRF: true }; diff --git a/apps/web/src/lib/ai/core/__tests__/integration-tool-resolver.test.ts b/apps/web/src/lib/ai/core/__tests__/integration-tool-resolver.test.ts index 424dc8b252..9615e6ecbb 100644 --- a/apps/web/src/lib/ai/core/__tests__/integration-tool-resolver.test.ts +++ b/apps/web/src/lib/ai/core/__tests__/integration-tool-resolver.test.ts @@ -12,26 +12,40 @@ vi.mock('@pagespace/db', () => ({ db: {}, })); -vi.mock('@pagespace/lib/integrations', () => ({ +vi.mock('@pagespace/lib/integrations/resolution/resolve-agent-integrations', () => ({ resolveAgentIntegrations: vi.fn(), resolveGlobalAssistantIntegrations: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/converter/ai-sdk', () => ({ convertIntegrationToolsToAISDK: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/saga/execute-tool', () => ({ createToolExecutor: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/repositories/connection-repository', () => ({ getConnectionWithProvider: vi.fn(), - logAuditEntry: vi.fn(), - listGrantsByAgent: vi.fn(), listUserConnections: vi.fn(), listDriveConnections: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/repositories/audit-repository', () => ({ + logAuditEntry: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/repositories/grant-repository', () => ({ + listGrantsByAgent: vi.fn(), +})); +vi.mock('@pagespace/lib/integrations/repositories/config-repository', () => ({ getConfig: vi.fn(), })); import { resolveAgentIntegrations, resolveGlobalAssistantIntegrations, +} from '@pagespace/lib/integrations/resolution/resolve-agent-integrations'; +import { convertIntegrationToolsToAISDK, - createToolExecutor, type GrantWithConnectionAndProvider, -} from '@pagespace/lib/integrations'; +} from '@pagespace/lib/integrations/converter/ai-sdk'; +import { createToolExecutor } from '@pagespace/lib/integrations/saga/execute-tool'; import { resolvePageAgentIntegrationTools, resolveGlobalAssistantIntegrationTools } from '../integration-tool-resolver'; const mockResolveAgentIntegrations = vi.mocked(resolveAgentIntegrations); diff --git a/apps/web/src/lib/ai/core/__tests__/mention-processor.test.ts b/apps/web/src/lib/ai/core/__tests__/mention-processor.test.ts index b505ef4969..68976f179c 100644 --- a/apps/web/src/lib/ai/core/__tests__/mention-processor.test.ts +++ b/apps/web/src/lib/ai/core/__tests__/mention-processor.test.ts @@ -1,9 +1,11 @@ import { describe, it, expect, vi } from 'vitest'; -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), debug: vi.fn(), warn: vi.fn(), error: vi.fn() }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); import { diff --git a/apps/web/src/lib/ai/core/__tests__/provider-factory.test.ts b/apps/web/src/lib/ai/core/__tests__/provider-factory.test.ts index ee18707a8b..141f7e84ef 100644 --- a/apps/web/src/lib/ai/core/__tests__/provider-factory.test.ts +++ b/apps/web/src/lib/ai/core/__tests__/provider-factory.test.ts @@ -64,7 +64,7 @@ vi.mock('ollama-ai-provider-v2', () => ({ })); // Mock security validation -vi.mock('@pagespace/lib/security', () => ({ +vi.mock('@pagespace/lib/security/url-validator', () => ({ validateLocalProviderURL: vi.fn(), })); @@ -128,7 +128,7 @@ import { createOpenAICompatible } from '@ai-sdk/openai-compatible'; import { createAnthropic } from '@ai-sdk/anthropic'; import { createXai } from '@ai-sdk/xai'; import { createOllama } from 'ollama-ai-provider-v2'; -import { validateLocalProviderURL } from '@pagespace/lib/security'; +import { validateLocalProviderURL } from '@pagespace/lib/security/url-validator'; const mockDb = vi.mocked(db); const mockDbMock = mockDb as unknown as MockDb; diff --git a/apps/web/src/lib/ai/core/agent-awareness.ts b/apps/web/src/lib/ai/core/agent-awareness.ts index 012fc6d7cd..29354b22bb 100644 --- a/apps/web/src/lib/ai/core/agent-awareness.ts +++ b/apps/web/src/lib/ai/core/agent-awareness.ts @@ -6,7 +6,8 @@ */ import { db, pages, drives, eq, and } from '@pagespace/db'; -import { getUserDriveAccess, canUserViewPage, loggers } from '@pagespace/lib/server'; +import { getUserDriveAccess, canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; interface DriveAgent { id: string; diff --git a/apps/web/src/lib/ai/core/ai-utils.ts b/apps/web/src/lib/ai/core/ai-utils.ts index 698f851dec..64af928600 100644 --- a/apps/web/src/lib/ai/core/ai-utils.ts +++ b/apps/web/src/lib/ai/core/ai-utils.ts @@ -1,7 +1,7 @@ import { db, userAiSettings, eq, and } from '@pagespace/db'; -import { decrypt } from '@pagespace/lib/server'; +import { decrypt } from '@pagespace/lib/encryption'; import { createId } from '@paralleldrive/cuid2'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { maskIdentifier } from '@/lib/logging/mask'; const aiLogger = loggers.ai.child({ module: 'ai-utils' }); diff --git a/apps/web/src/lib/ai/core/integration-tool-resolver.ts b/apps/web/src/lib/ai/core/integration-tool-resolver.ts index 59fb99f871..591c7e87c8 100644 --- a/apps/web/src/lib/ai/core/integration-tool-resolver.ts +++ b/apps/web/src/lib/ai/core/integration-tool-resolver.ts @@ -9,21 +9,26 @@ import { db } from '@pagespace/db'; import { resolveAgentIntegrations, resolveGlobalAssistantIntegrations, + type ResolutionDependencies, +} from '@pagespace/lib/integrations/resolution/resolve-agent-integrations'; +import { convertIntegrationToolsToAISDK, + type CoreTool, + type GrantWithConnectionAndProvider, +} from '@pagespace/lib/integrations/converter/ai-sdk'; +import { createToolExecutor, + type ExecuteToolDependencies, +} from '@pagespace/lib/integrations/saga/execute-tool'; +import { getConnectionWithProvider, - logAuditEntry, - listGrantsByAgent, listUserConnections, listDriveConnections, - getConfig, - type CoreTool, - type DriveRole, - type ResolutionDependencies, - type ExecuteToolDependencies, - type GrantWithConnectionAndProvider, - type GlobalAssistantConfigData, -} from '@pagespace/lib/integrations'; +} from '@pagespace/lib/integrations/repositories/connection-repository'; +import { logAuditEntry } from '@pagespace/lib/integrations/repositories/audit-repository'; +import { listGrantsByAgent } from '@pagespace/lib/integrations/repositories/grant-repository'; +import { getConfig } from '@pagespace/lib/integrations/repositories/config-repository'; +import { type DriveRole, type GlobalAssistantConfigData } from '@pagespace/lib/integrations/types'; /** The connection type expected by the tool executor's loadConnection dependency. */ type LoadConnectionResult = ExecuteToolDependencies['loadConnection'] extends diff --git a/apps/web/src/lib/ai/core/mention-processor.ts b/apps/web/src/lib/ai/core/mention-processor.ts index 35e0f2f21a..5ef099ddf9 100644 --- a/apps/web/src/lib/ai/core/mention-processor.ts +++ b/apps/web/src/lib/ai/core/mention-processor.ts @@ -6,7 +6,7 @@ * mention format: @[Label](id:type) and returns the IDs for processing. */ -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; export interface ProcessedMention { id: string; diff --git a/apps/web/src/lib/ai/core/message-utils.ts b/apps/web/src/lib/ai/core/message-utils.ts index 4338824a4a..84c0f12671 100644 --- a/apps/web/src/lib/ai/core/message-utils.ts +++ b/apps/web/src/lib/ai/core/message-utils.ts @@ -5,7 +5,7 @@ import { type DynamicToolUIPart, } from 'ai'; import { db, chatMessages, messages } from '@pagespace/db'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; /** Narrow a UIMessage part to TextUIPart */ function isTextPart(part: { type: string }): part is TextUIPart { diff --git a/apps/web/src/lib/ai/core/model-capabilities.ts b/apps/web/src/lib/ai/core/model-capabilities.ts index df13fb6bf9..8c7c38f4dc 100644 --- a/apps/web/src/lib/ai/core/model-capabilities.ts +++ b/apps/web/src/lib/ai/core/model-capabilities.ts @@ -1,4 +1,4 @@ -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { hasVisionCapability } from './vision-models'; const capabilityLogger = loggers.ai.child({ module: 'model-capabilities' }); diff --git a/apps/web/src/lib/ai/core/page-tree-context.ts b/apps/web/src/lib/ai/core/page-tree-context.ts index ceff77d284..ce78e7facc 100644 --- a/apps/web/src/lib/ai/core/page-tree-context.ts +++ b/apps/web/src/lib/ai/core/page-tree-context.ts @@ -6,8 +6,9 @@ */ import { db, pages, drives, eq, and, asc } from '@pagespace/db'; -import { getUserDriveAccess, loggers } from '@pagespace/lib/server'; -import { buildTree, formatTreeAsMarkdown, filterToSubtree } from '@pagespace/lib'; +import { getUserDriveAccess } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { buildTree, formatTreeAsMarkdown, filterToSubtree } from '@pagespace/lib/content/tree-utils'; interface TreeNode { id: string; diff --git a/apps/web/src/lib/ai/tools/__tests__/activity-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/activity-tools.test.ts index b5083c84e1..ef52a18927 100644 --- a/apps/web/src/lib/ai/tools/__tests__/activity-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/activity-tools.test.ts @@ -2,22 +2,22 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { z } from 'zod'; // Mock boundaries -vi.mock('@pagespace/lib', () => ({ - isUserDriveMember: vi.fn(), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + isUserDriveMember: vi.fn(), })); vi.mock('@pagespace/lib/content', () => ({ - groupActivitiesForDiff: vi.fn(), - generateStackedDiff: vi.fn(), - truncateDiffsToTokenBudget: vi.fn(), + groupActivitiesForDiff: vi.fn(), + generateStackedDiff: vi.fn(), + truncateDiffsToTokenBudget: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - readPageContent: vi.fn(), +vi.mock('@pagespace/lib/services/page-content-store', () => ({ + readPageContent: vi.fn(), })); import { activityTools } from '../activity-tools'; -import { isUserDriveMember } from '@pagespace/lib'; +import { isUserDriveMember } from '@pagespace/lib/permissions/permissions'; import type { ToolExecutionContext } from '../../core'; const mockIsUserDriveMember = vi.mocked(isUserDriveMember); diff --git a/apps/web/src/lib/ai/tools/__tests__/agent-communication-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/agent-communication-tools.test.ts index c0cda56b2e..d0ce927551 100644 --- a/apps/web/src/lib/ai/tools/__tests__/agent-communication-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/agent-communication-tools.test.ts @@ -19,9 +19,11 @@ vi.mock('@pagespace/db', () => ({ sql: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - canUserViewPage: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserViewPage: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { info: vi.fn(), warn: vi.fn(), @@ -29,6 +31,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('ai', () => ({ @@ -79,7 +83,7 @@ vi.mock('../../core', () => ({ import { agentCommunicationTools } from '../agent-communication-tools'; import { db } from '@pagespace/db'; -import { canUserViewPage } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; import { createAIProvider, saveMessageToDatabase } from '../../core'; import type { ToolExecutionContext } from '../../core'; import { generateText } from 'ai'; diff --git a/apps/web/src/lib/ai/tools/__tests__/agent-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/agent-tools.test.ts index c7a5089d42..7e5c2ba085 100644 --- a/apps/web/src/lib/ai/tools/__tests__/agent-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/agent-tools.test.ts @@ -2,13 +2,17 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import type { ToolExecutionContext } from '../../core'; // Mock repository seams - the proper boundary for tests -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - getActorInfo: vi.fn().mockResolvedValue({ +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), +})); +vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ + getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@example.com', actorDisplayName: 'Test User', }), - loggers: { +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -18,7 +22,10 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, - agentRepository: { + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/repositories', () => ({ + agentRepository: { findById: vi.fn(), }, })); @@ -45,7 +52,8 @@ vi.mock('../../core', () => ({ })); import { agentTools } from '../agent-tools'; -import { canUserEditPage, agentRepository } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { agentRepository } from '@pagespace/lib/repositories'; import { broadcastPageEvent } from '@/lib/websocket'; import { applyPageMutation } from '@/services/api/page-mutation-service'; diff --git a/apps/web/src/lib/ai/tools/__tests__/calendar-read-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/calendar-read-tools.test.ts index 07600ec1ff..ebe7cc169b 100644 --- a/apps/web/src/lib/ai/tools/__tests__/calendar-read-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/calendar-read-tools.test.ts @@ -40,12 +40,12 @@ vi.mock('@pagespace/db', () => ({ not: vi.fn(), })); -vi.mock('@pagespace/lib', () => ({ +vi.mock('@pagespace/lib/permissions/permissions', () => ({ isUserDriveMember: vi.fn(), getDriveIdsForUser: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ +vi.mock('@pagespace/lib/logging/logger-config', () => ({ loggers: { ai: { child: vi.fn(() => ({ @@ -56,6 +56,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/logging/mask', () => ({ @@ -64,7 +65,7 @@ vi.mock('@/lib/logging/mask', () => ({ import { calendarReadTools } from '../calendar-read-tools'; import { db } from '@pagespace/db'; -import { isUserDriveMember, getDriveIdsForUser } from '@pagespace/lib'; +import { isUserDriveMember, getDriveIdsForUser } from '@pagespace/lib/permissions/permissions'; import type { ToolExecutionContext } from '../../core'; const mockDb = vi.mocked(db); diff --git a/apps/web/src/lib/ai/tools/__tests__/calendar-write-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/calendar-write-tools.test.ts index 860749d1f8..ab55694302 100644 --- a/apps/web/src/lib/ai/tools/__tests__/calendar-write-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/calendar-write-tools.test.ts @@ -54,13 +54,15 @@ vi.mock('@pagespace/db', () => ({ inArray: vi.fn(), })); -vi.mock('@pagespace/lib', () => ({ - isUserDriveMember: vi.fn(), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + isUserDriveMember: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - getDriveMemberUserIds: vi.fn(), - loggers: { +vi.mock('@pagespace/lib/services/drive-member-service', () => ({ + getDriveMemberUserIds: vi.fn(), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -70,6 +72,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/websocket/calendar-events', () => ({ @@ -137,8 +140,8 @@ vi.mock('chrono-node', () => ({ import { calendarWriteTools } from '../calendar-write-tools'; import { db, inArray } from '@pagespace/db'; -import { isUserDriveMember } from '@pagespace/lib'; -import { getDriveMemberUserIds } from '@pagespace/lib/server'; +import { isUserDriveMember } from '@pagespace/lib/permissions/permissions'; +import { getDriveMemberUserIds } from '@pagespace/lib/services/drive-member-service'; import { broadcastCalendarEvent } from '@/lib/websocket/calendar-events'; import type { ToolExecutionContext } from '../../core'; diff --git a/apps/web/src/lib/ai/tools/__tests__/channel-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/channel-tools.test.ts index 5258fb2a53..cb02d46a38 100644 --- a/apps/web/src/lib/ai/tools/__tests__/channel-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/channel-tools.test.ts @@ -31,17 +31,19 @@ vi.mock('@pagespace/db', () => ({ and: vi.fn(), })); -vi.mock('@pagespace/lib/permissions', () => ({ - canUserEditPage: vi.fn(), - canUserViewPage: vi.fn(), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), + canUserViewPage: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - getActorInfo: vi.fn().mockResolvedValue({ +vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ + getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@example.com', actorDisplayName: 'Test User', }), - loggers: { +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -51,6 +53,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@pagespace/lib/auth/broadcast-auth', () => ({ @@ -73,8 +76,8 @@ vi.mock('@/lib/logging/mask', () => ({ })); import { channelTools } from '../channel-tools'; -import { canUserEditPage, canUserViewPage } from '@pagespace/lib/permissions'; -import { getActorInfo } from '@pagespace/lib/server'; +import { canUserEditPage, canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; import { db } from '@pagespace/db'; import { broadcastInboxEvent } from '@/lib/websocket/socket-utils'; import type { ToolExecutionContext } from '../../core'; diff --git a/apps/web/src/lib/ai/tools/__tests__/drive-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/drive-tools.test.ts index dbd37141b6..92ce930b6e 100644 --- a/apps/web/src/lib/ai/tools/__tests__/drive-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/drive-tools.test.ts @@ -12,8 +12,8 @@ vi.mock('@pagespace/db', () => ({ and: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -23,6 +23,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/websocket', () => ({ diff --git a/apps/web/src/lib/ai/tools/__tests__/page-read-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/page-read-tools.test.ts index 886ea933e1..0935ad7d66 100644 --- a/apps/web/src/lib/ai/tools/__tests__/page-read-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/page-read-tools.test.ts @@ -49,20 +49,18 @@ vi.mock('@pagespace/db', () => ({ min: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - getUserDriveAccess: vi.fn(), - getUserAccessLevel: vi.fn(), - getUserAccessiblePagesInDriveWithDetails: vi.fn(), - canUserViewPage: vi.fn(), - isDocumentPage: vi.fn((type) => type === 'DOCUMENT'), - isAIChatPage: vi.fn((type) => type === 'AI_CHAT'), - isChannelPage: vi.fn((type) => type === 'CHANNEL'), - getCreatablePageTypes: vi.fn(() => ['FOLDER', 'DOCUMENT', 'CHANNEL', 'AI_CHAT', 'CANVAS', 'SHEET', 'TASK_LIST', 'CODE']), - formatContentForAI: vi.fn((content) => content), - formatSheetForAI: vi.fn(), - formatTaskListForAI: vi.fn(), - getPagePath: vi.fn().mockResolvedValue('/drive/page'), - loggers: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + getUserDriveAccess: vi.fn(), + getUserAccessLevel: vi.fn(), + getUserAccessiblePagesInDriveWithDetails: vi.fn(), + canUserViewPage: vi.fn(), +})); +vi.mock('@pagespace/lib/content/page-types.config', () => ({ + getPageTypeEmoji: vi.fn((type: string) => '📄'), + isFolderPage: vi.fn((type: string) => type === 'FOLDER'), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -80,15 +78,15 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); - vi.mock('@/lib/logging/mask', () => ({ maskIdentifier: vi.fn((id) => `***${id?.slice(-4) || ''}`), })); import { pageReadTools } from '../page-read-tools'; import { db } from '@pagespace/db'; -import { getUserDriveAccess, getUserAccessLevel } from '@pagespace/lib/server'; +import { getUserDriveAccess, getUserAccessLevel } from '@pagespace/lib/permissions/permissions'; import type { ToolExecutionContext } from '../../core'; const mockDb = vi.mocked(db); diff --git a/apps/web/src/lib/ai/tools/__tests__/page-write-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/page-write-tools.test.ts index f51dcfed44..215415575d 100644 --- a/apps/web/src/lib/ai/tools/__tests__/page-write-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/page-write-tools.test.ts @@ -11,17 +11,27 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; */ // Mock repository seams - the proper architectural boundaries -vi.mock('@pagespace/lib/server', () => ({ - canUserEditPage: vi.fn(), - canUserDeletePage: vi.fn(), - logPageActivity: vi.fn(), - logDriveActivity: vi.fn(), - getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@example.com', actorDisplayName: 'Test User' }), - detectPageContentFormat: vi.fn(() => 'text'), - hashWithPrefix: vi.fn(() => 'content-ref'), - computePageStateHash: vi.fn(() => 'state-hash'), - createPageVersion: vi.fn().mockResolvedValue({ id: 'version-1', contentRef: 'content-ref', contentSize: 0 }), - PageType: { +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), + canUserDeletePage: vi.fn(), +})); +vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ + logPageActivity: vi.fn(), + logDriveActivity: vi.fn(), + getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@example.com', actorDisplayName: 'Test User' }), +})); +vi.mock('@pagespace/lib/content/page-content-format', () => ({ + detectPageContentFormat: vi.fn(() => 'text'), +})); +vi.mock('@pagespace/lib/utils/hash-utils', () => ({ + hashWithPrefix: vi.fn(() => 'content-ref'), +})); +vi.mock('@pagespace/lib/services/page-version-service', () => ({ + computePageStateHash: vi.fn(() => 'state-hash'), + createPageVersion: vi.fn().mockResolvedValue({ id: 'version-1', contentRef: 'content-ref', contentSize: 0 }), +})); +vi.mock('@pagespace/lib/utils/enums', () => ({ + PageType: { FOLDER: 'FOLDER', DOCUMENT: 'DOCUMENT', AI_CHAT: 'AI_CHAT', @@ -33,16 +43,22 @@ vi.mock('@pagespace/lib/server', () => ({ CODE: 'CODE', TERMINAL: 'TERMINAL', }, - getDefaultContent: vi.fn(() => ''), - getCreatablePageTypes: vi.fn(() => ['FOLDER', 'DOCUMENT', 'CHANNEL', 'AI_CHAT', 'CANVAS', 'SHEET', 'TASK_LIST', 'CODE']), - isAIChatPage: vi.fn((type) => type === 'AI_CHAT'), - isDocumentPage: vi.fn((type) => type === 'DOCUMENT'), - parseSheetContent: vi.fn(() => ({ rowCount: 10, columnCount: 5 })), - serializeSheetContent: vi.fn(() => ''), - updateSheetCells: vi.fn((data) => data), - isValidCellAddress: vi.fn((addr) => /^[A-Z]+\d+$/.test(addr.toUpperCase())), - isSheetType: vi.fn((type) => type === 'SHEET'), - loggers: { +})); +vi.mock('@pagespace/lib/content/page-types.config', () => ({ + getDefaultContent: vi.fn(() => ''), + getCreatablePageTypes: vi.fn(() => ['FOLDER', 'DOCUMENT', 'CHANNEL', 'AI_CHAT', 'CANVAS', 'SHEET', 'TASK_LIST', 'CODE']), + isAIChatPage: vi.fn((type) => type === 'AI_CHAT'), + isDocumentPage: vi.fn((type) => type === 'DOCUMENT'), +})); +vi.mock('@pagespace/lib/sheets', () => ({ + parseSheetContent: vi.fn(() => ({ rowCount: 10, columnCount: 5 })), + serializeSheetContent: vi.fn(() => ''), + updateSheetCells: vi.fn((data) => data), + isValidCellAddress: vi.fn((addr) => /^[A-Z]+\d+$/.test(addr.toUpperCase())), + isSheetType: vi.fn((type) => type === 'SHEET'), +})); +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -52,8 +68,10 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, - // Repository seams - pageRepository: { + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, +})); +vi.mock('@pagespace/lib/repositories', () => ({ + pageRepository: { findById: vi.fn(), findTrashedById: vi.fn(), existsInDrive: vi.fn(), @@ -65,7 +83,7 @@ vi.mock('@pagespace/lib/server', () => ({ restore: vi.fn(), getChildIds: vi.fn(), }, - driveRepository: { + driveRepository: { findById: vi.fn(), findByIdBasic: vi.fn(), findByIdAndOwner: vi.fn(), @@ -90,7 +108,8 @@ vi.mock('@/lib/logging/mask', () => ({ })); import { pageWriteTools } from '../page-write-tools'; -import { canUserEditPage, pageRepository, driveRepository } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { pageRepository, driveRepository } from '@pagespace/lib/repositories'; import { applyPageMutation } from '@/services/api/page-mutation-service'; import type { ToolExecutionContext } from '../../core'; diff --git a/apps/web/src/lib/ai/tools/__tests__/search-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/search-tools.test.ts index eae2bb94a7..75a5d5ff61 100644 --- a/apps/web/src/lib/ai/tools/__tests__/search-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/search-tools.test.ts @@ -2,12 +2,12 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; import { assert } from './riteway'; // Mock only the boundary we actually test -vi.mock('@pagespace/lib/server', () => ({ - getUserDriveAccess: vi.fn(), +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + getUserDriveAccess: vi.fn(), })); import { searchTools } from '../search-tools'; -import { getUserDriveAccess } from '@pagespace/lib/server'; +import { getUserDriveAccess } from '@pagespace/lib/permissions/permissions'; import type { ToolExecutionContext } from '../../core'; const mockGetUserDriveAccess = vi.mocked(getUserDriveAccess); diff --git a/apps/web/src/lib/ai/tools/__tests__/task-management-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/task-management-tools.test.ts index 0d10cc7472..03f7bb5edb 100644 --- a/apps/web/src/lib/ai/tools/__tests__/task-management-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/task-management-tools.test.ts @@ -29,21 +29,22 @@ vi.mock('@pagespace/db', () => ({ asc: vi.fn(), })); -vi.mock('@pagespace/lib/server', async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - canUserEditPage: vi.fn(), - canUserViewPage: vi.fn(), - getUserDriveAccess: vi.fn(), - logPageActivity: vi.fn(), - getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@test.com' }), - }; -}); +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + canUserEditPage: vi.fn(), + canUserViewPage: vi.fn(), + getUserDriveAccess: vi.fn(), +})); +vi.mock('@pagespace/lib/monitoring/activity-logger', () => ({ + logPageActivity: vi.fn(), + getActorInfo: vi.fn().mockResolvedValue({ actorEmail: 'test@test.com' }), +})); -vi.mock('@pagespace/lib', () => ({ +vi.mock('@pagespace/lib/content/page-types.config', () => ({ getDefaultContent: vi.fn(() => ''), - PageType: { DOCUMENT: 'DOCUMENT' }, + getCreatablePageTypes: vi.fn(() => ['DOCUMENT', 'FOLDER', 'TASK_LIST']), +})); +vi.mock('@pagespace/lib/utils/enums', () => ({ + PageType: { DOCUMENT: 'DOCUMENT' }, })); vi.mock('@/lib/websocket', () => ({ @@ -54,7 +55,7 @@ vi.mock('@/lib/websocket', () => ({ import { taskManagementTools } from '../task-management-tools'; import { db } from '@pagespace/db'; -import { canUserEditPage } from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; import type { ToolExecutionContext } from '../../core'; const mockDb = vi.mocked(db); diff --git a/apps/web/src/lib/ai/tools/__tests__/web-search-tools.test.ts b/apps/web/src/lib/ai/tools/__tests__/web-search-tools.test.ts index 622378d3f1..cd64803f94 100644 --- a/apps/web/src/lib/ai/tools/__tests__/web-search-tools.test.ts +++ b/apps/web/src/lib/ai/tools/__tests__/web-search-tools.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; // Mock dependencies -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { ai: { child: vi.fn(() => ({ info: vi.fn(), @@ -12,6 +12,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@/lib/logging/mask', () => ({ diff --git a/apps/web/src/lib/ai/tools/activity-tools.ts b/apps/web/src/lib/ai/tools/activity-tools.ts index cad9b8a798..74453fbf3f 100644 --- a/apps/web/src/lib/ai/tools/activity-tools.ts +++ b/apps/web/src/lib/ai/tools/activity-tools.ts @@ -15,16 +15,18 @@ import { isNull, inArray, } from '@pagespace/db'; -import { isUserDriveMember, getBatchPagePermissions, isDriveOwnerOrAdmin } from '@pagespace/lib'; +import { isUserDriveMember, getBatchPagePermissions, isDriveOwnerOrAdmin } from '@pagespace/lib/permissions/permissions'; import { groupActivitiesForDiff, - resolveStackedVersionContent, + type ActivityForDiff, +} from '@pagespace/lib/content/activity-diff-utils'; +import { resolveStackedVersionContent } from '@pagespace/lib/content/version-resolver'; +import { generateDiffsWithinBudget, calculateDiffBudget, - type ActivityForDiff, type DiffRequest, -} from '@pagespace/lib/content'; -import { readPageContent } from '@pagespace/lib/server'; +} from '@pagespace/lib/content/diff-generator'; +import { readPageContent } from '@pagespace/lib/services/page-content-store'; import { type ToolExecutionContext } from '../core'; /** diff --git a/apps/web/src/lib/ai/tools/agent-communication-tools.ts b/apps/web/src/lib/ai/tools/agent-communication-tools.ts index 20611a423f..2f4bd17365 100644 --- a/apps/web/src/lib/ai/tools/agent-communication-tools.ts +++ b/apps/web/src/lib/ai/tools/agent-communication-tools.ts @@ -3,7 +3,7 @@ import { finishTool, FINISH_TOOL_NAME } from './finish-tool'; import { z } from 'zod'; import { generateText, convertToModelMessages, UIMessage } from 'ai'; import { db, pages, chatMessages, drives, eq, and, sql } from '@pagespace/db'; -import { canUserViewPage } from '@pagespace/lib/server'; +import { canUserViewPage } from '@pagespace/lib/permissions/permissions'; import { sanitizeMessagesForModel, saveMessageToDatabase, @@ -23,7 +23,7 @@ import { pageWriteTools } from './page-write-tools'; import { searchTools } from './search-tools'; import { taskManagementTools } from './task-management-tools'; import { agentTools } from './agent-tools'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; // Nesting cap. Intent is 3+ for richer agent-to-agent composition, but held at 2 // until inner stepCountIs budget is reworked — see PR #713. Raising this without diff --git a/apps/web/src/lib/ai/tools/agent-tools.ts b/apps/web/src/lib/ai/tools/agent-tools.ts index 11a48efda6..12a8a5541f 100644 --- a/apps/web/src/lib/ai/tools/agent-tools.ts +++ b/apps/web/src/lib/ai/tools/agent-tools.ts @@ -1,11 +1,9 @@ import { tool } from 'ai'; import { z } from 'zod'; -import { - canUserEditPage, - getActorInfo, - loggers, - agentRepository, -} from '@pagespace/lib/server'; +import { canUserEditPage } from '@pagespace/lib/permissions/permissions'; +import { getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { agentRepository } from '@pagespace/lib/repositories'; import { broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; import { maskIdentifier } from '@/lib/logging/mask'; import { type ToolExecutionContext, pageSpaceTools } from '../core'; diff --git a/apps/web/src/lib/ai/tools/calendar-read-tools.ts b/apps/web/src/lib/ai/tools/calendar-read-tools.ts index 8265049c12..8cad393e66 100644 --- a/apps/web/src/lib/ai/tools/calendar-read-tools.ts +++ b/apps/web/src/lib/ai/tools/calendar-read-tools.ts @@ -15,7 +15,7 @@ import { desc, } from '@pagespace/db'; import type { CalendarTriggerMetadata } from '@pagespace/db'; -import { isUserDriveMember, getDriveIdsForUser } from '@pagespace/lib'; +import { isUserDriveMember, getDriveIdsForUser } from '@pagespace/lib/permissions/permissions'; import { type ToolExecutionContext } from '../core'; import { normalizeTimezone, getTimezoneOffsetMinutes, formatDateInTimezone, isNaiveISODatetime, parseNaiveDatetimeInTimezone } from '../core/timestamp-utils'; diff --git a/apps/web/src/lib/ai/tools/calendar-write-tools.ts b/apps/web/src/lib/ai/tools/calendar-write-tools.ts index 86fc3faee5..b3f3a2d846 100644 --- a/apps/web/src/lib/ai/tools/calendar-write-tools.ts +++ b/apps/web/src/lib/ai/tools/calendar-write-tools.ts @@ -12,8 +12,9 @@ import { inArray, } from '@pagespace/db'; import type { CalendarTriggerMetadata } from '@pagespace/db'; -import { isUserDriveMember } from '@pagespace/lib'; -import { getDriveMemberUserIds, loggers } from '@pagespace/lib/server'; +import { isUserDriveMember } from '@pagespace/lib/permissions/permissions'; +import { getDriveMemberUserIds } from '@pagespace/lib/services/drive-member-service'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { broadcastCalendarEvent } from '@/lib/websocket/calendar-events'; import { type ToolExecutionContext } from '../core'; import { normalizeTimezone, formatDateInTimezone, parseDateTime } from '../core/timestamp-utils'; diff --git a/apps/web/src/lib/ai/tools/channel-tools.ts b/apps/web/src/lib/ai/tools/channel-tools.ts index aac4cbd344..672d1a9175 100644 --- a/apps/web/src/lib/ai/tools/channel-tools.ts +++ b/apps/web/src/lib/ai/tools/channel-tools.ts @@ -1,11 +1,8 @@ import { tool } from 'ai'; import { z } from 'zod'; -import { canUserEditPage, canUserViewPage } from '@pagespace/lib/permissions'; -import { - loggers, - getActorInfo, - logMessageActivity, -} from '@pagespace/lib/server'; +import { canUserEditPage, canUserViewPage } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { getActorInfo, logMessageActivity } from '@pagespace/lib/monitoring/activity-logger'; import { db, channelMessages, channelReadStatus, pages, driveMembers, eq, and } from '@pagespace/db'; import { createSignedBroadcastHeaders } from '@pagespace/lib/auth/broadcast-auth'; import { broadcastInboxEvent } from '@/lib/websocket/socket-utils'; diff --git a/apps/web/src/lib/ai/tools/drive-tools.ts b/apps/web/src/lib/ai/tools/drive-tools.ts index 9b565d8405..2859481d33 100644 --- a/apps/web/src/lib/ai/tools/drive-tools.ts +++ b/apps/web/src/lib/ai/tools/drive-tools.ts @@ -1,7 +1,9 @@ import { tool } from 'ai'; import { z } from 'zod'; import { db, pages, drives, eq, and, driveMembers, pagePermissions, ne } from '@pagespace/db'; -import { slugify, logDriveActivity, getActorInfo, getDriveAccessWithDrive } from '@pagespace/lib/server'; +import { slugify } from '@pagespace/lib/utils/utils'; +import { logDriveActivity, getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; +import { getDriveAccessWithDrive } from '@pagespace/lib/services/drive-service'; import { broadcastDriveEvent, createDriveEventPayload } from '@/lib/websocket'; import { getDriveRecipientUserIds } from '@pagespace/lib/services/drive-member-service'; import { type ToolExecutionContext } from '../core'; diff --git a/apps/web/src/lib/ai/tools/page-read-tools.ts b/apps/web/src/lib/ai/tools/page-read-tools.ts index eacd8e2733..6fb69af796 100644 --- a/apps/web/src/lib/ai/tools/page-read-tools.ts +++ b/apps/web/src/lib/ai/tools/page-read-tools.ts @@ -1,7 +1,10 @@ import { tool } from 'ai'; import { z } from 'zod'; import { db, pages, taskItems, taskLists, chatMessages, channelMessages, eq, and, asc, isNotNull, count, max, min, inArray } from '@pagespace/db'; -import { buildTree, getUserAccessLevel, getUserDriveAccess, getUserAccessiblePagesInDriveWithDetails, getPageTypeEmoji, isFolderPage, PageType } from '@pagespace/lib/server'; +import { buildTree } from '@pagespace/lib/content/tree-utils'; +import { getUserAccessLevel, getUserDriveAccess, getUserAccessiblePagesInDriveWithDetails } from '@pagespace/lib/permissions/permissions'; +import { getPageTypeEmoji, isFolderPage } from '@pagespace/lib/content/page-types.config'; +import { PageType } from '@pagespace/lib/utils/enums'; import { type ToolExecutionContext, getSuggestedVisionModels } from '../core'; import { addLineBreaksForAI } from '@/lib/editor/line-breaks'; diff --git a/apps/web/src/lib/ai/tools/page-write-tools.ts b/apps/web/src/lib/ai/tools/page-write-tools.ts index a205cb7519..395a58e58b 100644 --- a/apps/web/src/lib/ai/tools/page-write-tools.ts +++ b/apps/web/src/lib/ai/tools/page-write-tools.ts @@ -1,31 +1,16 @@ import { tool } from 'ai'; import { z } from 'zod'; -import { - canUserEditPage, - canUserDeletePage, - PageType, - isAIChatPage, - isDocumentPage, - getDefaultContent, - getCreatablePageTypes, - parseSheetContent, - serializeSheetContent, - updateSheetCells, - isValidCellAddress, - isSheetType, - loggers, - logPageActivity, - logDriveActivity, - getActorInfo, - detectPageContentFormat, - hashWithPrefix, - computePageStateHash, - createPageVersion, - pageRepository, - driveRepository, - type ActivityOperation, -} from '@pagespace/lib/server'; -import { createChangeGroupId } from '@pagespace/lib/monitoring'; +import { canUserEditPage, canUserDeletePage } from '@pagespace/lib/permissions/permissions'; +import { PageType } from '@pagespace/lib/utils/enums'; +import { isAIChatPage, isDocumentPage, getDefaultContent, getCreatablePageTypes } from '@pagespace/lib/content/page-types.config'; +import { parseSheetContent, serializeSheetContent, updateSheetCells, isValidCellAddress, isSheetType } from '@pagespace/lib/sheets'; +import { loggers } from '@pagespace/lib/logging/logger-config'; +import { logPageActivity, logDriveActivity, getActorInfo, type ActivityOperation } from '@pagespace/lib/monitoring/activity-logger'; +import { detectPageContentFormat } from '@pagespace/lib/content/page-content-format'; +import { hashWithPrefix } from '@pagespace/lib/utils/hash-utils'; +import { computePageStateHash, createPageVersion } from '@pagespace/lib/services/page-version-service'; +import { pageRepository, driveRepository } from '@pagespace/lib/repositories'; +import { createChangeGroupId } from '@pagespace/lib/monitoring/change-group'; import { applyPageMutation, type PageMutationContext } from '@/services/api/page-mutation-service'; import { broadcastPageEvent, createPageEventPayload, broadcastDriveEvent, createDriveEventPayload } from '@/lib/websocket'; import { getDriveRecipientUserIds } from '@pagespace/lib/services/drive-member-service'; diff --git a/apps/web/src/lib/ai/tools/search-tools.ts b/apps/web/src/lib/ai/tools/search-tools.ts index 7e64480fcd..fadf278584 100644 --- a/apps/web/src/lib/ai/tools/search-tools.ts +++ b/apps/web/src/lib/ai/tools/search-tools.ts @@ -1,7 +1,7 @@ import { tool } from 'ai'; import { z } from 'zod'; import { db, pages, drives, chatMessages, eq, and, sql, inArray, asc } from '@pagespace/db'; -import { getUserDriveAccess, getUserAccessiblePagesInDriveWithDetails } from '@pagespace/lib/server'; +import { getUserDriveAccess, getUserAccessiblePagesInDriveWithDetails } from '@pagespace/lib/permissions/permissions'; import { type ToolExecutionContext } from '../core'; export const searchTools = { diff --git a/apps/web/src/lib/ai/tools/task-management-tools.ts b/apps/web/src/lib/ai/tools/task-management-tools.ts index 786679d97f..74da657f4f 100644 --- a/apps/web/src/lib/ai/tools/task-management-tools.ts +++ b/apps/web/src/lib/ai/tools/task-management-tools.ts @@ -3,8 +3,10 @@ import { z } from 'zod'; import { db, taskLists, taskItems, taskStatusConfigs, taskAssignees, pages, eq, and, desc, asc, isNull, inArray } from '@pagespace/db'; import { type ToolExecutionContext } from '../core'; import { broadcastTaskEvent, broadcastPageEvent, createPageEventPayload } from '@/lib/websocket'; -import { canUserEditPage, canUserViewPage, getUserDriveAccess, logPageActivity, getActorInfo } from '@pagespace/lib/server'; -import { getDefaultContent, PageType } from '@pagespace/lib'; +import { canUserEditPage, canUserViewPage, getUserDriveAccess } from '@pagespace/lib/permissions/permissions'; +import { logPageActivity, getActorInfo } from '@pagespace/lib/monitoring/activity-logger'; +import { getDefaultContent } from '@pagespace/lib/content/page-types.config'; +import { PageType } from '@pagespace/lib/utils/enums'; import { syncTaskDueDateTrigger, cancelTaskDueDateTrigger, diff --git a/apps/web/src/lib/ai/tools/web-search-tools.ts b/apps/web/src/lib/ai/tools/web-search-tools.ts index f431fa3c29..50eb184afa 100644 --- a/apps/web/src/lib/ai/tools/web-search-tools.ts +++ b/apps/web/src/lib/ai/tools/web-search-tools.ts @@ -1,7 +1,7 @@ import { tool } from 'ai'; import { z } from 'zod'; import { type ToolExecutionContext } from '../core'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { maskIdentifier } from '@/lib/logging/mask'; const webSearchLogger = loggers.ai.child({ module: 'web-search-tools' }); diff --git a/apps/web/src/lib/integrations/google-calendar/__tests__/map-attendees.test.ts b/apps/web/src/lib/integrations/google-calendar/__tests__/map-attendees.test.ts index a84eda2c5c..93677381e9 100644 --- a/apps/web/src/lib/integrations/google-calendar/__tests__/map-attendees.test.ts +++ b/apps/web/src/lib/integrations/google-calendar/__tests__/map-attendees.test.ts @@ -24,10 +24,12 @@ vi.mock('@pagespace/db', () => ({ sql: vi.fn((strings: TemplateStringsArray, ...values: unknown[]) => `lower(${String(values[0])})`), })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), error: vi.fn() }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); vi.mock('@paralleldrive/cuid2', () => ({ diff --git a/apps/web/src/lib/integrations/google-calendar/__tests__/sync-service.test.ts b/apps/web/src/lib/integrations/google-calendar/__tests__/sync-service.test.ts index ddb766077c..9aefc49e57 100644 --- a/apps/web/src/lib/integrations/google-calendar/__tests__/sync-service.test.ts +++ b/apps/web/src/lib/integrations/google-calendar/__tests__/sync-service.test.ts @@ -69,14 +69,16 @@ vi.mock('@pagespace/db', () => ({ desc: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); const mockGetValidAccessToken = vi.fn(); diff --git a/apps/web/src/lib/integrations/google-calendar/api-client.ts b/apps/web/src/lib/integrations/google-calendar/api-client.ts index 9e25750644..4fba4effeb 100644 --- a/apps/web/src/lib/integrations/google-calendar/api-client.ts +++ b/apps/web/src/lib/integrations/google-calendar/api-client.ts @@ -7,7 +7,7 @@ * API Reference: https://developers.google.com/calendar/api/v3/reference */ -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; const GOOGLE_CALENDAR_API_BASE = 'https://www.googleapis.com/calendar/v3'; diff --git a/apps/web/src/lib/integrations/google-calendar/push-service.ts b/apps/web/src/lib/integrations/google-calendar/push-service.ts index cac95293b6..f1b7a8b1dc 100644 --- a/apps/web/src/lib/integrations/google-calendar/push-service.ts +++ b/apps/web/src/lib/integrations/google-calendar/push-service.ts @@ -7,7 +7,7 @@ import { db, googleCalendarConnections, calendarEvents, eq, and } from '@pagespace/db'; import type { CalendarEvent } from '@pagespace/db'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { getValidAccessToken } from './token-refresh'; import { createGoogleEvent, diff --git a/apps/web/src/lib/integrations/google-calendar/sync-service.ts b/apps/web/src/lib/integrations/google-calendar/sync-service.ts index eb87db2e1c..fb7757f231 100644 --- a/apps/web/src/lib/integrations/google-calendar/sync-service.ts +++ b/apps/web/src/lib/integrations/google-calendar/sync-service.ts @@ -6,7 +6,7 @@ */ import { db, googleCalendarConnections, calendarEvents, eventAttendees, users, eq, and, isNull, inArray, sql, desc } from '@pagespace/db'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { maskIdentifier } from '@/lib/logging/mask'; import { getValidAccessToken, updateConnectionStatus } from './token-refresh'; import { listEvents, watchCalendar, stopChannel, type GoogleCalendarEvent, type GoogleEventAttendee } from './api-client'; diff --git a/apps/web/src/lib/integrations/google-calendar/token-refresh.ts b/apps/web/src/lib/integrations/google-calendar/token-refresh.ts index 7e00ebc118..cefd884050 100644 --- a/apps/web/src/lib/integrations/google-calendar/token-refresh.ts +++ b/apps/web/src/lib/integrations/google-calendar/token-refresh.ts @@ -11,8 +11,8 @@ */ import { db, googleCalendarConnections, eq, type GoogleCalendarConnection } from '@pagespace/db'; -import { encrypt, decrypt } from '@pagespace/lib'; -import { loggers } from '@pagespace/lib/server'; +import { encrypt, decrypt } from '@pagespace/lib/encryption'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { OAuth2Client } from 'google-auth-library'; // Buffer time before expiration to refresh (5 minutes) diff --git a/apps/web/src/lib/integrations/google-calendar/webhook-token.ts b/apps/web/src/lib/integrations/google-calendar/webhook-token.ts index 3c65d041f4..5cb39b8ed6 100644 --- a/apps/web/src/lib/integrations/google-calendar/webhook-token.ts +++ b/apps/web/src/lib/integrations/google-calendar/webhook-token.ts @@ -8,7 +8,7 @@ */ import crypto from 'crypto'; -import { secureCompare } from '@pagespace/lib'; +import { secureCompare } from '@pagespace/lib/auth/secure-compare'; /** * Generate an HMAC token for webhook authentication. diff --git a/apps/web/src/lib/mcp/__tests__/mcp-bridge.test.ts b/apps/web/src/lib/mcp/__tests__/mcp-bridge.test.ts index 530781f283..9fca4590d8 100644 --- a/apps/web/src/lib/mcp/__tests__/mcp-bridge.test.ts +++ b/apps/web/src/lib/mcp/__tests__/mcp-bridge.test.ts @@ -8,8 +8,8 @@ vi.mock('@/lib/websocket', () => ({ })); // Mock the logger -vi.mock('@pagespace/lib', () => ({ - logger: { +vi.mock('@pagespace/lib/logging/logger', () => ({ + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), diff --git a/apps/web/src/lib/mcp/mcp-bridge.ts b/apps/web/src/lib/mcp/mcp-bridge.ts index 36fcd09c99..e3cf173a00 100644 --- a/apps/web/src/lib/mcp/mcp-bridge.ts +++ b/apps/web/src/lib/mcp/mcp-bridge.ts @@ -1,5 +1,5 @@ import { getConnection, checkConnectionHealth } from '@/lib/websocket'; -import { logger } from '@pagespace/lib'; +import { logger } from '@pagespace/lib/logging/logger'; /** * MCP Bridge - Server-side WebSocket manager for tool execution diff --git a/apps/web/src/lib/memory/__tests__/compaction-service.test.ts b/apps/web/src/lib/memory/__tests__/compaction-service.test.ts index 30d551218e..ed3639b747 100644 --- a/apps/web/src/lib/memory/__tests__/compaction-service.test.ts +++ b/apps/web/src/lib/memory/__tests__/compaction-service.test.ts @@ -40,8 +40,8 @@ vi.mock('@/lib/ai/core', () => ({ })); // Mock loggers -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), @@ -49,6 +49,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); // Mock generateText diff --git a/apps/web/src/lib/memory/__tests__/discovery-service.test.ts b/apps/web/src/lib/memory/__tests__/discovery-service.test.ts index 42a1987661..a51e9077c5 100644 --- a/apps/web/src/lib/memory/__tests__/discovery-service.test.ts +++ b/apps/web/src/lib/memory/__tests__/discovery-service.test.ts @@ -42,8 +42,8 @@ vi.mock('@/lib/ai/core', () => ({ })); // Mock loggers -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), @@ -51,6 +51,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); // Mock generateText from AI SDK diff --git a/apps/web/src/lib/memory/__tests__/integration-service.test.ts b/apps/web/src/lib/memory/__tests__/integration-service.test.ts index 7127cd541f..13fa63d0de 100644 --- a/apps/web/src/lib/memory/__tests__/integration-service.test.ts +++ b/apps/web/src/lib/memory/__tests__/integration-service.test.ts @@ -40,8 +40,8 @@ vi.mock('@/lib/ai/core', () => ({ })); // Mock loggers -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), warn: vi.fn(), @@ -49,6 +49,8 @@ vi.mock('@pagespace/lib/server', () => ({ debug: vi.fn(), }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); // Mock generateText diff --git a/apps/web/src/lib/memory/compaction-service.ts b/apps/web/src/lib/memory/compaction-service.ts index aec3b5fc74..19f5cea3b9 100644 --- a/apps/web/src/lib/memory/compaction-service.ts +++ b/apps/web/src/lib/memory/compaction-service.ts @@ -8,7 +8,7 @@ import { generateText } from 'ai'; import { createAIProvider, isProviderError } from '@/lib/ai/core'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import { updatePersonalization, getCurrentPersonalization, diff --git a/apps/web/src/lib/memory/discovery-service.ts b/apps/web/src/lib/memory/discovery-service.ts index 4fda648c4b..410334029a 100644 --- a/apps/web/src/lib/memory/discovery-service.ts +++ b/apps/web/src/lib/memory/discovery-service.ts @@ -22,7 +22,7 @@ import { inArray, } from '@pagespace/db'; import { createAIProvider, isProviderError } from '@/lib/ai/core'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; export interface DiscoveryResult { worldview: string[]; diff --git a/apps/web/src/lib/memory/integration-service.ts b/apps/web/src/lib/memory/integration-service.ts index 89dfc6b0da..31263581e8 100644 --- a/apps/web/src/lib/memory/integration-service.ts +++ b/apps/web/src/lib/memory/integration-service.ts @@ -9,7 +9,7 @@ import { generateText } from 'ai'; import { db, userPersonalization, eq } from '@pagespace/db'; import { createAIProvider, isProviderError } from '@/lib/ai/core'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; import type { DiscoveryResult } from './discovery-service'; export interface UserPersonalizationData { diff --git a/apps/web/src/lib/workflows/__tests__/calendar-trigger-executor.test.ts b/apps/web/src/lib/workflows/__tests__/calendar-trigger-executor.test.ts index 86955822ca..462a529417 100644 --- a/apps/web/src/lib/workflows/__tests__/calendar-trigger-executor.test.ts +++ b/apps/web/src/lib/workflows/__tests__/calendar-trigger-executor.test.ts @@ -81,12 +81,11 @@ vi.mock('@/lib/logging/mask', () => ({ maskIdentifier: vi.fn((id: string) => `***${id?.slice(-4) || ''}`), })); -vi.mock('@pagespace/lib', () => ({ - isUserDriveMember: mockIsUserDriveMember, - logger: { child: vi.fn(() => makeChildLogger()) }, +vi.mock('@pagespace/lib/permissions/permissions', () => ({ + isUserDriveMember: mockIsUserDriveMember, })); - -vi.mock('@pagespace/lib/server', () => ({ +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + logger: { child: vi.fn(() => makeChildLogger()) }, loggers: { api: { child: vi.fn(() => makeChildLogger()), info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, ai: { child: vi.fn(() => makeChildLogger()), info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, diff --git a/apps/web/src/lib/workflows/__tests__/task-trigger-helpers.test.ts b/apps/web/src/lib/workflows/__tests__/task-trigger-helpers.test.ts index ad7d2afeca..16b2c72d56 100644 --- a/apps/web/src/lib/workflows/__tests__/task-trigger-helpers.test.ts +++ b/apps/web/src/lib/workflows/__tests__/task-trigger-helpers.test.ts @@ -43,8 +43,8 @@ vi.mock('../workflow-executor', () => ({ executeWorkflow: vi.fn(), })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { child: vi.fn(() => ({ info: vi.fn(), @@ -54,6 +54,7 @@ vi.mock('@pagespace/lib/server', () => ({ })), }, }, + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); import { diff --git a/apps/web/src/lib/workflows/__tests__/workflow-executor.test.ts b/apps/web/src/lib/workflows/__tests__/workflow-executor.test.ts index 63b370a189..e579026be3 100644 --- a/apps/web/src/lib/workflows/__tests__/workflow-executor.test.ts +++ b/apps/web/src/lib/workflows/__tests__/workflow-executor.test.ts @@ -57,10 +57,12 @@ vi.mock('@pagespace/lib/monitoring/ai-monitoring', () => ({ AIMonitoring: { trackUsage: vi.fn() }, })); -vi.mock('@pagespace/lib/server', () => ({ - loggers: { +vi.mock('@pagespace/lib/logging/logger-config', () => ({ + loggers: { api: { info: vi.fn(), error: vi.fn(), warn: vi.fn(), debug: vi.fn() }, }, + + logger: { child: vi.fn(() => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() })) }, })); import { executeWorkflow } from '../workflow-executor'; diff --git a/apps/web/src/lib/workflows/calendar-trigger-executor.ts b/apps/web/src/lib/workflows/calendar-trigger-executor.ts index a5fe3eb1c4..f7a62c2476 100644 --- a/apps/web/src/lib/workflows/calendar-trigger-executor.ts +++ b/apps/web/src/lib/workflows/calendar-trigger-executor.ts @@ -2,8 +2,8 @@ import { db, calendarTriggers, pages, eventAttendees, users, eq, and } from '@pa import type { CalendarTrigger, CalendarEvent } from '@pagespace/db'; import { executeWorkflow, type WorkflowExecutionResult } from './workflow-executor'; import { incrementUsage } from '@/lib/subscription/usage-service'; -import { isUserDriveMember } from '@pagespace/lib'; -import { loggers } from '@pagespace/lib/server'; +import { isUserDriveMember } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; const logger = loggers.api.child({ module: 'calendar-trigger-executor' }); diff --git a/apps/web/src/lib/workflows/task-trigger-helpers.ts b/apps/web/src/lib/workflows/task-trigger-helpers.ts index f592a25e25..03b5645c02 100644 --- a/apps/web/src/lib/workflows/task-trigger-helpers.ts +++ b/apps/web/src/lib/workflows/task-trigger-helpers.ts @@ -1,6 +1,6 @@ import { db, workflows, taskItems, pages, eq, and, inArray } from '@pagespace/db'; import { executeWorkflow } from './workflow-executor'; -import { loggers } from '@pagespace/lib/server'; +import { loggers } from '@pagespace/lib/logging/logger-config'; export interface AgentTriggerInput { agentPageId: string; diff --git a/apps/web/src/lib/workflows/workflow-executor.ts b/apps/web/src/lib/workflows/workflow-executor.ts index 995e7b2a0c..5932256f53 100644 --- a/apps/web/src/lib/workflows/workflow-executor.ts +++ b/apps/web/src/lib/workflows/workflow-executor.ts @@ -12,7 +12,8 @@ import { import { saveMessageToDatabase } from '@/lib/ai/core/message-utils'; import { AIMonitoring } from '@pagespace/lib/monitoring/ai-monitoring'; import { db, pages, drives, eq, and, inArray, workflows as workflowsTable, taskItems, taskAssignees, taskStatusConfigs, users } from '@pagespace/db'; -import { isUserDriveMember, loggers } from '@pagespace/lib/server'; +import { isUserDriveMember } from '@pagespace/lib/permissions/permissions'; +import { loggers } from '@pagespace/lib/logging/logger-config'; export interface WorkflowExecutionResult { success: boolean;