2025-06-15 14:47:15 +00:00
|
|
|
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 (
|
2025-06-18 12:05:24 +00:00
|
|
|
id varchar(20) PRIMARY KEY,
|
2025-06-15 14:47:15 +00:00
|
|
|
body text NOT NULL,
|
|
|
|
project text NOT NULL DEFAULT 'Project 1',
|
|
|
|
type text NOT NULL DEFAULT 'Info',
|
2025-06-18 12:05:24 +00:00
|
|
|
date text NOT NULL,
|
2025-06-15 14:47:15 +00:00
|
|
|
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`);
|
|
|
|
});
|