Re_Backend/src/migrations/20251104-create-admin-config.ts

135 lines
4.0 KiB
TypeScript

import { QueryInterface, DataTypes } from 'sequelize';
/**
* Migration to create admin_configurations table
* Stores system-wide configuration settings
*/
export async function up(queryInterface: QueryInterface): Promise<void> {
await queryInterface.createTable('admin_configurations', {
config_id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
config_key: {
type: DataTypes.STRING(100),
allowNull: false,
unique: true,
comment: 'Unique configuration key (e.g., "DEFAULT_TAT_EXPRESS", "MAX_FILE_SIZE")'
},
config_category: {
type: DataTypes.ENUM(
'TAT_SETTINGS',
'NOTIFICATION_RULES',
'DOCUMENT_POLICY',
'USER_ROLES',
'DASHBOARD_LAYOUT',
'AI_CONFIGURATION',
'WORKFLOW_SHARING',
'SYSTEM_SETTINGS'
),
allowNull: false,
comment: 'Category of the configuration'
},
config_value: {
type: DataTypes.TEXT,
allowNull: false,
comment: 'Configuration value (can be JSON string for complex values)'
},
value_type: {
type: DataTypes.ENUM('STRING', 'NUMBER', 'BOOLEAN', 'JSON', 'ARRAY'),
defaultValue: 'STRING',
comment: 'Data type of the value'
},
display_name: {
type: DataTypes.STRING(200),
allowNull: false,
comment: 'Human-readable name for UI display'
},
description: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Description of what this configuration does'
},
default_value: {
type: DataTypes.TEXT,
allowNull: true,
comment: 'Default value if reset'
},
is_editable: {
type: DataTypes.BOOLEAN,
defaultValue: true,
comment: 'Whether this config can be edited by admin'
},
is_sensitive: {
type: DataTypes.BOOLEAN,
defaultValue: false,
comment: 'Whether this contains sensitive data (e.g., API keys)'
},
validation_rules: {
type: DataTypes.JSONB,
defaultValue: {},
comment: 'Validation rules (min, max, regex, etc.)'
},
ui_component: {
type: DataTypes.STRING(50),
allowNull: true,
comment: 'UI component type (input, select, toggle, slider, etc.)'
},
options: {
type: DataTypes.JSONB,
allowNull: true,
comment: 'Options for select/radio inputs'
},
sort_order: {
type: DataTypes.INTEGER,
defaultValue: 0,
comment: 'Display order in admin panel'
},
requires_restart: {
type: DataTypes.BOOLEAN,
defaultValue: false,
comment: 'Whether changing this requires server restart'
},
last_modified_by: {
type: DataTypes.UUID,
allowNull: true,
references: {
model: 'users',
key: 'user_id'
},
comment: 'Admin who last modified this'
},
last_modified_at: {
type: DataTypes.DATE,
allowNull: true,
comment: 'When this was last modified'
},
created_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
},
updated_at: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW
}
});
// Indexes (with IF NOT EXISTS)
await queryInterface.sequelize.query('CREATE INDEX IF NOT EXISTS "admin_configurations_config_category" ON "admin_configurations" ("config_category");');
await queryInterface.sequelize.query('CREATE INDEX IF NOT EXISTS "admin_configurations_is_editable" ON "admin_configurations" ("is_editable");');
await queryInterface.sequelize.query('CREATE INDEX IF NOT EXISTS "admin_configurations_sort_order" ON "admin_configurations" ("sort_order");');
// Admin config table created
}
export async function down(queryInterface: QueryInterface): Promise<void> {
await queryInterface.dropTable('admin_configurations');
await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_admin_configurations_config_category";');
await queryInterface.sequelize.query('DROP TYPE IF EXISTS "enum_admin_configurations_value_type";');
// Admin config table dropped
}