src/controllers/upload.controller.
ts
import { Request, Response } from 'express';
import { FileParser } from '../utils/fileParser';
import { OpenAIService } from '../services/openai.service';
export class UploadController {
  static async uploadAndAnalyze(req: Request, res: Response): Promise<void> {
    try {
      const files = req.files as Express.Multer.File[];
          if (!files || files.length === 0) {
            res.status(400).json({
              error: 'No files uploaded'
            });
            return;
          }
          console.log(`Processing ${files.length} files...`);
      // Parse files
      const parsedFiles = await Promise.all(files.map(file =>
FileParser.parseFile(file)));
      console.log('Files parsed successfully');
          // Analyze with OpenAI
          const analysisResults = await OpenAIService.analyzeFiles(parsedFiles);
          console.log('Analysis completed');
          // Return formatted response
          res.json({
            success: true,
            filesProcessed: files.length,
            results: analysisResults,
            timestamp: new Date().toISOString()
          });
        } catch (error) {
          console.error('Upload and analysis error:', error);
          res.status(500).json({
            error: {
              message: (error as Error).message,
              type: 'PROCESSING_ERROR'
            }
          });
        }
    }
}
src/middleware/filevalidation.ts
import { Request, Response } from 'express';
import { FileParser } from '../utils/fileParser';
import { OpenAIService } from '../services/openai.service';
export class UploadController {
  static async uploadAndAnalyze(req: Request, res: Response): Promise<void> {
    try {
      const files = req.files as Express.Multer.File[];
          if (!files || files.length === 0) {
            res.status(400).json({
              error: 'No files uploaded'
            });
            return;
          }
          console.log(`Processing ${files.length} files...`);
      // Parse files
      const parsedFiles = await Promise.all(files.map(file =>
FileParser.parseFile(file)));
      console.log('Files parsed successfully');
          // Analyze with OpenAI
          const analysisResults = await OpenAIService.analyzeFiles(parsedFiles);
          console.log('Analysis completed');
          // Return formatted response
          res.json({
            success: true,
            filesProcessed: files.length,
            results: analysisResults,
            timestamp: new Date().toISOString()
          });
        } catch (error) {
          console.error('Upload and analysis error:', error);
          res.status(500).json({
            error: {
              message: (error as Error).message,
              type: 'PROCESSING_ERROR'
            }
          });
        }
    }
}
src/route/upload.route.ts
import { Router } from 'express';
import { upload, validateFileUpload } from '../middleware/fileValidation';
import { UploadController } from '../controllers/upload.controller';
const router = Router();
router.post(
   '/upload-analyse',
   upload.array('files', 3),
   validateFileUpload,
   UploadController.uploadAndAnalyze
);
export default router;
src/services/openai.service.ts
import dotenv from 'dotenv';
dotenv.config(); // Make sure .env is loaded
import OpenAI from 'openai';
console.log('OPENAI_API_KEY:', process.env.OPENAI_API_KEY);
console.log('Environment:', process.env.NODE_ENV);
let openai: OpenAI | null = null;
function getOpenAIInstance(): OpenAI {
  if (!process.env.OPENAI_API_KEY) {
    throw new Error('OPENAI_API_KEY is missing. Please check your .env file.');
  }
    if (!openai) {
      openai = new OpenAI({
        apiKey: process.env.OPENAI_API_KEY,
      });
    }
    return openai;
}
export interface OpenAIAnalysisResult {
  fileName: string;
  summary: string;
  keyInsights: string[];
  actionItems: string[];
}
export interface ParsedFile {
  fileName: string;
  content: string;
  fileType: string;
}
export class OpenAIService {
  static async analyzeFiles(files: ParsedFile[]): Promise<OpenAIAnalysisResult[]> {
    const results: OpenAIAnalysisResult[] = [];
        for (const file of files) {
          try {
            const analysis = await this.analyzeSingleFile(file);
            results.push(analysis);
          } catch (error) {
            console.error(`Error analyzing file ${file.fileName}:`, error);
            results.push({
              fileName: file.fileName,
              summary: `Error analyzing file: ${(error as Error).message}`,
              keyInsights: [],
              actionItems: []
            });
          }
        }
        return results;
    }
  private static async analyzeSingleFile(file: ParsedFile):
Promise<OpenAIAnalysisResult> {
    const prompt = `Please analyze the following document and provide a well-
structured summary, key insights, and any actionable points.
Document: ${file.fileName}
Content: ${file.content}
Please respond in the following JSON format:
{
  "summary": "Brief summary of the document",
  "keyInsights": ["insight 1", "insight 2", "insight 3"],
  "actionItems": ["action 1", "action 2", "action 3"]
}`;
    try {
      const openaiClient = getOpenAIInstance(); // Get instance here
      const response = await openaiClient.chat.completions.create({
        model: "gpt-3.5-turbo",
        messages: [
           {
              role: "system",
              content: "You are a helpful assistant that analyzes documents and
provides structured summaries, insights, and action items. Always respond with
valid JSON."
           },
           {
              role: "user",
              content: prompt
           }
        ],
        max_tokens: 1000,
        temperature: 0.3
      });
      const content = response.choices[0]?.message?.content;
      if (!content) {
        throw new Error('No response from OpenAI');
      }
      let parsedResponse;
      try {
        parsedResponse = JSON.parse(content);
      } catch (parseError) {
        parsedResponse = {
           summary: content.substring(0, 500),
           keyInsights: ["Analysis completed but response format needs refinement"],
           actionItems: ["Review the analysis and extract specific action items"]
        };
      }
      return {
         fileName: file.fileName,
         summary: parsedResponse.summary || "No summary available",
         keyInsights: Array.isArray(parsedResponse.keyInsights) ?
parsedResponse.keyInsights : [],
         actionItems: Array.isArray(parsedResponse.actionItems) ?
parsedResponse.actionItems : []
      };
        } catch (error) {
          console.error('OpenAI API error:', error);
          throw new Error(`OpenAI analysis failed: ${(error as Error).message}`);
        }
    }
}
src/utils/fileParse.ts
import pdfParse from 'pdf-parse';
import mammoth from 'mammoth';
import sharp from 'sharp';
export interface ParsedFile {
  fileName: string;
  content: string;
  fileType: string;
}
export class FileParser {
  static async parseFile(file: Express.Multer.File): Promise<ParsedFile> {
    const { originalname, mimetype, buffer } = file;
        try {
          let content = '';
      switch (mimetype) {
        case 'application/pdf':
          content = await this.parsePDF(buffer);
          break;
        case 'application/msword':
        case 'application/vnd.openxmlformats-
officedocument.wordprocessingml.document':
          content = await this.parseWord(buffer);
          break;
        case 'application/vnd.ms-powerpoint':
        case 'application/vnd.openxmlformats-
officedocument.presentationml.presentation':
          content = await this.parsePowerPoint(buffer);
          break;
        case 'image/png':
        case 'image/jpeg':
        case 'image/jpg':
          content = await this.parseImage(buffer);
          break;
        default:
          throw new Error(`Unsupported file type: ${mimetype}`);
      }
      return {
         fileName: originalname,
         content: content.trim(),
         fileType: mimetype
      };
    } catch (error) {
      console.error(`Error parsing file ${originalname}:`, error);
      throw new Error(`Failed to parse file ${originalname}: ${(error as
Error).message}`);
    }
}
    private static async parsePDF(buffer: Buffer): Promise<string> {
      const data = await pdfParse(buffer);
      return data.text;
    }
    private static async parseWord(buffer: Buffer): Promise<string> {
      const result = await mammoth.extractRawText({ buffer });
      return result.value;
    }
  private static async parsePowerPoint(buffer: Buffer): Promise<string> {
    // Note: pptx-parser might not be available or reliable
    // This is a placeholder implementation
    // You might need to use alternative libraries or services
    try {
      // For now, return a placeholder message
      return "PowerPoint content extraction not fully implemented. Please use
alternative methods for PPT files.";
    } catch (error) {
      throw new Error("PowerPoint parsing not available");
    }
  }
  private static async parseImage(buffer: Buffer): Promise<string> {
    // For image analysis, we'll return metadata and let OpenAI analyze the image
directly
    try {
      const metadata = await sharp(buffer).metadata();
      return `Image file - Format: ${metadata.format}, Width: ${metadata.width},
Height: ${metadata.height}. Content will be analyzed by AI vision capabilities.`;
    } catch (error) {
      return "Image file detected - content will be analyzed by AI vision
capabilities.";
    }
  }
  static async parseMultipleFiles(files: Express.Multer.File[]):
Promise<ParsedFile[]> {
    const parsePromises = files.map(file => this.parseFile(file));
    return Promise.all(parsePromises);
  }
}
src/index.ts
import   express from 'express';
import   cors from 'cors';
import   helmet from 'helmet';
import   dotenv from 'dotenv';
import   uploadRoutes from './routes/upload.route';
dotenv.config();
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(helmet());
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Routes
app.use('/api', uploadRoutes);
// Health check
app.get('/health', (req, res) => {
  res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
// Error handling middleware
app.use((err: any, req: express.Request, res: express.Response, next:
express.NextFunction) => {
  console.error('Error:', err);
  res.status(err.status || 500).json({
    error: {
      message: err.message || 'Internal Server Error',
      status: err.status || 500
    }
  });
});
// 404 handler
app.use('*', (req, res) => {
  res.status(404).json({ error: 'Route not found' });
});
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
  console.log(`Environment: ${process.env.NODE_ENV}`);
});
export default app;
.env.example
NODE_ENV=development
PORT=3000
OPENAI_API_KEY=sk-proj-1_-
MlZTsOgFj6D5da2l9sfg5v6DLq0GgYB5o3uc4oMLAlybze60xiPumiz7R93Qie7cmyVX3ANT3BlbkFJVDJO
d8Kd8iViMuc6LREp2dc_FkqlUMDrczHM--fyGLdH7zVkXmWxFy0MMqHPNNpgbmM_lVWmQA
MAX_FILE_SIZE=20971520
MAX_FILES=3
MAX_TOTAL_SIZE=104857600