File size: 3,197 Bytes
9ed06fa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const helmet = require('helmet');
const Analytics = require('./models/Analytics');

const app = express();
const PORT = process.env.PORT || 7860; // 7860 is the default for HuggingFace Spaces

// --- Middleware ---
app.use(helmet()); // Adds security headers
app.use(express.json()); // Parses JSON body
// In production, replace '*' with your frontend domain (e.g., 'https://comprex.pages.dev')
app.use(cors({ origin: '*' })); 

// --- Database Connection ---
const connectDB = async () => {
  try {
    // We use the MONGO_URI from .env
    await mongoose.connect(process.env.MONGO_URI);
    console.log('โœ… MongoDB Connected Successfully');
  } catch (err) {
    console.error('โŒ MongoDB Connection Error:', err);
    process.exit(1); // Exit if DB fails
  }
};
connectDB();

// --- Routes ---

// 1. Health Check
app.get('/', (req, res) => {
  res.json({ status: 'active', message: 'CompreX Backend is running' });
});

// 2. Track Compression (Frontend calls this after compressing a file)
app.post('/api/track', async (req, res) => {
  try {
    const { fileType, originalSize, compressedSize } = req.body;

    // Basic Validation
    if (!fileType || !originalSize || !compressedSize) {
      return res.status(400).json({ error: 'Missing required fields' });
    }

    const newStat = await Analytics.create({
      fileType,
      originalSize,
      compressedSize
    });

    res.status(201).json({ success: true, id: newStat._id });
  } catch (error) {
    console.error('Tracking Error:', error);
    res.status(500).json({ error: 'Server Error' });
  }
});

// 3. Get Dashboard Stats (For the Analytics Page)
app.get('/api/stats', async (req, res) => {
  try {
    // Aggregation Pipeline for Performance
    const stats = await Analytics.aggregate([
      {
        $group: {
          _id: null,
          totalFiles: { $sum: 1 },
          totalOriginal: { $sum: "$originalSize" },
          totalCompressed: { $sum: "$compressedSize" }
        }
      }
    ]);

    // Get Daily Activity for the last 7 days (For the Chart)
    const sevenDaysAgo = new Date();
    sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);

    const history = await Analytics.aggregate([
      { $match: { timestamp: { $gte: sevenDaysAgo } } },
      {
        $group: {
          _id: { $dateToString: { format: "%Y-%m-%d", date: "$timestamp" } },
          count: { $sum: 1 },
          savedBytes: { $sum: { $subtract: ["$originalSize", "$compressedSize"] } }
        }
      },
      { $sort: { _id: 1 } } // Sort by date ascending
    ]);

    const globalStats = stats[0] || { totalFiles: 0, totalOriginal: 0, totalCompressed: 0 };
    const totalSaved = globalStats.totalOriginal - globalStats.totalCompressed;

    res.json({
      totalFiles: globalStats.totalFiles,
      totalSavedBytes: totalSaved,
      history
    });

  } catch (error) {
    console.error('Stats Error:', error);
    res.status(500).json({ error: 'Server Error' });
  }
});

// --- Start Server ---
app.listen(PORT, () => {
  console.log(`๐Ÿš€ Server running on port ${PORT}`);
});