refactor: DB 제거 → 단일 hackathon.json (JSON only)

DB(sqlite + WAL) 제거. 모든 state를 단일 JSON 파일로 통합.
일회용/내부용이라 유지보수성/확장성보다 단순성 우선.

변경:
- app.py: sqlite3 import 제거. load_data/save_data + threading.RLock + atomic write
  - votes: list of dict
  - titles, tie_breaks, settings: dict
  - people: roster (assign_teams가 채움)
  - 누락 키 자동 보강
- assign_teams.py: hackathon.json 단일 출력. 기존 votes/titles 보존
- Dockerfile/compose: votes.db volume 제거. hackathon.json read-write mount
- tests/e2e.py: 12개 (12/12 통과). load/save/insert_vote/clear_votes/atomic 추가
- README: 새 데이터 구조 문서화
- roster.json/participants.json 제거 (hackathon.json으로 통합)

호스트 편집 워크플로:
- jq/vi로 hackathon.json 직접 편집
- 앱 매 요청 reload — 컨테이너 재시작 불필요

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
th-kim0823
2026-04-26 18:25:46 +09:00
parent 6cfc75e3b8
commit 6e517be918
8 changed files with 413 additions and 530 deletions

View File

@@ -240,7 +240,7 @@ def main():
mapping[name] = team_name
print()
# roster.json (단일 파일, 호스트에서 직접 편집 가능)
# 단일 hackathon.json (모든 state 포함). 기존 파일 있으면 votes/titles 등 보존.
people_records = []
for i, team in enumerate(teams, 1):
team_name = f"{i}"
@@ -260,20 +260,31 @@ def main():
}
)
roster_path = Path(__file__).parent / "roster.json"
roster_path.write_text(
json.dumps({"people": people_records}, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"저장: {roster_path}")
data_path = Path(__file__).parent / "hackathon.json"
if data_path.exists():
data = json.loads(data_path.read_text(encoding="utf-8"))
else:
data = {
"settings": {"voting_open": True},
"titles": {},
"tie_breaks": {},
"votes": [],
}
data["people"] = people_records
# 누락 키 보강
for k, v in [
("settings", {"voting_open": True}),
("titles", {}),
("tie_breaks", {}),
("votes", []),
]:
data.setdefault(k, v)
# 구 형식 호환 (legacy participants.json 도 함께 저장 — 마이그레이션 기간)
out = Path(__file__).parent / "participants.json"
out.write_text(
json.dumps(mapping, ensure_ascii=False, indent=2),
data_path.write_text(
json.dumps(data, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"저장: {out} (legacy)")
print(f"저장: {data_path}")
# teams.md 박제 (진행자 인쇄/공유용)
md_lines = ["# 해커톤 팀 배정 (확정)\n"]