import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); export default defineEventHandler(async (event) => { const method = getMethod(event); try { if (method === "GET") { // Get DMS settings let settings = await prisma.dms_settings.findFirst({ orderBy: { settingID: "desc" }, }); // If no settings exist, create default ones if (!settings) { settings = await prisma.dms_settings.create({ data: { settingCreatedDate: new Date(), settingModifiedDate: new Date(), }, }); } // Transform database fields to frontend structure const transformedSettings = { // User & Access Management access: { userRoles: settings.userRoles ? settings.userRoles.split(',') : ['Admin', 'Editor', 'Viewer', 'Uploader'], rbacEnabled: settings.rbacEnabled ?? true, userGroups: settings.userGroups ? settings.userGroups.split(',') : ['HR Department', 'Finance', 'IT', 'Legal'], permissions: { view: settings.permissionView ?? true, edit: settings.permissionEdit ?? true, delete: settings.permissionDelete ?? false, download: settings.permissionDownload ?? true, share: settings.permissionShare ?? true }, authentication: { ssoEnabled: settings.ssoEnabled ?? false, mfaRequired: settings.mfaRequired ?? false, ldapIntegration: settings.ldapIntegration ?? false, sessionTimeout: settings.sessionTimeout ?? 8 } }, // Document & Folder Settings documents: { folderHierarchy: { maxDepth: settings.folderMaxDepth ?? 5, defaultStructure: settings.folderDefaultStructure ? settings.folderDefaultStructure.split(',') : ['Department', 'Project', 'Category', 'Year'], folderTemplates: settings.folderTemplates ? settings.folderTemplates.split(',') : ['Standard', 'Project-based', 'Department-based'] }, namingConventions: { autoGenerate: settings.namingAutoGenerate ?? true, mandatoryFields: settings.namingMandatoryFields ? settings.namingMandatoryFields.split(',') : ['title', 'department', 'date'], pattern: settings.namingPattern ?? '{department}_{title}_{date}' }, retention: { enabled: settings.retentionEnabled ?? true, defaultDays: settings.retentionDefaultDays ?? 2555, archiveBeforeDelete: settings.retentionArchiveBeforeDelete ?? true }, versionControl: { enabled: settings.versionControlEnabled ?? true, maxVersions: settings.versionControlMaxVersions ?? 10, autoVersioning: settings.versionControlAutoVersioning ?? true } }, // Metadata & Tagging metadata: { customFields: settings.metadataCustomFields ? JSON.parse(settings.metadataCustomFields) : [ { name: 'Department', type: 'dropdown', required: true }, { name: 'Priority', type: 'select', required: false }, { name: 'Project Code', type: 'text', required: true }, { name: 'Review Date', type: 'date', required: false } ], tagging: { predefinedTags: settings.taggingPredefinedTags ? settings.taggingPredefinedTags.split(',') : ['urgent', 'confidential', 'public', 'draft', 'final'], userGeneratedTags: settings.taggingUserGeneratedTags ?? true, tagSuggestions: settings.taggingTagSuggestions ?? true }, classification: { autoClassification: settings.classificationAutoEnabled ?? true, rules: settings.classificationRules ? settings.classificationRules.split(',') : ['confidential-keywords', 'department-based', 'file-type'] } }, // Workflow & Automation workflow: { approvalFlows: { enabled: settings.workflowApprovalEnabled ?? true, defaultFlow: settings.workflowDefaultFlow ?? 'department-head-approval', customFlows: settings.workflowCustomFlows ? settings.workflowCustomFlows.split(',') : ['legal-review', 'finance-approval', 'director-sign-off'] }, notifications: { emailNotifications: settings.notificationEmail ?? true, inAppNotifications: settings.notificationInApp ?? true, uploadAlerts: settings.notificationUploadAlerts ?? true, deadlineReminders: settings.notificationDeadlineReminders ?? true }, automation: { triggers: settings.automationTriggers ? settings.automationTriggers.split(',') : ['document-uploaded', 'approval-completed', 'deadline-reached'], actions: settings.automationActions ? settings.automationActions.split(',') : ['move-to-folder', 'send-notification', 'create-task'] } }, // Upload & Storage Settings upload: { fileTypes: { allowed: settings.uploadAllowedFileTypes ? settings.uploadAllowedFileTypes.split(',') : ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'jpg', 'png'], blocked: settings.uploadBlockedFileTypes ? settings.uploadBlockedFileTypes.split(',') : ['exe', 'bat', 'cmd'] }, fileSizeLimit: settings.uploadFileSizeLimit ?? 100, quotas: { perUser: settings.uploadQuotaPerUser ?? 5000, perGroup: settings.uploadQuotaPerGroup ?? 50000, perProject: settings.uploadQuotaPerProject ?? 100000 }, storage: { type: settings.storageType ?? 'local', path: settings.storagePath ?? '/var/uploads/edms', backupEnabled: settings.storageBackupEnabled ?? true, compressionEnabled: settings.storageCompressionEnabled ?? false } }, // System Settings system: { timezone: settings.systemTimezone ?? 'Asia/Kuala_Lumpur', backupSchedule: settings.systemBackupSchedule ?? 'daily', logLevel: settings.systemLogLevel ?? 'info', maintenanceMode: settings.systemMaintenanceMode ?? false, autoUpdates: settings.systemAutoUpdates ?? false, systemMonitoring: settings.systemMonitoring ?? true, performanceMetrics: settings.systemPerformanceMetrics ?? true } }; return { statusCode: 200, message: "Success", data: transformedSettings, }; } if (method === "POST") { let body; try { body = await readBody(event); } catch (bodyError) { console.error("Error reading request body:", bodyError); return { statusCode: 400, message: "Invalid request body", error: bodyError.message, }; } // Validate required fields if (!body || typeof body !== 'object') { return { statusCode: 400, message: "Request body must be a valid JSON object", }; } // Check if settings exist const existingSettings = await prisma.dms_settings.findFirst(); // Transform frontend structure to database fields const dbData = { settingModifiedDate: new Date() }; // User & Access Management if (body.access) { if (body.access.userRoles) dbData.userRoles = body.access.userRoles.join(','); if (body.access.rbacEnabled !== undefined) dbData.rbacEnabled = body.access.rbacEnabled; if (body.access.userGroups) dbData.userGroups = body.access.userGroups.join(','); if (body.access.permissions) { if (body.access.permissions.view !== undefined) dbData.permissionView = body.access.permissions.view; if (body.access.permissions.edit !== undefined) dbData.permissionEdit = body.access.permissions.edit; if (body.access.permissions.delete !== undefined) dbData.permissionDelete = body.access.permissions.delete; if (body.access.permissions.download !== undefined) dbData.permissionDownload = body.access.permissions.download; if (body.access.permissions.share !== undefined) dbData.permissionShare = body.access.permissions.share; } if (body.access.authentication) { if (body.access.authentication.ssoEnabled !== undefined) dbData.ssoEnabled = body.access.authentication.ssoEnabled; if (body.access.authentication.mfaRequired !== undefined) dbData.mfaRequired = body.access.authentication.mfaRequired; if (body.access.authentication.ldapIntegration !== undefined) dbData.ldapIntegration = body.access.authentication.ldapIntegration; if (body.access.authentication.sessionTimeout !== undefined) dbData.sessionTimeout = body.access.authentication.sessionTimeout; } } // Document & Folder Settings if (body.documents) { if (body.documents.folderHierarchy) { if (body.documents.folderHierarchy.maxDepth !== undefined) dbData.folderMaxDepth = body.documents.folderHierarchy.maxDepth; if (body.documents.folderHierarchy.defaultStructure) dbData.folderDefaultStructure = body.documents.folderHierarchy.defaultStructure.join(','); if (body.documents.folderHierarchy.folderTemplates) dbData.folderTemplates = body.documents.folderHierarchy.folderTemplates.join(','); } if (body.documents.namingConventions) { if (body.documents.namingConventions.autoGenerate !== undefined) dbData.namingAutoGenerate = body.documents.namingConventions.autoGenerate; if (body.documents.namingConventions.mandatoryFields) dbData.namingMandatoryFields = body.documents.namingConventions.mandatoryFields.join(','); if (body.documents.namingConventions.pattern !== undefined) dbData.namingPattern = body.documents.namingConventions.pattern; } if (body.documents.retention) { if (body.documents.retention.enabled !== undefined) dbData.retentionEnabled = body.documents.retention.enabled; if (body.documents.retention.defaultDays !== undefined) dbData.retentionDefaultDays = body.documents.retention.defaultDays; if (body.documents.retention.archiveBeforeDelete !== undefined) dbData.retentionArchiveBeforeDelete = body.documents.retention.archiveBeforeDelete; } if (body.documents.versionControl) { if (body.documents.versionControl.enabled !== undefined) dbData.versionControlEnabled = body.documents.versionControl.enabled; if (body.documents.versionControl.maxVersions !== undefined) dbData.versionControlMaxVersions = body.documents.versionControl.maxVersions; if (body.documents.versionControl.autoVersioning !== undefined) dbData.versionControlAutoVersioning = body.documents.versionControl.autoVersioning; } } // Metadata & Tagging if (body.metadata) { if (body.metadata.customFields) dbData.metadataCustomFields = JSON.stringify(body.metadata.customFields); if (body.metadata.tagging) { if (body.metadata.tagging.predefinedTags) dbData.taggingPredefinedTags = body.metadata.tagging.predefinedTags.join(','); if (body.metadata.tagging.userGeneratedTags !== undefined) dbData.taggingUserGeneratedTags = body.metadata.tagging.userGeneratedTags; if (body.metadata.tagging.tagSuggestions !== undefined) dbData.taggingTagSuggestions = body.metadata.tagging.tagSuggestions; } if (body.metadata.classification) { if (body.metadata.classification.autoClassification !== undefined) dbData.classificationAutoEnabled = body.metadata.classification.autoClassification; if (body.metadata.classification.rules) dbData.classificationRules = body.metadata.classification.rules.join(','); } } // Workflow & Automation if (body.workflow) { if (body.workflow.approvalFlows) { if (body.workflow.approvalFlows.enabled !== undefined) dbData.workflowApprovalEnabled = body.workflow.approvalFlows.enabled; if (body.workflow.approvalFlows.defaultFlow !== undefined) dbData.workflowDefaultFlow = body.workflow.approvalFlows.defaultFlow; if (body.workflow.approvalFlows.customFlows) dbData.workflowCustomFlows = body.workflow.approvalFlows.customFlows.join(','); } if (body.workflow.notifications) { if (body.workflow.notifications.emailNotifications !== undefined) dbData.notificationEmail = body.workflow.notifications.emailNotifications; if (body.workflow.notifications.inAppNotifications !== undefined) dbData.notificationInApp = body.workflow.notifications.inAppNotifications; if (body.workflow.notifications.uploadAlerts !== undefined) dbData.notificationUploadAlerts = body.workflow.notifications.uploadAlerts; if (body.workflow.notifications.deadlineReminders !== undefined) dbData.notificationDeadlineReminders = body.workflow.notifications.deadlineReminders; } if (body.workflow.automation) { if (body.workflow.automation.triggers) dbData.automationTriggers = body.workflow.automation.triggers.join(','); if (body.workflow.automation.actions) dbData.automationActions = body.workflow.automation.actions.join(','); } } // Upload & Storage Settings if (body.upload) { if (body.upload.fileTypes) { if (body.upload.fileTypes.allowed) dbData.uploadAllowedFileTypes = body.upload.fileTypes.allowed.join(','); if (body.upload.fileTypes.blocked) dbData.uploadBlockedFileTypes = body.upload.fileTypes.blocked.join(','); } if (body.upload.fileSizeLimit !== undefined) dbData.uploadFileSizeLimit = body.upload.fileSizeLimit; if (body.upload.quotas) { if (body.upload.quotas.perUser !== undefined) dbData.uploadQuotaPerUser = body.upload.quotas.perUser; if (body.upload.quotas.perGroup !== undefined) dbData.uploadQuotaPerGroup = body.upload.quotas.perGroup; if (body.upload.quotas.perProject !== undefined) dbData.uploadQuotaPerProject = body.upload.quotas.perProject; } if (body.upload.storage) { if (body.upload.storage.type !== undefined) dbData.storageType = body.upload.storage.type; if (body.upload.storage.path !== undefined) dbData.storagePath = body.upload.storage.path; if (body.upload.storage.backupEnabled !== undefined) dbData.storageBackupEnabled = body.upload.storage.backupEnabled; if (body.upload.storage.compressionEnabled !== undefined) dbData.storageCompressionEnabled = body.upload.storage.compressionEnabled; } } // System Settings if (body.system) { if (body.system.timezone !== undefined) dbData.systemTimezone = body.system.timezone; if (body.system.backupSchedule !== undefined) dbData.systemBackupSchedule = body.system.backupSchedule; if (body.system.logLevel !== undefined) dbData.systemLogLevel = body.system.logLevel; if (body.system.maintenanceMode !== undefined) dbData.systemMaintenanceMode = body.system.maintenanceMode; if (body.system.autoUpdates !== undefined) dbData.systemAutoUpdates = body.system.autoUpdates; if (body.system.systemMonitoring !== undefined) dbData.systemMonitoring = body.system.systemMonitoring; if (body.system.performanceMetrics !== undefined) dbData.systemPerformanceMetrics = body.system.performanceMetrics; } let settings; if (existingSettings) { // Update existing settings settings = await prisma.dms_settings.update({ where: { settingID: existingSettings.settingID }, data: dbData, }); } else { // Create new settings settings = await prisma.dms_settings.create({ data: { ...dbData, settingCreatedDate: new Date(), }, }); } return { statusCode: 200, message: "DMS settings updated successfully", data: { settingID: settings.settingID }, }; } return { statusCode: 405, message: "Method not allowed", }; } catch (error) { console.error("DMS settings API error:", error); // Provide more specific error messages if (error.code === 'P2002') { return { statusCode: 400, message: "Duplicate entry error", error: error.message, }; } if (error.code === 'P2025') { return { statusCode: 404, message: "Record not found", error: error.message, }; } if (error.code && error.code.startsWith('P')) { return { statusCode: 400, message: "Database error", error: error.message, code: error.code, }; } return { statusCode: 500, message: "Internal server error", error: error.message, }; } finally { await prisma.$disconnect(); } });