All files / services/crawler-api/src index.js

81.72% Statements 76/93
60% Branches 6/10
100% Functions 2/2
81.72% Lines 76/93

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 941x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x             1x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x 1x 1x 1x 1x 1x       1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x 1x     1x 1x 1x  
/**
 * Crawler API Service
 * HTTP API for crawler service (split from monolithic crawler service)
 */
 
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
const config = require('./config');
const routes = require('./routes');
 
const app = express();
 
// Middleware
app.use(cors());
app.use(express.json());
 
// Health check
app.get('/health', async (req, res) => {
  res.json({
    status: 'healthy',
    version: '2.0.0',
    service: 'crawler-api',
    services: {
      mongodb: mongoose.connection.readyState === 1 ? 'up' : 'down',
    },
  });
});
 
// Single resource routes (no orgId in path) - mounted BEFORE org routes
// These follow the pattern: /crawler/:id for GET/PUT/DELETE
const singleResourceRoutes = require('./routes/single');
app.use('/', singleResourceRoutes);
 
// Routes with organizationId prefix
app.use('/:organizationId', routes);
 
// Error handler
app.use((err, req, res, next) => {
  console.error('[CrawlerAPI] Error:', err);
  res.status(500).json({
    success: false,
    message: 'Internal server error',
    error: err.message,
  });
});
 
// Connect to MongoDB
async function connectMongoDB() {
  try {
    await mongoose.connect(config.mongodbUri);
    console.log('[CrawlerAPI] MongoDB connected');
    return true;
  } catch (error) {
    console.error('[CrawlerAPI] MongoDB connection error:', error.message);
    return false;
  }
}
 
// Start server
async function startServer() {
  const mongoOk = await connectMongoDB();
  
  if (!mongoOk) {
    console.error('[CrawlerAPI] Failed to connect to MongoDB');
    process.exit(1);
  }
 
  app.listen(config.port, () => {
    console.log(`[CrawlerAPI] Running on port ${config.port}`);
    console.log(`[CrawlerAPI] MongoDB: ${config.mongodbUri.split('@')[1] || 'connected'}`);
  });
}
 
// Graceful shutdown
process.on('SIGTERM', async () => {
  console.log('[CrawlerAPI] SIGTERM received, shutting down...');
  await mongoose.connection.close();
  process.exit(0);
});
 
process.on('SIGINT', async () => {
  console.log('[CrawlerAPI] SIGINT received, shutting down...');
  await mongoose.connection.close();
  process.exit(0);
});
 
startServer().catch((error) => {
  console.error('[CrawlerAPI] Failed to start:', error);
  process.exit(1);
});
 
module.exports = app;