import { DataTypes, Model, Optional } from 'sequelize'; import { sequelize } from '@config/database'; import { User } from './User'; import { WorkflowRequest } from './WorkflowRequest'; interface DocumentAttributes { documentId: string; requestId: string; uploadedBy: string; fileName: string; originalFileName: string; fileType: string; fileExtension: string; fileSize: number; filePath: string; storageUrl?: string; mimeType: string; checksum: string; isGoogleDoc: boolean; googleDocUrl?: string; category: string; version: number; parentDocumentId?: string; isDeleted: boolean; downloadCount: number; uploadedAt: Date; } interface DocumentCreationAttributes extends Optional {} class Document extends Model implements DocumentAttributes { public documentId!: string; public requestId!: string; public uploadedBy!: string; public fileName!: string; public originalFileName!: string; public fileType!: string; public fileExtension!: string; public fileSize!: number; public filePath!: string; public storageUrl?: string; public mimeType!: string; public checksum!: string; public isGoogleDoc!: boolean; public googleDocUrl?: string; public category!: string; public version!: number; public parentDocumentId?: string; public isDeleted!: boolean; public downloadCount!: number; public uploadedAt!: Date; // Associations public request?: WorkflowRequest; public uploader?: User; public parentDocument?: Document; } Document.init( { documentId: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, field: 'document_id' }, requestId: { type: DataTypes.UUID, allowNull: false, field: 'request_id', references: { model: 'workflow_requests', key: 'request_id' } }, uploadedBy: { type: DataTypes.UUID, allowNull: false, field: 'uploaded_by', references: { model: 'users', key: 'user_id' } }, fileName: { type: DataTypes.STRING(255), allowNull: false, field: 'file_name' }, originalFileName: { type: DataTypes.STRING(255), allowNull: false, field: 'original_file_name' }, fileType: { type: DataTypes.STRING(100), allowNull: false, field: 'file_type' }, fileExtension: { type: DataTypes.STRING(10), allowNull: false, field: 'file_extension' }, fileSize: { type: DataTypes.BIGINT, allowNull: false, field: 'file_size', validate: { max: 10485760 // 10MB limit } }, filePath: { type: DataTypes.STRING(500), allowNull: false, field: 'file_path' }, storageUrl: { type: DataTypes.STRING(500), allowNull: true, field: 'storage_url' }, mimeType: { type: DataTypes.STRING(100), allowNull: false, field: 'mime_type' }, checksum: { type: DataTypes.STRING(64), allowNull: false }, isGoogleDoc: { type: DataTypes.BOOLEAN, defaultValue: false, field: 'is_google_doc' }, googleDocUrl: { type: DataTypes.STRING(500), allowNull: true, field: 'google_doc_url' }, category: { type: DataTypes.ENUM('SUPPORTING', 'APPROVAL', 'REFERENCE', 'FINAL', 'OTHER'), defaultValue: 'OTHER' }, version: { type: DataTypes.INTEGER, defaultValue: 1 }, parentDocumentId: { type: DataTypes.UUID, allowNull: true, field: 'parent_document_id', references: { model: 'documents', key: 'document_id' } }, isDeleted: { type: DataTypes.BOOLEAN, defaultValue: false, field: 'is_deleted' }, downloadCount: { type: DataTypes.INTEGER, defaultValue: 0, field: 'download_count' }, uploadedAt: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW, field: 'uploaded_at' } }, { sequelize, modelName: 'Document', tableName: 'documents', timestamps: false, indexes: [ { fields: ['request_id'] }, { fields: ['uploaded_by'] }, { fields: ['category'] }, { fields: ['is_deleted'] } ] } ); // Associations Document.belongsTo(WorkflowRequest, { as: 'request', foreignKey: 'requestId', targetKey: 'requestId' }); Document.belongsTo(User, { as: 'uploader', foreignKey: 'uploadedBy', targetKey: 'userId' }); Document.belongsTo(Document, { as: 'parentDocument', foreignKey: 'parentDocumentId', targetKey: 'documentId' }); export { Document };