봇(챗봇) 관리 — 서비스별 구분 설계
작성 2026-06-17. 승인된 설계 정본. 봇을 솔루션(서비스)별로 구분해 관리·설정하는 기능. 관련: ADMIN-PLAN.md §4-13(봇 명세),
malgn-helper-admin/composables/use-bots.ts(현 데모 모델).
1. 목표·범위
- 봇을 서비스(솔루션)별로 나누어 관리하고, 각 봇의 서비스 구분을 설정할 수 있게 한다.
- 현재
use-bots.ts는 localStorage 데모 — 이를 실 백엔드(hp_bot+/admin/bots)로 전환한다. - 이번 범위 = 관리/설정. 봇을 실제 챗 파이프라인에서 사용하는 런타임은 Phase 2(범위 밖).
핵심 결정
- 봇 1개 = 서비스 1개 (서비스 입장 1:N — 한 서비스에 여러 봇 가능).
service_idnullable = NULL이면 공통(전 서비스) 봇.- 서비스 목록은
hp_service카탈로그(정본) 에서 가져온다. 프론트 하드코딩SERVICE_OPTS제거 → 기존 슬러그 불일치(lms-refund/lms-public… vs DBstep/lms-mixed/lms-private/lms-public-security…) 해소.
YAGNI / 연기
hp_bot_source다대다 자료(material) 연결은 연기:/materials백엔드가 아직 없음(materials.vue는 셸).materialSetIds는 이번 백엔드 스키마에서 제외. 자료 API 도입 시 후속.- 소스 결합은
use_standard_answers/standard_answer_scope플래그만 유지.
2. 데이터 (DBA) — hp_bot (마이그레이션 004_bots.sql)
단일 테이블. 운영 MySQL(PMS, 221.143.42.213)에 적용.
| 컬럼 | 타입 | 비고 |
|---|---|---|
id | PK auto | |
service_id | INT NULL, FK→hp_service.id | NULL = 공통 봇 |
name | VARCHAR | |
avatar | VARCHAR(8) | 이모지 1자 |
description | VARCHAR/TEXT | |
status | VARCHAR(16) | active/inactive/draft. 소프트삭제 컨벤션은 DBA 판단(예: deleted_at 또는 status='archived') — 기존 topics/services의 status=-1과 정합되게 결정·문서화 |
tone | VARCHAR(16) | formal/friendly/concise |
traits | JSON | 성격 태그 배열 |
greeting | TEXT | |
system_prompt | TEXT | |
visibility | VARCHAR(16) | public/internal |
unknown_policy | VARCHAR(16) | strict/normal/lenient |
escalation_threshold | DECIMAL(3,2) | 0~1 |
refusal_topics | JSON | |
topics | JSON | |
use_standard_answers | TINYINT(1) | |
standard_answer_scope | VARCHAR(16) | all/service |
model | VARCHAR | |
temperature | DECIMAL(3,2) | |
max_tokens | INT | |
created_at,updated_at | DATETIME |
- 인덱스:
service_id,status. UNIQUE는 불필요(이름 중복 허용). - 시드 2~3개 — 기존
hp_service슬러그에 맞춰(예:lms-general일반봇,lms-public-security보안봇, 공통봇 1).use-bots.tsSEED_BOTS의 슬러그(lms-refund등)를 그대로 쓰지 말 것.
3. API (malgn-helper-api) — /admin/bots
기존 가드·페이지네이션 컨벤션 준수.
| 메서드 | 라우트 | 가드 | 비고 |
|---|---|---|---|
| GET | /admin/bots?service_id=&status=&limit=&offset= | requireRole(developer) | {total,limit,offset,rows}, 각 row에 서비스명 조인. service_id= 빈값/common 으로 공통 필터 |
| GET | /admin/bots/:id | requireRole(developer) | 단건 |
| POST | /admin/bots | requireRole(admin) | 생성 |
| PATCH | /admin/bots/:id | requireRole(admin) | 수정 |
| DELETE | /admin/bots/:id | requireRole(admin) | 소프트삭제 |
- 라우트 등록 순서: 정적 경로가 파라미터 경로보다 먼저(기존 settings 사례 참고).
- JSON 컬럼(traits/refusal_topics/topics) 직렬화·역직렬화 처리.
service_id유효성: 존재하는hp_service이거나 NULL(공통)만 허용.- SQL은
LIMIT ? OFFSET ?바인딩. total은 동일 WHERE COUNT.
4. 관리자단 (malgn-helper-admin)
composables/use-bots.ts: localStorage → 실 API.Bot인터페이스 최대 보존하되services: string[]→serviceId: number|null(단일·공통)로 변경.materialSetIds는 UI에 남기되 백엔드 미전송(또는 숨김) — 연기 표시.SERVICE_OPTS하드코딩 제거,/services에서 동적 로드.pages/bots/index.vue: 서비스별 섹션 그룹핑(공통 섹션 + 서비스별 섹션) + 서비스 필터. 카드 그리드 유지. 페이지네이션은 서비스 필터와 함께(섹션 그룹핑이면 서비스별 로드 또는 전체 로드 후 그룹 — 데이터량 적으니 후자 허용).pages/bots/[id].vue: 에디터를 API(POST/PATCH/GET) 연동. 서비스 선택 드롭다운(공통 포함) = "구분 설정"의 핵심 UI. 저장/삭제 실연동.- 메뉴 게이트 해제:
composables/use-admin-menu.ts에서 봇 메뉴 숨김(planner가 백엔드 전까지 숨김 처리한 것) 해제. - 외부/DB/LLM 직접호출 금지 — 전부
/admin/bots경유.
5. 검증 (QA)
- typecheck/build(api·admin), 무인증 가드(401), 로그인 후 CRUD·서비스 그룹핑·공통/서비스 필터 동작(가능 범위).
- 회귀: 봇 외 화면 영향 없음, 슬러그 정본화로 catalog/standard-answers 영향 없는지.
6. 배포
dba(스키마 적용·시드) → api 배포 → admin 배포. 커밋·배포는 사용자 승인 후 deployer. 이력 기록.
7. 후속 (이번 범위 밖)
hp_bot_source자료 연결(materials API 이후).- 봇 챗 파이프라인 런타임 사용(Phase 2).
escalation_threshold(봇별) vs 전역confidence_threshold(hp_setting safety) 우선순위 정책(REQUIREMENTS Q1).