문서

레거시 DB 인벤토리 — pms (테스트 서버)

조사일: 2026-05-18 대상: db.malgn.co.kr:3306/pms (테스트 서버, 읽기 권한 계정) 목적: AI 챗봇 학습 자산화 가능성 평가 및 인제스트 매핑 정의

자격 증명은 본 문서에 기록하지 않는다. 운영 시크릿 채널로 관리.


1. 결론 요약

  • 이 DB는 CS 전용 DB가 아니라 맑은소프트의 사내 PMS(프로젝트 관리 시스템).
  • 그러나 tb_post + tb_post_comment고객 문의와 맑은소프트 직원의 답변이 함께 누적되어 있어 CS Q&A 자산으로 가치가 있다.
  • 합리적 필터를 적용하면 약 1,358건의 Q&A 후보가 확보된다 (Site 1: 1,146, Site 2: 212).
  • HTML 본문·테스트 글·이미지 전용 글 등 정제가 필요. 정제 후 OpenSearch 인덱싱 대상으로 활용 가능.

2. DB 메타

항목
EngineMySQL 8.0.42
Charsetutf8mb3
Tables26개
성격PMS(게시판·프로젝트·채팅·일정·투표 통합)

3. 테이블 인벤토리 (행수 기준 상위)

테이블행수용도 추정CS AI 활용성
tb_post_read364,140게시글 읽음 처리✕ 사용 안 함
tb_post_file79,180게시글 첨부파일 메타◎ 텍스트 문서는 본문 부착, 이미지/동영상은 별도 정책 (§6 첨부파일 처리 전략)
tb_post_share68,380게시글 공유 이력
tb_project_user22,292프로젝트-사용자 매핑
tb_diligence7,137근태/근면 데이터
tb_post_comment5,684게시글 댓글 (답변 본문)◎ 핵심 자산
tb_project4,448프로젝트 메타△ 컨텍스트 (project_id 매핑)
tb_post_label3,778게시글 라벨(태그)△ 카테고리 후보
tb_user3,037사용자△ 작성자 메타용
tb_post2,437게시글 본문 (질문/요청)◎ 핵심 자산
tb_post_bookmark2,046즐겨찾기
tb_chat_message1,814사내 실시간 채팅✕ CS와 무관, 짧은 잡담 위주
tb_post_task1,464게시글 → 작업 변환
tb_session686로그인 세션
tb_user_log457사용자 활동 로그
tb_post_alram187게시글 알림
tb_post_template90문서 템플릿 (회의록/보고서 등)△ 양식이라 답변 데이터는 아님
tb_post_poll_user90투표 응답
tb_chat_file81채팅 첨부
tb_site63사이트(테넌트) 정보○ 필터 키
tb_post_poll33게시글 투표
tb_sequence22시퀀스 카운터
tb_group_user, tb_group8/6그룹
tb_post_confirm0(미사용)

tb_chat_message 샘플: "네~^^", "감사합니다ㅎㅎ" 등 사내 메신저 대화 — CS 자산으로 활용 부적합.


4. 핵심 테이블 스키마 (관련 컬럼만)

tb_post (질문/요청 본문)

컬럼타입의미 / 활용
idint게시글 PK
site_idint테넌트(사이트) — 필터 키
project_idint프로젝트 컨텍스트
type, ctypeint게시글 구분 — 필터 후보
template_idint사용된 템플릿
label_id, labelint/varchar카테고리 후보
writervarchar작성자(질문자)
subjectvarchar(255)제목 = 질문 요약
contentlongtext본문 = 질문 상세 (HTML)
is_noticeint공지 여부 — 제외
is_task/is_schedule/is_pollint작업/일정/투표 — 제외
comm_cntint댓글 수 — Q&A 페어 여부
reg_datevarchar(14)YYYYMMDDHHMMSS — 신선도
statusint1 = 정상

tb_post_comment (답변 본문)

컬럼타입의미 / 활용
idint댓글 PK
post_idint부모 게시글 FK
writervarchar작성자(답변자)
contentlongtext답변 본문 (HTML)
private_ynchar(1)'Y' 비공개 댓글 — 제외
reg_datevarchar(14)등록일
statusint1 = 정상
subjectvarchar보통 비어 있음

tb_site, tb_project, tb_user, tb_post_label

  • 메타데이터 결합용 — 작성자명·사이트명·프로젝트명·라벨명을 인덱스 메타 필드로 첨부.

5. Q&A 후보 데이터 규모

적용 필터

WHERE p.status = 1
  AND p.comm_cnt >= 1
  AND p.is_task = 0
  AND p.is_schedule = 0
  AND p.is_poll = 0
  AND p.is_notice = 0
  AND p.subject NOT LIKE '테스트%'
  AND CHAR_LENGTH(p.content) >= 20

결과

SiteSite 이름후보 게시글
1(주)맑은소프트1,146
2맑은소프트 내부212
합계1,358

Site 1이 외부 고객 문의 + 내부 글이 섞여 있을 가능성 있음. 표본 검수 후 site별 채택 여부 재결정 필요.


6. 데이터 품질 이슈

이슈처리 방안
본문이 HTML (<p>...)인덱싱 전 HTML 정제 (태그 제거, 엔티티 디코드, <img> 제거 후 alt만 보존)
일부 글은 이미지만 있음 (스크린샷 캡처)아래 이미지 처리 전략 참조 — 단계별 도입
<img src="/data/..."> 내부 경로메타 필드로 보존 후 외부 접근 가능한 URL로 치환 (R2 서명 URL 또는 프록시)
테스트 글(테스트%)이 많음제목·작성자·날짜 기반 필터, 화이트리스트 검토
private_yn = 'Y' 비공개 댓글반드시 제외
reg_datevarchar(14) (YYYYMMDDHHMMSS)인덱싱 시 DATETIME/epoch 변환, 신선도 가중치 적용
동일 질문에 여러 댓글모든 댓글을 후보로 보되 마지막 답변 또는 staff 답변 우선 등 정책 결정 필요
작성자가 동일한 Q&A (자기 답변)셀프 답변은 신뢰도 낮춤 또는 제외
PII 가능성 (이메일·전화·이름)인제스트 단계에서 마스킹 또는 사내용으로만 사용. 공개 챗봇에 그대로 노출 금지
사용자 작성 IP 컬럼 보유인덱싱 대상에서 제외
Site별로 도메인이 다를 수 있음사이트 1(맑은소프트 운영)만 우선 채택 후 확장
댓글이 1건 ↔ 다건(스레드)으로 섞임아래 스레드 처리 전략 참조
비공개 댓글(private_yn = 'Y')이 9.3% 존재아래 비공개 댓글 처리 전략 참조 — 단순 제외 아님
첨부파일이 Q&A 후보 64.9%에 존재 (총 78,784건)아래 첨부파일 처리 전략 참조 — 파일 종류별 분기

이미지 처리 전략

본 DB의 게시글 본문은 <p> 텍스트와 <img src="/data/..."> 이미지가 함께 들어 있다. 가치 있는 Q&A는 보통 텍스트 본문이 충분하고, 이미지만 있는 글은 테스트·사내 스크린샷이 대부분이라 단계별 도입으로 비용과 복잡도를 통제한다.

단계처리 방식비용적용 시점
A. 텍스트만 (MVP)HTML·<img> 태그 제거 후 본문 길이가 임계값(예: 30자) 미만이면 인덱싱 제외. 이미지 URL은 메타 필드로만 보존0Phase 1 즉시
B. OCR 추가텍스트와 이미지가 함께 있는 글에서 스크린샷의 텍스트(에러 메시지·관리자 화면 등)만 추출해 본문 뒤에 부착낮음 (Cloudflare AI / 외부 OCR)Phase 1 후반 ~ Phase 2
C. Vision LLM 캡션Claude Vision으로 이미지 내용 요약 캡션 생성 → 의미 검색 강화중간 (토큰 비용)Phase 2 품질 고도화

공통 원칙

  • 모든 단계에서 이미지 URL을 메타 필드로 보존 → 챗봇 답변에서 "관련 화면 참고: <링크>"로 인용 가능.
  • 이미지 경로(/data/...)는 외부 접근 가능한 URL로 치환 (R2 서명 URL 또는 프록시).
  • 단계 전환은 미커버 질문 분석 결과로 결정. 이미지 정보 없이 풀리지 않는 질문이 의미 있게 쌓이면 B 도입.

트레이드오프: 텍스트만은 단순·저비용이지만 "이 화면에서 어떻게 해요?" 같은 시각 의존 질문을 놓침. OCR/Vision은 잡을 수 있지만 복잡도·비용 증가.

스레드 처리 전략

게시글당 댓글 수 분포 (status=1 + 테스트 제외 후, 1,358건 후보 기준):

댓글 수게시글 수비율
1 (단일 응답)48736%
2~3 (짧은 스레드)48636%
4~6 (중간 스레드)23818%
7~15 (긴 스레드)1299%
16+ (매우 긴)181%

약 64%가 스레드형 — 단일 Q&A 페어로 가정하면 안 된다. 후속 질의·재확인·해결 과정을 모두 활용해야 답변 품질이 살아난다.

원칙: 스레드를 하나의 Q&A 도큐먼트로 압축해서 인덱싱한다.

항목처리
단위1개 게시글(+ 그 게시글의 모든 가시 댓글) = 1 도큐먼트
본문 구성질문(Q) → 답변1(A) → 추가질문(Q2) → 답변2(A2) → ... 시간순 결합
화자 표기각 턴 앞에 작성자/역할 라벨 (고객:, 상담사: 등) 부착 — LLM이 화자 추적 가능하게
잡담 필터본문 길이 5자 미만, "ddddd" 같은 반복 문자 등 노이즈 댓글 제거 (post 94221 사례 참조)
임베딩 입력결합된 전체 텍스트 (Q+A 누적)
BM25 인덱스제목·질문·답변 분리 필드 + 결합 필드 둘 다 보유해 가중치 조절 가능
청킹결합 본문이 임계값(예: 2000자) 초과 시 의미 단위 분할, 단 동일 doc_id로 묶음
메타turn_count, last_reply_at 보존 → 신선도·복잡도 가중치

비잡담 검증: 댓글 노이즈("ddddd", "xxxxxx") 검출 룰 — 동일 문자 반복, 길이 5자 미만, 의미 없는 단일 단어 등.

비공개 댓글 처리 전략

tb_post_comment.private_yn = 'Y' 댓글은 활성 댓글 5,021건 중 513건 (약 9.3%).

관찰: 일부 스레드는 알맹이 답변이 비공개에만 존재한다 (예: post 94221 — 공개 댓글은 잡담, 비공개 댓글이 실제 답변). 따라서 단순 제외하면 답변 자산을 잃는다. 그러나 비공개는 의도적으로 고객 비노출이므로 챗봇 노출은 금지.

해결: 가시성(visibility) 메타 필드로 계층 인덱싱.

인덱스 도큐먼트의 visibility포함 댓글
internal공개 + 비공개 댓글 모두 결합
public공개 댓글만 결합

같은 게시글에 대해 두 개 변형을 만들지 않고, 하나의 도큐먼트에 두 본문 필드를 유지하는 방식도 가능:

인덱스 필드내용
body_public공개 댓글만으로 구성한 결합 본문 (Phase 2 챗봇용 BM25/임베딩)
body_internal비공개 포함 결합 본문 (Phase 1 상담사 보조용 BM25/임베딩)
embedding_public / embedding_internal각 본문 기준 벡터
has_internal_only_answer공개 본문에는 답이 없고 비공개에만 있는 경우 표시 (Phase 2에서 자동 에스컬레이션 후보)

Phase별 사용:

Phase검색 대상
Phase 1 (상담사 보조)body_internal / embedding_internal — 내부 지식 활용 정당
Phase 2 (고객 챗봇)body_public / embedding_public — 공개 자산만 사용. has_internal_only_answer = true인 케이스는 "확인 후 답변 드리겠습니다" 또는 에스컬레이션

금지: 비공개 댓글 본문이 Phase 2 챗봇 응답에 직접 인용되거나 출처로 노출되어선 안 됨.

첨부파일 처리 전략

tb_post_file은 게시글/댓글에 첨부된 파일 메타. 활성 78,784건이 존재하고 Q&A 후보 1,358건 중 881건(64.9%)이 첨부 보유 — 무시 시 답변 자산의 절반 손실.

스키마 핵심: module(post/editor) + module_id(게시글 id) + realname(원본 파일명) + filetype(file/image/movie) + filesize.

파일 종류 분포 (확장자 상위):

분류확장자건수평균/최대 크기
이미지png, jpg, gif, jpeg, bmp38,063평균 ~수백KB
텍스트 문서pdf(11k), pptx(7k), hwp(5k), xlsx(5k), docx(2k), ppt(1.4k), doc(0.7k), txt(0.3k), csv(0.2k)34,125pdf 평균 2.3MB, pptx 평균 6.7MB / 최대 530MB
압축zip3,374평균 35MB / 최대 1.1GB
동영상mp4, mov, swf566mp4 평균 113MB / 최대 1.1GB
디자인psd, ai1,294평균 수MB ~ 수십MB
기타exe, sql, r, ttf 등소량

한국어 환경 특이점: HWP(한컴) 5,094건 — 별도 추출기(hwp.js 등) 필요.

종류별 처리 정책

파일 종류Phase 1 MVPPhase 1 후반Phase 2
인라인 이미지 (module=editor)§6 이미지 처리 전략 Stage AStage B (OCR)Stage C (Vision LLM)
이미지 첨부 (png/jpg/gif/jpeg/bmp)동일 — 메타만 보존OCR 텍스트 본문 부착Vision 캡션
텍스트 문서 (pdf/docx/hwp/txt/csv/xlsx)추출 텍스트를 본문에 부착 → 검색 대상청킹·구조 보존 개선
슬라이드 (pptx/ppt)텍스트 추출 (크기 상한 50MB)슬라이드 단위 청킹
압축파일 (zip)미추출, 메타만사례 검토 후 선택 도입Queue로 처리 검토
동영상 (mp4/mov/swf)미추출, 메타만Queue + 트랜스크립트 (Whisper 등)
디자인/실행 (psd/ai/exe)파일명만 메타

공통 원칙

  • 원본은 R2에 보관. DB의 realname/filename을 R2 키로 매핑. 답변 인용 시 R2 서명 URL 발급.
  • 가시성 상속: 댓글에 첨부된 파일은 그 댓글의 private_yn 값을 상속.
    • 공개 댓글 첨부 → 텍스트는 body_public·body_internal 모두에 부착
    • 비공개 댓글 첨부 → body_internal에만 부착, Phase 2 챗봇에서 노출 금지
    • 게시글 본문 첨부 → 공개 취급
  • 크기 상한: Phase 1에서는 50MB 초과 파일은 Queue 도입 전까지 보류. 메타만 인덱스에 보존.
  • 추출 실패 허용: 손상된 파일·미지원 포맷은 메타만 남기고 extraction_status: failed. 인덱싱 중단 사유 아님.
  • PII: 추출 텍스트에도 PII 검출·마스킹 적용 (이메일·전화·주민번호).
  • 챗봇 인용: 답변에 "참고: filename.pdf" 형식으로 출처 첨부 명시.

라이브러리 후보 (선정 보류)

포맷후보
PDFpdf-parse, pdfjs-dist
DOCXmammoth, docx
HWPhwp.js (한국 환경 필수)
XLSX/XLSxlsx (SheetJS)
PPTX자체 unzip + slide XML 파싱 또는 외부 변환 서비스
TXT/CSV직접 읽기

Cloudflare Workers의 CPU/메모리 제한으로 동기 추출은 일부 포맷·소형 파일만 가능. 대용량/복잡 추출은 별도 인덱서(로컬 백필 스크립트 또는 Phase 2 Queue Worker)에서 처리.

트레이드오프

  • 텍스트 문서 추출만 도입해도 답변 자산이 크게 늘어남(881건의 첨부 중 상당수가 매뉴얼·로그·샘플).
  • 그러나 추출 라이브러리·실패 케이스·대용량 처리 인프라 비용 증가.
  • 동영상 트랜스크립트는 즉시 도입 시 비용이 가장 크므로 Phase 2 Queue 도입과 정합.

7. 권장 인제스트 매핑 (초안)

OpenSearch chunks 인덱스 한 도큐먼트당:

인덱스 필드출처비고
doc_idlegacy:post:{tb_post.id}안정적 식별자
source_type"legacy_pms_qna"출처 구분
site_id / site_nametb_post.site_id + tb_site.name필터·메타
project_id / project_nametb_post.project_id + tb_project.name컨텍스트
labeltb_post_label.name카테고리
titletb_post.subject제목
question_text정제된 tb_post.content질문 본문
body_public공개 댓글만으로 구성한 스레드 결합 본문 (Q→A→Q2→A2…, 화자 라벨 포함)Phase 2 검색·임베딩
body_internal비공개 포함 스레드 결합 본문Phase 1 검색·임베딩
embedding_publictitle + question_text + body_public 기준 벡터Phase 2 k-NN
embedding_internaltitle + question_text + body_internal 기준 벡터Phase 1 k-NN
has_internal_only_answer공개 본문에는 답이 없고 비공개에만 있는 경우 truePhase 2 자동 에스컬레이션 트리거
image_urls본문/댓글에서 추출한 이미지 URL 배열인용용 메타 (외부 접근 URL로 치환)
attachments_public공개 영역(게시글 본문/공개 댓글)의 첨부 배열 — {filename, r2_url, filetype, size, visibility, extraction_status}Phase 2 인용 가능
attachments_internal비공개 댓글 첨부까지 포함한 전체 배열Phase 1 전용
extracted_text_public공개 첨부에서 추출한 텍스트(body_public에 부착 전 원본)청킹·재처리 용
extracted_text_internal비공개 포함 첨부 추출 텍스트Phase 1 전용
turn_count게시글 + 가시 댓글 수가중치·신선도 보조
askertb_post.writer메타
answerers가시 댓글 작성자 배열메타
reg_date_at / last_reply_attb_post.reg_date / 마지막 댓글 reg_date 변환신선도
comment_counttb_post.comm_cnt메타

청킹 전략: 스레드를 1 도큐먼트로 압축. 결합 본문(스레드 + 추출 첨부 텍스트)이 2000자 이상이면 의미 단위 분할 (동일 doc_id 유지). 짧은 단일 Q&A는 분할 없이 그대로. 첨부 추출 텍스트는 본문 결합 시 [첨부:{filename}] 헤더 뒤에 부착해 LLM이 출처를 인지 가능하게.

Phase별 쿼리: Phase 1은 body_internal + embedding_internal, Phase 2는 body_public + embedding_public을 검색 대상으로. 색인은 같은 도큐먼트라 운영 동기화 비용 1배수.


8. 표준 답변 후보 식별 전략

  • 동일/유사 질문에 같은 답변이 반복 등장 → 표준 답변 후보로 자동 추출.
  • 댓글 작성자가 맑은소프트 직원(tb_user에서 staff 플래그/도메인으로 식별) → 신뢰도 가중치 상향.
  • 후보 답변은 ROADMAP.md 1.9 피드백 루프의 자동 추천 흐름과 연결.

9. 다음 단계 (실행 항목)

  1. 표본 검수: site 1의 Q&A 후보 30~50건 추출 → 실제 CS 답변/내부 잡담 비율 확인 → 추가 필터 도출. 스레드형/단일형 분포와 비공개 댓글 영향도 함께 평가.
  2. HTML 정제 PoC: 5건 정도를 직접 정제해서 토큰 수·내용 유효성 측정.
  3. 노이즈 댓글 필터 룰 작성: 5자 미만, 동일 문자 반복(ddddd 등), 의미 없는 단일 단어 탐지.
  4. PII 검출 룰 작성: 이메일/전화/주민번호 정규식 + 마스킹 규칙.
  5. 가시성 정책 합의: Phase 1에서 비공개 댓글 활용 범위·노출 경로(상담사 화면에서만) 명문화. 첨부파일도 동일 정책 상속.
  6. 첨부 추출기 선정 PoC: PDF/DOCX/HWP/XLSX 추출 라이브러리 후보 평가 (한국어·표·이미지 포함 PDF에서의 정확도, Worker 적합성).
  7. R2 마이그레이션 계획: 78,784개 첨부의 R2 이관 전략 (전체 백필? 인덱싱 대상만? URL 매핑 테이블 유지?).
  8. 인제스트 파이프라인 설계: 일회성 백필 + 증분 동기화 (reg_date 기준) 정책. 스레드는 마지막 댓글 갱신 시 재인덱싱. 첨부 추출 실패는 메타만 보존.
  9. 사이트 채택 범위 합의: site 1만? 1+2? 다른 site는 외부 고객사 데이터라 사용 가능 여부 별도 확인 필요.
  10. 법적/내부 검토: 고객 문의 본문에 포함된 회사명·개인정보 사용 가능 범위, 비공개 댓글의 학습 자산화 가능 여부, 첨부 파일(특히 고객사 자료) 활용 가능 범위 확인.

10. 미사용 결정

다음은 본 DB에서 사용하지 않음으로 결론:

  • tb_chat_message — 짧은 사내 메신저, CS 자산 아님
  • tb_post_template — 양식/템플릿이라 답변 데이터 부재
  • 이미지만 있는 게시글 (Stage A 한정) — §6 이미지 처리 전략 참조. Stage B/C 도입 시 재평가
  • 노이즈 댓글 (5자 미만, 동일 문자 반복 등) — §6 스레드 처리 전략의 노이즈 필터로 제외
  • 압축파일(zip)·동영상·디자인/실행 파일 (Phase 1 MVP 한정) — §6 첨부파일 처리 전략 참조. zip은 검토 후 결정, 동영상은 Phase 2 Queue 도입 시 트랜스크립트 처리

비공개 댓글·첨부는 사용하지 않음이 아님. Phase 1 한정으로 활용. §6 비공개 댓글 / 첨부파일 처리 전략 참조.

Malgn Helper(고객상담 AI 챗봇) 프로젝트 문서·작업 이력