# task-637.1 완료 보고서: 대시보드 TODO 자동 동기화 시스템 구축

## SCQA

**S**: todo.json은 수동 관리로, 602건의 완료 태스크(task-timers.json)가 todo.json의 sub_items에 자동 반영되지 않아 대시보드 진행 상태가 실제와 불일치했다.

**C**: issue-007(Remotion 파이프라인), issue-010(Cloudflare /crawl) 등 진행 완료된 Phase가 전부 done=false로 표시되어 있었고, 향후 태스크 완료 시에도 수동 갱신이 필요한 상황이었다.

**Q**: 태스크 완료 시 todo.json이 자동 동기화되고, 과거 완료분도 소급 적용할 수 있는가?

**A**: todo_sync.py 유틸리티 구현 + notify-completion.py 연동으로 자동 동기화 파이프라인 구축 완료. retroactive_sync로 2건 소급 동기화 성공. pytest 29건 전체 통과, pyright 에러 0건.

## 생성/수정 파일 목록

- `/home/jay/workspace/utils/todo_sync.py` (신규) — 핵심 동기화 유틸리티
- `/home/jay/workspace/tests/test_todo_sync.py` (신규) — 단위 테스트 10개
- `/home/jay/workspace/scripts/notify-completion.py` (수정) — sync_task_completion 연동 추가
- `/home/jay/workspace/memory/todo.json` (수정) — retroactive_sync로 2건 동기화
- `/home/jay/workspace/memory/reports/todo-unmatched.md` (신규) — 미매칭 항목 보고서

## 테스트 결과

- test_todo_sync.py: **10/10 PASS** (0.06s)
- test_notify_completion.py: **19/19 PASS** (기존 테스트 회귀 없음)
- pyright: **0 errors, 0 warnings** (todo_sync.py, notify-completion.py, test_todo_sync.py)

## 구현 상세

### todo_sync.py 핵심 로직
- **sync_task_completion(task_id)**: 2단계 매칭 전략
  - 전략 1 (직접 매칭): sub_item.task_id == task_id → done=true
  - 전략 2 (linked_tasks 매칭): issue.linked_tasks에 task_id 포함 시 → 미완료 sub_item 첫 번째에 자동 연결
- **retroactive_sync()**: task-timers.json의 completed 태스크 602건 전수 스캔 → 매칭 2건 동기화
- **link_task_to_issue()**: 수동 태스크↔이슈 연결 CLI

### 안전장치
- .bak 백업 생성 (수정 전 상태 보존)
- fcntl 파일 락 (동시 수정 방지)
- 단방향 done=true (되돌리기 불가)
- last_synced 타임스탬프 기록

### notify-completion.py 연동
- 파일 상단에 `from utils.todo_sync import sync_task_completion` (ImportError safe)
- main()에서 체인 체크 전에 sync_task_completion(task_id) 호출
- 실패 시 WARNING 출력 후 기존 플로우 계속 진행 (비차단)

### 대시보드 연동
- dashboard/server.py는 todo.json을 직접 `json.load()`로 읽으므로 별도 수정 불필요
- 동기화된 데이터가 대시보드에 즉시 반영됨 (캐시 없음)

## retroactive_sync 실행 결과

- 스캔 대상: 602건 (completed)
- 자동 매칭: **2건**
  1. issue-007 "Phase 0: 환경 셋업" ← task-434.1 (linked_tasks 매칭)
  2. issue-010 "Phase 1: PoC" ← task-492.1 (linked_tasks 매칭)
- 미매칭 사유: 대부분의 sub_items에 task_id=None (아직 태스크 위임 미착수), 상세 → `memory/reports/todo-unmatched.md`

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **todo.json sub_items에 task_id 필드 부재** — task_id 필드가 없는 sub_items(issue-015~023)는 매칭 스킵 처리. 기존 구조 변경 없이 호환 유지.
2. **notify-completion.py에 utils 경로 미등록** — sys.path.insert(0, WORKSPACE_ROOT)로 해결. try/except로 ImportError safe하게 처리.
3. **linked_tasks 매칭 시 다수 미완료 sub_item 중 선택 모호성** — task_id=None인 첫 번째 미완료 sub_item에 자동 연결하는 전략 채택. 정확한 매칭이 필요하면 link_task_to_issue로 수동 연결.

### 범위 외 미해결 (1건)
1. **602건 완료 태스크 중 대부분이 todo.json에 연결 안 됨** — 범위 외 사유: todo.json의 sub_items 대부분이 미착수 항목(task_id=None)이며, 완료 태스크가 어느 sub_item에 해당하는지 자동 판별 불가. 향후 태스크 위임 시 link_task_to_issue로 명시적 연결 필요.

## 기존 테스트 실패 (본 작업 범위 외)

⚠️ 기존 테스트 실패 1건 (본 작업 범위 외): `tests/test_group_chat.py::TestLoadPersonas::test_org_loads_expected_count`
- 증상: `assert 20 == 21` — 조직 구조 페르소나 수 불일치
- 원인: organization-structure.json 변경 후 테스트 미갱신 (기존 이슈)
- 본 작업에서 변경한 파일: utils/todo_sync.py, scripts/notify-completion.py, tests/test_todo_sync.py — 모두 group_chat 무관

## QC 셀프 체크
- [x] 1. 다른 파일 영향: notify-completion.py (연동 추가), todo.json (동기화)
- [x] 2. 엣지 케이스: 빈 todo.json, 이미 done 항목, 매칭 없는 경우, linked_tasks 매칭 등 10개 테스트로 커버
- [x] 3. 작업 지시 일치: Phase 1(모듈+연동+CLI+테스트) + Phase 2(소급+unmatched 보고서+대시보드) 전체 구현
- [x] 4. 에러 처리: ImportError safe, fcntl 락, .bak 백업
- [x] 5. 테스트 커버리지: 직접매칭/미매칭/이미done/전체완료/소급/수동연결/백업/단방향/linked_tasks 10케이스
- [x] 6. 발견 이슈: 3건 자체 해결, 1건 범위 외 명시
