chore: remove legacy express backend directory
This commit is contained in:
parent
dc2c722e57
commit
29382d6067
|
|
@ -1,44 +0,0 @@
|
|||
const sqlite3 = require('sqlite3').verbose();
|
||||
const path = require('path');
|
||||
|
||||
const dbPath = path.resolve(__dirname, 'silat_monitor.db');
|
||||
const db = new sqlite3.Database(dbPath, (err) => {
|
||||
if (err) console.error('Error opening database:', err);
|
||||
else console.log('Database initialized at', dbPath);
|
||||
});
|
||||
|
||||
db.serialize(() => {
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS athletes (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
age INTEGER,
|
||||
height REAL,
|
||||
weight REAL,
|
||||
category TEXT,
|
||||
rfid_tag TEXT UNIQUE
|
||||
)
|
||||
`);
|
||||
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS attempts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
athlete_id INTEGER,
|
||||
force REAL,
|
||||
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY(athlete_id) REFERENCES athletes(id)
|
||||
)
|
||||
`);
|
||||
db.run(`
|
||||
CREATE TABLE IF NOT EXISTS admins (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT UNIQUE NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
)
|
||||
`);
|
||||
|
||||
// Inisialisasi admin default jika belum ada
|
||||
db.run(`INSERT OR IGNORE INTO admins (username, password) VALUES ('admin', 'admin123')`);
|
||||
});
|
||||
|
||||
module.exports = db;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "backend",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon server.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"sqlite3": "^5.1.7",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.21.2",
|
||||
"socket.io": "^4.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.1.9"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,265 +0,0 @@
|
|||
const express = require('express');
|
||||
const http = require('http');
|
||||
const { Server } = require("socket.io");
|
||||
const cors = require('cors');
|
||||
const db = require('./database');
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
const server = http.createServer(app);
|
||||
const io = new Server(server, {
|
||||
cors: {
|
||||
origin: "*",
|
||||
methods: ["GET", "POST"]
|
||||
}
|
||||
});
|
||||
|
||||
let currentTestSession = {
|
||||
athleteId: null,
|
||||
attempts: []
|
||||
};
|
||||
|
||||
// Helper for Promisified DB queries
|
||||
const dbAll = (sql, params = []) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all(sql, params, (err, rows) => {
|
||||
if (err) reject(err);
|
||||
else resolve(rows);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const dbGet = (sql, params = []) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.get(sql, params, (err, row) => {
|
||||
if (err) reject(err);
|
||||
else resolve(row);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const dbRun = (sql, params = []) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.run(sql, params, function (err) {
|
||||
if (err) reject(err);
|
||||
else resolve({ id: this.lastID, changes: this.changes });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// API Routes
|
||||
app.get('/api/athletes', async (req, res) => {
|
||||
try {
|
||||
const athletes = await dbAll('SELECT * FROM athletes ORDER BY id DESC');
|
||||
res.json(athletes);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/athletes/:id', async (req, res) => {
|
||||
try {
|
||||
const athlete = await dbGet('SELECT * FROM athletes WHERE id = ?', [req.params.id]);
|
||||
if (athlete) res.json(athlete);
|
||||
else res.status(404).json({ error: 'Athlete not found' });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/athletes', async (req, res) => {
|
||||
const { name, age, height, weight, category, rfid_tag } = req.body;
|
||||
try {
|
||||
const result = await dbRun(
|
||||
'INSERT INTO athletes (name, age, height, weight, category, rfid_tag) VALUES (?, ?, ?, ?, ?, ?)',
|
||||
[name, age, height, weight, category, rfid_tag]
|
||||
);
|
||||
res.json({ id: result.id, success: true });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete('/api/athletes/:id', async (req, res) => {
|
||||
try {
|
||||
await dbRun('DELETE FROM attempts WHERE athlete_id = ?', [req.params.id]);
|
||||
await dbRun('DELETE FROM athletes WHERE id = ?', [req.params.id]);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/leaderboard', async (req, res) => {
|
||||
try {
|
||||
const query = `
|
||||
SELECT a.name, a.category, MAX(at.force) as best_score
|
||||
FROM athletes a
|
||||
JOIN attempts at ON a.id = at.athlete_id
|
||||
GROUP BY a.id, a.name, a.category
|
||||
ORDER BY best_score DESC
|
||||
`;
|
||||
const leaderboard = await dbAll(query);
|
||||
res.json(leaderboard);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/attempts/:athleteId', async (req, res) => {
|
||||
try {
|
||||
const attempts = await dbAll(
|
||||
'SELECT * FROM attempts WHERE athlete_id = ? ORDER BY timestamp ASC',
|
||||
[req.params.athleteId]
|
||||
);
|
||||
res.json(attempts);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Get History for Chart (Option 3)
|
||||
app.get('/api/history/:athleteId', async (req, res) => {
|
||||
try {
|
||||
const history = await dbAll(`
|
||||
SELECT
|
||||
strftime('%Y-%m-%d %H:%M', timestamp) as date,
|
||||
force
|
||||
FROM attempts
|
||||
WHERE athlete_id = ?
|
||||
ORDER BY timestamp ASC
|
||||
`, [req.params.athleteId]);
|
||||
res.json(history);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
// Start/Stop Test Session logic
|
||||
app.post('/api/start-test', (req, res) => {
|
||||
const { athleteId } = req.body;
|
||||
// Reset session for this athlete
|
||||
currentTestSession = { athleteId: parseInt(athleteId), attempts: [] };
|
||||
io.emit('session_started', { athleteId: currentTestSession.athleteId });
|
||||
console.log(`Session started for athlete ${athleteId}`);
|
||||
res.json({ success: true });
|
||||
});
|
||||
|
||||
app.post('/api/stop-test', (req, res) => {
|
||||
currentTestSession = { athleteId: null, attempts: [] };
|
||||
io.emit('session_ended');
|
||||
console.log(`Session ended`);
|
||||
res.json({ success: true });
|
||||
});
|
||||
|
||||
app.post('/api/admin/login', async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
try {
|
||||
const admin = await dbGet('SELECT * FROM admins WHERE username = ?', [username]);
|
||||
if (admin && password === admin.password) {
|
||||
res.json({ success: true, token: 'mock-admin-token', username: admin.username });
|
||||
} else {
|
||||
res.status(401).json({ success: false, message: 'Username atau Password salah' });
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: 'Database error' });
|
||||
}
|
||||
});
|
||||
|
||||
// Admin Management APIs
|
||||
app.get('/api/admin/users', async (req, res) => {
|
||||
try {
|
||||
const admins = await dbAll('SELECT id, username FROM admins');
|
||||
res.json(admins);
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/admin/users', async (req, res) => {
|
||||
const { username, password } = req.body;
|
||||
try {
|
||||
await dbRun('INSERT INTO admins (username, password) VALUES (?, ?)', [username, password]);
|
||||
res.json({ success: true, message: 'Admin baru ditambahkan' });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: 'Username sudah digunakan atau gagal simpan' });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete('/api/admin/users/:id', async (req, res) => {
|
||||
try {
|
||||
await dbRun('DELETE FROM admins WHERE id = ?', [req.params.id]);
|
||||
res.json({ success: true });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/admin/update-password', async (req, res) => {
|
||||
const { username, oldPassword, newPassword } = req.body;
|
||||
try {
|
||||
const admin = await dbGet('SELECT * FROM admins WHERE username = ?', [username]);
|
||||
if (!admin || oldPassword !== admin.password) {
|
||||
return res.status(400).json({ success: false, message: 'Password lama salah' });
|
||||
}
|
||||
await dbRun('UPDATE admins SET password = ? WHERE username = ?', [newPassword, username]);
|
||||
res.json({ success: true, message: 'Password berhasil diubah' });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: 'Gagal mengubah password' });
|
||||
}
|
||||
});
|
||||
|
||||
// Socket.io
|
||||
io.on('connection', (socket) => {
|
||||
console.log('Client connected', socket.id);
|
||||
|
||||
// Received from RFID reader (simulation)
|
||||
socket.on('rfid_scan', (tagId) => {
|
||||
console.log('RFID Scanned:', tagId);
|
||||
io.emit('rfid_scanned', tagId);
|
||||
});
|
||||
|
||||
// Received from Impact Sensor (simulation)
|
||||
// Stream for graph visualization
|
||||
socket.on('sensor_stream', (value) => {
|
||||
io.emit('sensor_live_data', value);
|
||||
});
|
||||
|
||||
// Impact detected (Peak value or significant hit)
|
||||
socket.on('impact_detected', async (forceValue) => {
|
||||
console.log('Impact detected:', forceValue);
|
||||
|
||||
if (currentTestSession.athleteId) {
|
||||
const athleteId = currentTestSession.athleteId;
|
||||
|
||||
// Save to DB
|
||||
try {
|
||||
await dbRun('INSERT INTO attempts (athlete_id, force) VALUES (?, ?)', [athleteId, forceValue]);
|
||||
|
||||
currentTestSession.attempts.push(forceValue);
|
||||
const attemptCount = currentTestSession.attempts.length;
|
||||
|
||||
io.emit('new_attempt_result', {
|
||||
force: forceValue,
|
||||
attemptNumber: attemptCount,
|
||||
athleteId
|
||||
});
|
||||
|
||||
if (attemptCount >= 3) {
|
||||
io.emit('test_milestone_reached', { athleteId, count: 3 });
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error saving attempt:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const PORT = 3000;
|
||||
server.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
});
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
const io = require('socket.io-client');
|
||||
|
||||
const socket = io('http://localhost:3000');
|
||||
|
||||
const tagId = process.argv[2] || 'TAG-' + Math.floor(Math.random() * 100000);
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('Connected to server as RFID Reader');
|
||||
console.log(`Scanning tag: ${tagId}`);
|
||||
socket.emit('rfid_scan', tagId);
|
||||
|
||||
setTimeout(() => {
|
||||
socket.disconnect();
|
||||
}, 1000);
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
const io = require('socket.io-client');
|
||||
|
||||
const socket = io('http://localhost:3000');
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('Connected to server as Impact Sensor');
|
||||
simulatePunch();
|
||||
});
|
||||
|
||||
function simulatePunch() {
|
||||
console.log('Simulating punch...');
|
||||
|
||||
// 1. Send low noise (idle)
|
||||
let steps = 0;
|
||||
const idleInterval = setInterval(() => {
|
||||
const noise = Math.random() * 5;
|
||||
socket.emit('sensor_stream', noise);
|
||||
steps++;
|
||||
|
||||
if (steps > 20) {
|
||||
clearInterval(idleInterval);
|
||||
sendImpact();
|
||||
}
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function sendImpact() {
|
||||
// 2. Send spike (Impact)
|
||||
let force = 0;
|
||||
const peak = 500 + Math.random() * 500; // Random peak between 500 and 1000
|
||||
let up = true;
|
||||
|
||||
const impactInterval = setInterval(() => {
|
||||
if (up) {
|
||||
force += 100;
|
||||
if (force >= peak) {
|
||||
force = peak;
|
||||
up = false;
|
||||
// Emit event at peak
|
||||
socket.emit('impact_detected', Math.round(peak));
|
||||
}
|
||||
} else {
|
||||
force -= 100;
|
||||
if (force <= 0) {
|
||||
force = 0;
|
||||
clearInterval(impactInterval);
|
||||
socket.emit('sensor_stream', 0);
|
||||
console.log(`Punch finished. Peak: ${Math.round(peak)}`);
|
||||
socket.disconnect(); // Or keep running for next punch
|
||||
}
|
||||
}
|
||||
socket.emit('sensor_stream', force);
|
||||
}, 20); // Fast update for impact
|
||||
}
|
||||
Loading…
Reference in New Issue