diff --git a/docs/superpowers/specs/2026-05-15-stock-lab-rename-to-stock.md b/docs/superpowers/specs/2026-05-15-stock-lab-rename-to-stock.md new file mode 100644 index 0000000..a66024d --- /dev/null +++ b/docs/superpowers/specs/2026-05-15-stock-lab-rename-to-stock.md @@ -0,0 +1,214 @@ +# stock-lab → stock 리네이밍 Design + +**작성일**: 2026-05-15 +**작성자**: gahusb +**상태**: Approved for implementation +**선행 spec**: Confidence Signal Pipeline V2 Phase 0 (`2026-05-15-confidence-signal-pipeline-v2-architecture.md`) + +--- + +## 1. 목표 + +`stock-lab` 컨테이너/디렉토리/환경변수의 `-lab` 접미사를 제거해 **stock** 으로 graduation. lab 네이밍 규칙 (`feedback_lab_naming.md`) 에 따라 정식 서비스로 명확화. + +본 리네이밍은 **Confidence Signal Pipeline V2 Phase 1** 작업 시작 전 선행. 이름이 stock-lab인 채로 Phase 1 spec/plan/code 가 작성되면 다시 갱신하는 비용 회피. + +**Why**: 메모리 `feedback_lab_naming.md` 정책 — "-lab은 개발/연구 단계에만, 정식 서비스에는 미사용". stock 서비스는 (a) 8 노드 screener 완성, (b) 캔버스 UI, (c) AI 뉴스 Phase 1, (d) V2 시그널 파이프라인의 중심 = 정식 graduation 단계. + +--- + +## 2. 범위 + +**포함**: +- web-backend 디렉토리 `git mv stock-lab stock` +- `docker-compose.yml` 4 곳 갱신 +- agent-office 환경변수 `STOCK_LAB_URL` → `STOCK_URL` 코드 + 컴포즈 +- nginx config (`nginx/default.conf` in web-backend repo) `upstream stock-lab` → `stock` +- 운영 문서 (`web-backend/CLAUDE.md`, `README.md`, `STATUS.md`, scripts) +- workspace `CLAUDE.md` + web-ui `CLAUDE.md` +- 메모리 4개 (`project_workspace.md`, `project_scale.md`, `project_stock_screener.md`, `nas_infra.md`) +- 메모리 정책 추가 (`feedback_lab_naming.md` 에 stock graduation 케이스 등재) + +**범위 외 (NOT)**: +- API URL 경로 (`/api/stock/...` 그대로) +- Python `app.*` import 경로 +- DB 파일명 (`stock.db` 그대로) +- frontend 라우트 (`/stock/*` 그대로) +- 다른 lab 의 이름 (lotto/music-lab/blog-lab/realestate-lab/packs-lab/travel-proxy 모두 그대로) +- 과거 spec/plan 문서 (`docs/superpowers/specs|plans/2026-05-*.md`) — 역사적 기록 유지 +- `.venv` 디렉토리 — gitignore, 사용자 로컬에서 재생성 + +--- + +## 3. 변경 매트릭스 + +### 3.1 web-backend 코드 (필수) + +| 파일 | 변경 | +|------|------| +| `stock-lab/` → `stock/` | `git mv` | +| `docker-compose.yml` | service key `stock-lab` → `stock` (1) / container_name `stock-lab` → `stock` (1) / build.context `./stock-lab` → `./stock` (1) / frontend.depends_on의 `stock-lab` → `stock` (1) | +| `agent-office/app/config.py` | `STOCK_LAB_URL = os.getenv("STOCK_LAB_URL", ...)` → `STOCK_URL = os.getenv("STOCK_URL", ...)` | +| `agent-office/app/service_proxy.py` | `from .config import STOCK_LAB_URL` → `STOCK_URL`. 함수 본문의 `STOCK_LAB_URL` 사용처 5개 (fetch_stock_news / fetch_stock_indices / summarize_stock_news / refresh_screener_snapshot / run_stock_screener) → `STOCK_URL` | +| `agent-office/app/agents/stock.py` | `STOCK_LAB_URL` 직접 참조 시 갱신 (만약 있다면) | +| `agent-office/tests/test_stock_screener_job.py` | mock URL 또는 env var 참조 갱신 | +| `agent-office docker-compose.yml 부분` | `STOCK_LAB_URL=http://stock-lab:8000` → `STOCK_URL=http://stock:8000` | +| `nginx/default.conf` | `upstream stock-lab { server stock-lab:8000; }` → `upstream stock { server stock:8000; }` + `proxy_pass http://stock-lab` → `http://stock` | +| `web-backend/CLAUDE.md` | stock-lab 언급 모두 stock 으로 | +| `web-backend/README.md` | 동일 | +| `web-backend/STATUS.md` | 동일 | +| `web-backend/scripts/deploy-nas.sh`, `deploy.sh` | stock-lab 호출/경로 갱신 | + +### 3.2 web-ui (문서만) + +| 파일 | 변경 | +|------|------| +| `web-ui/CLAUDE.md` | stock-lab 언급을 stock 으로 (디렉토리 경로 표 포함) | + +**과거 spec/plan 문서들** (`web-ui/docs/superpowers/specs|plans/2026-05-*.md`): 역사적 기록 유지 — **변경 없음**. + +### 3.3 workspace 최상위 + +| 파일 | 변경 | +|------|------| +| `workspace/CLAUDE.md` | "stock-lab" 컨테이너 이름 표 + 디렉토리 경로 갱신 | + +### 3.4 메모리 (controller 직접 적용) + +| 메모리 | 변경 | +|--------|------| +| `project_workspace.md` | stock-lab → stock | +| `project_scale.md` | 백엔드 서비스 표의 stock-lab 행 갱신, `stock-lab/` 디렉토리 → `stock/` | +| `project_stock_screener.md` | 다수 언급 (백엔드 위치) 갱신 | +| `nas_infra.md` | Docker 서비스 포트 표 + nginx 라우팅 | +| `feedback_lab_naming.md` | stock graduation 사례 추가 (2026-05-15) | + +--- + +## 4. 작업 순서 + +``` +1. 사전 검토 (10분) + - 본 spec 의 3장 매트릭스 모든 파일이 grep 결과와 일치하는지 cross-check + - `.venv` / `__pycache__` 제외 확인 + - nginx default.conf 의 정확한 변경 줄 식별 + +2. web-backend 디렉토리 + 컴포즈 + agent-office 코드 (한 commit) + - git mv stock-lab stock + - docker-compose.yml 4 곳 + - agent-office config.py, service_proxy.py, agents/stock.py, tests/ + - nginx/default.conf + - web-backend의 CLAUDE.md, README.md, STATUS.md, scripts/ + +3. workspace + web-ui CLAUDE.md (별도 commit, 각 repo) + - workspace/CLAUDE.md + - web-ui/CLAUDE.md + +4. 메모리 갱신 (controller 직접) + - 4개 메모리 파일 + feedback_lab_naming.md graduation 케이스 + +5. 배포 검증 + - web-backend push → Gitea webhook → deployer rsync + docker compose up + - docker logs stock --tail 30 + - docker ps 에서 stock 컨테이너 healthy + - curl https://gahusb.synology.me/api/stock/news (200) + - curl https://gahusb.synology.me/api/stock/screener/runs (200) + - agent-office 다음 16:30 cron 결과 (텔레그램) 정상 도착 확인 또는 수동 트리거 +``` + +--- + +## 5. 위험 및 완화 + +| 위험 | 완화 | +|------|------| +| nginx config 가 옛 호스트 `stock-lab` 으로 라우팅 → 502 | nginx config 도 같은 commit 에 포함. deployer rsync 가 web-backend repo 의 nginx 폴더를 NAS runtime 에 동기화 | +| agent-office 가 옛 환경변수 `STOCK_LAB_URL` 사용 → connection refused | 컴포즈의 환경변수 항목 동시 변경. agent-office 재기동 후 새 변수 적용 | +| `.env` 파일에 `STOCK_LAB_URL=...` 남아 있으면 새 변수 빈 값 → 기본값 `http://stock:8000` fallback | service_proxy 의 `os.getenv("STOCK_URL", "http://stock:8000")` default 확인. 운영 .env 갱신은 사용자 1회 작업 | +| 다른 lab 의 stock-lab 호출 누락 | grep `STOCK_LAB_URL` 결과 5개 파일 모두 commit 에 포함. 추가 누락 시 다음 cron 실패로 즉시 발견 | +| 컨테이너 교체 다운타임 | 약 10초 (docker compose up 의 stop+start). 1인 운영 + 비치명적, 허용 | +| Python `app.*` import 경로 회귀 | 디렉토리 이름만 변경. 빌드 컨텍스트 변경으로 도커 이미지 안의 app 패키지 그대로. 회귀 없음 (76 + 신규 테스트 전부 통과 검증) | +| 메모리 갱신 누락 | grep "stock-lab" / "STOCK_LAB" 메모리 폴더 0건 검증 | +| 과거 spec/plan 문서의 stock-lab 언급 | 역사적 기록 — 의도적 보존. 미래 spec 부터 stock 사용 | + +--- + +## 6. 테스트 / 검증 + +### 6.1 자동 (코드 검증) + +```bash +# stock-lab 잔여 참조 0건 (의도적 보존 spec/plan 제외) +grep -rln "stock-lab\|STOCK_LAB" /c/Users/jaeoh/Desktop/workspace/web-backend/ \ + | grep -v "\.venv" | grep -v "__pycache__" | grep -v "/docs/" | grep -v "\.git" +# Expected: 0 lines + +# agent-office 테스트 +cd /c/Users/jaeoh/Desktop/workspace/web-backend/agent-office +python -m pytest tests/test_stock_screener_job.py -v +# Expected: PASS + +# stock pytest +cd /c/Users/jaeoh/Desktop/workspace/web-backend/stock +python -m pytest --ignore=app/test_scraper.py -q +# Expected: 76+ tests passed +``` + +### 6.2 수동 (배포 검증) + +배포 후 NAS: +```bash +docker logs stock --tail 30 +docker logs agent-office --tail 20 +docker ps --format "{{.Names}}: {{.Status}}" | grep stock +``` + +브라우저 / curl: +- `https://gahusb.synology.me/api/stock/news` → 200 +- `https://gahusb.synology.me/api/stock/screener/runs` → 200 +- `https://gahusb.synology.me/stock/screener` (web-ui) → 캔버스 모드 진입 정상 + +agent-office 수동 트리거 (다음 cron 기다리지 않고): +```bash +curl -X POST "https://gahusb.synology.me/api/agent-office/command" \ + -H "Content-Type: application/json" \ + -d '{"agent":"stock","action":"run_ai_news"}' +``` +응답 `{"ok": true}` + 텔레그램 도착 → stock 호스트 라우팅 정상. + +--- + +## 7. 운영 영향 + +| 항목 | 영향 | +|------|------| +| 다운타임 | ~10초 (컨테이너 교체) | +| 사용자 영향 | 없음 (API URL/UI 경로 그대로) | +| .env 파일 갱신 | 사용자 1회 (STOCK_LAB_URL 줄 삭제 또는 STOCK_URL 추가) | +| frontend 재배포 | 불필요 (web-ui 는 문서만 변경) | +| 다른 lab 영향 | agent-office 만 영향 (환경변수). 나머지 lab 무영향 | + +--- + +## 8. Phase 1 와의 관계 + +본 리네이밍 완료 후 즉시 **Confidence Signal Pipeline V2 Phase 1** spec 작성 (이전 발표 디자인 그대로, 새 이름 `stock` 기준). 의존성: +``` +[본 리네이밍 spec/plan/실행] → [Phase 1 spec → plan → 실행] + 1-2시간 1주 +``` + +--- + +## 9. 완료 조건 (DoD) + +- [ ] `web-backend/stock-lab/` 디렉토리 사라지고 `stock/` 존재 (git history 보존) +- [ ] `docker-compose.yml` 의 4 곳 갱신 +- [ ] agent-office env 변수 `STOCK_LAB_URL` 코드/컴포즈/문서에서 0건 +- [ ] nginx config `upstream stock-lab` 0건, `upstream stock` 존재 +- [ ] grep "stock-lab" 결과: 의도적 보존 (`docs/superpowers/*`) 외 0건 +- [ ] stock pytest 76+ tests passed +- [ ] 배포 후 `docker ps` 에 `stock` 컨테이너 healthy +- [ ] curl `/api/stock/news`, `/api/stock/screener/runs` 200 +- [ ] agent-office `run_ai_news` 수동 트리거 텔레그램 도착 +- [ ] 메모리 4 파일 갱신 + `feedback_lab_naming.md` graduation 케이스 등재