| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245 | 
							- /**
 
-  * Server-side Attachment Migration System
 
-  * Handles migration of attachments from old structure to new structure
 
-  */
 
- import { Meteor } from 'meteor/meteor';
 
- import { ReactiveVar } from 'meteor/reactive-var';
 
- import { check } from 'meteor/check';
 
- import { ReactiveCache } from '/imports/reactiveCache';
 
- import Attachments from '/models/attachments';
 
- // Reactive variables for tracking migration progress
 
- const migrationProgress = new ReactiveVar(0);
 
- const migrationStatus = new ReactiveVar('');
 
- const unconvertedAttachments = new ReactiveVar([]);
 
- // Track migrated boards on server side
 
- const migratedBoards = new Set();
 
- class AttachmentMigrationService {
 
-   constructor() {
 
-     this.migrationCache = new Map();
 
-   }
 
-   /**
 
-    * Check if a board has been migrated
 
-    * @param {string} boardId - The board ID
 
-    * @returns {boolean} - True if board has been migrated
 
-    */
 
-   isBoardMigrated(boardId) {
 
-     return migratedBoards.has(boardId);
 
-   }
 
-   /**
 
-    * Migrate all attachments for a board
 
-    * @param {string} boardId - The board ID
 
-    */
 
-   async migrateBoardAttachments(boardId) {
 
-     try {
 
-       // Check if board has already been migrated
 
-       if (this.isBoardMigrated(boardId)) {
 
-         console.log(`Board ${boardId} has already been migrated, skipping`);
 
-         return { success: true, message: 'Board already migrated' };
 
-       }
 
-       console.log(`Starting attachment migration for board: ${boardId}`);
 
-       
 
-       // Get all attachments for the board
 
-       const attachments = Attachments.find({
 
-         'meta.boardId': boardId
 
-       }).fetch();
 
-       const totalAttachments = attachments.length;
 
-       let migratedCount = 0;
 
-       migrationStatus.set(`Migrating ${totalAttachments} attachments...`);
 
-       migrationProgress.set(0);
 
-       for (const attachment of attachments) {
 
-         try {
 
-           // Check if attachment needs migration
 
-           if (this.needsMigration(attachment)) {
 
-             await this.migrateAttachment(attachment);
 
-             this.migrationCache.set(attachment._id, true);
 
-           }
 
-           
 
-           migratedCount++;
 
-           const progress = Math.round((migratedCount / totalAttachments) * 100);
 
-           migrationProgress.set(progress);
 
-           migrationStatus.set(`Migrated ${migratedCount}/${totalAttachments} attachments...`);
 
-           
 
-         } catch (error) {
 
-           console.error(`Error migrating attachment ${attachment._id}:`, error);
 
-         }
 
-       }
 
-       // Update unconverted attachments list
 
-       const remainingUnconverted = this.getUnconvertedAttachments(boardId);
 
-       unconvertedAttachments.set(remainingUnconverted);
 
-       migrationStatus.set('Attachment migration completed');
 
-       migrationProgress.set(100);
 
-       // Mark board as migrated
 
-       migratedBoards.add(boardId);
 
-       console.log(`Attachment migration completed for board: ${boardId}`);
 
-       console.log(`Marked board ${boardId} as migrated`);
 
-       return { success: true, message: 'Migration completed' };
 
-     } catch (error) {
 
-       console.error(`Error migrating attachments for board ${boardId}:`, error);
 
-       migrationStatus.set(`Migration failed: ${error.message}`);
 
-       throw error;
 
-     }
 
-   }
 
-   /**
 
-    * Check if an attachment needs migration
 
-    * @param {Object} attachment - The attachment object
 
-    * @returns {boolean} - True if attachment needs migration
 
-    */
 
-   needsMigration(attachment) {
 
-     if (this.migrationCache.has(attachment._id)) {
 
-       return false; // Already migrated
 
-     }
 
-     // Check if attachment has old structure
 
-     return !attachment.meta || 
 
-            !attachment.meta.cardId || 
 
-            !attachment.meta.boardId ||
 
-            !attachment.meta.listId;
 
-   }
 
-   /**
 
-    * Migrate a single attachment
 
-    * @param {Object} attachment - The attachment object
 
-    */
 
-   async migrateAttachment(attachment) {
 
-     try {
 
-       // Get the card to find board and list information
 
-       const card = ReactiveCache.getCard(attachment.cardId);
 
-       if (!card) {
 
-         console.warn(`Card not found for attachment ${attachment._id}`);
 
-         return;
 
-       }
 
-       const list = ReactiveCache.getList(card.listId);
 
-       if (!list) {
 
-         console.warn(`List not found for attachment ${attachment._id}`);
 
-         return;
 
-       }
 
-       // Update attachment with new structure
 
-       const updateData = {
 
-         meta: {
 
-           cardId: attachment.cardId,
 
-           boardId: list.boardId,
 
-           listId: card.listId,
 
-           userId: attachment.userId,
 
-           createdAt: attachment.createdAt || new Date(),
 
-           migratedAt: new Date()
 
-         }
 
-       };
 
-       // Preserve existing meta data if it exists
 
-       if (attachment.meta) {
 
-         updateData.meta = {
 
-           ...attachment.meta,
 
-           ...updateData.meta
 
-         };
 
-       }
 
-       Attachments.update(attachment._id, { $set: updateData });
 
-       console.log(`Migrated attachment ${attachment._id}`);
 
-     } catch (error) {
 
-       console.error(`Error migrating attachment ${attachment._id}:`, error);
 
-       throw error;
 
-     }
 
-   }
 
-   /**
 
-    * Get unconverted attachments for a board
 
-    * @param {string} boardId - The board ID
 
-    * @returns {Array} - Array of unconverted attachments
 
-    */
 
-   getUnconvertedAttachments(boardId) {
 
-     try {
 
-       const attachments = Attachments.find({
 
-         'meta.boardId': boardId
 
-       }).fetch();
 
-       return attachments.filter(attachment => this.needsMigration(attachment));
 
-     } catch (error) {
 
-       console.error('Error getting unconverted attachments:', error);
 
-       return [];
 
-     }
 
-   }
 
-   /**
 
-    * Get migration progress
 
-    * @param {string} boardId - The board ID
 
-    * @returns {Object} - Migration progress data
 
-    */
 
-   getMigrationProgress(boardId) {
 
-     const progress = migrationProgress.get();
 
-     const status = migrationStatus.get();
 
-     const unconverted = this.getUnconvertedAttachments(boardId);
 
-     return {
 
-       progress,
 
-       status,
 
-       unconvertedAttachments: unconverted
 
-     };
 
-   }
 
- }
 
- const attachmentMigrationService = new AttachmentMigrationService();
 
- // Meteor methods
 
- Meteor.methods({
 
-   async 'attachmentMigration.migrateBoardAttachments'(boardId) {
 
-     check(boardId, String);
 
-     
 
-     if (!this.userId) {
 
-       throw new Meteor.Error('not-authorized');
 
-     }
 
-     return await attachmentMigrationService.migrateBoardAttachments(boardId);
 
-   },
 
-   'attachmentMigration.getProgress'(boardId) {
 
-     check(boardId, String);
 
-     
 
-     if (!this.userId) {
 
-       throw new Meteor.Error('not-authorized');
 
-     }
 
-     return attachmentMigrationService.getMigrationProgress(boardId);
 
-   },
 
-   'attachmentMigration.getUnconvertedAttachments'(boardId) {
 
-     check(boardId, String);
 
-     
 
-     if (!this.userId) {
 
-       throw new Meteor.Error('not-authorized');
 
-     }
 
-     return attachmentMigrationService.getUnconvertedAttachments(boardId);
 
-   },
 
-   'attachmentMigration.isBoardMigrated'(boardId) {
 
-     check(boardId, String);
 
-     
 
-     if (!this.userId) {
 
-       throw new Meteor.Error('not-authorized');
 
-     }
 
-     return attachmentMigrationService.isBoardMigrated(boardId);
 
-   }
 
- });
 
- export { attachmentMigrationService };
 
 
  |