const express = require('express'); const cors = require('cors'); const fs = require('fs'); const path = require('path'); const { LRUCache } = require('lru-cache'); const app = express(); const PORT = process.env.PORT || 7860; const dbDirectory = path.join(__dirname, 'database'); if (!fs.existsSync(dbDirectory)) { fs.mkdirSync(dbDirectory); } const cache = new LRUCache({ max: 500, ttl: 1000 * 60 * 60 * 24 * 30, allowStale: false, updateAgeOnGet: true, updateAgeOnHas: true, }); function loadDatabasesIntoCache() { const ownerDirs = fs.readdirSync(dbDirectory); for (const owner of ownerDirs) { const ownerPath = path.join(dbDirectory, owner); if (fs.statSync(ownerPath).isDirectory()) { const files = fs.readdirSync(ownerPath); for (const file of files) { if (path.extname(file) === '.json') { const dbName = path.basename(file, '.json'); const filePath = path.join(ownerPath, file); const cacheKey = `${owner}_${dbName}`; try { const data = fs.readFileSync(filePath, 'utf8'); cache.set(cacheKey, JSON.parse(data)); } catch (e) { console.error(`Gagal memuat ${file} untuk owner ${owner} ke cache.`, e); } } } } } console.log('Semua database dari disk telah dimuat ke LRU Cache.'); } app.use(cors()); app.use(express.json({ limit: '50mb' })); app.get('/db/:owner/:name', (req, res) => { const { owner, name } = req.params; const cacheKey = `${owner}_${name}`; const data = cache.get(cacheKey); if (data) { return res.status(200).json(data); } const filePath = path.join(dbDirectory, owner, `${name}.json`); if (fs.existsSync(filePath)) { try { const fileData = JSON.parse(fs.readFileSync(filePath, 'utf8')); cache.set(cacheKey, fileData); return res.status(200).json(fileData); } catch (e) { return res.status(500).json({ success: false, message: 'Gagal membaca database.' }); } } else { return res.status(200).json({}); } }); app.post('/db/:owner/:name', (req, res) => { try { const { owner, name } = req.params; const data = req.body; const cacheKey = `${owner}_${name}`; cache.set(cacheKey, data); const ownerDir = path.join(dbDirectory, owner); if (!fs.existsSync(ownerDir)) { fs.mkdirSync(ownerDir, { recursive: true }); } const filePath = path.join(ownerDir, `${name}.json`); fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); res.status(200).json({ success: true, message: 'Database berhasil disimpan.' }); } catch (error) { res.status(500).json({ success: false, message: 'Terjadi kesalahan internal.' }); } }); app.listen(PORT, () => { loadDatabasesIntoCache(); console.log(`Server database multi-tenant berjalan di port ${PORT}.`); });