# HMM 백오피스 환경 기반 공통 카탈로그 전환

- Redmine: #723
- 기준 설계: Smilegate #722 `docs/design/722-configurable-data-catalog/README.md`
- 기준 커밋: `53342e7` (`smilegate`)
- 적용 브랜치: `hmm-backoffice`
- 운영 주소: `https://hmm-backoffice.cloud-handson.com`

## 1. 배경

현재 HMM 백오피스는 정형 데이터 목록을 별도 JSON 파일로 분리했지만 제품명, MCP 도구,
마스킹 대상, 보안 SQL 목록 등은 Java와 Thymeleaf에 남아 있다. 같은 백오피스 틀을 다른
고객사에 재사용하려면 소스를 수정하고 다시 빌드해야 한다.

Smilegate #722는 데이터 객체, 제품 표시명, 마스킹 정책, MCP/Select AI, 보안 SQL 목록을
환경 설정으로 옮겼다. HMM에는 이 구조를 적용하되 다음 현행 기능을 보존해야 한다.

- HMM 직원 Bearer token을 해시로 검증한다.
- MCP discovery와 tool call 모두 인증한다.
- AI Agent Tool 실행과 같은 DB 세션에서 `HMM_ACCESS_CTX`를 설정하고 반드시 해제한다.
- 용어 변환, 정형 HR 조회, 규정 PDF 검색의 세 MCP 도구를 계속 제공한다.
- 팀장과 팀원의 VPD 행 접근 규칙 및 마스킹 관리 기능을 유지한다.

## 2. 목표

1. 승인 데이터 객체와 객체 유형을 환경 JSON으로 설정한다.
2. TABLE과 VIEW를 모두 읽기 전용 미리보기 대상으로 지원한다.
3. DB comment는 TABLE/VIEW에 지원하고 Oracle annotation 변경은 TABLE에만 허용한다.
4. Data Redaction 관리 대상과 정책명을 별도 환경 JSON으로 설정한다.
5. 제품명, 페이지 타이틀, 데이터 명칭, MCP 공개 주소와 도구 계약을 환경 설정으로 옮긴다.
6. Smilegate #722의 단일 Select AI 도구 설정과 HMM의 복수 Agent Tool 설정을 모두 수용한다.
7. 번들 보안 SQL 화면의 노출 목록을 환경 allowlist로 제한한다.
8. 잘못된 설정은 애플리케이션 시작 시 거부한다.

## 3. 제외 범위

- HMM 사용자·그룹·역할·권한 테이블 구조 변경
- HMM 지식 문서 적재 구조 변경
- 기존 VPD 함수와 Data Redaction 정책 DDL 재작성
- Select AI 프로파일의 object list 자동 변경
- 운영 Bearer token 원문을 설정이나 Git에 저장

## 4. 설정 계약

### 4.1 데이터 카탈로그

```text
BACKOFFICE_CATALOG_OWNER
BACKOFFICE_CATALOG_OBJECTS
```

`BACKOFFICE_CATALOG_OBJECTS`는 아래 필드를 갖는 JSON 배열이다.

```json
[
  {
    "key": "employees",
    "tableName": "HMM_HR_EMPLOYEES",
    "objectType": "TABLE",
    "businessName": "직원 원장",
    "description": "직원·매니저·소속팀 정보",
    "previewColumns": ["EMPLOYEE_ID", "EMPLOYEE_CODE", "EMPLOYEE_NAME"]
  }
]
```

검증 규칙:

- owner와 tableName은 Oracle simple identifier만 허용한다.
- key는 소문자 영문으로 시작하고 소문자, 숫자, 하이픈만 허용한다.
- objectType은 `TABLE` 또는 `VIEW`만 허용한다.
- key와 tableName은 각각 중복될 수 없다.
- businessName과 description은 비어 있을 수 없다.
- previewColumns는 선택값이다. 지정하면 검증된 컬럼만 조회하며 VECTOR/BLOB 등 관리자
  미리보기에 부적합한 컬럼을 제외할 수 있다.
- 빈 목록이나 잘못된 JSON이면 애플리케이션 시작을 실패시킨다.

정형 데이터 미리보기는 카탈로그에서 선택한 객체만 SQL 식별자로 사용하고 최대 50건만
반환한다. 요청 파라미터를 SQL 객체명으로 직접 사용하지 않는다.

### 4.2 제품 표시

```text
BACKOFFICE_PRODUCT_NAME
BACKOFFICE_PRODUCT_TITLE
BACKOFFICE_PRODUCT_DATA_LABEL
```

공통 레이아웃, 데이터 화면, 메타데이터 화면, MCP 화면은 이 값을 사용한다. HMM 운영값은
`HMM HR Access Console`과 `HMM HR 데이터`이다.

### 4.3 마스킹 정책

```text
BACKOFFICE_MASKING_POLICIES
```

```json
[
  {
    "objectName": "HMM_HR_EMPLOYEES",
    "policyName": "HMM_EMPLOYEE_PII_REDACT"
  }
]
```

객체명과 정책명은 Oracle simple identifier로 검증하고, objectName과 policyName 중복을
각각 거부한다. 빈 값이면 관리 가능한 Data Redaction 정책이 없는 fail-closed 상태로
동작한다.

### 4.4 MCP

Smilegate #722의 단일 Select AI 도구 환경변수를 호환한다.

```text
BACKOFFICE_MCP_PUBLIC_URL
BACKOFFICE_MCP_SERVER_NAME
BACKOFFICE_MCP_TOOL_NAME
BACKOFFICE_MCP_TOOL_LABEL
BACKOFFICE_MCP_TOOL_DESCRIPTION
BACKOFFICE_MCP_PROMPT_DESCRIPTION
```

HMM처럼 여러 DBMS Cloud AI Agent Tool을 노출하는 배포는 다음 JSON을 사용한다.

```text
BACKOFFICE_MCP_TOOLS
```

```json
[
  {
    "name": "resolve_hr_term",
    "label": "HMM HR 용어 표준화",
    "description": "휴가·근태 표현을 표준 용어와 코드로 변환합니다.",
    "argumentName": "term",
    "argumentDescription": "확인할 휴가·근태 용어, 동의어 또는 코드입니다.",
    "executionType": "AGENT_TOOL",
    "targetName": "HMM_HR_TERM_RESOLVER",
    "targetParameterName": "P_TERM"
  }
]
```

`executionType`은 `AGENT_TOOL` 또는 `SELECT_AI`만 허용한다. `BACKOFFICE_MCP_TOOLS`가
비어 있으면 #722의 단일 `SELECT_AI` 도구 설정을 사용한다. HMM 운영은 세 개의
`AGENT_TOOL` 정의를 환경에 둔다.

MCP 보안 경계:

1. initialize, tools/list, tools/call 모두 유효한 HMM 사용자 Bearer token이 필요하다.
2. token 원문은 로그, 응답, DB에 저장하지 않는다.
3. AGENT_TOOL 실행 전 같은 JDBC 연결에서
   `ADMIN.HMM_ACCESS_CTX_PKG.SET_USER_BY_BEARER`를 실행한다.
4. 성공·실패와 관계없이 같은 연결에서 `CLEAR_USER`를 실행한다.
5. MCP JSON-RPC 오류에 DB password, SQL 전체 stack trace를 포함하지 않는다.

### 4.5 Select AI

```text
BACKOFFICE_SELECT_AI_DB_URL
BACKOFFICE_SELECT_AI_DB_USERNAME
BACKOFFICE_SELECT_AI_DB_PASSWORD
BACKOFFICE_SELECT_AI_PROFILE
```

단일 Select AI 도구는 프로파일 소유 계정으로 SHOWSQL을 생성한 후 다음 검증을 모두
통과한 SQL만 읽기 전용 트랜잭션에서 실행한다.

- 첫 문장은 SELECT 또는 WITH
- 세미콜론을 이용한 다중 문장 금지
- DDL, DML, transaction, lock, PL/SQL, DBMS/UTL/SYS 호출 금지
- 최대 100건, query timeout 30초
- 실행 후 항상 rollback

HMM 운영 MCP는 현재 세 개의 Agent Tool을 사용하므로 Select AI 접속은 선택 설정이다.
다른 고객사는 단일 Select AI 도구만 설정할 수 있다.

### 4.6 보안 SQL

```text
BACKOFFICE_SECURITY_SQL_SCRIPTS
```

번들된 `database/adb` 경로 안의 파일만 허용하며 요청값을 resource path로 사용하지 않는다.
HMM 운영에서는 `72_hmm_leave_team_vpd.sql` 등 HMM 관련 SQL만 노출한다.

## 5. 코드 구조

| 구성 | 역할 |
|---|---|
| `DataCatalog` | 승인 객체 조회 인터페이스 |
| `EnvironmentDataCatalog` | 환경 JSON 파싱, 정규화, fail-fast 검증 |
| `MaskingPolicyCatalog` | 관리 가능한 Data Redaction 대상 조회 |
| `EnvironmentMaskingPolicyCatalog` | 마스킹 환경 JSON 파싱과 검증 |
| `ProductProperties` | 제품명, 타이틀, 데이터 표시명 |
| `McpProperties` | 공개 URL, 서버명, 단일 Select AI 호환 설정, 복수 도구 JSON |
| `EnvironmentMcpToolCatalog` | MCP 도구 계약 파싱과 allowlist |
| `McpSseService` | JSON-RPC와 인증 경계, 설정 기반 도구 dispatch |
| `SelectAiService` | SHOWSQL 생성, 읽기 전용 검증 및 제한 실행 |
| `SecuritySqlScriptProperties` | 보안 SQL allowlist |

고객사별 이름과 객체는 `application.yml`의 환경 매핑과 운영 env에만 둔다. HMM의 DB
매퍼와 VPD 함수는 HMM 업무 모델 자체이므로 이번 공통화 대상이 아니다.

## 6. TABLE/VIEW 메타데이터

- `all_tab_comments`, `all_tab_columns`, `all_col_comments`는 TABLE/VIEW 공통 조회에 쓴다.
- `COMMENT ON TABLE`과 `COMMENT ON COLUMN`은 승인 객체에만 실행한다.
- Oracle annotation 조회·변경은 TABLE에만 허용한다.
- VIEW를 선택한 경우 annotation 입력 UI를 숨기고 서버도 요청을 거부한다.
- 화면에는 카탈로그의 objectType과 owner를 표시한다.

## 7. 운영 이행

1. 기존 `/etc/vpd-backoffice.env`를 백업한다.
2. 기존 DB 비밀번호와 remember-me secret은 변경하지 않는다.
3. 데이터 카탈로그 6개, 마스킹 정책 4개, MCP 도구 3개, HMM 보안 SQL 목록을 추가한다.
4. `BACKOFFICE_HMM_MCP_PUBLIC_URL`은
   `BACKOFFICE_MCP_PUBLIC_URL`로 이전하되 한 릴리스 동안 fallback을 지원한다.
5. JAR 교체 후 systemd를 재시작한다.
6. 10초 간격으로 health, 로그인, 정형 데이터, 메타데이터, 마스킹, MCP를 확인한다.
7. 실패 시 기존 JAR와 env 백업으로 복구한다.

## 8. 검증

자동 검증:

- 카탈로그 정상/빈 값/잘못된 식별자/중복 key/중복 object 테스트
- TABLE/VIEW 미리보기 SQL과 row limit 테스트
- VIEW annotation 변경 거부 테스트
- 마스킹 정책 정상/빈 값/중복 테스트
- MCP 3개 도구 discovery, 정확한 argument/target dispatch, 인증 거부 테스트
- Select AI 안전 SQL 검증 테스트
- 보안 SQL resource allowlist 테스트
- 전체 `mvn test`

운영 검증:

- 관리자 로그인과 지속 로그인
- 전체 메뉴 HTTP 200 및 HMM 데이터 표시
- 정형 데이터 6개 객체 조회
- 메타데이터 6개 객체 조회
- 마스킹 정책 4개 상태 조회
- MCP 무토큰 401, 잘못된 token 401
- 임시 사용자 token으로 tools/list와 세 도구 call
- 서비스 로그에 startup 오류와 비밀정보 출력이 없는지 확인

## 9. 완료 조건

- HMM 백오피스의 고객사별 카탈로그와 표시 설정이 운영 env로 이전되어 있다.
- 기존 HMM 토큰 인증과 VPD 컨텍스트 적용이 회귀하지 않는다.
- Maven 테스트와 운영 전수 검증이 통과한다.
- Gitea `hmm-backoffice`에 #723 커밋이 push되어 있다.
- Redmine #723이 Planner부터 Documenter까지 근거와 함께 완료되어 있다.
