HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux mail.btech-izolacje.pl 5.15.0-140-generic #150-Ubuntu SMP Sat Apr 12 06:00:09 UTC 2025 x86_64
User: pewna6876 (1017)
PHP: 8.2.28
Disabled: NONE
Upload Files
File: //srv/rmgun_admin/admin-next/express/src/index.ts
import express, { Express, Request, Response } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import dotenv from 'dotenv';
import cron from 'node-cron';
import * as path from 'path';
import * as fs from 'fs';
import { initializeFirebase } from './config/firebase';
import { CsvExportService } from './services/csv-export-service';
import { EmailService } from './services/email-service';
import { RegistrationService } from './services/registration-service';
import testRouter from './routes/test';

// Load .env from parent directory (shared with Next.js)
dotenv.config({ path: path.join(__dirname, '../../.env') });

const app: Express = express();
const PORT = process.env.PORT || 4000;

// Initialize Firebase
try {
  initializeFirebase();
} catch (error) {
  console.error('Failed to initialize Firebase. Service will continue without Firestore access.');
}

app.use(helmet());
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.get('/health', (_req: Request, res: Response) => {
  res.status(200).json({
    status: 'healthy',
    uptime: process.uptime(),
    timestamp: new Date().toISOString(),
    schedulerEnabled: process.env.SCHEDULER_ENABLED === 'true'
  });
});

app.get('/', (_req: Request, res: Response) => {
  res.json({
    message: 'Express service is running',
    version: '1.0.0',
    features: {
      scheduler: process.env.SCHEDULER_ENABLED === 'true',
      weeklyExport: true
    }
  });
});

// Manual export endpoint with optional email sending
app.get('/export/weekly', async (req: Request, res: Response) => {
  try {
    const sendEmail = req.query.email !== 'false'; // Default to true
    const filepath = await CsvExportService.exportWeeklyRegistrations();

    if (filepath) {
      let emailSent = false;

      if (sendEmail) {
        const registrations = await RegistrationService.getWeeklyRegistrations();
        emailSent = await EmailService.sendWeeklyExport(filepath, registrations.length);
      }

      res.json({
        success: true,
        message: 'Weekly export completed',
        file: path.basename(filepath),
        emailSent
      });
    } else {
      res.json({
        success: false,
        message: 'No registrations found for export'
      });
    }
  } catch (error) {
    console.error('Export error:', error);
    res.status(500).json({
      success: false,
      error: 'Failed to export registrations'
    });
  }
});

// List exported files
app.get('/export/list', (_req: Request, res: Response) => {
  const files = CsvExportService.getExportedFiles();
  res.json({
    files,
    count: files.length
  });
});

// Download exported file
app.get('/export/download/:filename', (req: Request, res: Response): void => {
  const filename = req.params.filename;
  const filepath = path.join(__dirname, '../exports', filename);

  if (!fs.existsSync(filepath)) {
    res.status(404).json({ error: 'File not found' });
    return;
  }

  res.download(filepath);
});

// Mount test routes (only in development/test environments)
if (process.env.NODE_ENV !== 'production') {
  app.use('/test', testRouter);
  console.log('๐Ÿงช Test routes enabled at /test/*');
}

// Scheduler setup
if (process.env.SCHEDULER_ENABLED === 'true') {
  const timezone = process.env.SCHEDULER_TIMEZONE || 'Europe/Warsaw';

  // Weekly export - Every Sunday at 22:00
  cron.schedule('0 22 * * 0', async () => {
    console.log('๐Ÿš€ Starting weekly CSV export with email (Sunday 22:00)');
    try {
      const filepath = await CsvExportService.exportWeeklyRegistrations();

      if (filepath) {
        console.log(`โœ… Weekly export completed: ${path.basename(filepath)}`);

        // Send email with CSV attachment
        const registrations = await RegistrationService.getWeeklyRegistrations();
        const emailSent = await EmailService.sendWeeklyExport(filepath, registrations.length);

        if (emailSent) {
          console.log('๐Ÿ“ง Weekly report email sent successfully');
        } else {
          console.log('โš ๏ธ Failed to send email or email disabled');
        }
      } else {
        console.log('โš ๏ธ No registrations to export this week');
      }

      // Clean old exports (keep last 4 weeks)
      await CsvExportService.cleanOldExports();
    } catch (error) {
      console.error('โŒ Weekly export failed:', error);
    }
  }, {
    scheduled: true,
    timezone
  });

  // Optional: Daily cleanup of old exports
  cron.schedule('0 3 * * *', async () => {
    console.log('๐Ÿงน Running daily cleanup of old exports');
    try {
      await CsvExportService.cleanOldExports();
    } catch (error) {
      console.error('Cleanup failed:', error);
    }
  }, {
    scheduled: true,
    timezone
  });

  console.log(`๐Ÿ“… Scheduler enabled with timezone: ${timezone}`);
  console.log('โฐ Weekly export scheduled for Sunday 22:00');
}

app.listen(PORT, () => {
  console.log(`โšก๏ธ[server]: Express service is running at http://localhost:${PORT}`);
  console.log(`โš™๏ธ [environment]: ${process.env.NODE_ENV || 'development'}`);
  console.log(`๐Ÿ“… [scheduler]: ${process.env.SCHEDULER_ENABLED === 'true' ? 'Enabled' : 'Disabled'}`);
  console.log(`๐Ÿ“ [exports]: Available at /export/*`);
});