# 설계서: 스마일게이트 백오피스 잔여 UI 전환 및 운영 검증

## 추적성

- Redmine: #703 `[Smilegate] 백오피스 잔여 UI 전환 및 운영 검증`
- 관련 설계: `docs/design/smilegate-demo-rebranding/README.md`, `docs/design/smilegate-identity-administration/README.md`
- 구현 대상: `src/main/resources/templates/`, `src/main/resources/static/js/app.js`, `src/main/java/com/cloudhandson/vpdbackoffice/`, `poc4_active_source_20260714/`
- 검증 대상: Maven·Streamlit 설정 테스트, 인증 후 핵심 메뉴 HTTP 응답, 화면의 잔여 고객사 문구 검사
- 상태: Implemented / deployment pending

## 프로젝트 개요

이 저장소의 Spring Boot 백오피스는 Oracle VPD, Data Redaction, FGA, ORDS 및 Select AI PoC의 운영 설정을 확인하고 관리한다. 공개 데모의 고객·업무 대상은 스마일게이트 게임 로그와 서비스 데이터 분석이다.

## 목표

백오피스에 남은 KB손해보험/보험 업무 예시를 스마일게이트 게임 데이터 기준으로 전환한다. 화면 문구만 바꾸지 않고, 실제 MCP Select AI 안내·행 접근 규칙 요약·마스킹 동기화 대상도 `SGMP_POC` 게임 데이터와 모순되지 않게 맞춘다.

## 범위

1. 웹 화면과 브라우저에서 실행되는 JavaScript에 노출된 기존 보험 업무 예시를 게임 사용자·게임 서비스·판매/환불 데이터 예시로 교체한다.
2. 권한 규칙의 표시명과 미리보기는 기존 조건 코드의 저장 형식을 보존하면서 게임 데이터 의미로 설명한다.
3. MCP 데모의 tool 식별자·설명·질의 예시를 `SGMP_POC` Select AI 프로파일 기반으로 전환한다. 행 접근 토큰을 전제로 하는 기존 KB ORDS endpoint를 게임 데이터 endpoint인 것처럼 표시하지 않는다.
4. Data Redaction 동기화는 `SGMP_POC`의 실제 게임 사용자·판매 데이터 컬럼만 관리 대상으로 삼는다.
5. 내부 호환용 `CB_*` 뷰와 과거 SQL 이력은 실행 경로에서 제외한다. Smilegate 공개 화면·MCP 설정은 이력의 고객 데이터나 endpoint를 참조하지 않는다.
6. Streamlit 외피는 Smilegate 프로필·게임 데이터 시나리오·`oracle.select_ai.smilegate_game_text2sql` MCP 하나만 노출한다. 이전 고객용 토큰 프리셋 및 감사·보안관리 탭은 기본 실행 경로에서 제외한다.
7. `/schema-metadata`의 테이블 comment·컬럼 comment·annotation 조회와 저장 DDL은 모두 `SchemaMetadataMapper`로 수행한다. 메타데이터 조회는 `SGMP_POC` owner와 허용된 테이블 목록으로 한정한다.

## 설계 결정

### 1. 업무 용어는 데이터 모델의 사실에 맞춘다

- 사용자 식별자: `CZN_COMN_USER_MST.GUID`/`AUID`, `COMN_SALES_USER_MST.USER_KEY_VAL`
- 게임 서비스 식별: `COMN_GAME_ALIAS_BAS`의 `GAME_ID`, `GAME_PREFIX`, `GAME_NM`, `GAME_ALIAS_NM`
- 거래/서비스 데이터: `COMN_SALES_TXN`, `COMN_REFUND_TXN`, `CZN_CUSTOM_*`

화면 예시는 위 객체를 사용하되, 실제로 존재하지 않는 담당자·채널 컬럼을 SQL 예시로 만들지 않는다.

### 2. 조건 코드의 호환성과 표시 의미를 분리한다

`OWN_CONTRACT`, `CHANNEL_CONTRACT`, `OWN_CUSTOMER`, `CHANNEL_CUSTOMER` 같은 과거 코드값은 저장값 호환을 위해 유지한다. 화면에는 각각 `담당 게임 서비스`, `토큰 채널 게임 서비스`, `담당 게임 사용자 데이터`, `토큰 채널 게임 사용자 데이터`로 표시한다. VPD 구현이 게임 데이터에 대한 실제 관계를 갖지 않는 조건은 설명에서 일반적인 보안 범위 조건으로만 제시하고, 존재하지 않는 조인 SQL을 제안하지 않는다.

### 3. MCP/Select AI는 현재 실행 경계를 정직하게 표시한다

MCP tool은 `SGMP_POC_HAIKU45` 프로파일을 기준으로 게임 데이터의 읽기 전용 `SELECT`/`WITH` 질의를 **생성**하는 용도로 안내한다. 생성 단계는 `SHOWSQL`만 사용하며 모델이 만든 SQL을 백오피스가 자동 실행하지 않는다. 운영자는 Database Actions 또는 검증된 실행 경로에서 SQL을 검토·실행한다.

프로파일은 `SGMP_POC` 소유이므로 일반 백오피스 관리 DB 연결(ADMIN)에서 사용할 수 없다. MCP Text2SQL 서비스는 별도 `BACKOFFICE_SELECT_AI_DB_URL`, `BACKOFFICE_SELECT_AI_DB_USERNAME`, `BACKOFFICE_SELECT_AI_DB_PASSWORD` 환경 변수로 `SGMP_POC` 연결을 만들고, 설정이 없을 때는 명확한 설정 오류만 반환한다. 비밀 값은 Git·화면·로그에 저장하지 않는다.

호출 전에 백오피스의 Bearer 토큰 해시를 검증하고 활성 사용자 토큰에만 Text2SQL 요청을 허용한다. 현재 PoC의 두 데모 운영 사용자는 게임 데이터 전체 권한을 갖지만, 후속 권한 세분화 시 이 지점에 역할별 데이터 범위 검증을 추가한다.

### 4. 마스킹 대상은 관리 가능한 실제 객체로 제한한다

마스킹 동기화 대상 owner는 `SGMP_POC`다. 관리 정책은 실제 컬럼 존재 여부를 검증한 뒤 사용자 식별자와 거래 사용자 식별자에만 적용한다. 대상에 없는 규칙은 DBMS_REDACT 호출 전에 화면 설정 오류로 처리한다.

### 5. 스키마 메타데이터 접근은 MyBatis로 통일한다

`/schema-metadata`는 화면 카드 목록을 정적 허용 목록에서 만들고, 선택된 테이블의 comment·컬럼·annotation만 조회한다. 서비스 계층에는 JDBC 직접 실행을 두지 않는다. table/column comment 사전 조회는 `owner = 'SGMP_POC'` 조건을 갖는다. Oracle의 `ALL_ANNOTATIONS_USAGE`에는 객체 owner 컬럼이 없으므로 annotation 조회는 허용 목록에서 선택된 정확한 `OBJECT_NAME`과 `OBJECT_TYPE='TABLE'`로 한정한다. DDL에 쓰이는 테이블·컬럼·annotation 이름은 호출 전에 대문자 식별자 규칙과 허용 테이블 목록으로 검증한다.

백오피스 도메인은 Caddy에서 `gzip`만 사용한다. Edge가 HTTP/2 `zstd` HTML 응답을 완료된 상태에서도 pending으로 표시한 운영 증거가 있어, Streamlit 콘솔과 분리해 관리 UI 응답의 압축 호환성을 우선한다.

공통 화면 head의 외부 UI 보조 스크립트는 `defer`로 로드한다. CDN 지연이 정적 서버 렌더링 화면의 HTML 파싱·첫 표시를 막아서는 안 된다. `schema-metadata`는 서버 렌더링만으로 테이블 선택과 comment/annotation 보기를 제공한다.


## 변경 파일과 책임

| 영역 | 파일 | 변경 |
| --- | --- | --- |
| 행 접근 화면 | `templates/permissions.html`, `static/js/app.js`, `PermissionView.java` | 보험 용어와 존재하지 않는 KB SQL 예시 제거 |
| 마스킹 화면 | `templates/masking-rules.html`, `templates/user-masking-rules.html`, `MaskingPolicySynchronizer.java` | 게임 데이터 예시 및 실제 `SGMP_POC` 관리 대상 사용 |
| VPD/운영 화면 | `templates/vpd-filter-runtime.html`, `templates/operation-status.html` | 게임 데이터 상태 표시 예시 적용 |
| MCP 화면 | `templates/mcp-sse.html`, `McpSseService.java`, `SmilegateSelectAiService.java` | 게임 데이터 Select AI 도구, 토큰 검증 및 SHOWSQL 생성 |
| 보안 스크립트 화면 | `SecuritySqlScriptService.java` | UI에 노출되는 KB 설명을 게임 데이터 설명으로 교체 |
| Streamlit 외피 | `poc4_active_source_20260714/config/`, `apps/poc4/mcp_discovery_ui.py` | Smilegate 로그인/헤더/시나리오와 단일 게임 Text2SQL MCP 계약 적용 |
| 스키마 메타데이터 | `SchemaMetadataService.java`, `SchemaMetadataMapper.java`, `SchemaMetadataMapper.xml` | 직접 JDBC 제거, MyBatis 조회·DDL 통일, `SGMP_POC` owner 조건 강제 |

## 완료 기준

1. Smilegate 공개 화면·활성 MCP 설정에서 기존 고객사명·보험 원장·기존 endpoint가 검색되지 않는다. 과거 SQL 이력 및 미실행 호환 코드는 제외한다.
2. `SGMP_POC` 게임 데이터 객체만 마스킹 동기화 대상으로 선택된다.
3. `mvn test`가 통과한다.
4. 인증된 `admin`으로 주요 메뉴가 오류 배너 없이 200 응답을 반환하고, Streamlit의 MCP는 Text2SQL 생성 결과를 정상 표기한다.
5. 변경 사항은 #703을 참조하는 Git 커밋과 Redmine 작업 로그로 남긴다.

## 위험 및 완화

- 과거 KB ORDS API는 게임 데이터 정책을 보장하지 않는다. endpoint 이름만 치환해 기존 API를 재사용하지 않는다.
- 운영 VM SSH 키 인증이 거부될 수 있다. 로컬 빌드·공개 URL 확인을 먼저 수행하고, 배포 시에는 승인된 운영 접속 경로를 사용한다.
