import { createServer } from 'http'; import { URL } from 'url'; import pkg from 'pg'; import { authenticateBasic } from './middleware/auth.js'; import { validateLogData } from './utils/validation.js'; import { createLogEntry } from './services/logService.js'; const { Client } = pkg; const PORT = process.env.PORT || 3000; // PostgreSQL connection configuration from environment variables const dbConfig = { host: process.env.DB_HOST || 'localhost', port: process.env.DB_PORT || 5432, database: process.env.DB_NAME || 'postgres', user: process.env.DB_USER || 'postgres', password: process.env.DB_PASSWORD || 'password', ssl: process.env.DB_SSL === 'true' ? { rejectUnauthorized: false } : false }; // Initialize PostgreSQL client const client = new Client(dbConfig); // Connect to PostgreSQL try { await client.connect(); console.log('Connected to PostgreSQL database'); // Create logs table if it doesn't exist await client.query(` CREATE TABLE IF NOT EXISTS logs ( id varchar(20) PRIMARY KEY, body text NOT NULL, project text NOT NULL DEFAULT 'Project 1', type text NOT NULL DEFAULT 'Info', date text NOT NULL, avatar_src text NOT NULL DEFAULT '/rectangle-15.png', owner text NOT NULL DEFAULT 'N/A', description text NOT NULL, created_at timestamptz NOT NULL DEFAULT now(), status text NOT NULL DEFAULT 'Pending' ) `); console.log('Logs table ready'); } catch (error) { console.error('Failed to connect to PostgreSQL:', error); process.exit(1); } const server = createServer(async (req, res) => { // Set CORS headers res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // Handle preflight requests if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; } const url = new URL(req.url, `http://localhost:${PORT}`); try { // Health check endpoint if (req.method === 'GET' && url.pathname === '/health') { res.writeHead(200, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ status: 'healthy', timestamp: new Date().toISOString() })); return; } // Log entry endpoint if (req.method === 'POST' && url.pathname === '/logs') { // Authenticate request const authResult = authenticateBasic(req); if (!authResult.success) { res.writeHead(401, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Unauthorized', message: authResult.message })); return; } // Parse request body let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const data = JSON.parse(body); // Validate input data const validation = validateLogData(data); if (!validation.isValid) { res.writeHead(400, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Invalid input', errors: validation.errors })); return; } // Create log entry const logEntry = await createLogEntry(client, data); res.writeHead(201, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ success: true, message: 'Log entry created successfully', id: logEntry.id })); } catch (error) { console.error('Error processing request:', error); res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Internal server error' })); } }); return; } // 404 for unknown routes res.writeHead(404, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Not found' })); } catch (error) { console.error('Server error:', error); res.writeHead(500, { 'Content-Type': 'application/json' }); res.end(JSON.stringify({ error: 'Internal server error' })); } }); server.listen(PORT, () => { console.log(`Log microservice running on port ${PORT}`); console.log(`Health check available at: http://localhost:${PORT}/health`); console.log(`Log endpoint available at: http://localhost:${PORT}/logs`); });