# 설계서: 정형 데이터 원장 조회 (#618) > **상태**: Implemented · QA passed · deployed > **작성**: [AI] Architect · **최종수정**: 2026-07-07 > **추적성** — Redmine: #618 · 관련 ADR: 없음 > · 구현 파일: `StructuredDataController`, `StructuredDataService`, `structured-data.html` · 테스트: `StructuredDataServiceTest`, `GuidedFlowTemplateTest` ## 1. 목적 (Why) VPD 권한 운영자가 KBAIPOC의 정형 보험 원장 데이터를 별도 SQL 도구 없이 빠르게 확인할 수 있게 한다. ## 2. 범위 (Scope) - **포함**: `POC_2`의 고객·상품·계약·담보·청구·외부보유·이해관계자 7개 테이블 선택, 컬럼명, 최대 50건 읽기 전용 미리보기. - **제외 (out of scope)**: 임의 SQL 실행, 데이터 수정·삭제, VPD 정책 자동 생성, RAG/약관/백업·시스템 테이블 표시. ## 3. 인수조건 (Acceptance Criteria) - [x] 연동 도구 메뉴에서 정형 데이터 조회 화면으로 이동할 수 있다. - [x] 지정된 7개 테이블만 선택할 수 있다. - [x] 선택한 테이블의 컬럼 순서와 최대 50건의 행을 표시한다. - [x] 허용 목록 밖의 table 파라미터는 SQL 문자열에 포함되지 않고 거부된다. - [x] 데이터가 없거나 DB 조회가 실패해도 안전한 안내를 표시한다. ## 4. 컨텍스트 & 제약 - 데이터 owner는 현재 KBAIPOC의 `POC_2`로 고정한다. - 백오피스는 관리자용 읽기 화면이므로 페이지를 인증 뒤에만 제공한다. - 고객 식별 정보는 현 POC의 `RRN_MASKED`처럼 이미 마스킹된 컬럼만 사용한다. 운영 데이터에 적용하기 전에는 별도 VPD/마스킹 정책을 연결한다. ## 5. 아키텍처 개요 ``` 브라우저 GET /structured-data?table=customers ↓ StructuredDataController ↓ StructuredDataService (7개 고정 allowlist) ↓ JdbcTemplate → POC_2.KB_CUSTOMERS (ROWNUM <= 50) ↓ Thymeleaf 표 미리보기 ``` 사용자 입력은 allowlist key 선택에만 쓰고, DB owner·테이블명은 서버 상수에서만 가져온다. JDBC I/O는 서비스에 두고, 테이블 카탈로그 검증은 순수 메서드로 분리한다. ## 6. 데이터 모델 | key | DB 테이블 | 업무명 | |---|---|---| | `customers` | `KB_CUSTOMERS` | 고객원장 / 고객 기본정보 | | `products` | `KB_PRODUCTS` | 상품원장 / 보험상품 마스터 | | `contracts` | `KB_CONTRACTS` | 계약원장 / 보험계약 정보 | | `coverages` | `KB_COVERAGES` | 담보원장 / 보장·특약 정보 | | `claims` | `KB_CLAIMS` | 청구원장 / 보험금 청구·지급 정보 | | `external-holdings` | `KB_EXTERNAL_HOLDINGS` | 외부보유정보 원장 / 타사·외부 가입·보유 정보 | | `stakeholders` | `KB_STAKEHOLDERS` | 이해관계자 원장 / 역할·담당자 매핑 | ## 7. 함수 명세 (Function Specs) | 함수 | 책임 | 입력 | 출력 | 에러/실패 | 복잡? | |---|---|---|---|---|---| | `requireTable` | allowlist key를 테이블 정의로 해석 | key | table definition | 알 수 없는 key 거부 | 단순 | | `preview` | 컬럼과 제한된 행을 조회 | key | preview view | DB 접근 오류를 안전한 메시지로 변환 | 단순 | ## 8. 흐름 / 알고리즘 1. 기본값으로 고객원장을 선택한다. 2. 요청 key가 7개 allowlist에 있는지 검증한다. 3. `ALL_TAB_COLUMNS`에서 표시 컬럼 순서를 읽는다. 4. 고정 owner/table로 최대 50건을 조회한다. 5. 컬럼 헤더와 행을 표로 렌더링한다. ## 9. 엣지케이스 & 에러 처리 - 알 수 없는 key: SQL을 만들지 않고 안내 메시지를 표시한다. - 대상 테이블이 없거나 권한이 없음: DB 오류 원문 대신 대상/권한 점검 안내를 표시한다. - 0건: 빈 결과 안내와 함께 컬럼 헤더는 유지한다. ## 10. 테스트 계획 - 카탈로그가 정확히 7개 key와 테이블을 포함하는지 단위 테스트한다. - 허용 목록 밖 key를 거부하는지 단위 테스트한다. - 템플릿·메뉴가 정형 데이터 조회 경로와 읽기 전용 안내를 포함하는지 정적 템플릿 테스트한다. ## 11. 리스크 & 대안 검토 - 관리자 JDBC로 직접 조회하므로 운영 개인정보를 그대로 보여줄 수 있다. 따라서 임의 SQL과 RAG/백업 테이블 노출을 제외하고, 현 POC에서는 마스킹된 고객 식별자만 있는 7개 원장으로 범위를 제한한다. - 최종 사용자별 행 보기가 필요하면 이 페이지가 아니라 ORDS + VPD 검증 경로를 사용한다. ## 12. 미해결 질문 (Open Questions) - 운영 전환 시 `POC_2` owner를 환경 설정으로 분리할지 결정한다. - 행 단위 VPD 적용 결과를 이 화면에서 볼 필요가 생기면 검증 세션을 필수 입력으로 하는 별도 화면으로 분리한다. ## 13. 구현·배포 검증 - `mvn test` 통과: allowlist 7개 테이블과 비허용 key 거부 단위 테스트, 메뉴·도움말 템플릿 검증을 포함한다. - VM SQLcl에서 백오피스 계정으로 `POC_2.KB_CUSTOMERS` 110건을 읽을 수 있음을 확인했다. - `vpd-backoffice.service`에 새 JAR를 배포한 뒤 인증된 `/structured-data?table=customers` 응답에서 `KB_CUSTOMERS`, `CUST_ID`, `고객원장` 렌더링을 확인했다.