2026-04-11 개발 로그
세션 요약
역대급 생산성 날 — Sprint 1~9.5 일괄 처리 + Nexus Credits 런칭 준비
Loren /effort max + "ㄱㄱ 존나 중요한 작업" → 하루 단위 sprint 9개 (1, 2, 3, 4, 5, 6, 7, 8, 9, 9.5) 를 로컬→push→staging→prod 전부 완료. BYOK 폐기 + Nexus Credits 통합 결제 + 4단계 Role + Watchdog 확장 + 사용량 대시보드 + dashboard 리팩토링까지.
통계
- 커밋: 수십 개 (파일별 분리 커밋 원칙 준수)
- 신규 파일: 40+ (billing.js, 9 pages/*.js, i18n 분리, panels, migrations, etc)
- 500줄 한도 해소:
dashboard/index.html1214→254,board/i18n.js848→분리 - 남은 부채:
webhook/claude-bridge.js961 (P1), nginx drift (P0 결정 대기)
Sprint 1 — 블록 해제 ✅
목표: Vite vuln, subprocessors 링크, T71 verifyAdminAuth, T72 Sidebar
npm audit fix→ Vite 6.4.1→6.4.2 (high vuln 해소)subprocessors.md→subprocessors.ko.mdrename + 참조 3곳 업데이트- T71:
verifyAdminAuth에서company_admin제거 → super_admin only - T72: Sidebar AI팀/두뇌 메뉴
superAdminOnly플래그 - 두 repo 분리 커밋 + staging + prod 배포
부채 발견: #47 LegalPanel 에 subprocessors/dpa 링크 추가 (pending)
Sprint 2 — API 슬롯 준비 ✅
목표: 외부 API 5개 (mailer, alimtalk, biz-lookup, payments, tax-invoice) 모듈 + billing.js 신규
- 발견: 5개 모듈 전부 이미 구현되어 있음 —
config.EXTERNAL_FEATURES.{name}기반 폴백 완비. 키 주입만 하면 즉시 작동 - 신규:
modules/billing.js(335→461줄) — Nexus Credits 코어 (PLANS/TOPUP_PACKAGES/getBalance/deduct/topup/getHistory/setAutoTopup/calculateCost/canExecute/getMonthlyReport) - 신규:
config/token-rates.json— 10 모델 원가 요율 (+10% buffer) - 신규:
server/migrations/2026-04-11-nexus-credits.sql— billing_transactions 테이블 + companies plan enum 확장
Sprint 3 — 500줄 부채 정리 ✅
목표: board i18n.js 848줄 + PostDetail.jsx 576줄 분리
src/i18n/생성 → ko.js (491) + ja.js (482) + index.js (28 re-export)PostDetail.jsx576 → 249 +panels/(markdown 101 / StepProgress 130 / DeliveryList 124 / CommentThread 94)- Vite 빌드 검증 + 커밋 + push + 배포
Sprint 4 — Role 4단계 DB/서버 ✅
목표: super_admin / company_owner / company_admin / company_user 4단계 + 승인 플로우
- Migration:
users.roleENUM 4값 +status/approved_by/approved_at컬럼,invites.status/permissions/approval_note추가 - rls.js:
isCompanyOwner,isCompanyOwnerOrHigher,isCompanyAdminOrHigherhelper 추가 - signup.js: 첫 가입자 =
company_owner+pending_approval(ER_BAD_FIELD_ERROR fallback) - admin/invites.js: owner = 직원/관리자 초대, admin 승인 필요 / approve 엔드포인트 2개 (invites, users)
- staging + prod 마이그 실행 (wai_board 공유)
Sprint 5 — Role 4단계 클라 ✅
목표: board-approval-system UI 4단계 대응
- Sidebar.jsx: 4단계 재분류 + "결제" 메뉴 추가 (
companyOwnerOnly) - App.jsx:
/billinglazy import + BalanceBadge mount - BillingPage.jsx: placeholder 작성 (Sprint 7 에서 실구현)
- InvitePanel.jsx: 템플릿 버튼 2개 (직원/관리자) + 권한 토글 + status 뱃지
- i18n ko/ja
companyOwner키 동기화
Sprint 6 — Nexus Credits DB + 서버 ✅
목표: billing.js 실 wiring + cost-tracker 차감 + NEXUS_CREDITS_ENFORCE 플래그
plugins/board/billing.js신규 — HTTP dispatch (/billing/plans /balance /usage /topup /auto-topup /enterprise-inquiry /usage/report)plugins/board/dispatch.js신규 — approvals + billing 라우팅 체인 (index.js 500줄 한도 지키려)cost-tracker.js: companyId 파라미터 + billing.deduct hook (NEXUS_CREDITS_ENFORCE === 'true'일 때만)- claude-bridge.js 에 billing.init + /billing/* wiring
- TossPayments 공식 테스트 키 주입:
test_gck_docs_Ovk5rk1EwkEbP0W43n07xlzm/test_gsk_docs_OaPz8LKGPzuLAD1tbHd4dDWBD - hotfix: billing.getPool() →
require('../plugins/board/shared')직접 pool 참조 (초기 db_not_ready 에러)
Sprint 7 — Nexus Credits UI ✅
목표: BillingPage 실구현 + 상단바 뱃지 + 소진 경고 모달
BillingPage.jsx(315줄) — 4 탭 (플랜/충전/자동/이력) + Enterprise 문의 모달BalanceBadge.jsx(88줄) — 30초 polling, 상단바InsufficientCreditsModal.jsx(61줄) — 소진 경고lib/api.js— billing 함수 6개 (+Sprint 8 getUsageReport)- 빌드 + tar + scp + 서버 배포
- hotfix: test mode 감지 (
test_gck_docs_/test_gsk_docs_prefix) → topup 400 에러 해소
Sprint 8 — 사용량 대시보드 ✅
목표: 월간 사용량 리포트 + 직원/카테고리/에이전트 breakdown + 예측
- 서버:
GET /billing/usage/report?month=YYYY-MM+getMonthlyReport() - hotfix: MySQL SUM BIGINT →
Number()강제 변환 (clientfmtKrw깨짐) - 클라:
CostDashboard.jsx확장 — "이번 달 크레딧 사용량" 섹션 + Agent Top 10 바 차트 + 남은일 × 일일 평균 예측 - i18n ko/ja 사용량 키
Sprint 9 — Watchdog 확장 (TB-1) ✅
목표: watchdog.js 에 metric source type + 트리거 이력 persistent + dashboard 탭
modules/local-db.js:watchdog_triggers테이블 + 3 metric helper (agent_error_count,agent_avg_duration_ms,login_attempt_count)modules/watchdog.js:check.type === 'metric'분기 +recordWatchdogTriggerpersistent +runtimeToggleMap (재시작 시 초기화 의도)- HTTP handle:
/watchdog/rules,/triggers,/rules/:id/toggle— super_admin 전용 config/auto-evolution.json: 3 신규 metric rules (agent_error_spike, login_anomaly, agent_slow_response)dashboard/index.htmlWatchdog 탭 추가 (룰 관리 + 트리거 이력)- staging + prod 배포 — watchdog tick 로그 정상
주의: Sprint 9 에서 dashboard Watchdog 탭 HTML 만 검증했고 /api/watchdog/ nginx proxy 는 누락 → Sprint 9.5.1b 에서 발견
Sprint 9.5 — Dashboard JS 분리 ✅
목표: dashboard/index.html 1214줄 → 500줄 한도 맞추기
결과: 1214 → 254 (CSS + HTML + 초기 로드 script 태그 10개 + checkAuth bootstrap)
신규 파일 (11개):
dashboard/
├── index.html (254) ← HTML only + link/script 참조
├── styles.css (349) ← CSS 전체 분리
├── core.js (154) ← api/auth/nav/theme/mobile/escapeHtml/전역 state
└── pages/
├── overview.js (108) ← loadOverview + renderServices + renderAgents
├── agents.js (78) ← agentsCache + detail modal + filter
├── neurons.js (74) ← NeuronFS 7 region 렌더
├── monitor.js (66) ← /status + /events
├── creative.js (44) ← /image-gen
├── settings.js (46) ← /scores + /audit
├── sites.js (33) ← 사이트 목록 + /backup
└── watchdog.js (69) ← /watchdog/rules + /triggers + toggle
설계 결정: IIFE 해체 → 전역 스코프 통일. 페이지 함수 (loadX) 는 호출 시점 late-binding. Load 순서: core → pages → <script>checkAuth();</script> bootstrap.
커밋 12개 (파일별 분리):
d2246f7fix(nginx): /api/watchdog/ proxy location (Sprint 9 누락 hotfix)b0b6583refactor: styles.css 분리028a197refactor: core.js 분리96428c3refactor: pages/overview.js606fda2refactor: pages/agents.js77bc418refactor: pages/neurons.js4b3a84crefactor: pages/creative.jse2047c7refactor: pages/monitor.js5c60c6erefactor: pages/sites.js670ccd9refactor: pages/watchdog.js5c67927refactor: pages/settings.js9d4994drefactor: index.html 1214→254
Prod 배포 검증 (curl 11개 파일 모두 HTTP 200):
index.html: 200 (14226b)
styles.css: 200 (15769b)
core.js: 200 (6949b)
pages/*.js: 200 (9개, 사이즈 일치)
✅ Sprint 9.5.13 — Certbot-aware nginx split (옵션 D 채택, 해결)
Loren 선택 "장기로 지금 당장 정확하게 돌리고 잔여부채 없애야할듯" → 옵션 D (snippets/ include 패턴).
결과:
config/nginx-snippets/wai-proxy.conf신규 (231줄, 24 location union)config/nginx-snippets/README.md패턴 설명 + 배포 절차config/nginx-dashboard.conf삭제 (장식용 파일 제거)/etc/nginx/snippets/wai-proxy.conf프로덕션 배포/etc/nginx/sites-enabled/dashboard재작성 (100+줄 → 43줄) — Certbot SSL + server_name + root + php + hidden +include snippets/wai-proxy.conf;nginx -tOK +systemctl reload nginx무중단 (uptime 1주일 유지)- 백업:
/root/nginx-dashboard.bak.20260411-225600 - 커밋:
7201d2efeat(nginx): snippets/wai-proxy.conf 통합
검증 (24 routes 전수):
/api/watchdog/rules 200 → {"ok":true,"rules":[6개]}
/api/watchdog/triggers 200 → {"ok":true,"triggers":[]}
/api/audit 200 → {"ok":true,"logs":[…실로그]}
/api/image-gen/models 200 → {"models":{…5개}}
/api/erp/ 401 (proxy 경유, auth 대기)
/api/board/ 401 (proxy 경유, auth 대기)
/api/health 200 (기존 유지)
/api/status 200 (기존 유지)
/api/scores 200 (기존 유지)
/api/agents 200 (기존 유지)
/api/events 200 (기존 유지)
/api/board 200 (기존 유지)
/api/auth/me 401 (기존 유지)
/api/proxy/paljalab 200 (기존 유지)
/gateway/ 502 — OpenClaw 18789 OFF (Loren 의도적, 부채 아님)
참고: OpenClaw 18789 NOT LISTENING 은 Loren 의도적 OFF 상태 (4/11 확인). feedback_openclaw_resurrection.md 의 "복원 지시" 는 보류 중. 함부로 켜지 않음.
장기 운영 패턴:
- 프록시 추가/수정은
config/nginx-snippets/wai-proxy.conf편집 → push → 서버 pull → cp → reload /etc/nginx/sites-enabled/dashboard는 Certbot 관리, 건드리지 마- Certbot renew 해도 snippet 무관
🔴 Sprint 9.5.11 배포 중 발견 — Prod nginx config drift (해결 완료, 위 9.5.13)
심각도: P0 → 해결 — Sprint 9.5.13 옵션 D
현상:
- 로컬 repo
config/nginx-dashboard.conf(8012 bytes, HTTP +/api/watchdog/포함) - 서버 실제
/etc/nginx/sites-enabled/dashboard(4280 bytes, HTTPS + Certbot + 다른 webhook 세트) - 두 파일이 완전히 다름
prod 에만 있는 것 (덮어쓰면 날아감):
listen 443 ssl;+ Certbot 인증서 경로 (letsencrypt)- HTTP → HTTPS 301 리다이렉트
/api/a2a,/api/token-sync,/api/telegram-webhook,/api/user-telegram-webhookserver_name watoneai.cafe24.com _;(catch-all)php8.1-fpm.sock(repo 는 버전 없이)
repo 에만 있는 것 (prod 에 반영 필요):
/api/watchdog/← Sprint 9 에서 추가했지만 prod 반영 안됨/api/audit,/api/image-gen,/api/erp/,/api/board/,/gateway/location /(try_files 정적 서빙)
원인 추정: 과거에 서버에서 /etc/nginx/sites-enabled/dashboard 직접 편집한 이력 → 그 이후 repo 업데이트는 prod 에 sync 한 적 없음. Certbot 이 HTTPS 블록 managed.
영향받는 기능 (현재 prod 에서 동작 안 함):
- Dashboard Watchdog 탭 API 호출 전부
/api/audit,/api/image-gen,/api/erp/,/api/board/,/gateway/
결정 대기 — 4개 옵션:
- A: 풀 싱크 (repo → prod) — HTTPS + Certbot + 4 webhook 날아감. 매우 위험
- B: 서지컬 (prod 현재 파일에
/api/watchdog/블록만 추가) — 단기 추천. 하지만 drift 유지 - C: 풀 역동기 (prod → repo) — 정석. repo config 를 prod 실제로 업데이트 후 정식 배포
- D: Certbot-aware split —
snippets/wai-proxy.conf분리 +include패턴. 장기적으로 가장 깔끔
메모리: project_nginx_prod_drift.md 에 전체 분석 저장
남은 부채 (발견 시점 기록)
| # | 항목 | 우선순위 | 상태 |
|---|---|---|---|
| #47 | LegalPanel subprocessors/dpa 링크 | 🟢 P3 | pending |
| #111 | claude-bridge.js 961줄 500 한도 | 🟠 P1 | pending |
| #162 | nginx BRIDGE_TOKEN 평문 9곳 (이제 snippet 안) | 🟡 P2 (private repo 보류) | pending |
| ✅ 해결 (9.5.13 옵션 D) |
부채 아님: OpenClaw 18789 NOT LISTENING — Loren 의도적 OFF (4/11 확인). /gateway/ 502 는 정상 상태
핵심 교훈
- granular task = 가시성: Loren 이 "테스크 안띄움? 테스크도 만들라고" 극대노 → 이후 Sprint 9.5 는 서브스텝 12개 전부 TaskCreate. "지금 뭐 하는지" 명확해짐
- /effort max = 1회 최적화 승부: 뭉쳐서 9개 스프린트 한 번에 돌파. 중간 블로커 (billing pool, SUM 스트링, test mode, 500 한도) 를 hotfix 로 그때그때 해결
- 배포 후 실측 필수: curl HTTP 코드 + 사이즈 매칭 + 서비스 active 검증 없이는 "했습니다" 금지 (feedback_no_skip_verify.md)
- 드리프트는 침묵한다: prod nginx 가 repo 와 완전히 달랐는데 Sprint 9 배포 검증은 "dashboard HTML curl 200" 만 본 탓에 발견 못함. Sprint 9.5 에서 config 파일을 실제로 cat 해보기 전까지 몰랐음 → 이후 프로덕션 상태 인벤토리 정기 체크 필요
내일 이후 작업
- #163 nginx drift 결정 — Loren 응답 대기. 옵션 B 선택 시 즉시 dashboard Watchdog 탭 살아남
- Sprint 10 (브랜딩 통일) 또는 Sprint 11 (트라이얼/상한/알림톡)
- TB-5 NeuronFS 자동 기록 확장
- TB-6 뉴런 내용 보강 (NeuronFS 로컬 세팅 선행)
- #111 claude-bridge.js 961 리팩토링 (dispatch 패턴 확장)