135 lines
4.0 KiB
TypeScript
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
|
|
}
|
|
|