EDMS/server/api/dms/settings.js
2025-05-31 12:12:00 +08:00

350 lines
17 KiB
JavaScript

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();
}
});