123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- const express = require('express');
- const cors = require('cors');
- const helmet = require('helmet');
- const morgan = require('morgan');
- const { Pool } = require('pg');
- require('dotenv').config();
- const app = express();
- const PORT = process.env.PORT || 5000;
- // Database configuration
- const pool = new Pool({
- connectionString: process.env.DATABASE_URL || 'postgresql://postgres:password@localhost:5432/byop_sample',
- ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
- });
- // Middleware
- app.use(helmet());
- app.use(cors());
- app.use(morgan('combined'));
- app.use(express.json());
- app.use(express.urlencoded({ extended: true }));
- // Health check endpoint
- app.get('/health', (req, res) => {
- res.status(200).json({
- status: 'healthy',
- timestamp: new Date().toISOString(),
- uptime: process.uptime(),
- environment: process.env.NODE_ENV || 'development'
- });
- });
- // Root endpoint
- app.get('/', (req, res) => {
- res.json({
- message: '🚀 BYOP Sample Backend API',
- version: '1.0.0',
- endpoints: {
- health: '/health',
- users: '/api/users',
- stats: '/api/stats'
- },
- database: {
- status: 'connected',
- host: process.env.DATABASE_URL ? 'configured' : 'localhost'
- }
- });
- });
- // Initialize database tables
- async function initializeDatabase() {
- try {
- await pool.query(`
- CREATE TABLE IF NOT EXISTS users (
- id SERIAL PRIMARY KEY,
- name VARCHAR(255) NOT NULL,
- email VARCHAR(255) UNIQUE NOT NULL,
- role VARCHAR(100) DEFAULT 'user',
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
- )
- `);
-
- console.log('✅ Database tables initialized');
- } catch (error) {
- console.error('❌ Database initialization error:', error);
- }
- }
- // Get all users
- app.get('/api/users', async (req, res) => {
- try {
- const result = await pool.query('SELECT * FROM users ORDER BY created_at DESC');
- res.json(result.rows);
- } catch (error) {
- console.error('Error fetching users:', error);
- res.status(500).json({ error: 'Failed to fetch users', details: error.message });
- }
- });
- // Get user by ID
- app.get('/api/users/:id', async (req, res) => {
- try {
- const { id } = req.params;
- const result = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
-
- if (result.rows.length === 0) {
- return res.status(404).json({ error: 'User not found' });
- }
-
- res.json(result.rows[0]);
- } catch (error) {
- console.error('Error fetching user:', error);
- res.status(500).json({ error: 'Failed to fetch user', details: error.message });
- }
- });
- // Create new user
- app.post('/api/users', async (req, res) => {
- try {
- const { name, email, role = 'user' } = req.body;
-
- if (!name || !email) {
- return res.status(400).json({ error: 'Name and email are required' });
- }
-
- const result = await pool.query(
- 'INSERT INTO users (name, email, role) VALUES ($1, $2, $3) RETURNING *',
- [name, email, role]
- );
-
- res.status(201).json(result.rows[0]);
- } catch (error) {
- console.error('Error creating user:', error);
-
- if (error.code === '23505') { // Unique violation
- return res.status(409).json({ error: 'User with this email already exists' });
- }
-
- res.status(500).json({ error: 'Failed to create user', details: error.message });
- }
- });
- // Update user
- app.put('/api/users/:id', async (req, res) => {
- try {
- const { id } = req.params;
- const { name, email, role } = req.body;
-
- const result = await pool.query(
- 'UPDATE users SET name = COALESCE($1, name), email = COALESCE($2, email), role = COALESCE($3, role), updated_at = CURRENT_TIMESTAMP WHERE id = $4 RETURNING *',
- [name, email, role, id]
- );
-
- if (result.rows.length === 0) {
- return res.status(404).json({ error: 'User not found' });
- }
-
- res.json(result.rows[0]);
- } catch (error) {
- console.error('Error updating user:', error);
- res.status(500).json({ error: 'Failed to update user', details: error.message });
- }
- });
- // Delete user
- app.delete('/api/users/:id', async (req, res) => {
- try {
- const { id } = req.params;
- const result = await pool.query('DELETE FROM users WHERE id = $1 RETURNING *', [id]);
-
- if (result.rows.length === 0) {
- return res.status(404).json({ error: 'User not found' });
- }
-
- res.json({ message: 'User deleted successfully', user: result.rows[0] });
- } catch (error) {
- console.error('Error deleting user:', error);
- res.status(500).json({ error: 'Failed to delete user', details: error.message });
- }
- });
- // Get application statistics
- app.get('/api/stats', async (req, res) => {
- try {
- const totalUsersResult = await pool.query('SELECT COUNT(*) as count FROM users');
- const recentUsersResult = await pool.query('SELECT COUNT(*) as count FROM users WHERE created_at > NOW() - INTERVAL \'7 days\'');
-
- const stats = {
- totalUsers: parseInt(totalUsersResult.rows[0].count),
- activeUsers: parseInt(recentUsersResult.rows[0].count),
- serverStatus: 'Running',
- databaseStatus: 'Connected',
- uptime: Math.floor(process.uptime()),
- timestamp: new Date().toISOString(),
- environment: process.env.NODE_ENV || 'development'
- };
-
- res.json(stats);
- } catch (error) {
- console.error('Error fetching stats:', error);
- res.status(500).json({
- error: 'Failed to fetch stats',
- details: error.message,
- serverStatus: 'Running',
- databaseStatus: 'Error',
- totalUsers: 0,
- activeUsers: 0
- });
- }
- });
- // Error handling middleware
- app.use((err, req, res, next) => {
- console.error('Unhandled error:', err);
- res.status(500).json({
- error: 'Internal server error',
- details: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong'
- });
- });
- // 404 handler
- app.use('*', (req, res) => {
- res.status(404).json({ error: 'Endpoint not found' });
- });
- // Start server
- app.listen(PORT, '0.0.0.0', async () => {
- console.log(`🚀 BYOP Sample Backend running on port ${PORT}`);
- console.log(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
- console.log(`🔗 Database: ${process.env.DATABASE_URL ? 'Configured' : 'Default local'}`);
-
- // Initialize database
- await initializeDatabase();
-
- console.log('✅ Server ready to accept connections');
- });
- // Graceful shutdown handling
- process.on('SIGTERM', () => {
- console.log('🛑 SIGTERM received, shutting down gracefully');
- server.close(() => {
- console.log('💤 Process terminated');
- pool.end();
- });
- });
- process.on('SIGINT', () => {
- console.log('🛑 SIGINT received, shutting down gracefully');
- process.exit(0);
- });
|