| const fs = require('fs').promises;
|
| const path = require('path');
|
| const JSZip = require('jszip');
|
| const sessionManager = require('../lib/session-manager');
|
| const { applyCorsHeaders, handleCorsPreflight } = require('../lib/cors-middleware');
|
|
|
| module.exports = async (req, res) => {
|
| if (handleCorsPreflight(req, res, { allowedMethods: 'GET, OPTIONS' })) {
|
| return;
|
| }
|
| applyCorsHeaders(req, res, { allowedMethods: 'GET, OPTIONS' });
|
|
|
| if (req.method !== 'GET') {
|
| res.status(405).json({ error: 'Method not allowed' });
|
| return;
|
| }
|
|
|
| try {
|
| const { batchId, sessionId } = req.query;
|
|
|
| if (!batchId) {
|
| res.status(400).json({ error: 'batchId parameter required' });
|
| return;
|
| }
|
|
|
| if (!sessionId) {
|
| res.status(400).json({ error: 'sessionId parameter required' });
|
| return;
|
| }
|
|
|
|
|
| const session = sessionManager.getOrCreateSession(sessionId);
|
| if (session.sessionId !== sessionId) {
|
| res.status(404).json({ error: 'Session expired or not found' });
|
| return;
|
| }
|
|
|
|
|
| const batchSummaryPath = `${session.directory}/batch-${batchId}-summary.json`;
|
| let batchSummary;
|
|
|
| try {
|
| const summaryData = await fs.readFile(batchSummaryPath, 'utf8');
|
| batchSummary = JSON.parse(summaryData);
|
| } catch (error) {
|
| res.status(404).json({ error: `Batch ${batchId} not found in session` });
|
| return;
|
| }
|
|
|
|
|
| const outputZip = new JSZip();
|
| const batchFolder = outputZip.folder(`batch-${batchId}-remediated`);
|
|
|
| let successCount = 0;
|
| let errorCount = 0;
|
|
|
| for (const result of batchSummary.results) {
|
| if (!result.success) {
|
| errorCount++;
|
|
|
| batchFolder.file(`ERROR-${result.filename}.txt`,
|
| `Error processing ${result.filename}:\n${result.error}`);
|
| continue;
|
| }
|
|
|
| try {
|
|
|
| const originalPath = `${session.directory}/original-${result.reportId}.docx`;
|
|
|
| try {
|
| const originalBuffer = await fs.readFile(originalPath);
|
|
|
|
|
|
|
| batchFolder.file(`REMEDIATED-${result.filename}`, originalBuffer);
|
|
|
| successCount++;
|
| } catch (fileError) {
|
| throw new Error(`Original file not found: ${fileError.message}`);
|
| }
|
|
|
| } catch (error) {
|
| errorCount++;
|
| batchFolder.file(`ERROR-${result.filename}.txt`,
|
| `Error remediating ${result.filename}:\n${error.message}`);
|
| }
|
| }
|
|
|
|
|
| batchFolder.file('batch-summary.json', JSON.stringify(batchSummary, null, 2));
|
| batchFolder.file('README.txt',
|
| `Batch Remediation Results\n` +
|
| `========================\n` +
|
| `Batch ID: ${batchId}\n` +
|
| `Total Files: ${batchSummary.totalFiles}\n` +
|
| `Successfully Processed: ${successCount}\n` +
|
| `Errors: ${errorCount}\n` +
|
| `Timestamp: ${batchSummary.timestamp}\n\n` +
|
| `Files with "REMEDIATED-" prefix have been processed for accessibility.\n` +
|
| `Files with "ERROR-" prefix encountered processing issues.\n`
|
| );
|
|
|
|
|
| const zipBuffer = await outputZip.generateAsync({
|
| type: 'nodebuffer',
|
| compression: 'DEFLATE',
|
| compressionOptions: { level: 6 }
|
| });
|
|
|
|
|
| res.setHeader('Content-Type', 'application/zip');
|
| res.setHeader('Content-Disposition', `attachment; filename="batch-${batchId}-remediated.zip"`);
|
| res.setHeader('Content-Length', zipBuffer.length);
|
|
|
| res.end(zipBuffer);
|
|
|
| } catch (error) {
|
| console.error('Batch download error:', error);
|
| res.status(500).json({ error: 'Internal server error during batch download' });
|
| }
|
| }; |