Add comprehensive database setup and user management system

- Implement PostgreSQL database schema with users and bookmarks tables
- Add database connection pooling with retry logic and error handling
- Create migration system with automatic schema initialization
- Add database CLI tools for management (init, status, validate, etc.)
- Include comprehensive error handling and diagnostics
- Add development seed data and testing utilities
- Implement health monitoring and connection pool statistics
- Create detailed documentation and troubleshooting guide

Database features:
- Users table with authentication fields and email verification
- Bookmarks table with user association and metadata
- Proper indexes for performance optimization
- Automatic timestamp triggers
- Transaction support with rollback handling
- Connection pooling (20 max connections, 30s idle timeout)
- Graceful shutdown handling

CLI commands available:
- npm run db:init - Initialize database
- npm run db:status - Check database status
- npm run db:validate - Validate schema
- npm run db:test - Run database tests
- npm run db:diagnostics - Full diagnostics
This commit is contained in:
2025-07-19 23:21:50 +02:00
commit 0abee5b794
66 changed files with 45023 additions and 0 deletions

113
backend/src/app.js Normal file
View File

@ -0,0 +1,113 @@
const express = require('express');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const cookieParser = require('cookie-parser');
require('dotenv').config();
const app = express();
// Security middleware
app.use(helmet());
// Rate limiting
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later.'
});
app.use(limiter);
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser());
// CORS middleware
app.use((req, res, next) => {
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.setHeader('Access-Control-Allow-Credentials', 'true');
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
// Health check endpoint
app.get('/health', async (req, res) => {
try {
const dbConnection = require('./database/connection');
const dbUtils = require('./database/utils');
const health = await dbConnection.healthCheck();
const diagnostics = await dbUtils.diagnostics();
res.json({
status: health.healthy ? 'OK' : 'ERROR',
timestamp: new Date().toISOString(),
database: health,
diagnostics: diagnostics
});
} catch (error) {
res.status(500).json({
status: 'ERROR',
timestamp: new Date().toISOString(),
error: error.message
});
}
});
// Database status endpoint
app.get('/db-status', async (req, res) => {
try {
const dbInitializer = require('./database/init');
const dbUtils = require('./database/utils');
const status = await dbInitializer.getStatus();
const validation = await dbUtils.validateSchema();
res.json({
timestamp: new Date().toISOString(),
...status,
schema: validation
});
} catch (error) {
res.status(500).json({
error: error.message,
timestamp: new Date().toISOString()
});
}
});
// API routes will be added here
// app.use('/api/auth', require('./routes/auth'));
// app.use('/api/user', require('./routes/user'));
// app.use('/api/bookmarks', require('./routes/bookmarks'));
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: 'Something went wrong!',
timestamp: new Date().toISOString()
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({
error: 'Route not found',
timestamp: new Date().toISOString()
});
});
module.exports = app;