feat: add DB reset button to dashboard

- POST /api/reset endpoint: clears all tables and restarts log parser
- UI: Reset DB button in footer with confirmation dialog

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
21in7
2026-03-05 20:57:00 +09:00
parent f75ad9f6b1
commit 6f3ea44edb
2 changed files with 35 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ dashboard_api.py — 로그 파서가 채운 SQLite DB를 읽어서 대시보드
import sqlite3 import sqlite3
import os import os
import signal
from fastapi import FastAPI, Query from fastapi import FastAPI, Query
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from pathlib import Path from pathlib import Path
@@ -106,3 +107,21 @@ def health():
return {"status": "error", "detail": str(e)} return {"status": "error", "detail": str(e)}
@app.post("/api/reset")
def reset_db():
"""DB 전체 초기화 후 파서 재시작 (로그를 처음부터 다시 파싱)"""
with get_db() as db:
for table in ["trades", "daily_pnl", "parse_state", "bot_status", "candles"]:
db.execute(f"DELETE FROM {table}")
db.commit()
# 파서 프로세스 재시작 (entrypoint.sh의 백그라운드 프로세스)
import subprocess
# 기존 파서 종료
subprocess.run(["pkill", "-f", "log_parser.py"], capture_output=True)
# 새 파서 시작
subprocess.Popen(["python", "log_parser.py"])
return {"status": "ok", "message": "DB 초기화 완료, 파서 재시작됨"}

View File

@@ -621,12 +621,28 @@ export default function App() {
<div style={{ <div style={{
textAlign: "center", padding: "24px 0 8px", marginTop: 24, textAlign: "center", padding: "24px 0 8px", marginTop: 24,
borderTop: "1px solid rgba(255,255,255,0.03)", borderTop: "1px solid rgba(255,255,255,0.03)",
display: "flex", justifyContent: "center", alignItems: "center", gap: 16,
}}> }}>
<span style={{ fontSize: 10, color: "rgba(255,255,255,0.12)", fontFamily: S.mono }}> <span style={{ fontSize: 10, color: "rgba(255,255,255,0.12)", fontFamily: S.mono }}>
{lastUpdate {lastUpdate
? `Synced: ${lastUpdate.toLocaleTimeString("ko-KR")} · 15s polling` ? `Synced: ${lastUpdate.toLocaleTimeString("ko-KR")} · 15s polling`
: "API 연결 대기 중…"} : "API 연결 대기 중…"}
</span> </span>
<button
onClick={async () => {
if (!confirm("DB를 초기화하고 로그를 처음부터 다시 파싱합니다. 계속할까요?")) return;
try {
const r = await fetch("/api/reset", { method: "POST" });
if (r.ok) { alert("초기화 완료. 잠시 후 데이터가 다시 채워집니다."); location.reload(); }
else alert("초기화 실패: " + r.statusText);
} catch (e) { alert("초기화 실패: " + e.message); }
}}
style={{
fontSize: 10, fontFamily: S.mono, padding: "3px 10px",
background: "rgba(255,255,255,0.04)", color: "rgba(255,255,255,0.2)",
border: "1px solid rgba(255,255,255,0.06)", borderRadius: 6, cursor: "pointer",
}}
>Reset DB</button>
</div> </div>
</div> </div>