[{"data":1,"prerenderedAt":854},["ShallowReactive",2],{"doc:\u002Fbots-plan":3},{"id":4,"title":5,"body":6,"description":830,"extension":847,"meta":848,"navigation":849,"path":850,"seo":851,"stem":852,"__hash__":853},"docs\u002FBOTS-PLAN.md","봇(챗봇) 관리 — 서비스별 구분 설계",{"type":7,"value":8,"toc":829},"minimark",[9,13,36,41,85,90,153,157,203,214,221,523,559,569,572,685,708,715,787,791,799,803,806,810],[10,11,5],"h1",{"id":12},"봇챗봇-관리-서비스별-구분-설계",[14,15,16],"blockquote",{},[17,18,19,20,24,25,30,31,35],"p",{},"작성 2026-06-17. 승인된 설계 정본. 봇을 ",[21,22,23],"strong",{},"솔루션(서비스)별로 구분","해 관리·설정하는 기능.\n관련: ",[26,27,29],"a",{"href":28},"ADMIN-PLAN","ADMIN-PLAN.md"," §4-13(봇 명세), ",[32,33,34],"code",{},"malgn-helper-admin\u002Fcomposables\u002Fuse-bots.ts","(현 데모 모델).",[37,38,40],"h2",{"id":39},"_1-목표범위","1. 목표·범위",[42,43,44,56,75],"ul",{},[45,46,47,48,51,52,55],"li",{},"봇을 ",[21,49,50],{},"서비스(솔루션)별로 나누어"," 관리하고, 각 봇의 ",[21,53,54],{},"서비스 구분을 설정","할 수 있게 한다.",[45,57,58,59,62,63,66,67,70,71,74],{},"현재 ",[32,60,61],{},"use-bots.ts","는 ",[21,64,65],{},"localStorage 데모"," — 이를 실 백엔드(",[32,68,69],{},"hp_bot"," + ",[32,72,73],{},"\u002Fadmin\u002Fbots",")로 전환한다.",[45,76,77,80,81,84],{},[21,78,79],{},"이번 범위 = 관리\u002F설정",". 봇을 실제 챗 파이프라인에서 ",[21,82,83],{},"사용","하는 런타임은 Phase 2(범위 밖).",[86,87,89],"h3",{"id":88},"핵심-결정","핵심 결정",[42,91,92,98,111],{},[45,93,94,97],{},[21,95,96],{},"봇 1개 = 서비스 1개"," (서비스 입장 1:N — 한 서비스에 여러 봇 가능).",[45,99,100,106,107,110],{},[21,101,102,105],{},[32,103,104],{},"service_id"," nullable"," = NULL이면 ",[21,108,109],{},"공통(전 서비스) 봇",".",[45,112,113,114,120,121,124,125,128,129,132,133,136,137,132,140,132,143,132,146,149,150,110],{},"서비스 목록은 ",[21,115,116,119],{},[32,117,118],{},"hp_service"," 카탈로그(정본)"," 에서 가져온다. 프론트 하드코딩 ",[32,122,123],{},"SERVICE_OPTS"," ",[21,126,127],{},"제거"," → 기존 슬러그 불일치(",[32,130,131],{},"lms-refund","\u002F",[32,134,135],{},"lms-public","… vs DB ",[32,138,139],{},"step",[32,141,142],{},"lms-mixed",[32,144,145],{},"lms-private",[32,147,148],{},"lms-public-security","…) ",[21,151,152],{},"해소",[86,154,156],{"id":155},"yagni-연기","YAGNI \u002F 연기",[42,158,159,189],{},[45,160,161,164,165,168,169,172,173,176,177,180,181,184,185,188],{},[32,162,163],{},"hp_bot_source"," 다대다 ",[21,166,167],{},"자료(material) 연결","은 ",[21,170,171],{},"연기",": ",[32,174,175],{},"\u002Fmaterials"," 백엔드가 아직 없음(",[32,178,179],{},"materials.vue","는 셸). ",[32,182,183],{},"materialSetIds","는 이번 백엔드 스키마에서 ",[21,186,187],{},"제외",". 자료 API 도입 시 후속.",[45,190,191,192,195,196,124,199,202],{},"소스 결합은 ",[32,193,194],{},"use_standard_answers"," \u002F ",[32,197,198],{},"standard_answer_scope",[21,200,201],{},"플래그만"," 유지.",[37,204,206,207,209,210,213],{"id":205},"_2-데이터-dba-hp_bot-마이그레이션-004_botssql","2. 데이터 (DBA) — ",[32,208,69],{}," (마이그레이션 ",[32,211,212],{},"004_bots.sql",")",[17,215,216,217,220],{},"단일 테이블. 운영 MySQL(PMS, ",[32,218,219],{},"221.143.42.213",")에 적용.",[222,223,224,240],"table",{},[225,226,227],"thead",{},[228,229,230,234,237],"tr",{},[231,232,233],"th",{},"컬럼",[231,235,236],{},"타입",[231,238,239],{},"비고",[241,242,243,256,273,285,298,310,344,356,369,381,392,404,416,429,440,451,462,473,484,495,507],"tbody",{},[228,244,245,251,254],{},[246,247,248],"td",{},[32,249,250],{},"id",[246,252,253],{},"PK auto",[246,255],{},[228,257,258,262,268],{},[246,259,260],{},[32,261,104],{},[246,263,264,265],{},"INT NULL, FK→",[32,266,267],{},"hp_service.id",[246,269,270],{},[21,271,272],{},"NULL = 공통 봇",[228,274,275,280,283],{},[246,276,277],{},[32,278,279],{},"name",[246,281,282],{},"VARCHAR",[246,284],{},[228,286,287,292,295],{},[246,288,289],{},[32,290,291],{},"avatar",[246,293,294],{},"VARCHAR(8)",[246,296,297],{},"이모지 1자",[228,299,300,305,308],{},[246,301,302],{},[32,303,304],{},"description",[246,306,307],{},"VARCHAR\u002FTEXT",[246,309],{},[228,311,312,317,320],{},[246,313,314],{},[32,315,316],{},"status",[246,318,319],{},"VARCHAR(16)",[246,321,322,132,325,132,328,331,332,335,336,339,340,343],{},[32,323,324],{},"active",[32,326,327],{},"inactive",[32,329,330],{},"draft",". 소프트삭제 컨벤션은 DBA 판단(예: ",[32,333,334],{},"deleted_at"," 또는 ",[32,337,338],{},"status='archived'",") — 기존 topics\u002Fservices의 ",[32,341,342],{},"status=-1","과 정합되게 결정·문서화",[228,345,346,351,353],{},[246,347,348],{},[32,349,350],{},"tone",[246,352,319],{},[246,354,355],{},"formal\u002Ffriendly\u002Fconcise",[228,357,358,363,366],{},[246,359,360],{},[32,361,362],{},"traits",[246,364,365],{},"JSON",[246,367,368],{},"성격 태그 배열",[228,370,371,376,379],{},[246,372,373],{},[32,374,375],{},"greeting",[246,377,378],{},"TEXT",[246,380],{},[228,382,383,388,390],{},[246,384,385],{},[32,386,387],{},"system_prompt",[246,389,378],{},[246,391],{},[228,393,394,399,401],{},[246,395,396],{},[32,397,398],{},"visibility",[246,400,319],{},[246,402,403],{},"public\u002Finternal",[228,405,406,411,413],{},[246,407,408],{},[32,409,410],{},"unknown_policy",[246,412,319],{},[246,414,415],{},"strict\u002Fnormal\u002Flenient",[228,417,418,423,426],{},[246,419,420],{},[32,421,422],{},"escalation_threshold",[246,424,425],{},"DECIMAL(3,2)",[246,427,428],{},"0~1",[228,430,431,436,438],{},[246,432,433],{},[32,434,435],{},"refusal_topics",[246,437,365],{},[246,439],{},[228,441,442,447,449],{},[246,443,444],{},[32,445,446],{},"topics",[246,448,365],{},[246,450],{},[228,452,453,457,460],{},[246,454,455],{},[32,456,194],{},[246,458,459],{},"TINYINT(1)",[246,461],{},[228,463,464,468,470],{},[246,465,466],{},[32,467,198],{},[246,469,319],{},[246,471,472],{},"all\u002Fservice",[228,474,475,480,482],{},[246,476,477],{},[32,478,479],{},"model",[246,481,282],{},[246,483],{},[228,485,486,491,493],{},[246,487,488],{},[32,489,490],{},"temperature",[246,492,425],{},[246,494],{},[228,496,497,502,505],{},[246,498,499],{},[32,500,501],{},"max_tokens",[246,503,504],{},"INT",[246,506],{},[228,508,509,518,521],{},[246,510,511,514,515],{},[32,512,513],{},"created_at",",",[32,516,517],{},"updated_at",[246,519,520],{},"DATETIME",[246,522],{},[42,524,525,534],{},[45,526,527,528,530,531,533],{},"인덱스: ",[32,529,104],{},", ",[32,532,316],{},". UNIQUE는 불필요(이름 중복 허용).",[45,535,536,539,540,542,543,546,547,549,550,124,552,555,556,558],{},[21,537,538],{},"시드 2~3개"," — 기존 ",[32,541,118],{}," 슬러그에 맞춰(예: ",[32,544,545],{},"lms-general"," 일반봇, ",[32,548,148],{}," 보안봇, 공통봇 1). ",[32,551,61],{},[32,553,554],{},"SEED_BOTS","의 슬러그(",[32,557,131],{}," 등)를 그대로 쓰지 말 것.",[37,560,562,563,566,567],{"id":561},"_3-api-malgn-helper-api-adminbots","3. API (",[32,564,565],{},"malgn-helper-api",") — ",[32,568,73],{},[17,570,571],{},"기존 가드·페이지네이션 컨벤션 준수.",[222,573,574,589],{},[225,575,576],{},[228,577,578,581,584,587],{},[231,579,580],{},"메서드",[231,582,583],{},"라우트",[231,585,586],{},"가드",[231,588,239],{},[241,590,591,620,636,653,669],{},[228,592,593,596,601,606],{},[246,594,595],{},"GET",[246,597,598],{},[32,599,600],{},"\u002Fadmin\u002Fbots?service_id=&status=&limit=&offset=",[246,602,603],{},[32,604,605],{},"requireRole(developer)",[246,607,608,611,612,615,616,619],{},[32,609,610],{},"{total,limit,offset,rows}",", 각 row에 서비스명 조인. ",[32,613,614],{},"service_id="," 빈값\u002F",[32,617,618],{},"common"," 으로 공통 필터",[228,621,622,624,629,633],{},[246,623,595],{},[246,625,626],{},[32,627,628],{},"\u002Fadmin\u002Fbots\u002F:id",[246,630,631],{},[32,632,605],{},[246,634,635],{},"단건",[228,637,638,641,645,650],{},[246,639,640],{},"POST",[246,642,643],{},[32,644,73],{},[246,646,647],{},[32,648,649],{},"requireRole(admin)",[246,651,652],{},"생성",[228,654,655,658,662,666],{},[246,656,657],{},"PATCH",[246,659,660],{},[32,661,628],{},[246,663,664],{},[32,665,649],{},[246,667,668],{},"수정",[228,670,671,674,678,682],{},[246,672,673],{},"DELETE",[246,675,676],{},[32,677,628],{},[246,679,680],{},[32,681,649],{},[246,683,684],{},"소프트삭제",[42,686,687,690,693,701],{},[45,688,689],{},"라우트 등록 순서: 정적 경로가 파라미터 경로보다 먼저(기존 settings 사례 참고).",[45,691,692],{},"JSON 컬럼(traits\u002Frefusal_topics\u002Ftopics) 직렬화·역직렬화 처리.",[45,694,695,697,698,700],{},[32,696,104],{}," 유효성: 존재하는 ",[32,699,118],{},"이거나 NULL(공통)만 허용.",[45,702,703,704,707],{},"SQL은 ",[32,705,706],{},"LIMIT ? OFFSET ?"," 바인딩. total은 동일 WHERE COUNT.",[37,709,711,712,213],{"id":710},"_4-관리자단-malgn-helper-admin","4. 관리자단 (",[32,713,714],{},"malgn-helper-admin",[42,716,717,749,760,772,781],{},[45,718,719,724,725,728,729,732,733,738,739,741,742,744,745,748],{},[21,720,721],{},[32,722,723],{},"composables\u002Fuse-bots.ts",": localStorage → 실 API. ",[32,726,727],{},"Bot"," 인터페이스 최대 보존하되 ",[32,730,731],{},"services: string[]"," → ",[21,734,735],{},[32,736,737],{},"serviceId: number|null","(단일·공통)로 변경. ",[32,740,183],{},"는 UI에 남기되 백엔드 미전송(또는 숨김) — 연기 표시. ",[32,743,123],{}," 하드코딩 제거, ",[32,746,747],{},"\u002Fservices","에서 동적 로드.",[45,750,751,172,756,759],{},[21,752,753],{},[32,754,755],{},"pages\u002Fbots\u002Findex.vue",[21,757,758],{},"서비스별 섹션 그룹핑","(공통 섹션 + 서비스별 섹션) + 서비스 필터. 카드 그리드 유지. 페이지네이션은 서비스 필터와 함께(섹션 그룹핑이면 서비스별 로드 또는 전체 로드 후 그룹 — 데이터량 적으니 후자 허용).",[45,761,762,767,768,771],{},[21,763,764],{},[32,765,766],{},"pages\u002Fbots\u002F[id].vue",": 에디터를 API(POST\u002FPATCH\u002FGET) 연동. ",[21,769,770],{},"서비스 선택 드롭다운(공통 포함)"," = \"구분 설정\"의 핵심 UI. 저장\u002F삭제 실연동.",[45,773,774,172,777,780],{},[21,775,776],{},"메뉴 게이트 해제",[32,778,779],{},"composables\u002Fuse-admin-menu.ts","에서 봇 메뉴 숨김(planner가 백엔드 전까지 숨김 처리한 것) 해제.",[45,782,783,784,786],{},"외부\u002FDB\u002FLLM 직접호출 금지 — 전부 ",[32,785,73],{}," 경유.",[37,788,790],{"id":789},"_5-검증-qa","5. 검증 (QA)",[42,792,793,796],{},[45,794,795],{},"typecheck\u002Fbuild(api·admin), 무인증 가드(401), 로그인 후 CRUD·서비스 그룹핑·공통\u002F서비스 필터 동작(가능 범위).",[45,797,798],{},"회귀: 봇 외 화면 영향 없음, 슬러그 정본화로 catalog\u002Fstandard-answers 영향 없는지.",[37,800,802],{"id":801},"_6-배포","6. 배포",[17,804,805],{},"dba(스키마 적용·시드) → api 배포 → admin 배포. 커밋·배포는 사용자 승인 후 deployer. 이력 기록.",[37,807,809],{"id":808},"_7-후속-이번-범위-밖","7. 후속 (이번 범위 밖)",[42,811,812,817,820],{},[45,813,814,816],{},[32,815,163],{}," 자료 연결(materials API 이후).",[45,818,819],{},"봇 챗 파이프라인 런타임 사용(Phase 2).",[45,821,822,824,825,828],{},[32,823,422],{},"(봇별) vs 전역 ",[32,826,827],{},"confidence_threshold","(hp_setting safety) 우선순위 정책(REQUIREMENTS Q1).",{"title":830,"searchDepth":831,"depth":831,"links":832},"",3,[833,838,840,842,844,845,846],{"id":39,"depth":834,"text":40,"children":835},2,[836,837],{"id":88,"depth":831,"text":89},{"id":155,"depth":831,"text":156},{"id":205,"depth":834,"text":839},"2. 데이터 (DBA) — hp_bot (마이그레이션 004_bots.sql)",{"id":561,"depth":834,"text":841},"3. API (malgn-helper-api) — \u002Fadmin\u002Fbots",{"id":710,"depth":834,"text":843},"4. 관리자단 (malgn-helper-admin)",{"id":789,"depth":834,"text":790},{"id":801,"depth":834,"text":802},{"id":808,"depth":834,"text":809},"md",{},true,"\u002Fbots-plan",{"title":5,"description":830},"BOTS-PLAN","ou1fpqG3zj8A8rrdXEUsRGEDuZ4yfHmiTt9mbiyjgeM",1783932938619]