127 lines
4.0 KiB
JavaScript
127 lines
4.0 KiB
JavaScript
|
|
import express from 'express';
|
|
import path from 'path';
|
|
import cors from 'cors';
|
|
import { fileURLToPath } from 'url';
|
|
import dotenv from 'dotenv';
|
|
|
|
// Load environment variables
|
|
dotenv.config();
|
|
|
|
// Import database and routes
|
|
import pool, { testConnection } from './server/db.js';
|
|
import authRoutes from './server/routes/auth.js';
|
|
import masterDataRoutes from './server/routes/master-data.js';
|
|
import settingsRoutes from './server/routes/settings.js';
|
|
import damageReportsRoutes from './server/routes/damage-reports.js';
|
|
import inspectionsRoutes from './server/routes/inspections.js';
|
|
import inventoryRoutes from './server/routes/inventory.js';
|
|
import persediaanRoutes from './server/routes/persediaan.js';
|
|
|
|
// Konfigurasi __dirname untuk ES Modules
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3005;
|
|
|
|
// Middleware
|
|
app.use(cors());
|
|
app.use(express.json({ limit: '50mb' }));
|
|
app.use(express.urlencoded({ extended: true, limit: '50mb' }));
|
|
|
|
// Request Logger for Debugging
|
|
app.use((req, res, next) => {
|
|
console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
|
|
next();
|
|
});
|
|
|
|
// API Routes - Moved before static to prioritize matching
|
|
app.use('/api', authRoutes);
|
|
app.use('/api', masterDataRoutes);
|
|
app.use('/api', settingsRoutes);
|
|
app.use('/api', damageReportsRoutes);
|
|
app.use('/api', inspectionsRoutes);
|
|
app.use('/api', inventoryRoutes);
|
|
app.use('/api', persediaanRoutes);
|
|
|
|
// Menyajikan file statis dari folder 'public' (gambar lokal, dll)
|
|
app.use(express.static(path.join(__dirname, 'public')));
|
|
|
|
// Menyajikan file statis dari folder 'dist' (hasil build Vite)
|
|
app.use(express.static(path.join(__dirname, 'dist')));
|
|
|
|
// Image Proxy Endpoint - Bypass CORS for Google Drive images
|
|
app.get('/api/image-proxy', async (req, res) => {
|
|
const imageUrl = req.query.url;
|
|
|
|
if (!imageUrl) {
|
|
return res.status(400).send('Missing url parameter');
|
|
}
|
|
|
|
console.log('[Image Proxy] Fetching:', imageUrl);
|
|
|
|
try {
|
|
// Dynamic import for node-fetch (ESM compatible)
|
|
const fetch = (await import('node-fetch')).default;
|
|
|
|
const response = await fetch(imageUrl, {
|
|
headers: {
|
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8',
|
|
'Accept-Language': 'en-US,en;q=0.9'
|
|
},
|
|
redirect: 'follow'
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.log('[Image Proxy] Failed with status:', response.status);
|
|
return res.status(response.status).send('Failed to fetch image');
|
|
}
|
|
|
|
const contentType = response.headers.get('content-type') || 'image/png';
|
|
const arrayBuffer = await response.arrayBuffer();
|
|
const buffer = Buffer.from(arrayBuffer);
|
|
|
|
console.log('[Image Proxy] Success, size:', buffer.length, 'bytes');
|
|
|
|
// Set CORS headers
|
|
res.set({
|
|
'Content-Type': contentType,
|
|
'Access-Control-Allow-Origin': '*',
|
|
'Cache-Control': 'public, max-age=86400' // Cache for 1 day
|
|
});
|
|
|
|
res.send(buffer);
|
|
} catch (error) {
|
|
console.error('[Image Proxy] Error:', error.message);
|
|
res.status(500).send('Failed to proxy image: ' + error.message);
|
|
}
|
|
});
|
|
|
|
|
|
// Wildcard route untuk Single Page Application (SPA)
|
|
// Mengembalikan index.html untuk semua route yang tidak dikenali server
|
|
// Ini penting agar React Router menangani routing di sisi klien
|
|
app.get('*', (req, res) => {
|
|
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
|
|
});
|
|
|
|
// Start server with database connection test
|
|
const startServer = async () => {
|
|
// Test database connection
|
|
const dbConnected = await testConnection();
|
|
|
|
if (!dbConnected) {
|
|
console.warn('⚠️ Database connection failed. Server will start but API calls may fail.');
|
|
}
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`\n🚀 Server is running on port ${PORT}`);
|
|
console.log(`📍 Access locally at http://localhost:${PORT}`);
|
|
console.log(`🗄️ Database: ${process.env.DB_NAME || 'Not configured'}`);
|
|
});
|
|
};
|
|
|
|
startServer();
|