[{"data":1,"prerenderedAt":2036},["ShallowReactive",2],{"doc:\u002Fhp-schema":3},{"id":4,"title":5,"body":6,"description":2029,"extension":2030,"meta":2031,"navigation":1257,"path":2032,"seo":2033,"stem":2034,"__hash__":2035},"docs\u002FHP-SCHEMA.md","Malgn Helper — DB 스키마 설계 (hp_* 테이블)",{"type":7,"value":8,"toc":2004},"minimark",[9,19,35,53,56,61,127,129,133,143,145,149,158,348,353,368,380,382,390,570,574,591,593,601,608,775,779,804,806,814,817,986,990,1003,1005,1013,1024,1196,1200,1219,1221,1225,1820,1822,1826,1830,1836,1840,1846,1850,1856,1860,1866,1868,1872,1875,1909,1915,1917,1921,2000],[10,11,13,14,18],"h1",{"id":12},"malgn-helper-db-스키마-설계-hp_-테이블","Malgn Helper — DB 스키마 설계 (",[15,16,17],"code",{},"hp_*"," 테이블)",[20,21,22,23,30,31,34],"p",{},"PMS DB 안에 ",[24,25,26,29],"strong",{},[15,27,28],{},"hp_"," 접두사","로 헬퍼 전용 테이블을 둔다. 운영 PMS 테이블(",[15,32,33],{},"tb_*",")과 명확히 격리되며, 추후 별도 DB로 마이그레이션할 때도 검색·이전이 쉽다.",[36,37,38],"blockquote",{},[20,39,40,41,44,45,48,49,52],{},"약어 ",[15,42,43],{},"hp"," = ",[24,46,47],{},"H","elper ",[24,50,51],{},"P","roject. 모든 헬퍼 테이블 공통 접두사.",[54,55],"hr",{},[57,58,60],"h2",{"id":59},"_1-설계-원칙","1. 설계 원칙",[62,63,64,74,84,97,107,117],"ol",{},[65,66,67,73],"li",{},[24,68,69,70,72],{},"PMS 운영 테이블(",[15,71,33],{},")에는 외래키 걸지 않는다."," 참조만 하고 검증은 애플리케이션 레벨에서. PMS 스키마 변경에 영향받지 않기 위해.",[65,75,76,83],{},[24,77,78,79,82],{},"모든 테이블에 ",[15,80,81],{},"status TINYINT"," (1=활성, -1=삭제)"," — soft delete 통일.",[65,85,86,93,94,96],{},[24,87,88,89,92],{},"시간 컬럼은 ",[15,90,91],{},"DATETIME"," 사용"," (",[15,95,33],{},"은 varchar(14) 레거시. 신규 테이블은 표준형).",[65,98,99,102,103,106],{},[24,100,101],{},"LLM 결과는 통째로 JSON 컬럼에","(",[15,104,105],{},"LONGTEXT"," + JSON serialization). 향후 스키마 진화에 유연.",[65,108,109,112,113,116],{},[24,110,111],{},"자주 정렬·조회되는 핵심 값은 별도 컬럼","으로 빼서 인덱스 (예: ",[15,114,115],{},"hp_qa_eval.overall_score",").",[65,118,119,122,123,126],{},[24,120,121],{},"버전 이력 보존"," — 같은 프로젝트\u002F게시글의 재생성은 같은 row 갱신이 아니라 ",[24,124,125],{},"새 row append",". 시계열 분석·되돌리기 가능.",[54,128],{},[57,130,132],{"id":131},"_2-erd-텍스트","2. ERD (텍스트)",[134,135,140],"pre",{"className":136,"code":138,"language":139},[137],"language-text","tb_project   tb_post\n   │            │\n   │ project_id │ post_id\n   ▼            ▼\n┌─────────────────────┐    ┌─────────────────────┐\n│  hp_briefing        │    │  hp_qa_eval         │\n│  (프로젝트 브리핑   │    │  (게시글 Q&A 평가   │\n│   여러 버전 누적)   │    │   여러 버전 누적)   │\n└──────────┬──────────┘    └──────────┬──────────┘\n           │                          │\n           │  saved_from              │  source_post_id\n           ▼                          ▼\n        ┌─────────────────────────────────┐\n        │  hp_standard_answer             │\n        │  (표준 답변 카탈로그            │\n        │   — 챗봇 응답 1순위 소스)       │\n        └─────────────────────────────────┘\n\n  (모든 LLM 호출은 hp_llm_log로 집계 — entity_type\u002Fid로 위 3개 테이블과 느슨 연결)\n","text",[15,141,138],{"__ignoreMap":142},"",[54,144],{},[57,146,148],{"id":147},"_3-테이블-상세","3. 테이블 상세",[150,151,153,154,157],"h3",{"id":152},"_3-1-hp_briefing-프로젝트-브리핑-카드-캐시","3-1. ",[15,155,156],{},"hp_briefing"," — 프로젝트 브리핑 카드 캐시",[159,160,161,177],"table",{},[162,163,164],"thead",{},[165,166,167,171,174],"tr",{},[168,169,170],"th",{},"컬럼",[168,172,173],{},"타입",[168,175,176],{},"설명",[178,179,180,193,209,222,244,260,273,285,296,307,323,336],"tbody",{},[165,181,182,188,191],{},[183,184,185],"td",{},[15,186,187],{},"id",[183,189,190],{},"INT PK AI",[183,192],{},[165,194,195,200,203],{},[183,196,197],{},[15,198,199],{},"project_id",[183,201,202],{},"INT NOT NULL",[183,204,205,208],{},[15,206,207],{},"tb_project.id"," (FK 없음)",[165,210,211,216,219],{},[183,212,213],{},[15,214,215],{},"generated_at",[183,217,218],{},"DATETIME NOT NULL",[183,220,221],{},"LLM 생성 시각",[165,223,224,229,232],{},[183,225,226],{},[15,227,228],{},"generator",[183,230,231],{},"VARCHAR(20) NOT NULL",[183,233,234,237,238,237,241],{},[15,235,236],{},"db_only"," \u002F ",[15,239,240],{},"llm",[15,242,243],{},"hybrid",[165,245,246,251,254],{},[183,247,248],{},[15,249,250],{},"llm_model",[183,252,253],{},"VARCHAR(50) NULL",[183,255,256,257],{},"예: ",[15,258,259],{},"claude-sonnet-4-6",[165,261,262,267,270],{},[183,263,264],{},[15,265,266],{},"llm_input_hash",[183,268,269],{},"CHAR(64) NULL",[183,271,272],{},"동일 입력 캐시 키 (project state SHA-256)",[165,274,275,280,283],{},[183,276,277],{},[15,278,279],{},"prompt_tokens",[183,281,282],{},"INT NULL",[183,284],{},[165,286,287,292,294],{},[183,288,289],{},[15,290,291],{},"completion_tokens",[183,293,282],{},[183,295],{},[165,297,298,303,305],{},[183,299,300],{},[15,301,302],{},"latency_ms",[183,304,282],{},[183,306],{},[165,308,309,314,317],{},[183,310,311],{},[15,312,313],{},"briefing_json",[183,315,316],{},"LONGTEXT NOT NULL",[183,318,319,322],{},[15,320,321],{},"Briefing"," 객체 전체",[165,324,325,330,333],{},[183,326,327],{},[15,328,329],{},"status",[183,331,332],{},"TINYINT NOT NULL DEFAULT 1",[183,334,335],{},"1=활성 \u002F -1=삭제",[165,337,338,343,346],{},[183,339,340],{},[15,341,342],{},"created_at",[183,344,345],{},"DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP",[183,347],{},[20,349,350],{},[24,351,352],{},"인덱스",[354,355,356,362],"ul",{},[65,357,358,361],{},[15,359,360],{},"idx_project_status_gen (project_id, status, generated_at DESC)"," — 프로젝트별 최신 N건",[65,363,364,367],{},[15,365,366],{},"idx_input_hash (llm_input_hash)"," — 캐시 lookup",[20,369,370,373,374,376,377,379],{},[24,371,372],{},"캐시 정책",": 같은 ",[15,375,199],{}," + 같은 ",[15,378,266],{},"가 24시간 이내면 재사용. 그 외엔 새 LLM 호출.",[54,381],{},[150,383,385,386,389],{"id":384},"_3-2-hp_qa_eval-게시글-qa-평가-캐시","3-2. ",[15,387,388],{},"hp_qa_eval"," — 게시글 Q&A 평가 캐시",[159,391,392,402],{},[162,393,394],{},[165,395,396,398,400],{},[168,397,170],{},[168,399,173],{},[168,401,176],{},[178,403,404,414,428,439,449,459,469,480,490,500,510,524,537,550,560],{},[165,405,406,410,412],{},[183,407,408],{},[15,409,187],{},[183,411,190],{},[183,413],{},[165,415,416,421,423],{},[183,417,418],{},[15,419,420],{},"post_id",[183,422,202],{},[183,424,425],{},[15,426,427],{},"tb_post.id",[165,429,430,434,436],{},[183,431,432],{},[15,433,199],{},[183,435,202],{},[183,437,438],{},"조회 편의(중복 저장)",[165,440,441,445,447],{},[183,442,443],{},[15,444,215],{},[183,446,218],{},[183,448],{},[165,450,451,455,457],{},[183,452,453],{},[15,454,228],{},[183,456,231],{},[183,458],{},[165,460,461,465,467],{},[183,462,463],{},[15,464,250],{},[183,466,253],{},[183,468],{},[165,470,471,475,477],{},[183,472,473],{},[15,474,266],{},[183,476,269],{},[183,478,479],{},"post + 댓글 본문 해시",[165,481,482,486,488],{},[183,483,484],{},[15,485,279],{},[183,487,282],{},[183,489],{},[165,491,492,496,498],{},[183,493,494],{},[15,495,291],{},[183,497,282],{},[183,499],{},[165,501,502,506,508],{},[183,503,504],{},[15,505,302],{},[183,507,282],{},[183,509],{},[165,511,512,517,519],{},[183,513,514],{},[15,515,516],{},"eval_json",[183,518,316],{},[183,520,521,322],{},[15,522,523],{},"QaEval",[165,525,526,531,534],{},[183,527,528],{},[15,529,530],{},"overall_score",[183,532,533],{},"DECIMAL(3,2) NULL",[183,535,536],{},"정렬·필터용 (예: 4.20)",[165,538,539,544,547],{},[183,540,541],{},[15,542,543],{},"overall_verdict",[183,545,546],{},"VARCHAR(100) NULL",[183,548,549],{},"표시용 한 줄 평 (예: \"알림톡 기능 추가 절차를 명확하게 안내함\") — 2026-05-29 VARCHAR(20)→100 마이그레이션",[165,551,552,556,558],{},[183,553,554],{},[15,555,329],{},[183,557,332],{},[183,559],{},[165,561,562,566,568],{},[183,563,564],{},[15,565,342],{},[183,567,345],{},[183,569],{},[20,571,572],{},[24,573,352],{},[354,575,576,581,587],{},[65,577,578],{},[15,579,580],{},"idx_post_status_gen (post_id, status, generated_at DESC)",[65,582,583,586],{},[15,584,585],{},"idx_project_score (project_id, overall_score DESC)"," — 프로젝트별 우수\u002F취약 응대 정렬",[65,588,589],{},[15,590,366],{},[54,592],{},[150,594,596,597,600],{"id":595},"_3-3-hp_standard_answer-표준-답변-카탈로그","3-3. ",[15,598,599],{},"hp_standard_answer"," — 표준 답변 카탈로그",[20,602,603,604,607],{},"QaEval 카드에서 \"표준답변으로 저장\" 액션 → 이 테이블에 누적. ",[24,605,606],{},"챗봇 응답의 1순위 소스",".",[159,609,610,620],{},[162,611,612],{},[165,613,614,616,618],{},[168,615,170],{},[168,617,173],{},[168,619,176],{},[178,621,622,632,645,658,670,681,693,706,718,731,743,753,763],{},[165,623,624,628,630],{},[183,625,626],{},[15,627,187],{},[183,629,190],{},[183,631],{},[165,633,634,639,642],{},[183,635,636],{},[15,637,638],{},"label",[183,640,641],{},"VARCHAR(100) NOT NULL",[183,643,644],{},"카드\u002F탭 헤더",[165,646,647,652,655],{},[183,648,649],{},[15,650,651],{},"question",[183,653,654],{},"TEXT NOT NULL",[183,656,657],{},"다루는 질문 패턴",[165,659,660,665,667],{},[183,661,662],{},[15,663,664],{},"answer",[183,666,654],{},[183,668,669],{},"답변 본문",[165,671,672,676,678],{},[183,673,674],{},[15,675,199],{},[183,677,282],{},[183,679,680],{},"NULL = 전사 공통, 값 있으면 해당 프로젝트 전용",[165,682,683,688,690],{},[183,684,685],{},[15,686,687],{},"source_post_id",[183,689,282],{},[183,691,692],{},"출처 게시글",[165,694,695,700,703],{},[183,696,697],{},[15,698,699],{},"source_axis",[183,701,702],{},"VARCHAR(10) NULL",[183,704,705],{},"QaEval 축 (A\u002FB\u002FC\u002FD\u002FE)",[165,707,708,713,715],{},[183,709,710],{},[15,711,712],{},"created_by",[183,714,546],{},[183,716,717],{},"저장한 직원 이메일 (인증 도입 후)",[165,719,720,725,728],{},[183,721,722],{},[15,723,724],{},"usage_count",[183,726,727],{},"INT NOT NULL DEFAULT 0",[183,729,730],{},"챗봇이 사용한 횟수",[165,732,733,738,741],{},[183,734,735],{},[15,736,737],{},"last_used_at",[183,739,740],{},"DATETIME NULL",[183,742],{},[165,744,745,749,751],{},[183,746,747],{},[15,748,329],{},[183,750,332],{},[183,752],{},[165,754,755,759,761],{},[183,756,757],{},[15,758,342],{},[183,760,345],{},[183,762],{},[165,764,765,770,773],{},[183,766,767],{},[15,768,769],{},"updated_at",[183,771,772],{},"DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP",[183,774],{},[20,776,777],{},[24,778,352],{},[354,780,781,786,792,798],{},[65,782,783],{},[15,784,785],{},"idx_project_status (project_id, status)",[65,787,788,791],{},[15,789,790],{},"idx_usage (status, usage_count DESC)"," — 인기 답변 순회",[65,793,794,797],{},[15,795,796],{},"idx_source_post (source_post_id)"," — 출처 역추적",[65,799,800,803],{},[15,801,802],{},"FULLTEXT idx_qa (question, answer)"," — InnoDB FULLTEXT (MySQL 5.6.4+ 지원)",[54,805],{},[150,807,809,810,813],{"id":808},"_3-4-hp_llm_log-llm-호출-감사-로그","3-4. ",[15,811,812],{},"hp_llm_log"," — LLM 호출 감사 로그",[20,815,816],{},"비용·지연·실패 추적. 전 엔티티 공통.",[159,818,819,829],{},[162,820,821],{},[165,822,823,825,827],{},[168,824,170],{},[168,826,173],{},[168,828,176],{},[178,830,831,842,858,880,892,904,914,924,934,946,962,975],{},[165,832,833,837,840],{},[183,834,835],{},[15,836,187],{},[183,838,839],{},"BIGINT PK AI",[183,841],{},[165,843,844,849,851],{},[183,845,846],{},[15,847,848],{},"route",[183,850,641],{},[183,852,853,854,857],{},"호출 라우트 (예: ",[15,855,856],{},"POST \u002Fpms\u002Fprojects\u002F:id\u002Fbriefing\u002Fgenerate",")",[165,859,860,865,868],{},[183,861,862],{},[15,863,864],{},"entity_type",[183,866,867],{},"VARCHAR(30) NOT NULL",[183,869,870,237,873,237,876,879],{},[15,871,872],{},"briefing",[15,874,875],{},"qa_eval",[15,877,878],{},"chat"," 등",[165,881,882,887,889],{},[183,883,884],{},[15,885,886],{},"entity_id",[183,888,282],{},[183,890,891],{},"위 3개 테이블의 id (생성 후 채움)",[165,893,894,899,902],{},[183,895,896],{},[15,897,898],{},"model",[183,900,901],{},"VARCHAR(50) NOT NULL",[183,903],{},[165,905,906,910,912],{},[183,907,908],{},[15,909,279],{},[183,911,282],{},[183,913],{},[165,915,916,920,922],{},[183,917,918],{},[15,919,291],{},[183,921,282],{},[183,923],{},[165,925,926,930,932],{},[183,927,928],{},[15,929,302],{},[183,931,282],{},[183,933],{},[165,935,936,941,944],{},[183,937,938],{},[15,939,940],{},"cost_usd",[183,942,943],{},"DECIMAL(10,6) NULL",[183,945],{},[165,947,948,953,956],{},[183,949,950],{},[15,951,952],{},"cache_hit",[183,954,955],{},"TINYINT NOT NULL DEFAULT 0",[183,957,958,959,961],{},"1 = ",[15,960,266],{}," 매치로 LLM 미호출",[165,963,964,969,972],{},[183,965,966],{},[15,967,968],{},"error",[183,970,971],{},"TEXT NULL",[183,973,974],{},"실패 시 메시지",[165,976,977,982,984],{},[183,978,979],{},[15,980,981],{},"request_at",[183,983,345],{},[183,985],{},[20,987,988],{},[24,989,352],{},[354,991,992,997],{},[65,993,994],{},[15,995,996],{},"idx_entity (entity_type, entity_id, request_at)",[65,998,999,1002],{},[15,1000,1001],{},"idx_request_at (request_at)"," — 일별 비용 집계",[54,1004],{},[150,1006,1008,1009,1012],{"id":1007},"_3-5-hp_image_asset-pms-자산-이미지-메타-vision-자동-분석","3-5. ",[15,1010,1011],{},"hp_image_asset"," — PMS 자산 이미지 메타 (Vision 자동 분석)",[20,1014,1015,1016,1019,1020,1023],{},"게시물 본문·답변에서 발견된 ",[15,1017,1018],{},"\u002Fdata\u002F..."," 이미지의 자동 캡션·설명. ",[24,1021,1022],{},"src_path 기준 UNIQUE","라 한 이미지는 한 번만 분석되고 이후 재사용. 챗봇·표준답변 생성 시 이미지 문맥을 텍스트로 인용 가능.",[159,1025,1026,1036],{},[162,1027,1028],{},[165,1029,1030,1032,1034],{},[168,1031,170],{},[168,1033,173],{},[168,1035,176],{},[178,1037,1038,1048,1065,1078,1090,1104,1117,1130,1141,1152,1164,1175,1186],{},[165,1039,1040,1044,1046],{},[183,1041,1042],{},[15,1043,187],{},[183,1045,190],{},[183,1047],{},[165,1049,1050,1055,1058],{},[183,1051,1052],{},[15,1053,1054],{},"src_path",[183,1056,1057],{},"VARCHAR(500) NOT NULL",[183,1059,1060,1061,1064],{},"원본 src (예: ",[15,1062,1063],{},"\u002Fdata\u002F1\u002Fc52ef0c2....png",") — 절대 URL은 코드에서 prefix",[165,1066,1067,1072,1075],{},[183,1068,1069],{},[15,1070,1071],{},"title",[183,1073,1074],{},"VARCHAR(200) NOT NULL",[183,1076,1077],{},"Vision이 생성한 짧은 제목 (예: \"알림톡 코드 확인 화면\")",[165,1079,1080,1085,1087],{},[183,1081,1082],{},[15,1083,1084],{},"description",[183,1086,654],{},[183,1088,1089],{},"Vision이 생성한 본문 설명 (메뉴\u002F버튼\u002F필드명·맥락)",[165,1091,1092,1097,1099],{},[183,1093,1094],{},[15,1095,1096],{},"first_seen_post_id",[183,1098,282],{},[183,1100,1101,1102],{},"처음 발견된 ",[15,1103,427],{},[165,1105,1106,1111,1113],{},[183,1107,1108],{},[15,1109,1110],{},"first_seen_project_id",[183,1112,282],{},[183,1114,1101,1115],{},[15,1116,207],{},[165,1118,1119,1124,1127],{},[183,1120,1121],{},[15,1122,1123],{},"source",[183,1125,1126],{},"ENUM('inquiry','reply') NULL",[183,1128,1129],{},"문의 본문 \u002F 답변 어느 쪽에서 발견",[165,1131,1132,1136,1138],{},[183,1133,1134],{},[15,1135,250],{},[183,1137,253],{},[183,1139,1140],{},"분석에 사용한 모델",[165,1142,1143,1148,1150],{},[183,1144,1145],{},[15,1146,1147],{},"analyzed_at",[183,1149,345],{},[183,1151],{},[165,1153,1154,1158,1161],{},[183,1155,1156],{},[15,1157,724],{},[183,1159,1160],{},"INT NOT NULL DEFAULT 1",[183,1162,1163],{},"같은 src가 다른 게시물에서 재발견된 횟수",[165,1165,1166,1170,1172],{},[183,1167,1168],{},[15,1169,737],{},[183,1171,740],{},[183,1173,1174],{},"재발견 시 갱신",[165,1176,1177,1181,1183],{},[183,1178,1179],{},[15,1180,329],{},[183,1182,332],{},[183,1184,1185],{},"1=활성, -1=숨김",[165,1187,1188,1192,1194],{},[183,1189,1190],{},[15,1191,342],{},[183,1193,345],{},[183,1195],{},[20,1197,1198],{},[24,1199,352],{},[354,1201,1202,1208,1213],{},[65,1203,1204,1207],{},[15,1205,1206],{},"UNIQUE KEY uk_src_path (src_path)"," — 중복 분석 방지",[65,1209,1210],{},[15,1211,1212],{},"KEY idx_project (first_seen_project_id, analyzed_at)",[65,1214,1215,1218],{},[15,1216,1217],{},"KEY idx_usage (status, usage_count DESC)"," — 자주 쓰이는 이미지 순회",[54,1220],{},[57,1222,1224],{"id":1223},"_4-ddl-한-파일로-일괄-실행","4. DDL (한 파일로 일괄 실행)",[134,1226,1230],{"className":1227,"code":1228,"language":1229,"meta":142,"style":142},"language-sql shiki shiki-themes github-light github-dark","-- malgn-helper-api\u002Fmigrations\u002F001_init_hp_tables.sql\n-- 실행 위치: PMS DB (pms)\n-- 안전: 기존 tb_* 테이블에 영향 없음. CREATE TABLE IF NOT EXISTS 사용.\n\nCREATE TABLE IF NOT EXISTS hp_briefing (\n  id                INT NOT NULL AUTO_INCREMENT,\n  project_id        INT NOT NULL,\n  generated_at      DATETIME NOT NULL,\n  generator         VARCHAR(20) NOT NULL,\n  llm_model         VARCHAR(50) NULL,\n  llm_input_hash    CHAR(64) NULL,\n  prompt_tokens     INT NULL,\n  completion_tokens INT NULL,\n  latency_ms        INT NULL,\n  briefing_json     LONGTEXT NOT NULL,\n  status            TINYINT NOT NULL DEFAULT 1,\n  created_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (id),\n  KEY idx_project_status_gen (project_id, status, generated_at),\n  KEY idx_input_hash (llm_input_hash)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n\nCREATE TABLE IF NOT EXISTS hp_qa_eval (\n  id                INT NOT NULL AUTO_INCREMENT,\n  post_id           INT NOT NULL,\n  project_id        INT NOT NULL,\n  generated_at      DATETIME NOT NULL,\n  generator         VARCHAR(20) NOT NULL,\n  llm_model         VARCHAR(50) NULL,\n  llm_input_hash    CHAR(64) NULL,\n  prompt_tokens     INT NULL,\n  completion_tokens INT NULL,\n  latency_ms        INT NULL,\n  eval_json         LONGTEXT NOT NULL,\n  overall_score     DECIMAL(3,2) NULL,\n  overall_verdict   VARCHAR(100) NULL,\n  status            TINYINT NOT NULL DEFAULT 1,\n  created_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (id),\n  KEY idx_post_status_gen (post_id, status, generated_at),\n  KEY idx_project_score (project_id, overall_score),\n  KEY idx_input_hash (llm_input_hash)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n\nCREATE TABLE IF NOT EXISTS hp_standard_answer (\n  id              INT NOT NULL AUTO_INCREMENT,\n  label           VARCHAR(100) NOT NULL,\n  question        TEXT NOT NULL,\n  answer          TEXT NOT NULL,\n  project_id      INT NULL,\n  source_post_id  INT NULL,\n  source_axis     VARCHAR(10) NULL,\n  created_by      VARCHAR(100) NULL,\n  usage_count     INT NOT NULL DEFAULT 0,\n  last_used_at    DATETIME NULL,\n  status          TINYINT NOT NULL DEFAULT 1,\n  created_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  updated_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n  PRIMARY KEY (id),\n  KEY idx_project_status (project_id, status),\n  KEY idx_usage (status, usage_count),\n  KEY idx_source_post (source_post_id),\n  FULLTEXT KEY idx_qa (question, answer)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n\nCREATE TABLE IF NOT EXISTS hp_llm_log (\n  id                BIGINT NOT NULL AUTO_INCREMENT,\n  route             VARCHAR(100) NOT NULL,\n  entity_type       VARCHAR(30) NOT NULL,\n  entity_id         INT NULL,\n  model             VARCHAR(50) NOT NULL,\n  prompt_tokens     INT NULL,\n  completion_tokens INT NULL,\n  latency_ms        INT NULL,\n  cost_usd          DECIMAL(10,6) NULL,\n  cache_hit         TINYINT NOT NULL DEFAULT 0,\n  error             TEXT NULL,\n  request_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (id),\n  KEY idx_entity (entity_type, entity_id, request_at),\n  KEY idx_request_at (request_at)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n\nCREATE TABLE IF NOT EXISTS hp_image_asset (\n  id                       INT NOT NULL AUTO_INCREMENT,\n  src_path                 VARCHAR(500) NOT NULL,\n  title                    VARCHAR(200) NOT NULL,\n  description              TEXT NOT NULL,\n  first_seen_post_id       INT NULL,\n  first_seen_project_id    INT NULL,\n  source                   ENUM('inquiry','reply') NULL,\n  llm_model                VARCHAR(50) NULL,\n  analyzed_at              DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  usage_count              INT NOT NULL DEFAULT 1,\n  last_used_at             DATETIME NULL,\n  status                   TINYINT NOT NULL DEFAULT 1,\n  created_at               DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  PRIMARY KEY (id),\n  UNIQUE KEY uk_src_path (src_path),\n  KEY idx_project (first_seen_project_id, analyzed_at),\n  KEY idx_usage (status, usage_count)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n","sql",[15,1231,1232,1240,1246,1252,1259,1265,1271,1277,1283,1289,1295,1301,1307,1313,1319,1325,1331,1337,1343,1349,1355,1361,1366,1372,1377,1383,1388,1393,1398,1403,1408,1413,1418,1423,1429,1435,1441,1446,1451,1456,1462,1468,1473,1478,1483,1489,1495,1501,1507,1513,1519,1525,1531,1537,1543,1549,1555,1561,1567,1572,1578,1584,1590,1596,1601,1606,1612,1618,1624,1630,1636,1642,1647,1652,1657,1663,1669,1675,1681,1686,1692,1698,1703,1708,1714,1720,1726,1732,1738,1744,1750,1756,1762,1768,1774,1780,1786,1792,1797,1803,1809,1815],{"__ignoreMap":142},[1233,1234,1237],"span",{"class":1235,"line":1236},"line",1,[1233,1238,1239],{},"-- malgn-helper-api\u002Fmigrations\u002F001_init_hp_tables.sql\n",[1233,1241,1243],{"class":1235,"line":1242},2,[1233,1244,1245],{},"-- 실행 위치: PMS DB (pms)\n",[1233,1247,1249],{"class":1235,"line":1248},3,[1233,1250,1251],{},"-- 안전: 기존 tb_* 테이블에 영향 없음. CREATE TABLE IF NOT EXISTS 사용.\n",[1233,1253,1255],{"class":1235,"line":1254},4,[1233,1256,1258],{"emptyLinePlaceholder":1257},true,"\n",[1233,1260,1262],{"class":1235,"line":1261},5,[1233,1263,1264],{},"CREATE TABLE IF NOT EXISTS hp_briefing (\n",[1233,1266,1268],{"class":1235,"line":1267},6,[1233,1269,1270],{},"  id                INT NOT NULL AUTO_INCREMENT,\n",[1233,1272,1274],{"class":1235,"line":1273},7,[1233,1275,1276],{},"  project_id        INT NOT NULL,\n",[1233,1278,1280],{"class":1235,"line":1279},8,[1233,1281,1282],{},"  generated_at      DATETIME NOT NULL,\n",[1233,1284,1286],{"class":1235,"line":1285},9,[1233,1287,1288],{},"  generator         VARCHAR(20) NOT NULL,\n",[1233,1290,1292],{"class":1235,"line":1291},10,[1233,1293,1294],{},"  llm_model         VARCHAR(50) NULL,\n",[1233,1296,1298],{"class":1235,"line":1297},11,[1233,1299,1300],{},"  llm_input_hash    CHAR(64) NULL,\n",[1233,1302,1304],{"class":1235,"line":1303},12,[1233,1305,1306],{},"  prompt_tokens     INT NULL,\n",[1233,1308,1310],{"class":1235,"line":1309},13,[1233,1311,1312],{},"  completion_tokens INT NULL,\n",[1233,1314,1316],{"class":1235,"line":1315},14,[1233,1317,1318],{},"  latency_ms        INT NULL,\n",[1233,1320,1322],{"class":1235,"line":1321},15,[1233,1323,1324],{},"  briefing_json     LONGTEXT NOT NULL,\n",[1233,1326,1328],{"class":1235,"line":1327},16,[1233,1329,1330],{},"  status            TINYINT NOT NULL DEFAULT 1,\n",[1233,1332,1334],{"class":1235,"line":1333},17,[1233,1335,1336],{},"  created_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n",[1233,1338,1340],{"class":1235,"line":1339},18,[1233,1341,1342],{},"  PRIMARY KEY (id),\n",[1233,1344,1346],{"class":1235,"line":1345},19,[1233,1347,1348],{},"  KEY idx_project_status_gen (project_id, status, generated_at),\n",[1233,1350,1352],{"class":1235,"line":1351},20,[1233,1353,1354],{},"  KEY idx_input_hash (llm_input_hash)\n",[1233,1356,1358],{"class":1235,"line":1357},21,[1233,1359,1360],{},") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;\n",[1233,1362,1364],{"class":1235,"line":1363},22,[1233,1365,1258],{"emptyLinePlaceholder":1257},[1233,1367,1369],{"class":1235,"line":1368},23,[1233,1370,1371],{},"CREATE TABLE IF NOT EXISTS hp_qa_eval (\n",[1233,1373,1375],{"class":1235,"line":1374},24,[1233,1376,1270],{},[1233,1378,1380],{"class":1235,"line":1379},25,[1233,1381,1382],{},"  post_id           INT NOT NULL,\n",[1233,1384,1386],{"class":1235,"line":1385},26,[1233,1387,1276],{},[1233,1389,1391],{"class":1235,"line":1390},27,[1233,1392,1282],{},[1233,1394,1396],{"class":1235,"line":1395},28,[1233,1397,1288],{},[1233,1399,1401],{"class":1235,"line":1400},29,[1233,1402,1294],{},[1233,1404,1406],{"class":1235,"line":1405},30,[1233,1407,1300],{},[1233,1409,1411],{"class":1235,"line":1410},31,[1233,1412,1306],{},[1233,1414,1416],{"class":1235,"line":1415},32,[1233,1417,1312],{},[1233,1419,1421],{"class":1235,"line":1420},33,[1233,1422,1318],{},[1233,1424,1426],{"class":1235,"line":1425},34,[1233,1427,1428],{},"  eval_json         LONGTEXT NOT NULL,\n",[1233,1430,1432],{"class":1235,"line":1431},35,[1233,1433,1434],{},"  overall_score     DECIMAL(3,2) NULL,\n",[1233,1436,1438],{"class":1235,"line":1437},36,[1233,1439,1440],{},"  overall_verdict   VARCHAR(100) NULL,\n",[1233,1442,1444],{"class":1235,"line":1443},37,[1233,1445,1330],{},[1233,1447,1449],{"class":1235,"line":1448},38,[1233,1450,1336],{},[1233,1452,1454],{"class":1235,"line":1453},39,[1233,1455,1342],{},[1233,1457,1459],{"class":1235,"line":1458},40,[1233,1460,1461],{},"  KEY idx_post_status_gen (post_id, status, generated_at),\n",[1233,1463,1465],{"class":1235,"line":1464},41,[1233,1466,1467],{},"  KEY idx_project_score (project_id, overall_score),\n",[1233,1469,1471],{"class":1235,"line":1470},42,[1233,1472,1354],{},[1233,1474,1476],{"class":1235,"line":1475},43,[1233,1477,1360],{},[1233,1479,1481],{"class":1235,"line":1480},44,[1233,1482,1258],{"emptyLinePlaceholder":1257},[1233,1484,1486],{"class":1235,"line":1485},45,[1233,1487,1488],{},"CREATE TABLE IF NOT EXISTS hp_standard_answer (\n",[1233,1490,1492],{"class":1235,"line":1491},46,[1233,1493,1494],{},"  id              INT NOT NULL AUTO_INCREMENT,\n",[1233,1496,1498],{"class":1235,"line":1497},47,[1233,1499,1500],{},"  label           VARCHAR(100) NOT NULL,\n",[1233,1502,1504],{"class":1235,"line":1503},48,[1233,1505,1506],{},"  question        TEXT NOT NULL,\n",[1233,1508,1510],{"class":1235,"line":1509},49,[1233,1511,1512],{},"  answer          TEXT NOT NULL,\n",[1233,1514,1516],{"class":1235,"line":1515},50,[1233,1517,1518],{},"  project_id      INT NULL,\n",[1233,1520,1522],{"class":1235,"line":1521},51,[1233,1523,1524],{},"  source_post_id  INT NULL,\n",[1233,1526,1528],{"class":1235,"line":1527},52,[1233,1529,1530],{},"  source_axis     VARCHAR(10) NULL,\n",[1233,1532,1534],{"class":1235,"line":1533},53,[1233,1535,1536],{},"  created_by      VARCHAR(100) NULL,\n",[1233,1538,1540],{"class":1235,"line":1539},54,[1233,1541,1542],{},"  usage_count     INT NOT NULL DEFAULT 0,\n",[1233,1544,1546],{"class":1235,"line":1545},55,[1233,1547,1548],{},"  last_used_at    DATETIME NULL,\n",[1233,1550,1552],{"class":1235,"line":1551},56,[1233,1553,1554],{},"  status          TINYINT NOT NULL DEFAULT 1,\n",[1233,1556,1558],{"class":1235,"line":1557},57,[1233,1559,1560],{},"  created_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n",[1233,1562,1564],{"class":1235,"line":1563},58,[1233,1565,1566],{},"  updated_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n",[1233,1568,1570],{"class":1235,"line":1569},59,[1233,1571,1342],{},[1233,1573,1575],{"class":1235,"line":1574},60,[1233,1576,1577],{},"  KEY idx_project_status (project_id, status),\n",[1233,1579,1581],{"class":1235,"line":1580},61,[1233,1582,1583],{},"  KEY idx_usage (status, usage_count),\n",[1233,1585,1587],{"class":1235,"line":1586},62,[1233,1588,1589],{},"  KEY idx_source_post (source_post_id),\n",[1233,1591,1593],{"class":1235,"line":1592},63,[1233,1594,1595],{},"  FULLTEXT KEY idx_qa (question, answer)\n",[1233,1597,1599],{"class":1235,"line":1598},64,[1233,1600,1360],{},[1233,1602,1604],{"class":1235,"line":1603},65,[1233,1605,1258],{"emptyLinePlaceholder":1257},[1233,1607,1609],{"class":1235,"line":1608},66,[1233,1610,1611],{},"CREATE TABLE IF NOT EXISTS hp_llm_log (\n",[1233,1613,1615],{"class":1235,"line":1614},67,[1233,1616,1617],{},"  id                BIGINT NOT NULL AUTO_INCREMENT,\n",[1233,1619,1621],{"class":1235,"line":1620},68,[1233,1622,1623],{},"  route             VARCHAR(100) NOT NULL,\n",[1233,1625,1627],{"class":1235,"line":1626},69,[1233,1628,1629],{},"  entity_type       VARCHAR(30) NOT NULL,\n",[1233,1631,1633],{"class":1235,"line":1632},70,[1233,1634,1635],{},"  entity_id         INT NULL,\n",[1233,1637,1639],{"class":1235,"line":1638},71,[1233,1640,1641],{},"  model             VARCHAR(50) NOT NULL,\n",[1233,1643,1645],{"class":1235,"line":1644},72,[1233,1646,1306],{},[1233,1648,1650],{"class":1235,"line":1649},73,[1233,1651,1312],{},[1233,1653,1655],{"class":1235,"line":1654},74,[1233,1656,1318],{},[1233,1658,1660],{"class":1235,"line":1659},75,[1233,1661,1662],{},"  cost_usd          DECIMAL(10,6) NULL,\n",[1233,1664,1666],{"class":1235,"line":1665},76,[1233,1667,1668],{},"  cache_hit         TINYINT NOT NULL DEFAULT 0,\n",[1233,1670,1672],{"class":1235,"line":1671},77,[1233,1673,1674],{},"  error             TEXT NULL,\n",[1233,1676,1678],{"class":1235,"line":1677},78,[1233,1679,1680],{},"  request_at        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n",[1233,1682,1684],{"class":1235,"line":1683},79,[1233,1685,1342],{},[1233,1687,1689],{"class":1235,"line":1688},80,[1233,1690,1691],{},"  KEY idx_entity (entity_type, entity_id, request_at),\n",[1233,1693,1695],{"class":1235,"line":1694},81,[1233,1696,1697],{},"  KEY idx_request_at (request_at)\n",[1233,1699,1701],{"class":1235,"line":1700},82,[1233,1702,1360],{},[1233,1704,1706],{"class":1235,"line":1705},83,[1233,1707,1258],{"emptyLinePlaceholder":1257},[1233,1709,1711],{"class":1235,"line":1710},84,[1233,1712,1713],{},"CREATE TABLE IF NOT EXISTS hp_image_asset (\n",[1233,1715,1717],{"class":1235,"line":1716},85,[1233,1718,1719],{},"  id                       INT NOT NULL AUTO_INCREMENT,\n",[1233,1721,1723],{"class":1235,"line":1722},86,[1233,1724,1725],{},"  src_path                 VARCHAR(500) NOT NULL,\n",[1233,1727,1729],{"class":1235,"line":1728},87,[1233,1730,1731],{},"  title                    VARCHAR(200) NOT NULL,\n",[1233,1733,1735],{"class":1235,"line":1734},88,[1233,1736,1737],{},"  description              TEXT NOT NULL,\n",[1233,1739,1741],{"class":1235,"line":1740},89,[1233,1742,1743],{},"  first_seen_post_id       INT NULL,\n",[1233,1745,1747],{"class":1235,"line":1746},90,[1233,1748,1749],{},"  first_seen_project_id    INT NULL,\n",[1233,1751,1753],{"class":1235,"line":1752},91,[1233,1754,1755],{},"  source                   ENUM('inquiry','reply') NULL,\n",[1233,1757,1759],{"class":1235,"line":1758},92,[1233,1760,1761],{},"  llm_model                VARCHAR(50) NULL,\n",[1233,1763,1765],{"class":1235,"line":1764},93,[1233,1766,1767],{},"  analyzed_at              DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n",[1233,1769,1771],{"class":1235,"line":1770},94,[1233,1772,1773],{},"  usage_count              INT NOT NULL DEFAULT 1,\n",[1233,1775,1777],{"class":1235,"line":1776},95,[1233,1778,1779],{},"  last_used_at             DATETIME NULL,\n",[1233,1781,1783],{"class":1235,"line":1782},96,[1233,1784,1785],{},"  status                   TINYINT NOT NULL DEFAULT 1,\n",[1233,1787,1789],{"class":1235,"line":1788},97,[1233,1790,1791],{},"  created_at               DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,\n",[1233,1793,1795],{"class":1235,"line":1794},98,[1233,1796,1342],{},[1233,1798,1800],{"class":1235,"line":1799},99,[1233,1801,1802],{},"  UNIQUE KEY uk_src_path (src_path),\n",[1233,1804,1806],{"class":1235,"line":1805},100,[1233,1807,1808],{},"  KEY idx_project (first_seen_project_id, analyzed_at),\n",[1233,1810,1812],{"class":1235,"line":1811},101,[1233,1813,1814],{},"  KEY idx_usage (status, usage_count)\n",[1233,1816,1818],{"class":1235,"line":1817},102,[1233,1819,1360],{},[54,1821],{},[57,1823,1825],{"id":1824},"_5-사용-흐름","5. 사용 흐름",[150,1827,1829],{"id":1828},"_5-1-브리핑-카드-생성","5-1. 브리핑 카드 생성",[134,1831,1834],{"className":1832,"code":1833,"language":139},[137],"화면: [AI 요약 카드 생성하기] 클릭\n    │\n    ▼\nAPI: POST \u002Fpms\u002Fprojects\u002F:id\u002Fbriefing\u002Fgenerate\n    │\n    ├─ 1. DB 집계 → input 객체 구성 (현재 GET \u002Fbriefing 로직 재사용)\n    ├─ 2. input SHA-256 = input_hash\n    ├─ 3. hp_briefing에 input_hash 매치 + 24h 이내 활성 row 있나?\n    │      ├─ YES → 그 row 반환 (cache_hit=1, hp_llm_log 기록)\n    │      └─ NO  → LLM 호출\n    │              ├─ Claude → hotTopics\u002Ffaq\u002Fpolicies\u002FoneLine 요약 생성\n    │              ├─ DB 집계 + LLM 결과 병합한 briefing_json 저장 (status=1)\n    │              └─ hp_llm_log 기록 (cache_hit=0, 토큰·지연·비용)\n    └─ 4. 응답: { briefing }\n",[15,1835,1833],{"__ignoreMap":142},[150,1837,1839],{"id":1838},"_5-2-qa-평가-생성","5-2. Q&A 평가 생성",[134,1841,1844],{"className":1842,"code":1843,"language":139},[137],"화면: 게시글 상세에서 [평가 카드 생성]\n    │\n    ▼\nAPI: POST \u002Fpms\u002Fposts\u002F:id\u002Feval\u002Fgenerate\n    │\n    ├─ 1. tb_post + tb_post_comment + tb_user로 input 구성\n    ├─ 2. input_hash 계산\n    ├─ 3. hp_qa_eval 캐시 lookup (post_id + input_hash)\n    │      └─ HIT 또는 MISS → LLM 호출 후 새 row append\n    └─ 4. overall_score를 별도 컬럼으로 추출 저장\n",[15,1845,1843],{"__ignoreMap":142},[150,1847,1849],{"id":1848},"_5-3-표준답변-저장-사용자-액션","5-3. 표준답변 저장 (사용자 액션)",[134,1851,1854],{"className":1852,"code":1853,"language":139},[137],"QaEval 카드의 \"이 템플릿을 표준답변으로 저장\" 버튼\n    │\n    ▼\nAPI: POST \u002Fstandard-answers\n  body: { label, question, answer, projectId?, sourcePostId, sourceAxis }\n    │\n    └─ hp_standard_answer INSERT (status=1, usage_count=0)\n",[15,1855,1853],{"__ignoreMap":142},[150,1857,1859],{"id":1858},"_5-4-표준답변-검색-챗봇-응답-1순위","5-4. 표준답변 검색 (챗봇 응답 1순위)",[134,1861,1864],{"className":1862,"code":1863,"language":139},[137],"챗봇 질의 → API: GET \u002Fstandard-answers\u002Fmatch?q=...\n    │\n    ├─ FULLTEXT MATCH (question, answer) AGAINST (?)\n    ├─ 같은 project_id 우선, 그 다음 NULL(전사 공통)\n    ├─ usage_count 증가 + last_used_at 업데이트\n    └─ 챗봇 응답 컴포저로 전달\n",[15,1865,1863],{"__ignoreMap":142},[54,1867],{},[57,1869,1871],{"id":1870},"_6-향후-분리-시나리오","6. 향후 분리 시나리오",[20,1873,1874],{},"PMS 운영팀과 분리 협의가 필요해지면:",[62,1876,1877,1884,1891,1897,1903],{},[65,1878,1879,1880,1883],{},"새 Aurora MySQL DB(",[15,1881,1882],{},"malgn_helper",") 구축",[65,1885,1886,1887,1890],{},"Hyperdrive에 새 connection string 등록 (",[15,1888,1889],{},"HYPERDRIVE_HELPER"," 바인딩 추가)",[65,1892,1893,1896],{},[15,1894,1895],{},"mysqldump --tables hp_*"," → 새 DB 로드",[65,1898,1899,1900,1902],{},"API 코드에서 ",[15,1901,17],{}," 쿼리만 새 바인딩으로 전환",[65,1904,1905,1906,1908],{},"PMS DB의 ",[15,1907,17],{}," 테이블은 1주일 보존 후 DROP",[20,1910,1911,1912,607],{},"테이블 접두사를 일관되게 둔 이유 = ",[24,1913,1914],{},"이 단계를 단순화하기 위함",[54,1916],{},[57,1918,1920],{"id":1919},"_7-보안운영-메모","7. 보안·운영 메모",[159,1922,1923,1933],{},[162,1924,1925],{},[165,1926,1927,1930],{},[168,1928,1929],{},"항목",[168,1931,1932],{},"방침",[178,1934,1935,1949,1960,1969,1980,1992],{},[165,1936,1937,1943],{},[183,1938,1939,1940,857],{},"비공개 댓글 본문(",[15,1941,1942],{},"tb_post_comment.private_yn='Y'",[183,1944,1945,1948],{},[15,1946,1947],{},"hp_qa_eval.eval_json","에 절대 저장 금지. LLM 입력 단계에서 필터링",[165,1950,1951,1954],{},[183,1952,1953],{},"직원\u002F고객 분류",[183,1955,1956,1959],{},[15,1957,1958],{},"@malgnsoft.com"," 매칭 결과만 저장. PII는 추가 저장 안 함",[165,1961,1962,1966],{},[183,1963,1964],{},[15,1965,712],{},[183,1967,1968],{},"인증 도입 전까지는 NULL. 도입 후엔 직원 이메일 필수",[165,1970,1971,1974],{},[183,1972,1973],{},"비용 추적",[183,1975,1976,1979],{},[15,1977,1978],{},"hp_llm_log.cost_usd","를 일별 GROUP BY로 대시보드 (별도 페이지)",[165,1981,1982,1985],{},[183,1983,1984],{},"캐시 무효화",[183,1986,1987,1988,1991],{},"화면의 \"새 카드 생성\" 버튼 = ",[15,1989,1990],{},"?force=1"," 쿼리로 캐시 우회",[165,1993,1994,1997],{},[183,1995,1996],{},"백업",[183,1998,1999],{},"PMS DB 전체 백업에 포함 (별도 백업 불필요 — 분리 전까지)",[2001,2002,2003],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":142,"searchDepth":1248,"depth":1248,"links":2005},[2006,2007,2008,2020,2021,2027,2028],{"id":59,"depth":1242,"text":60},{"id":131,"depth":1242,"text":132},{"id":147,"depth":1242,"text":148,"children":2009},[2010,2012,2014,2016,2018],{"id":152,"depth":1248,"text":2011},"3-1. hp_briefing — 프로젝트 브리핑 카드 캐시",{"id":384,"depth":1248,"text":2013},"3-2. hp_qa_eval — 게시글 Q&A 평가 캐시",{"id":595,"depth":1248,"text":2015},"3-3. hp_standard_answer — 표준 답변 카탈로그",{"id":808,"depth":1248,"text":2017},"3-4. hp_llm_log — LLM 호출 감사 로그",{"id":1007,"depth":1248,"text":2019},"3-5. hp_image_asset — PMS 자산 이미지 메타 (Vision 자동 분석)",{"id":1223,"depth":1242,"text":1224},{"id":1824,"depth":1242,"text":1825,"children":2022},[2023,2024,2025,2026],{"id":1828,"depth":1248,"text":1829},{"id":1838,"depth":1248,"text":1839},{"id":1848,"depth":1248,"text":1849},{"id":1858,"depth":1248,"text":1859},{"id":1870,"depth":1242,"text":1871},{"id":1919,"depth":1242,"text":1920},"PMS DB 안에 hp_ 접두사로 헬퍼 전용 테이블을 둔다. 운영 PMS 테이블(tb_*)과 명확히 격리되며, 추후 별도 DB로 마이그레이션할 때도 검색·이전이 쉽다.","md",{},"\u002Fhp-schema",{"title":5,"description":2029},"HP-SCHEMA","tvO7CBQ3rJaCFEUlze0Sos7g50dvAm-fk7X0OZD62ic",1780986551103]