import express from 'express'; import sqlite3 from 'sqlite3'; import cors from 'cors'; import { open } from 'sqlite'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); const PORT = process.env.PORT || 3000; const isDebug = process.env.NODE_ENV !== 'production' || process.env.DEBUG === 'true'; // Middleware app.use(cors()); app.use(express.json()); // Database setup let db; async function initializeDB() { const dbPath = path.join(__dirname, 'wifi_markers.db'); db = await open({ filename: dbPath, driver: sqlite3.Database }); // Enable WAL mode for concurrency await db.exec('PRAGMA journal_mode = WAL;'); // Create table await db.exec(` CREATE TABLE IF NOT EXISTS markers ( id TEXT PRIMARY KEY, name TEXT NOT NULL, ssid TEXT NOT NULL, password TEXT, lat REAL NOT NULL, lng REAL NOT NULL, securityType TEXT NOT NULL, iconType TEXT NOT NULL, description TEXT, addedBy TEXT, createdAt INTEGER, isPublic INTEGER DEFAULT 1 ) `); console.log(`[DB] Database initialized at: ${dbPath}`); console.log('[DB] WAL mode enabled for concurrent writes.'); const count = await db.get('SELECT COUNT(*) as count FROM markers'); console.log(`[DB] Current Status: ${count.count} markers stored in database.`); } // Routes app.get('/api/markers', async (req, res) => { const host = req.headers.host; if (isDebug) console.log(`[API] GET /api/markers - Host: ${host} - Fetching from SQLite`); try { const markers = await db.all('SELECT * FROM markers'); if (isDebug) console.log(`[API] Found ${markers.length} markers`); // Convert isPublic from 0/1 to boolean const formattedMarkers = markers.map(m => ({ ...m, isPublic: !!m.isPublic })); res.json(formattedMarkers); } catch (error) { console.error(error); res.status(500).json({ error: 'Failed to fetch markers' }); } }); app.post('/api/markers', async (req, res) => { const { id, name, ssid, password, lat, lng, securityType, iconType, description, addedBy, createdAt, isPublic } = req.body; if (isDebug) console.log(`[API] POST /api/markers - Saving marker: ${name} (${ssid}) to SQLite`); try { await db.run(` INSERT OR REPLACE INTO markers (id, name, ssid, password, lat, lng, securityType, iconType, description, addedBy, createdAt, isPublic) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `, [id, name, ssid, password, lat, lng, securityType, iconType, description || '', addedBy, createdAt, isPublic ? 1 : 0]); if (isDebug) console.log(`[API] Successfully saved marker: ${id}`); res.json({ success: true }); } catch (error) { console.error(error); res.status(500).json({ error: 'Failed to save marker' }); } }); app.delete('/api/markers/:id', async (req, res) => { const { id } = req.params; if (isDebug) console.log(`[API] DELETE /api/markers/${id} - Deleting marker from SQLite`); try { await db.run('DELETE FROM markers WHERE id = ?', [id]); if (isDebug) console.log(`[API] Successfully deleted marker: ${id}`); res.json({ success: true }); } catch (error) { console.error(error); res.status(500).json({ error: 'Failed to delete marker' }); } }); // Serve static files from dist app.use(express.static(path.join(__dirname, 'dist'))); // Fallback for SPA app.get(/.*/, (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); }); initializeDB().then(() => { app.listen(PORT, '0.0.0.0', () => { console.log(`Server running on http://0.0.0.0:${PORT}`); }); });