docs/qa에 정의된 149건이 자동화 스펙 파일에 151건 구현되어 커버리지는 100%입니다. 이 중 0건은 요구사항 변경으로 삭제, 0건은 UI 출시 대기, 3건은 수동 검증 영역입니다.
docs/qa 기준 모듈별 자동화 스펙 구현 진행률 — 이번 빌드 기준 100% 달성
docs/qa 151건의 모듈별 PASS · FAIL · 삭제 · 대기 · 수동 · 스킵 분포
OAuth · 이메일 인증 · SMS · PG 결제 · PDF 내용 등 자동화가 불가하거나 권장되지 않는 케이스
| TC-ID | 설명 | 수동 검증 이유 |
|---|---|---|
| LO-1-07 | 진짜 GitHub OAuth | 수동 검증 필요 — 자동화 불가 영역 |
| LO-1-08 | 진짜 Google OAuth | 수동 검증 필요 — 자동화 불가 영역 |
| SU-1-13 | 진짜 install.sh + launchctl | 수동 검증 필요 — 자동화 불가 영역 |
로그인 — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| LO-0-01 | PASS | 비로그인 /dashboard → /login |
| LO-0-02 | PASS | 비로그인 /team → /login |
| LO-0-03 | PASS | 비로그인 /setup-status → /login |
| LO-0-04 | PASS | 비로그인 /api/cli-auth → /login?callbackUrl=... |
| LO-0-05 | PASS | 비로그인 /member → /login |
| LO-1-01 | PASS | GitHub 버튼 visible + 텍스트 |
| LO-1-02 | PASS | Google 버튼 visible + 텍스트 |
| LO-1-03 | PASS | query string 없음 → 에러 박스 미렌더 |
| LO-1-04 | PASS | ?error=domain → 도메인 에러 박스 + 정확 텍스트 |
| LO-1-05 | PASS | ?error=db → 기타 에러 박스 + 정확 텍스트 |
| LO-1-06 | PASS | ?error=other → 기타 에러 박스 (default 분기) |
| LO-1-07 | 수동 | 진짜 GitHub OAuth |
| LO-1-08 | 수동 | 진짜 Google OAuth |
| LO-1-09 | PASS | mock 도메인 통과 → 세션 발급 |
| LO-1-10 | PASS | mock 도메인 미일치 → ?error=domain 리다이렉트 |
| LO-1-11 | PASS | auth.ts DB insert 실패 → ?error=db (route stub 으로 대체) |
| LO-1-12 | PASS | 이미 로그인 + /login 자체 접근 가능 |
| LO-1-13 | PASS | non-admin Nav 탭 3종 visible (개인/팀/셋업) |
| LO-1-14 | PASS | nav-user-toggle 클릭 → nav-logout visible |
| LO-1-15 | PASS | admin Nav 4탭 (개인/팀/팀원/셋업) |
셋업 — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| SU-0-01 | PASS | 비로그인 /setup → /login |
| SU-1-01 | PASS | UA Macintosh → 'macOS' + curl install |
| SU-1-02 | PASS | UA Windows → 'Windows' + irm install |
| SU-1-03 | PASS | UA Linux → 'Linux' (코드 fallback) + npx-cmd visible |
| SU-1-04 | PASS | setup-npx-cmd 정확 텍스트 |
| SU-1-05 | PASS | install 복사 → 클립보드 = setup-install-cmd 텍스트 |
| SU-1-06 | PASS | tz=Asia/Seoul context → setup-tz-select value 'Asia/Seoul' |
| SU-1-07 | PASS | tz 변경 → PATCH /api/user/timezone 발생 |
| SU-1-08 | PASS | not ready → step-hook visible (진행중) |
| SU-1-09 | PASS | ready → setup-go-dashboard visible + 텍스트 |
| SU-1-10 | PASS | setup-go-dashboard 클릭 → /dashboard URL |
| SU-1-11 | PASS | 폴링 2s — /api/setup/status 5.5초간 ≥2회 호출 |
| SU-1-12 | PASS | tz invalid → PATCH 400 |
| SU-1-13 | 수동 | 진짜 install.sh + launchctl |
| SU-1-14 | PASS | /api/setup/status 500 → setup-fetch-error + retry visible |
대시보드 (공유 — #3·#6·#7) — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| DB-0-01 | PASS | 비로그인 /dashboard → /login |
| DB-0-02 | PASS | P1 lastSyncedAt=null + 로그인 → /setup 리다이렉트 |
| DB-0-03 | PASS | non-admin /team/[userId]/dashboard → /team/[userId] |
| DB-0-04 | PASS | admin viewOnly 진입 + dash-overview-bar visible |
| DB-0-05 | PASS | non-admin /member → /dashboard 리다이렉트 |
| DB-0-06 | PASS | localStorage 셀렉터 복구 (admin) |
| DB-1-01 | PASS | loading visible (route delay) |
| DB-1-02 | PASS | /api/dashboard 500 → fetch-error + retry visible |
| DB-1-03 | PASS | retry 클릭 → 회복 |
| DB-1-04 | PASS | P7 sync-needed 박스 visible + sync-cmd 정확 텍스트 |
| DB-1-05 | PASS | sync 복사 → 클립보드 |
| DB-1-06 | PASS | admin viewOnly + overview=null stub → '아직 데이터가 없습니다' |
| DB-1-07 | PASS | period tab 5종 visible |
| DB-1-08 | PASS | period today 클릭 → /api/dashboard?period=today 요청 |
| DB-1-09 | PASS | period=today → day-offset dropdown visible |
| DB-1-10 | PASS | day-offset 선택 → /api/dashboard?dayOffset=1 요청 |
| DB-1-11 | PASS | 카드 12종 visible |
| DB-1-12 | PASS | overview-bar 비용 텍스트 양수 (period=all) |
| DB-1-13 | PASS | by-project 16개 → scroll 영역 |
| DB-1-14 | PASS | efficiency cache 91% → 양호 |
| DB-1-15 | PASS | cache=96 → 탁월 |
| DB-1-16 | PASS | cache=80 → 보통 |
| DB-1-17 | PASS | cache=59 → 경고 |
| DB-1-18 | PASS | cache=70 → 부족 |
| DB-1-19 | PASS | oneshot=0.95 → 탁월 |
| DB-1-23 | PASS | 메트릭 modal — 설명 버튼 클릭 |
| DB-1-25 | PASS | cost=0 → level 0 + fill #1e293b |
| DB-1-26 | PASS | cost=4.99 → level 1 + fill #4338ca |
| DB-1-27 | PASS | cost=24.99 → level 2 + fill #6366f1 |
| DB-1-28 | PASS | cost=99.99 → level 3 + fill #818cf8 |
| DB-1-29 | PASS | cost=100 → level 4 + fill #a5b4fc |
| DB-1-30 | PASS | dwell=0 → level 0 + fill #1e293b |
| DB-1-31 | PASS | dwell=119 → level 1 + fill #854d0e |
| DB-1-32 | PASS | dwell=299 → level 2 + fill #a16207 |
| DB-1-33 | PASS | dwell=899 → level 3 + fill #ca8a04 |
| DB-1-34 | PASS | dwell=900 → level 4 + fill #facc15 |
| DB-1-35 | PASS | mount 시 /api/visit POST |
| DB-1-36 | PASS | visibility hidden → visit-end POST |
| DB-1-37 | PASS | visit-end sec=-5 무시 (응답 200) |
| DB-1-38 | PASS | visit-end sec=20000 → 14400 cap 적용 (응답 200) |
| DB-1-39 | PASS | tz-btn 클릭 → tz-list visible |
| DB-1-40 | PASS | tz 선택 → PATCH /api/user/timezone |
| DB-1-41 | PASS | /member 셀렉터 멤버 목록 ≥ 3 |
| DB-1-42 | PASS | 셀렉터 선택 → localStorage 저장 |
| DB-1-43 | PASS | P8 admin + 본인 no snapshot → /setup 리다이렉트 |
| DB-1-44 | PASS | daily-cost length=46 → scroll 영역 (overflow-y-auto class) |
| DB-1-45 | PASS | top-sessions 6개 → 5 cap (5개만 렌더) |
| DB-1-46 | PASS | activity heatmap 26주 max (heatmapDaily 200개 → 26주 cap) |
| DB-1-47 | PASS | dailyTokens=[] no data 텍스트 |
| DB-1-48 | PASS | overview-missing → 4s 폴링 (>=2회 호출 in 9초) |
팀 랭킹 — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| TM-0-01 | PASS | 비로그인 /team → /login |
| TM-0-02 | PASS | P2 non-admin → engagement / top-sessions 미렌더 |
| TM-0-03 | PASS | P3 admin → engagement / top-sessions visible |
| TM-1-01 | PASS | period tab 5종 visible |
| TM-1-02 | PASS | period 8days 클릭 → /api/team?period=8days 요청 |
| TM-1-03 | PASS | summary-bar visible |
| TM-1-04 | PASS | byEfficiency 빈 응답 (route stub) → team-empty 메시지 |
| TM-1-05 | PASS | activity / cost 카드 visible (P2) |
| TM-1-06 | PASS | P2 alice cache 91 → efficiency 행 visible (양호) |
| TM-1-07 | PASS | bob cache=91 → cell title='양호' |
| TM-1-08 | PASS | carol cache=80 → cell title='보통' |
| TM-1-09 | PASS | dave cache=70 → cell title='부족' |
| TM-1-10 | PASS | eugene cache=50 → cell title='경고' |
| TM-1-11 | PASS | P4 bob (60h stale) → sync-badge yellow + '2일전' |
| TM-1-12 | PASS | P5 carol (8d stale) → sync-badge red + '⚠' |
| TM-1-13 | PASS | 미수신 배지 (lastSyncedAt=null user) |
| TM-1-14 | PASS | P6 dave (ccusage missing) → ccusage❌ 배지 + tooltip |
| TM-1-15 | PASS | admin 진입 → engagement 카드 헤더 'ADMIN' 배지 |
| TM-1-16 | PASS | engagement row + visits cell — P2 alice 양수 |
| TM-1-17 | PASS | P5 carol visits 0 → red class |
| TM-1-18 | PASS | P4 bob visits 2 → yellow class |
| TM-1-19 | PASS | P2 alice visits 5 → normal class (red/yellow 모두 아님) |
| TM-1-20 | PASS | top-sessions 응답 length ≤ 15 (서버 cap, supertest) |
| TM-1-21 | PASS | P2 fixture 30일 daily → industry card visible |
| TM-1-22 | PASS | industry-external — 외부 6 출처 텍스트 포함 |
| TM-1-23 | PASS | industry-ours — 5 percentile + active day 평균 |
| TM-1-24 | PASS | industry punch — multiplier 텍스트 (활용 팀) |
| TM-1-25 | PASS | industryComparison undefined → 카드 미렌더 |
| TM-1-26 | PASS | activeDayCount=0 → 카드 미렌더 |
| TM-1-27 | PASS | multiplier 3.0 정확 (activeDayAvg=39 stub) |
| TM-1-28 | PASS | by-member 차트 visible — dailyByMember stub |
| TM-1-29 | PASS | /api/team 500 → team-fetch-error + retry visible |
| TM-1-30 | PASS | engagement 정렬 — stale (P5) 우선 (lastSyncedAt 오래된 순) |
| TM-1-31 | PASS | stale 멤버 (P5 carol) cost 0 처리 |
멤버 프로필 — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| TP-0-01 | PASS | 비로그인 /team/10 → /login 리다이렉트 |
| TP-0-02 | PASS | 존재하지 않는 userId → API 404 + 화면 not-found 메시지 |
| TP-1-01 | PASS | summary-cost 텍스트 = $423.78 |
| TP-1-02 | PASS | summary-sessions 텍스트 = 92회 |
| TP-1-03 | PASS | summary-cache 텍스트 = 91% (정수 반올림) |
| TP-1-04 | PASS | summary-streak 양수 (30일 daily 전부 cost>0) |
| TP-1-05 | PASS | 4주 heatmap 카드 visible |
| TP-1-06 | PASS | projects 행 1~10개 (fixture 3개) |
| TP-1-07 | PASS | cost=0 → level 0 fill #1e293b |
| TP-1-08 | PASS | cost=4 → level 1 fill #4338ca |
| TP-1-09 | PASS | cost=24 → level 2 fill #6366f1 |
| TP-1-10 | PASS | cost=99 → level 3 fill #818cf8 |
| TP-1-11 | PASS | cost=100 → level 4 fill #a5b4fc |
| TP-1-12 | PASS | projects 11개 → 10 cap (route stub) |
| TP-1-13 | PASS | P2 시드 + 본인 (id=10) — snapshots 있으나 /team/10 정상 렌더 (P1 정의 자체는 sign-in 모순으로 대체 검증) |
| TP-1-14 | PASS | admin (id=12) 자기 프로필 — non-admin 과 동일 렌더 (#5 admin 분기 없음) |
| TP-1-15 | PASS | daily 모두 0 → streak=0 |
셋업 상태 — TC-ID · 결과 · 설명
| TC-ID | 결과 | 설명 |
|---|---|---|
| SS-0-01 | PASS | 비로그인 /setup-status → /login |
| SS-1-01 | PASS | P2 lastSyncedAt 신선 → status-overall '정상 작동 중' |
| SS-1-02 | PASS | P1 lastSyncedAt=null → '셋업 진행 중' |
| SS-1-03 | PASS | P5 lastSyncedAt 8일 → ⚠ 박스 visible |
| SS-1-04 | PASS | step 3종 visible |
| SS-1-05 | PASS | cli 명령 클립보드 복사 |
| SS-1-06 | PASS | stale-warning 텍스트 = '⚠️ 수집이 멈췄을 수 있어요' |
| SS-1-07 | PASS | stale 23h boundary → 미렌더 |
| SS-1-08 | PASS | stale 25h boundary → 렌더 |
| SS-1-09 | PASS | /api/setup/status 500 → fetch-error + retry visible |
| SS-1-10 | PASS | retry 클릭 → 회복 |
| SS-1-11 | PASS | status-faq-no-data 토글 |
| SS-1-12 | PASS | status-faq-reset-key 토글 |
| SS-1-13 | PASS | status-faq-backfill 토글 |
| SS-1-14 | PASS | status-faq-win-hook 토글 |