# HMM ADB-RDS PostgreSQL DB Link 녹화 절차

- Redmine: #730
- 적용 브랜치: `hmm-backoffice`
- 실행 위치: Oracle ADB Database Actions SQL Worksheet
- 실행 사용자: `ADMIN`
- 원격 DB: AWS RDS for PostgreSQL
- 원격 데이터베이스/스키마: `postgres` / `hmm_demo`

## 1. 목적

ADB SQL Worksheet에서 AWS RDS PostgreSQL을 Database Link로 연결하고, HMM 가상 선사
실적을 Oracle 로컬 View로 노출하는 전 과정을 녹화한다.

녹화 순서는 다음과 같이 고정한다.

1. 사전 점검
2. PostgreSQL 접속 Credential 생성
3. 대상 호스트 ACL 등록과 조회
4. Oracle 관리형 PostgreSQL Database Link 생성
5. 원격 테이블 직접 조회
6. Select AI에서 사용할 로컬 View와 메타데이터 생성
7. 행 수와 최신 실적 검증

## 2. 기준 자료

사내 교육자료를 실행 구문의 1차 기준으로 사용한다.

- `/Users/joungminko/devkit/fy26_ai/fy26_ai_internal_training/2회차/proxy_database/README.md`
- PostgreSQL 절차: `3.2 PostgreSQL Database 연결`
- 검증된 주의사항:
  - `gateway_params`의 `db_type`은 소문자 `postgres`
  - `port`는 문자열이 아닌 숫자 `5432`
  - PostgreSQL 스키마, 테이블, 컬럼 이름은 큰따옴표로 감싼다.
  - Select AI에는 원격 테이블을 직접 등록하지 않고 메타데이터를 부여한 Oracle View를
    등록한다.

## 3. 연결값과 객체명

| 항목 | 값 |
|---|---|
| RDS host | `database-1.czaaygccsncp.ap-northeast-2.rds.amazonaws.com` |
| RDS port | `5432` |
| PostgreSQL database | `postgres` |
| PostgreSQL user | `postgres` |
| ADB Credential | `HMM_RDS_PG_CRED` |
| ADB Database Link | `HMM_RDS_PG_LINK` |
| 원격 schema | `hmm_demo` |
| 로컬 carrier View | `HMM_RDS_CARRIERS_V` |
| 로컬 월간 실적 View | `HMM_RDS_CARRIER_PERF_V` |
| 로컬 최신 실적 View | `HMM_RDS_CARRIER_LATEST_V` |

비밀번호는 SQL 파일에 저장하지 않는다. 녹화 직전 Worksheet에 붙여 넣은 Credential
구문의 `<RDS_PASSWORD>`만 실제 값으로 바꾸고, 비밀번호가 보이는 화면은 녹화에서
가리거나 일시 정지한다.

운영 전환 시에는 PostgreSQL master 사용자 대신 `hmm_federation_reader`만 상속한 전용
LOGIN 사용자를 만들어 Credential을 교체한다.

## 4. ACL의 역할

사내 교육자료의 Oracle 관리형 heterogeneous Database Link 절차에는
`DBMS_NETWORK_ACL_ADMIN` 호출이 포함되지 않는다. DB Link 연결은
`DBMS_CLOUD_ADMIN.CREATE_DATABASE_LINK`의 관리형 gateway가 수행한다.

이번 데모의 ACL 스크립트는 요청한 네트워크 통제 절차를 명시적으로 보여주고, `ADMIN`에게
RDS host의 이름 해석과 5432 포트 연결 권한이 등록되었음을 `DBA_HOST_ACES`로 확인하기
위한 단계다. 이 ACL을 AWS RDS Security Group 허용이나 관리형 gateway의 출발 IP 허용과
동일한 것으로 설명하지 않는다.

- `resolve` ACE: 포트 범위를 지정하지 않는다.
- `connect` ACE: `5432`만 지정한다.
- AWS 측에서는 RDS가 public access 가능해야 하고, Security Group이 Oracle 관리형
  gateway에서 오는 접속을 허용해야 한다.
- 로컬 `global-bundle.pem`은 `psql` 검증용이다. 관리형 DB Link 생성 구문에 업로드하거나
  `directory_name`으로 지정하지 않는다.

## 5. View 설계

### 5.1 `HMM_RDS_CARRIERS_V`

`hmm_demo.carriers`의 Select AI용 기준정보 View다. PostgreSQL `boolean`과
`timestamptz` 컬럼은 이번 분석 범위에서 제외해 이기종 타입 변환 변수를 줄인다.

### 5.2 `HMM_RDS_CARRIER_PERF_V`

`hmm_demo.carrier_monthly_performance`의 18개월 KPI 144행을 제공한다. 복합 Primary Key는
`CARRIER_CODE + PERFORMANCE_MONTH`이며 `CARRIER_CODE`는 carrier View를 참조한다는 관계를
View comment에 기록한다.

### 5.3 `HMM_RDS_CARRIER_LATEST_V`

원격 `hmm_demo.carrier_performance_latest_v`를 노출해 2026-07 최신월 선사 8건을 제공한다.

각 View는 원격 소문자 컬럼을 Oracle의 일반 대문자 식별자로 명시적으로 alias한다. 따라서
후속 SQL과 Select AI metadata에서는 큰따옴표 없이 안정적으로 사용할 수 있다.

### 5.4 기존 접근 그룹을 이용한 직원별 선사 배정

직원별 담당 선사는 신규 업무 테이블을 만들지 않고 기존 백오피스 접근 그룹 모델을
재사용한다.

| 기존 객체 | 선사 배정에서의 역할 |
|---|---|
| `HMM_HR_EMPLOYEES` | 직원, 팀장, 팀 관계 |
| `HMM_ACCESS_GROUPS` | `CARRIER_C001`부터 `CARRIER_C008`까지 선사 접근 그룹 |
| `HMM_ACCESS_GROUP_MEMBERS` | 직원과 담당 선사의 연결 |
| `HMM_CARRIER_ASSIGNMENTS_V` | 기존 세 테이블을 Select AI가 사용하기 쉬운 형태로 정규화 |

`HMM_CARRIER_ASSIGNMENTS_V.CARRIER_CODE`는 그룹 코드에서 `CARRIER_` 접두어를 제거해
만들며, PostgreSQL 기반 `HMM_RDS_*_V.CARRIER_CODE`와 조인한다. 이 구조를 사용하면 기존
백오피스의 접근 그룹 화면에서 담당자 변경이 가능하고 별도 관리 화면이나 중복 테이블이
필요하지 않다.

`HMM_ACCESS_PERMISSION_RULES`는 행 접근 정책을 정의하는 보안 메타데이터이므로 담당 선사
원장으로 사용하지 않는다.

Select AI가 이 관계를 추론에만 의존하지 않도록 네 View의 table comment와
`CARRIER_CODE` column comment 양쪽에 상대 객체명과 조인 키를 기록한다.

- `HMM_CARRIER_ASSIGNMENTS_V.CARRIER_CODE`
  ↔ `HMM_RDS_CARRIERS_V.CARRIER_CODE`
- `HMM_CARRIER_ASSIGNMENTS_V.CARRIER_CODE`
  ↔ `HMM_RDS_CARRIER_PERF_V.CARRIER_CODE`
- `HMM_CARRIER_ASSIGNMENTS_V.CARRIER_CODE`
  ↔ `HMM_RDS_CARRIER_LATEST_V.CARRIER_CODE`

## 6. 녹화용 실행 파일

| 순서 | 파일 | 화면에서 확인할 결과 |
|---|---|---|
| 0 | `73_hmm_rds_pg_00_precheck.sql` | 현재 사용자 `ADMIN`, 기존 객체 유무 |
| 1 | `74_hmm_rds_pg_01_credential.sql` | Credential 1건, 사용자명 `postgres` |
| 2 | `75_hmm_rds_pg_02_acl.sql` | `resolve`, `connect:5432` ACE |
| 3 | `76_hmm_rds_pg_03_dblink.sql` | `HMM_RDS_PG_LINK` 1건 |
| 4 | `77_hmm_rds_pg_04_remote_query.sql` | 선사 8건, 월간 실적 144건 |
| 5 | `78_hmm_rds_pg_05_views.sql` | Oracle 로컬 View 3개 |
| 6 | `79_hmm_rds_pg_06_verify.sql` | `8 / 144 / 8`, 위험도 3종 |
| 재촬영 전 | `80_hmm_rds_pg_99_cleanup.sql` | View, DB Link, Credential만 제거 |
| 7 | `81_hmm_carrier_access_groups.sql` | 선사 그룹 8건, 구성원 8건, federation 조인 8건 |
| 8 | `82_hmm_federation_relationship_comments.sql` | 양쪽 View의 명시적 조인 관계 metadata |

## 7. 성공 기준

- `ALL_CREDENTIALS`에서 `HMM_RDS_PG_CRED`가 조회된다.
- `DBA_HOST_ACES`에서 RDS host의 `resolve`, `connect`가 조회된다.
- `USER_DB_LINKS`에서 `HMM_RDS_PG_LINK`가 조회된다.
- 원격 직접 조회가 선사 8건과 실적 144건을 반환한다.
- 로컬 View 3개가 `VALID` 상태다.
- 최신 View가 8건을 반환하고 `GREEN`, `AMBER`, `RED`가 모두 존재한다.
- `CARRIER_%` 접근 그룹 8개와 직원-그룹 구성원 8건이 존재한다.
- `HMM_CARRIER_ASSIGNMENTS_V`와 `HMM_RDS_CARRIER_LATEST_V`의 조인이 8건을 반환한다.
- Credential password가 SQL 파일, Git diff, 화면 출력에 남지 않는다.

## 8. 실패 시 판별

| 증상 | 우선 확인 |
|---|---|
| `ORA-01031` | `ADMIN`으로 실행했는지 확인 |
| Credential already exists | 재촬영 전 cleanup 실행 여부 확인 |
| Database link already exists | 재촬영 전 cleanup 실행 여부 확인 |
| `ORA-28500`, `ORA-02063`, timeout | RDS 상태, public access, Security Group, endpoint/port 확인 |
| relation does not exist | `"hmm_demo"."..."` 큰따옴표와 객체명 확인 |
| 인증 실패 | Credential의 PostgreSQL 사용자/비밀번호 확인 |
| View comment 대상 오류 | 로컬 View/컬럼은 큰따옴표 없는 대문자 식별자 사용 |

## 9. 제외 범위

- 별도 직원-선사 담당 테이블은 만들지 않고 기존 접근 그룹 객체를 재사용한다.
- 선사별 VPD 정책 적용은 후속 단계에서 수행한다.
- Select AI profile과 MCP tool 등록은 로컬 View 검증 후 후속 단계에서 수행한다.
- 실제 실행은 녹화를 진행하는 사용자가 SQL Worksheet에서 수행한다.
