DB 인사이트 AI는 소스텔 ERP 데이터베이스에 읽기/쓰기 접근이 가능한 AI 챗봇입니다. 사용자가 자연어로 질문하면 AI가 적절한 SQL 쿼리를 생성하여 실행하고, 결과를 이해하기 쉬운 형태로 답변합니다.
| 구성요소 | 기술 | 역할 |
|---|---|---|
| 프론트엔드 | ERP 내 채팅 UI (JS) | 채팅 인터페이스, 대화 이력, 테이블/차트 렌더링 |
| PHP API | PHP (프록시) | 인증 확인 → Python 서버로 요청 전달 → 응답 반환 |
| AI 엔진 | Python (FastAPI) | 자연어 분석 → SQL 생성 → 실행 → 답변 생성 |
| LLM | Claude API / OpenAI API | 자연어 이해 + SQL 변환 + 답변 포맷팅 |
| DB 접근 | MySQL Connector | 읽기(SELECT) + 쓰기(INSERT/UPDATE) |
AI가 정확한 SQL을 생성하려면 DB 구조를 알아야 합니다. Python 엔진에 아래 정보를 사전 로딩합니다:
| 정보 | 내용 |
|---|---|
| 테이블 목록 | items, inventory, lots, serials, purchase_orders, receivings, production_orders, production_inputs, production_outputs, shipments, shipping_requests, disposals, warehouses, vendors, users, departments, approvals, 등 30+ 테이블 |
| 컬럼 정보 | 각 테이블의 컬럼명, 타입, NULL 여부, 기본값, 코멘트 |
| 관계(FK) | items.id → inventory.item_id, purchase_orders.vendor_id → vendors.id 등 |
| ENUM 값 | status 컬럼의 DRAFT/PENDING_APPROVAL/CONFIRMED 등 상태값 의미 |
| 비즈니스 용어 | "입고" = receivings, "발주" = purchase_orders, "투입" = production_inputs 등 한글↔테이블 매핑 |
INFORMATION_SCHEMA에서 테이블/컬럼 정보를 자동으로 가져옵니다. DB 구조가 변경되어도 재시작만 하면 반영됩니다.
| 보안 항목 | 대책 | 설명 |
|---|---|---|
| SQL 인젝션 차단 | 파라미터 바인딩 강제 | AI가 생성한 SQL도 반드시 파라미터화 처리 |
| 위험 쿼리 차단 | 화이트리스트 방식 | SELECT, INSERT만 허용. UPDATE는 특정 테이블만. DROP/DELETE/TRUNCATE 원천 차단 |
| 쓰기 확인 | 2단계 확인 | INSERT/UPDATE 실행 전 사용자에게 확인 요청 필수 |
| 권한 연동 | 역할 기반 제한 | 대표: 전체 테이블 접근 / 실무자: 본인 관련 테이블만 (자기 부서, 자기 요청) |
| 감사 로그 | 모든 쿼리 기록 | AI가 실행한 모든 SQL을 audit_logs에 저장 (who, when, what) |
| 데이터 노출 방지 | 민감 컬럼 마스킹 | password_hash, API 키 등 민감 컬럼은 조회 결과에서 자동 제외 |
| 실행 제한 | 쿼리 타임아웃 | 5초 이상 걸리는 쿼리 자동 중단, 결과 1,000행 제한 |
| 파일 | 역할 |
|---|---|
ai_server/main.py | FastAPI 앱 진입점, API 라우터 |
ai_server/db_schema.py | DB 스키마 자동 로딩 (INFORMATION_SCHEMA) |
ai_server/query_builder.py | LLM에 스키마 컨텍스트 전달 → SQL 생성 요청 |
ai_server/query_validator.py | 생성된 SQL 안전성 검증 (화이트리스트 체크) |
ai_server/query_executor.py | MySQL 쿼리 실행 (타임아웃/행 제한 적용) |
ai_server/response_formatter.py | 쿼리 결과 → 자연어 답변 + 테이블/차트 변환 |
ai_server/conversation.py | 대화 이력 관리 (맥락 유지) |
ai_server/permissions.py | 역할 기반 테이블/컬럼 접근 제어 |
ai_server/config.py | DB 접속 정보, LLM API 키, 보안 설정 |
| 파일 | 역할 |
|---|---|
pages/ai/api/chat.php | 프론트 → Python 서버 프록시 (인증 체크 + 요청 전달) |
pages/ai/index.php | 채팅 UI 페이지 (ERP 레이아웃 내) |
| 파일 | 역할 |
|---|---|
pages/ai/chat.js | 채팅 UI, 메시지 렌더링, 테이블/차트 표시 |
pages/ai/chat.css | 채팅 스타일 (말풍선, 코드 블록, 테이블) |
| 방법 | 위치 | 용도 |
|---|---|---|
| 전용 페이지 | 사이드바 메뉴 "AI 인사이트" | 깊은 분석, 복합 질문, 대화 이력 관리 |
| 플로팅 위젯 | 우하단 채팅 버블 | 빠른 질문 (어느 페이지에서든 접근) |
| 카테고리 | 질문 예시 | SQL 유형 |
|---|---|---|
| 재고 | 현재고, 안전재고 이하, 로트별 잔여, 시리얼 위치, 창고별 분포 | SELECT + JOIN + GROUP BY |
| 입고 | 이번 달 입고 현황, 거래처별 입고 금액, 미입고 발주, 입고 지연 | SELECT + SUM + DATEDIFF |
| 생산 | 생산오더 현황, 투입 진행률, BOM 부품 충분 여부, 생산 실적 | SELECT + 서브쿼리 + BOM 재귀 |
| 출고 | 출고 현황, 사업별 출고 금액, 미출고 건, 출고 지연 | SELECT + JOIN |
| 구매 | 발주 현황, 거래처별 매입 비교, 단가 변동, 발주 대기 | SELECT + GROUP BY + 기간 비교 |
| 추적 | 시리얼 이력, 로트 소비 이력, 시리얼 계보(genealogy) | SELECT + 다중 JOIN |
| 회계 | 매입/매출 전표 합계, 수금/지급 현황, 원가 분석 | SELECT + SUM + 기간별 |
| 분석 | 월별 추이, 전월 대비, 거래처 비교, 재고 회전율 | 복합 집계 + 비교 |
| 등록 | 발주요청, 자재요청, 메모 등록 | INSERT (확인 후) |
| 일반 | 시스템 사용법, 메뉴 안내, 용어 설명 | SQL 불필요 (지식 응답) |
INFORMATION_SCHEMA)pages/ai/api/chat.php)| 확인 | 점검 항목 (Q) | 판단 기준 / 예시 답변 (A) | 비고 |
|---|---|---|---|
| ☐ | AI 채팅 페이지에 정상 진입 되는가? | 사이드바 "AI 인사이트" 클릭 시 채팅 화면 표시 | 필수 |
| ☐ | 자연어로 재고 질문이 가능한가? | "현재 원자재A 재고 몇 개야?" → 정확한 수량 답변 | 필수 |
| ☐ | 테이블 형태로 결과가 표시되는가? | 목록형 답변 시 정렬 가능한 테이블로 렌더링 | 필수 |
| ☐ | 복합 분석 질문에 답변 가능한가? | "다음 달 뭘 발주해야 해?" → BOM + 재고 분석 결과 | 주요 |
| ☐ | 쓰기 요청 시 확인 단계가 있는가? | "발주요청 올려줘" → [확인]/[취소] 버튼 표시 후 실행 | 필수 |
| ☐ | 위험 쿼리가 차단되는가? | DROP/DELETE/TRUNCATE 요청 시 차단 메시지 표시 | 필수 |
| ☐ | 역할 기반 접근 제어가 동작하는가? | 실무자 계정 → 민감 테이블(users, audit_logs) 조회 불가 | 주요 |
| ☐ | 대화 맥락이 유지되는가? | "아까 그 품목" → 이전 대화의 품목을 참조하여 답변 | |
| ☐ | 실행된 SQL을 확인할 수 있는가? | 답변 하단 "SQL 보기" 클릭 시 실행된 쿼리 표시 | |
| ☐ | 결과를 엑셀로 내보낼 수 있는가? | 테이블 결과에 "엑셀 다운로드" 버튼 존재 및 동작 | |
| ☐ | 플로팅 위젯이 모든 페이지에서 동작하는가? | 우하단 채팅 버블 클릭 → 미니 채팅창 표시 |