# InsuRo Pyright 에러 67건 근본 해결 — 헬퍼 함수 + 재발 방지

## 작업 레벨: Lv.2

## 프로젝트
- InsuRo: `/home/jay/projects/InsuRo`
- 서버: `/home/jay/projects/InsuRo/server`

## 배경 (Agent 미팅 합의)
- 미팅 기록: `/home/jay/workspace/memory/meetings/2026-04-28-pyright-root-cause.md`
- 4명 전원(로키/마아트/헤르메스/토르) 합의: B(헬퍼) + 재발 방지
- A(pyrightconfig 완화) 보안팀 거부권으로 채택 불가

## 수정 사항

### 1. server/sb_helpers.py 신규 생성
```python
"""Supabase 응답 타입 안전 헬퍼 — Pyright JSON 유니온 문제 근본 해결."""
from typing import Any, cast

def sb_rows(res: Any) -> list[dict[str, Any]]:
    """List 응답 → list[dict] 안전 캐스팅. 런타임 비용 0."""
    return cast(list[dict[str, Any]], getattr(res, 'data', None) or [])

def sb_first(res: Any) -> dict[str, Any] | None:
    """List 응답 첫 행 → dict 또는 None."""
    rows = sb_rows(res)
    return rows[0] if rows else None

def sb_single(res: Any) -> dict[str, Any] | None:
    """.single() 응답 → dict 또는 None."""
    data = getattr(res, 'data', None)
    return cast(dict[str, Any], data) if data else None
```

### 2. main.py 67건 일괄 수정
에러 발생 위치 (12 unique 라인):
- L4918: `ai_queue.create_job(user_id=...)` — user_id 타입 단언
- L5423~5439: `analyze-performance` — `sb_rows()` 적용
- L5511~5527: `analyze-customer` — `sb_rows()`, `sb_single()` 적용

패턴 변환:
```python
# 기존 (에러 발생)
contents = contents_resp.data or []
content_ids = [c["id"] for c in contents]

# 변경 (헬퍼 사용)
from sb_helpers import sb_rows, sb_first, sb_single
contents = sb_rows(contents_resp)
content_ids = [c["id"] for c in contents]
```

### 3. 기존 # type: ignore 정리
헬퍼 적용으로 불필요해진 `# type: ignore` 제거.

### 4. 검증
```bash
cd /home/jay/projects/InsuRo/server && pyright main.py 2>&1 | tail -3
# 목표: 0 errors
```

## affected_files
- `server/sb_helpers.py` (신규)
- `server/main.py` (수정 — 67건 헬퍼 적용)

## 검증 시나리오
1. `pyright main.py` → 0 errors
2. pytest 전량 통과
3. npm run build 성공
4. 서버 재시작 정상