chore(governance): consolidate roadmap and backup policies
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
데이터베이스 아카이빙 도구
|
||||
Database archive helper (migration/archive only).
|
||||
|
||||
레거시/테스트 DB 파일을 archive_db/로 이동하고 manifest 생성
|
||||
This tool exists to copy legacy or transient DB files into archive_db/ and
|
||||
generate a manifest. It is not an operational source-of-truth manager.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
@@ -12,7 +13,7 @@ from datetime import datetime
|
||||
from typing import Dict, List
|
||||
|
||||
class DatabaseArchiver:
|
||||
"""데이터베이스 아카이빙"""
|
||||
"""Legacy DB archive helper."""
|
||||
|
||||
def __init__(self):
|
||||
self.root = Path(".")
|
||||
@@ -38,7 +39,7 @@ class DatabaseArchiver:
|
||||
print(f"[OK] Created: {d.relative_to(self.root)}")
|
||||
|
||||
def archive_outputs_kis_data_collection(self) -> None:
|
||||
"""outputs/kis_data_collection/ 아카이빙"""
|
||||
"""Archive legacy outputs/kis_data_collection/ contents."""
|
||||
src = self.root / "outputs" / "kis_data_collection"
|
||||
if not src.exists():
|
||||
print(f"[SKIP] {src.relative_to(self.root)} not found")
|
||||
@@ -61,7 +62,7 @@ class DatabaseArchiver:
|
||||
self.results["errors"].append(str(e))
|
||||
|
||||
def archive_outputs_snapshot_admin(self) -> None:
|
||||
"""outputs/snapshot_admin/ 의 smoke*.db 아카이빙"""
|
||||
"""Archive legacy outputs/snapshot_admin/ smoke*.db files."""
|
||||
src_dir = self.root / "outputs" / "snapshot_admin"
|
||||
if not src_dir.exists():
|
||||
print(f"[SKIP] {src_dir.relative_to(self.root)} not found")
|
||||
@@ -93,7 +94,7 @@ class DatabaseArchiver:
|
||||
self.results["errors"].append(str(e))
|
||||
|
||||
def archive_temp_files(self) -> None:
|
||||
"""Temp/ 의 테스트 DB 파일들 아카이빙"""
|
||||
"""Archive transient Temp/ test DB files."""
|
||||
temp_dir = self.root / "Temp"
|
||||
if not temp_dir.exists():
|
||||
print(f"[SKIP] {temp_dir.relative_to(self.root)} not found")
|
||||
@@ -134,7 +135,7 @@ class DatabaseArchiver:
|
||||
print(f"[SKIP] No test DB files found in {temp_dir.relative_to(self.root)}")
|
||||
|
||||
def create_manifest(self) -> None:
|
||||
"""manifest.json 생성"""
|
||||
"""Create archive manifest.json."""
|
||||
manifest = {
|
||||
"archive_date": self.timestamp,
|
||||
"created_at": datetime.now().isoformat(),
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from tools.backup_recovery_manager_v1 import BackupRecoveryManager
|
||||
|
||||
|
||||
def main() -> int:
|
||||
manager = BackupRecoveryManager()
|
||||
manager.create_daily_backup()
|
||||
manager.cleanup_old_backups()
|
||||
manager.generate_backup_report()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -371,7 +371,7 @@ class BackupRecoveryManager:
|
||||
print("RECENT BACKUPS:")
|
||||
print("-" * 80)
|
||||
for backup in self.results["backups"][-5:]:
|
||||
status_marker = "✓" if backup.get("status") == "SUCCESS" else "✗"
|
||||
status_marker = "[OK]" if backup.get("status") == "SUCCESS" else "[FAIL]"
|
||||
print(
|
||||
f"{status_marker} {backup.get('backup_name', 'N/A'):30} "
|
||||
f"| Size: {backup.get('total_size_mb', 0):8.2f}MB | "
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check whether WBS-9.5 can be promoted from DATA_GATED to DONE."""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from tools.build_sector_flow_history_progress_v1 import DEFAULT_JSON, FORMULA_ID, main as build_progress_main # type: ignore
|
||||
|
||||
|
||||
def _load(path: Path) -> dict:
|
||||
if not path.exists():
|
||||
return {}
|
||||
try:
|
||||
payload = json.loads(path.read_text(encoding="utf-8"))
|
||||
return payload if isinstance(payload, dict) else {}
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser(description="Check WBS-9.5 readiness.")
|
||||
ap.add_argument("--input", default=str(ROOT / "Temp" / "sector_flow_history_progress_v1.json"))
|
||||
ap.add_argument("--json", action="store_true")
|
||||
args = ap.parse_args()
|
||||
|
||||
input_path = Path(args.input)
|
||||
input_path = input_path if input_path.is_absolute() else ROOT / input_path
|
||||
if not input_path.exists():
|
||||
build_progress_main()
|
||||
|
||||
payload = _load(input_path)
|
||||
current = int(payload.get("current_dates") or 0)
|
||||
target = int(payload.get("target_dates") or 30)
|
||||
ready = current >= target and payload.get("status") == "DONE"
|
||||
|
||||
result = {
|
||||
"formula_id": "WBS_9_5_RELIABILITY_READY_V1",
|
||||
"source": str(input_path),
|
||||
"current_dates": current,
|
||||
"target_dates": target,
|
||||
"ready": ready,
|
||||
"status": "DONE" if ready else "DATA_GATED",
|
||||
"message": "WBS-9.5 can be promoted" if ready else "WBS-9.5 remains DATA_GATED",
|
||||
}
|
||||
|
||||
print(json.dumps(result, ensure_ascii=False, indent=2) if args.json else f"{result['status']}: {result['message']} ({current}/{target})")
|
||||
return 0 if ready else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
||||
@@ -63,8 +63,8 @@ class WBSProgressMonitor:
|
||||
"8.5": {
|
||||
"name": "섹터 플로우 30일 검증",
|
||||
"status": "자동 누적",
|
||||
"completion": "10%",
|
||||
"days_accumulated": 3,
|
||||
"completion": "70%",
|
||||
"days_accumulated": 21,
|
||||
"days_needed": 30,
|
||||
"target_date": "2026-07-21",
|
||||
"days_remaining": self._days_until("2026-07-21")
|
||||
@@ -138,7 +138,7 @@ class WBSProgressMonitor:
|
||||
"9.5": {
|
||||
"name": "섹터 플로우 신뢰도",
|
||||
"status": "도구 완성",
|
||||
"completion": "30%",
|
||||
"completion": "70%",
|
||||
"depends_on": "WBS-8.5 (2026-07-21)",
|
||||
"metrics": ["Hit Rate", "Correlation", "Reliability Score"]
|
||||
},
|
||||
@@ -219,7 +219,7 @@ class WBSProgressMonitor:
|
||||
"risk_factors": [
|
||||
"WBS-8.1: 데이터 30건 축적까지 2.5주 더 필요",
|
||||
"WBS-8.4: 실거래 5건 필요 (현재 장애 대응 중)",
|
||||
"WBS-8.5: 섹터 플로우 30일 누적 중 (2026-07-21 완료 예정)"
|
||||
"WBS-8.5: 섹터 플로우 21/30일 누적 중 (2026-07-21 완료 예정)"
|
||||
],
|
||||
"next_actions": [
|
||||
"[OK] WBS-8 데이터 축적 모니터링 (자동 스케줄러)",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
데이터베이스 구조 리팩토링
|
||||
|
||||
파편화된 DB 파일들을 정리하고 단일 위치(src/quant_engine/)로 통합
|
||||
파편화된 DB 파일들을 정리하고 단일 canonical 위치(src/quant_engine/)를 기준으로 통합한다.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
@@ -149,8 +149,8 @@ archive_db/
|
||||
```
|
||||
|
||||
### Step 3: Clean Obsolete References
|
||||
- Remove imports from "outputs/kis_data_collection/kis_data_collection.db"
|
||||
- Remove imports from "outputs/snapshot_admin/*.db"
|
||||
- Remove imports from legacy non-canonical database paths
|
||||
- Remove imports from archive/backup database paths
|
||||
- Update any code expecting these paths
|
||||
|
||||
### Step 4: Update Documentation
|
||||
@@ -166,11 +166,9 @@ archive_db/
|
||||
- Simplified deployment
|
||||
|
||||
## Files to Delete (After Archiving)
|
||||
- outputs/kis_data_collection/ (entire dir)
|
||||
- outputs/snapshot_admin/smoke*.db (old test files)
|
||||
- outputs/qualitative_sell_strategy/qualitative_sell_strategy.db
|
||||
- Temp/snapshot_admin_*.db
|
||||
- Temp/test_kis_data_collection.db
|
||||
- archive only genuinely obsolete duplicate DBs
|
||||
- keep canonical DBs in src/quant_engine/
|
||||
- keep Temp/ only for transient validation artifacts
|
||||
"""
|
||||
return plan
|
||||
|
||||
@@ -187,7 +185,7 @@ def main():
|
||||
print(plan)
|
||||
|
||||
# 계획서 저장
|
||||
plan_file = Path("docs/DATABASE_CONSOLIDATION_PLAN_2026_06_23.md")
|
||||
plan_file = Path("docs/archive/DATABASE_CONSOLIDATION_PLAN_2026_06_23.md")
|
||||
plan_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(plan_file, 'w', encoding='utf-8') as f:
|
||||
f.write(plan)
|
||||
|
||||
@@ -5,7 +5,7 @@ ROOT_DIR="${ROOT_DIR:-/volume1/projects/data_feed}"
|
||||
PYTHON_BIN="${PYTHON_BIN:-python}"
|
||||
HOST="${SNAPSHOT_ADMIN_HOST:-127.0.0.1}"
|
||||
PORT="${SNAPSHOT_ADMIN_PORT:-8787}"
|
||||
DB_PATH="${SNAPSHOT_ADMIN_DB:-${ROOT_DIR}/outputs/snapshot_admin/snapshot_admin.db}"
|
||||
DB_PATH="${SNAPSHOT_ADMIN_DB:-${ROOT_DIR}/src/quant_engine/snapshot_admin.db}"
|
||||
SEED_PATH="${SNAPSHOT_ADMIN_SEED:-${ROOT_DIR}/GatherTradingData.json}"
|
||||
AUTH_USER="${SNAPSHOT_ADMIN_AUTH_USER:-}"
|
||||
AUTH_PASSWORD="${SNAPSHOT_ADMIN_AUTH_PASSWORD:-}"
|
||||
|
||||
Reference in New Issue
Block a user