/** * Cleanup Dealer Claims Script * Removes all dealer claim related data for a fresh start * * Usage: npm run cleanup:dealer-claims * * WARNING: This will permanently delete all CLAIM_MANAGEMENT requests and related data! */ import { sequelize } from '../config/database'; import { QueryTypes } from 'sequelize'; import logger from '../utils/logger'; async function cleanupDealerClaims(): Promise { const transaction = await sequelize.transaction(); try { logger.info('[Cleanup] Starting dealer claim cleanup...'); // Step 1: Find all CLAIM_MANAGEMENT request IDs logger.info('[Cleanup] Finding all CLAIM_MANAGEMENT requests...'); const claimRequests = await sequelize.query<{ request_id: string }>( `SELECT request_id FROM workflow_requests WHERE workflow_type = 'CLAIM_MANAGEMENT'`, { type: QueryTypes.SELECT, transaction } ); const requestIds = claimRequests.map(r => r.request_id); const count = requestIds.length; if (count === 0) { logger.info('[Cleanup] No CLAIM_MANAGEMENT requests found. Nothing to clean up.'); await transaction.commit(); return; } logger.info(`[Cleanup] Found ${count} CLAIM_MANAGEMENT request(s) to delete`); // Step 2: Delete in order (respecting foreign key constraints) // Start with child tables, then parent tables // Convert UUID array to PostgreSQL array format const requestIdsArray = `{${requestIds.map(id => `'${id}'`).join(',')}}`; // Delete from claim_budget_tracking (new table) logger.info('[Cleanup] Deleting from claim_budget_tracking...'); await sequelize.query( `DELETE FROM claim_budget_tracking WHERE request_id = ANY(ARRAY[${requestIds.map(() => '?').join(',')}]::uuid[])`, { replacements: requestIds, type: QueryTypes.DELETE, transaction } ); // Step 2: Delete in order (respecting foreign key constraints) // Start with child tables, then parent tables // Helper function to delete with array const deleteWithArray = async (tableName: string, columnName: string = 'request_id') => { await sequelize.query( `DELETE FROM ${tableName} WHERE ${columnName} = ANY(ARRAY[${requestIds.map(() => '?').join(',')}]::uuid[])`, { replacements: requestIds, type: QueryTypes.DELETE, transaction } ); }; // Delete from claim_budget_tracking (new table) logger.info('[Cleanup] Deleting from claim_budget_tracking...'); await deleteWithArray('claim_budget_tracking'); // Delete from internal_orders (new table) logger.info('[Cleanup] Deleting from internal_orders...'); await deleteWithArray('internal_orders'); // Delete from dealer_proposal_cost_items logger.info('[Cleanup] Deleting from dealer_proposal_cost_items...'); await deleteWithArray('dealer_proposal_cost_items'); // Delete from dealer_completion_details logger.info('[Cleanup] Deleting from dealer_completion_details...'); await deleteWithArray('dealer_completion_details'); // Delete from dealer_proposal_details logger.info('[Cleanup] Deleting from dealer_proposal_details...'); await deleteWithArray('dealer_proposal_details'); // Delete from dealer_claim_details logger.info('[Cleanup] Deleting from dealer_claim_details...'); await deleteWithArray('dealer_claim_details'); // Delete from activities (workflow activities) logger.info('[Cleanup] Deleting from activities...'); await deleteWithArray('activities'); // Delete from work_notes logger.info('[Cleanup] Deleting from work_notes...'); await deleteWithArray('work_notes'); // Delete from documents logger.info('[Cleanup] Deleting from documents...'); await deleteWithArray('documents'); // Delete from participants logger.info('[Cleanup] Deleting from participants...'); await deleteWithArray('participants'); // Delete from approval_levels logger.info('[Cleanup] Deleting from approval_levels...'); await deleteWithArray('approval_levels'); // Note: subscriptions table doesn't have request_id - it's for push notification subscriptions // Skip subscriptions as it's not related to workflow requests // Delete from notifications logger.info('[Cleanup] Deleting from notifications...'); await deleteWithArray('notifications'); // Delete from request_summaries logger.info('[Cleanup] Deleting from request_summaries...'); await deleteWithArray('request_summaries'); // Delete from shared_summaries logger.info('[Cleanup] Deleting from shared_summaries...'); await deleteWithArray('shared_summaries'); // Delete from conclusion_remarks logger.info('[Cleanup] Deleting from conclusion_remarks...'); await deleteWithArray('conclusion_remarks'); // Delete from tat_alerts logger.info('[Cleanup] Deleting from tat_alerts...'); await deleteWithArray('tat_alerts'); // Finally, delete from workflow_requests logger.info('[Cleanup] Deleting from workflow_requests...'); await deleteWithArray('workflow_requests'); await transaction.commit(); logger.info(`[Cleanup] ✅ Successfully deleted ${count} CLAIM_MANAGEMENT request(s) and all related data!`); logger.info('[Cleanup] Database is now clean and ready for fresh dealer claim requests.'); } catch (error) { await transaction.rollback(); logger.error('[Cleanup] ❌ Error during cleanup:', error); throw error; } } // Run cleanup if called directly if (require.main === module) { cleanupDealerClaims() .then(() => { logger.info('[Cleanup] Cleanup completed successfully'); process.exit(0); }) .catch((error) => { logger.error('[Cleanup] Cleanup failed:', error); process.exit(1); }); } export { cleanupDealerClaims };