씩씩이

씩씩이 — 개발 핸드오프 운영 전환

스테이징에서 동작 중인 사장님 AI를 운영으로 넘기기 위한 개발 문서

작성 2026-06-25 · 작성자 morty · 대상 개발팀

0개요

‘씩씩이’는 사장님의 실제 발주 데이터를 분석해 메뉴 재료·최저가·발주 타이밍을 안내하는 식자재 발주 AI입니다. 현재 스테이징에서 정상 동작하며, 파일럿(사장님 ~50명, 약 2주)을 위해 운영 전환이 필요합니다.

이 문서는 운영 전환에 필요한 아키텍처 · 실행법 · 시크릿 · 식별 주입 지점 · 보안 게이트 · 알려진 한계 · 배포 체크리스트를 담습니다. 분석·추천·테넌트 격리 로직은 이미 사장님(member_id) 단위로 구현되어 있어, 핵심 작업은 ‘로그인 사용자 식별 주입 + 보안/배포’입니다.

1아키텍처

[사장님 브라우저] │ (단일 origin, /api/* 프록시) ▼ [Next.js 16 프론트] ──/api/*──▶ [FastAPI 백엔드] · 챗 UI / 어드민 │ ├─ reference 두뇌 import (cards·llm·storage) │ ├─ 채팅 로그 DB (SQLite: 세션·메시지·피드백·추천큐) │ ├─ STG 발주 DB (PostgreSQL, 읽기전용) ── 발주 이력·카탈로그·가격 │ └─ BizRouter (Anthropic 호환) ── Claude Haiku
구성스택역할
프론트Next.js 16 · shadcn/ui · Turbopack챗/어드민 UI. next.config.ts rewrite로 /api/*를 백엔드에 프록시(단일 origin)
백엔드FastAPI · uvicorn (:8000)SSE 챗, 추천/피드백/세션, 어드민 집계. app/brain.py가 reference 두뇌를 import
두뇌reference/ (v1 파이썬)카드 라우팅·핸들러, 프롬프트, DB 접근. 백엔드가 그대로 재사용
채팅 로그 DBSQLite (storage/db)세션·메시지·라우팅로그·피드백·추천큐
발주 DBSTG PostgreSQL발주 이력·상품 카탈로그·가격 (읽기전용)
LLMBizRouter → Claude HaikuAnthropic 호환 게이트웨이

레포: ~/Documents/orderhero-ai-v2 (git, main). 구조: frontend/ · backend/ · reference/.

2레포 & 로컬 실행

백엔드

cd backend && source venv/bin/activate && uvicorn app.main:app --port 8000

프론트

cd frontend && npm install && npm run build && npm run start (개발: npm run dev)

주요 경로내용
backend/app/routes/chat.pyPOST /api/chat (SSE)
backend/app/routes/{sessions,admin}.py추천·피드백·세션·능동제안 / 어드민 집계
backend/app/deps.pyget_member_id — 식별 주입 지점 (4장)
reference/cards/router.py카드 라우팅(키워드 모드)
reference/cards/card1..6, recommendations.py카드 핸들러·추천 빌드
reference/storage/orders_repo.pySTG 발주/카탈로그/가격·집계
reference/storage/db.py채팅 로그 DB + 어드민 집계 쿼리
reference/llm/{client,anthropic_client}.pyLLM 스트리밍 / 도구 루프

3환경변수 & 시크릿

두 .env는 git에 올리지 않습니다(gitignore 유지). 운영에선 시크릿 매니저/환경변수로 주입하세요.

reference/.env (백엔드 두뇌)

값/설명
LLM_MODEreal (실 LLM) / mock(무료 오프라인)
ANTHROPIC_BASE_URLhttps://api.bizrouter.ai (BizRouter 게이트웨이)
MODEL_NAMEclaude-haiku-4-5-20251001
ANTHROPIC_API_KEYBizRouter 키 (sk-br-…) — 재발급 필요
ORDERS_SOURCEstg_db
ROUTER_MODEkeyword (LLM 분류 호출 없음 → 빠름/저비용)
STG_DB_*STG PostgreSQL 접속(host/port/name/user/password) — 재발급 필요

frontend/.env.local

  • NEXT_PUBLIC_API_BASE = 빈 값(같은 origin 프록시). 직접 백엔드 지정 시만 채움
  • NEXT_PUBLIC_MEMBER_ID = 0000003268 (스테이징 단일 사장님 — 운영에선 제거, 4장 참조)
🔴 시크릿 로테이트. BizRouter API 키·STG 자격증명은 데모 과정에서 노출 이력이 있습니다. 운영 전 반드시 재발급하고 시크릿 매니저로 관리하세요. (이 문서엔 실제 값 미포함)

4식별 / 인증 — 운영 전환 핵심

백엔드는 사장님을 X-Member-Id 헤더에서 받습니다(app/deps.pyget_member_id). 코드 주석에 "운영 전환 시 실제 인증(JWT 클레임)으로 교체"로 명시돼 있습니다.

현재(스테이징): 프론트 NEXT_PUBLIC_MEMBER_ID(0000003268) ──X-Member-Id──▶ 백엔드 운영(전환 후): 앱 로그인 회원 idx ───────────────────────▶ X-Member-Id(또는 JWT claim) ──▶ 백엔드
  • 해야 할 일: 로그인한 사장님의 idx(member_id)X-Member-Id(또는 검증된 JWT 클레임)로 주입.
  • 그 외 분석·추천·어드민·테넌트 격리는 이미 member_id 단위로 동작 — 재작업 없음.
  • 격리: 요청마다 runtime_context.set_current_member()로 테넌트 고정. 도구 호출엔 member_id를 서버가 강제 주입(LLM 입력 신뢰 안 함).
  • 노출 대상: 파일럿 50명만. 로그인/접근 권한에서 게이팅(앱 측).
✅ 식별만 꽂으면 끝나는 깨끗한 seam입니다. 분석 로직은 손대지 않아도 50명이 각자 정확히 분리됩니다.

5데이터 소스

  • STG 발주 DB (PostgreSQL, 읽기전용) — order_placement(created_at, target_seller_id/name, target_main_product_name, target_quantity, target_unit_price 등), 상품 카탈로그, seller_product_price_log(시장가 추이). 접속 실패 시 더미로 폴백.
  • 채팅 로그 DB — 현재 SQLite 파일(storage/db). 세션·메시지·피드백·추천큐·라우팅로그.
⚠️ 운영에서 백엔드를 다중 인스턴스로 띄우면 SQLite 파일은 부적합 → 관리형 Postgres 등으로 이전 권장. 발주 DB는 운영 STG/PROD 자격증명으로 교체.

6LLM · 비용

  • 게이트웨이 BizRouter(Anthropic 호환), 모델 Claude Haiku 4.5. Anthropic SDK의 base_url 오버라이드로 호출.
  • 라우팅은 키워드 모드라 분류용 LLM 호출이 없습니다(지연·비용 절감).
  • card3(메뉴추천)/card4(분석)만 추천 카드 생성. card3 응답 ~수십초(에이전트성) — 최적화 여지(10장).
  • 어드민 ‘비용·토큰’은 글자수 기반 추정치 — 정확 청구는 BizRouter 대시보드.

7API 계약

엔드포인트설명
POST /api/chat헤더 X-Member-Id, body {message, session_id?} → SSE 이벤트 meta·delta·cards·done·error
GET /api/proactive능동 제안(발주 타이밍·최저가) — 홈 배너 진입점 콘텐츠 소스
GET /api/cart · POST /api/recommendations장바구니 / 추천 담기
POST /api/feedback👍/👎 + VOC 텍스트
GET /api/sessions[/{id}/messages]대화 목록 · 복원
GET /api/admin/*dashboard·recommendations·voc·conversations·merchants·cost·routing·errors·prompts

모든 사용자 데이터 조회/쓰기는 X-Member-Id 기준으로 스코프됩니다.

8카드 · 라우팅

카드역할추천카드
card1발주 이력(월별 총액·거래처/품목 TOP·등락) — Python 집계
card2시즌·시세(정성)
card3메뉴 재료 추천✅ 담기
card4가격·재발주·최저가 비교✅ 담기/발주타이밍
card5운영 인사이트(패턴 변화)
card6발주 정산(발주액·예치금)
out_of_scope / blocked범위 밖 차단·안내

가드레일: 프롬프트 유출·주입 방어, 본인 데이터만(타 회원 요청 거절), 범위 밖 차단 — 마스터 페르소나에 명시.

9운영 전 필수 (Must-do)

🔴 어드민 인증. 현재 /admin·/api/admin/*인증이 없습니다. 운영 전 반드시 인증·권한(사내 전용)으로 보호하세요. (사장님 발주·VOC 데이터 노출)
🔴 시크릿 로테이트 — BizRouter 키·STG 자격증명 재발급 + 시크릿 매니저 (3장).
⚠️ 식별 주입 — 로그인 idx → X-Member-Id (4장).
⚠️ 채팅 로그 DB — 다중 인스턴스면 SQLite→Postgres (5장).
⚠️ 진입점 디자인 — 홈 상단 ‘씩씩이 제안 배너’ 비주얼(오더히어로 톤). 콘텐츠는 /api/proactive가 공급.

10알려진 한계 & TODO

항목내용상태
카탈로그 매칭일부 품목 매칭 부정확(예: ‘김치’→‘김치만두’ — 깔끔한 매칭 상품이 카탈로그에 없을 때)개선
발주액 소스 정합‘이번 달 발주액’이 card1(order_placement 합)과 card6(정산 this_month)에서 다를 수 있음 — 소스 일원화 필요정합
card3 본문↔카드스트리밍 본문을 SSoT로 재사용하도록 수정됨(이중 LLM 루프 제거)완료
응답 속도(card3)에이전트성 ~21초 — 프롬프트 캐싱·도구 병렬·DB 연결 풀링으로 추가 단축 여지최적화
DB 연결 풀링요청마다 psycopg2.connect(원격 재연결) — 운영 시 풀링 권장최적화
비용 지표글자수 기반 추정 — 정확값은 BizRouter참고

11배포 체크리스트

  • ☐ 프론트 호스팅(예: Vercel/CF Pages) + 백엔드 호스팅(서버/컨테이너, uvicorn)
  • ☐ 채팅 로그 DB → 관리형 Postgres(다중 인스턴스 시)
  • ☐ 시크릿 매니저로 BizRouter 키·STG 자격증명 주입(+로테이트)
  • 어드민 인증 적용
  • ☐ 로그인 idx → X-Member-Id 주입, NEXT_PUBLIC_MEMBER_ID 제거
  • ☐ 파일럿 50명만 접근 게이팅
  • ☐ 홈 상단 진입 배너 비주얼 + /api/proactive 연결
  • ☐ 도메인·HTTPS·모니터링(에러·비용)

오더히어로 사장님 AI ‘씩씩이’ · 개발 핸드오프 · 문의 morty
현 코드/스냅샷 기준이며 진행에 따라 갱신됩니다.