import { DataTypes, Model, Optional } from 'sequelize'; import { sequelize } from '@config/database'; import { WorkflowRequest } from './WorkflowRequest'; import { ApprovalLevel } from './ApprovalLevel'; import { User } from './User'; export enum SnapshotType { PROPOSAL = 'PROPOSAL', COMPLETION = 'COMPLETION', INTERNAL_ORDER = 'INTERNAL_ORDER', WORKFLOW = 'WORKFLOW', APPROVE = 'APPROVE' } // Type definitions for snapshot data structures export interface ProposalSnapshotData { documentUrl?: string; totalBudget?: number; comments?: string; expectedCompletionDate?: string; costItems?: Array<{ description: string; amount: number; order: number; }>; } export interface CompletionSnapshotData { documentUrl?: string; totalExpenses?: number; comments?: string; expenses?: Array<{ description: string; amount: number; }>; } export interface IOSnapshotData { ioNumber?: string; blockedAmount?: number; availableBalance?: number; remainingBalance?: number; sapDocumentNumber?: string; } export interface WorkflowSnapshotData { status?: string; currentLevel?: number; } export interface ApprovalSnapshotData { action: 'APPROVE' | 'REJECT'; comments?: string; rejectionReason?: string; approverName?: string; approverEmail?: string; levelName?: string; } interface DealerClaimHistoryAttributes { historyId: string; requestId: string; approvalLevelId?: string; levelNumber?: number; levelName?: string; version: number; snapshotType: SnapshotType; snapshotData: ProposalSnapshotData | CompletionSnapshotData | IOSnapshotData | WorkflowSnapshotData | ApprovalSnapshotData | any; changeReason?: string; changedBy: string; createdAt: Date; } interface DealerClaimHistoryCreationAttributes extends Optional { } class DealerClaimHistory extends Model implements DealerClaimHistoryAttributes { public historyId!: string; public requestId!: string; public approvalLevelId?: string; public levelNumber?: number; public version!: number; public snapshotType!: SnapshotType; public snapshotData!: ProposalSnapshotData | CompletionSnapshotData | IOSnapshotData | WorkflowSnapshotData | any; public changeReason?: string; public changedBy!: string; public createdAt!: Date; } DealerClaimHistory.init( { historyId: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, field: 'history_id' }, requestId: { type: DataTypes.UUID, allowNull: false, field: 'request_id', references: { model: 'workflow_requests', key: 'request_id' } }, approvalLevelId: { type: DataTypes.UUID, allowNull: true, field: 'approval_level_id', references: { model: 'approval_levels', key: 'level_id' } }, levelNumber: { type: DataTypes.INTEGER, allowNull: true, field: 'level_number' }, levelName: { type: DataTypes.STRING(255), allowNull: true, field: 'level_name' }, version: { type: DataTypes.INTEGER, allowNull: false }, snapshotType: { type: DataTypes.ENUM('PROPOSAL', 'COMPLETION', 'INTERNAL_ORDER', 'WORKFLOW', 'APPROVE'), allowNull: false, field: 'snapshot_type' }, snapshotData: { type: DataTypes.JSONB, allowNull: false, field: 'snapshot_data' }, changeReason: { type: DataTypes.TEXT, allowNull: true, field: 'change_reason' }, changedBy: { type: DataTypes.UUID, allowNull: false, field: 'changed_by', references: { model: 'users', key: 'user_id' } }, createdAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW, field: 'created_at' } }, { sequelize, modelName: 'DealerClaimHistory', tableName: 'dealer_claim_history', timestamps: false, indexes: [ { fields: ['request_id', 'level_number', 'version'], name: 'idx_history_request_level_version' }, { fields: ['approval_level_id', 'version'], name: 'idx_history_level_version' }, { fields: ['request_id', 'snapshot_type'], name: 'idx_history_request_type' }, { fields: ['snapshot_type', 'level_number'], name: 'idx_history_type_level' } ] } ); DealerClaimHistory.belongsTo(WorkflowRequest, { foreignKey: 'requestId' }); DealerClaimHistory.belongsTo(ApprovalLevel, { foreignKey: 'approvalLevelId' }); DealerClaimHistory.belongsTo(User, { as: 'changer', foreignKey: 'changedBy' }); export { DealerClaimHistory };