# task-1080.1 완료 보고서: 대시보드 신호등 — 논리적 팀 상태 표시 수정

## SCQA

**S**: 대시보드 헤더의 신호등(봇 활동 표시)은 `_enrich_bot_activity()`가 `team_to_bot` 딕셔너리로 팀→봇 매핑하여 `has_running_tasks`를 결정한다. 논리적 팀(마케팅/컨설팅)은 `dispatch.py`가 가용 물리 봇을 동적 배정하며, task-timers.json에 `bot` 필드로 기록한다.

**C**: `team_to_bot`에 `dev1-team`~`dev8-team`만 존재하고 논리적 팀이 없어, marketing 작업이 bot-b에서 실행 중이어도 dev1 신호등이 꺼져 있었다. 또한 `LogicalTeamCard`의 멤버 상태 로직이 `runningCount`를 참조하지 않아 서브에이전트가 항상 'available'로 표시되었다.

**Q**: 논리적 팀이 물리 봇을 사용할 때 해당 봇의 신호등을 켜고, 서브에이전트 상태를 올바르게 표시할 수 있는가?

**A**: `_enrich_bot_activity()`에 `bot` 필드 기반 역매핑(bot-b→dev1 등)을 추가하고, `LogicalTeamCard`의 멤버 상태 결정 로직에 `runningCount > 0` 분기를 추가하여 해결. pytest 70건 중 69건 통과 (1건 기존 실패, 범위 외), pyright 에러 0건.

## 수정 내용

### 1. server.py — `_enrich_bot_activity()` (522-591줄)

기존 `team_to_bot` 매핑 이후, task-timers.json의 running task 중 `bot` 필드가 있는 것을 추가 처리하는 블록 삽입:

- `bot_to_dev_id` 매핑: `{"bot-b": "dev1", ..., "bot-i": "dev8"}`
- running + non-stale + bot 필드 있는 task → 해당 dev_id의 `has_running_tasks = True`
- stale 판단은 `STALE_TASK_RUNNING_SECONDS` 기준 동일 적용

### 2. utils.js — `LogicalTeamCard` (265-413줄)

**리드 상태 (294-299줄)**: break 상태 명시적 분기 추가 → break가 running task 여부와 무관하게 최우선 반영

**멤버 상태 (372-382줄)**: 비-composite 논리적 팀의 상태 결정에 `runningCount > 0` 고려:
- break → break (최우선)
- working → working (member-status.json 기반)
- runningCount > 0 → standby (팀에 작업 중)
- 그 외 → 기존 로직 유지

### 3. test_server.py — `TestEnrichBotActivity` 클래스 추가

- `test_logical_team_with_bot_field_sets_has_running_tasks`: marketing + bot=bot-b → dev1.has_running_tasks=True
- `test_logical_team_without_bot_field_does_not_affect_dev`: bot 필드 없음 → dev1.has_running_tasks=False
- `test_stale_bot_task_does_not_set_has_running_tasks`: 3시간 전 시작(stale) → dev1.has_running_tasks=False

## 수정 파일 목록

- `/home/jay/workspace/dashboard/server.py` — `_enrich_bot_activity()` 확장 (554-588줄 추가)
- `/home/jay/workspace/dashboard/components/utils.js` — `LogicalTeamCard` 상태 로직 수정 (294-299, 372-382줄)
- `/home/jay/workspace/dashboard/test_server.py` — `TestEnrichBotActivity` 테스트 클래스 추가

## 발견 이슈 및 해결

### 자체 해결 (3건)

1. **리드 break 상태 미분리** — `LogicalTeamCard`에서 비-composite 리드 상태가 `leadMsEntry?.status`를 OR로 처리하여 break가 running 상태에 덮일 수 있었음. 명시적 break 분기 추가로 해결.
2. **멤버 상태 runningCount 미참조** — 비-composite 멤버가 `msEntry?.status || m.status || 'available'`로만 결정되어 running task가 있어도 available로 표시됨. `runningCount > 0` 시 standby 분기 추가.
3. **bot_to_dev_id 매핑에서 bots 딕셔너리 미존재 케이스** — bot이 bots에 없을 때 새 항목 생성 로직 포함.

### 범위 외 미해결 (1건)

1. **`TestMemberStatusTimezone::test_timezone_aware_since_not_stuck_working` 기존 실패** — timezone Z suffix 처리 관련 기존 버그. 본 작업 범위 외.

## 테스트 결과

- pytest: 69 passed, 1 failed (기존 실패, 범위 외)
- pyright: 0 errors, 0 warnings, 0 informations
- black/isort: 적용 완료

⚠️ 기존 테스트 실패 1건 (본 작업 범위 외): `TestMemberStatusTimezone::test_timezone_aware_since_not_stuck_working`

## 대시보드 재시작

수정 반영을 위해 대시보드 서버 재시작이 필요합니다. 재시작 여부는 아누(개발실장) 판단에 위임합니다.
