@@ -3,7 +3,7 @@
|
||||
> **상태**: Draft
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-06-23
|
||||
> **추적성** — Redmine: #424 · 관련 ADR: 없음
|
||||
> · 구현 파일: `pom.xml`, `src/main/**`, `src/test/**` · 테스트: `mvn test`
|
||||
> · 구현 파일: `vpd-backoffice/pom.xml`, `vpd-backoffice/src/main/**`, `vpd-backoffice/src/test/**` · 테스트: `mvn test`
|
||||
|
||||
## 1. 목적 (Why)
|
||||
|
||||
@@ -58,8 +58,8 @@
|
||||
### 모듈/파일 구조
|
||||
|
||||
```text
|
||||
pom.xml
|
||||
src/main/java/com/cloudhandson/vpdbackoffice/
|
||||
vpd-backoffice/pom.xml
|
||||
vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/
|
||||
VpdBackofficeApplication.java
|
||||
config/
|
||||
DataSourceConfig.java
|
||||
@@ -88,13 +88,13 @@ src/main/java/com/cloudhandson/vpdbackoffice/
|
||||
TokenController.java
|
||||
ProbeController.java
|
||||
DashboardController.java
|
||||
src/main/resources/
|
||||
vpd-backoffice/src/main/resources/
|
||||
application.yml
|
||||
mapper/*.xml
|
||||
templates/**/*.html
|
||||
static/css/app.css
|
||||
static/js/app.js
|
||||
src/test/java/com/cloudhandson/vpdbackoffice/
|
||||
vpd-backoffice/src/test/java/com/cloudhandson/vpdbackoffice/
|
||||
```
|
||||
|
||||
### 데이터 흐름
|
||||
@@ -251,7 +251,7 @@ MCP-style reasoning
|
||||
|
||||
## 12. 미해결 질문 (Open Questions)
|
||||
|
||||
- ORDS 검증 API는 기존 `sql/adb/22_agent_ords_security_ords_handler_setup.sql`의 Handler를 그대로 사용할지, 백오피스 전용 Handler를 추가할지 결정이 필요하다.
|
||||
- ORDS 검증 API는 기존 `database/adb/22_agent_ords_security_ords_handler_setup.sql`의 Handler를 그대로 사용할지, 백오피스 전용 Handler를 추가할지 결정이 필요하다.
|
||||
- 백오피스 관리자 로그인은 초기에는 local user로 둘지, 사내 인증과 연결할지 후속 결정이 필요하다.
|
||||
- 컬럼 정책을 Redaction DDL까지 자동 생성할지, 관리 테이블 저장 후 DBA 적용으로 둘지 결정이 필요하다.
|
||||
- 실제 구현 issue를 별도 Redmine 하위 이슈로 나눌지, #424를 Developer 단계로 계속 이동할지 결정이 필요하다.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
> **상태**: Approved
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-06-25
|
||||
> **추적성** — Redmine: #456 · 관련 ADR: 없음
|
||||
> · 구현 파일: `sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`, `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`, `mvn test`
|
||||
> · 구현 파일: `database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`, `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`, `mvn test`
|
||||
|
||||
## 1. 목적 (Why)
|
||||
|
||||
@@ -78,8 +78,8 @@ I/O와 순수 로직 경계:
|
||||
|
||||
## 10. 테스트 계획
|
||||
|
||||
- SQLcl: `@sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
|
||||
- SQLcl: `@sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
- SQLcl: `@database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
|
||||
- SQLcl: `@database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
- Maven: `mvn test`
|
||||
- ORDS smoke: 기존 HR=3, SELF=1, ALL=6 결과 유지 확인.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 함수 설계서: `cb_agent_doc_vpd_filter` (#456)
|
||||
|
||||
> **부모 설계서**: ./README.md · **상태**: Approved
|
||||
> **작성**: [AI] Architect · **구현**: `sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql:cb_agent_doc_vpd_filter` · **테스트**: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
> **작성**: [AI] Architect · **구현**: `database/adb/26_agent_ords_security_dynamic_vpd_filter.sql:cb_agent_doc_vpd_filter` · **테스트**: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
|
||||
## 1. 시그니처
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
> **상태**: Approved
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-06-25
|
||||
> **추적성** — Redmine: #462 · 관련 ADR: 없음
|
||||
> · 구현 파일: `sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: SQLcl `27`, `./run.sh backoffice-vpd-ords-test`, `mvn test`
|
||||
> · 구현 파일: `database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql` · 테스트: SQLcl `27`, `./run.sh backoffice-vpd-ords-test`, `mvn test`
|
||||
|
||||
## 1. 목적 (Why)
|
||||
|
||||
@@ -67,8 +67,8 @@ malicious cb_permission_rule rows
|
||||
|
||||
## 10. 테스트 계획
|
||||
|
||||
- `@sql/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
|
||||
- `@sql/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
- `@database/adb/26_agent_ords_security_dynamic_vpd_filter.sql`
|
||||
- `@database/adb/27_agent_ords_security_dynamic_vpd_filter_test.sql`
|
||||
- `./run.sh backoffice-vpd-ords-test`
|
||||
- `mvn test`
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
> **상태**: Approved
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-06-28
|
||||
> **추적성** — Redmine: #547 · 관련 ADR: 없음
|
||||
> · 구현 파일: `src/main/resources/application.yml`, `SecurityConfig.java`, `scripts/deploy-backoffice-vm.sh`, `scripts/configure-backoffice-https-vm.sh`, `deploy/caddy/Caddyfile.template`
|
||||
> · 구현 파일: `vpd-backoffice/src/main/resources/application.yml`, `SecurityConfig.java`, `scripts/deploy-backoffice-vm.sh`, `scripts/configure-backoffice-https-vm.sh`, `deploy/vpd-backoffice/caddy/Caddyfile.template`
|
||||
> · 테스트: `TransportSecurityTest.java`, `scripts/test-backoffice-https-config.sh`
|
||||
|
||||
## 1. 목적 (Why)
|
||||
@@ -49,7 +49,7 @@ Internet client
|
||||
Internet client ── HTTP :8082 ──X (loopback bind + firewalld/NSG deny)
|
||||
```
|
||||
|
||||
- `deploy/caddy/Caddyfile.template`: TLS/redirect/HSTS/reverse proxy의 선언적 설정.
|
||||
- `deploy/vpd-backoffice/caddy/Caddyfile.template`: TLS/redirect/HSTS/reverse proxy의 선언적 설정.
|
||||
- `scripts/configure-backoffice-https-vm.sh`: 입력 검증, 원격 설정 검증·백업·적용·확인.
|
||||
- `scripts/deploy-backoffice-vm.sh`: 앱 배포 시 운영 보안 환경값을 강제하고 루프백 헬스체크.
|
||||
- Spring 설정: proxy가 전달한 HTTPS scheme을 인식하고 직접 HTTP 요청을 거부한다.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> **상태**: VPD·DDS 병행 검증 완료, 토큰 기반 객체별 Data Grant 적용 완료
|
||||
> **추적성**: Redmine #565, #566 · DDS 구현 커밋 `1e48864`, `a5e70bc`, `04cca64`, `8978be4`
|
||||
> **기준 구현**: `sql/adb/32_dds_vector_tag_setup.sql`, `sql/adb/34_dds_token_data_grant_common_auth.sql`, `sql/adb/36_dds_sales_knowledge_scenario.sql`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsGrantPublisher.java`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsVectorKnowledgeService.java`
|
||||
> **기준 구현**: `database/adb/32_dds_vector_tag_setup.sql`, `database/adb/34_dds_token_data_grant_common_auth.sql`, `database/adb/36_dds_sales_knowledge_scenario.sql`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsGrantPublisher.java`, `dds-backoffice/src/main/java/com/cloudhandson/ddsbackoffice/service/DdsVectorKnowledgeService.java`
|
||||
|
||||
## 목적
|
||||
|
||||
|
||||
@@ -77,8 +77,8 @@ Authorization: Bearer <masked>
|
||||
|
||||
## 설치와 운영 절차
|
||||
|
||||
1. `ADMIN`으로 [42_agent_ords_fga_execution_audit.sql](../../../sql/adb/42_agent_ords_fga_execution_audit.sql)을 실행해 활성 보호 객체마다 FGA `SELECT` 정책을 만든다.
|
||||
2. `CB_ORDS`로 [22_agent_ords_security_ords_handler_setup.sql](../../../sql/adb/22_agent_ords_security_ords_handler_setup.sql), [29_agent_ords_vector_search_ords.sql](../../../sql/adb/29_agent_ords_vector_search_ords.sql), [43_agent_ords_probe_id_handler_patch.sql](../../../sql/adb/43_agent_ords_probe_id_handler_patch.sql)을 순서대로 실행한다.
|
||||
1. `ADMIN`으로 [42_agent_ords_fga_execution_audit.sql](../../../database/adb/42_agent_ords_fga_execution_audit.sql)을 실행해 활성 보호 객체마다 FGA `SELECT` 정책을 만든다.
|
||||
2. `CB_ORDS`로 [22_agent_ords_security_ords_handler_setup.sql](../../../database/adb/22_agent_ords_security_ords_handler_setup.sql), [29_agent_ords_vector_search_ords.sql](../../../database/adb/29_agent_ords_vector_search_ords.sql), [43_agent_ords_probe_id_handler_patch.sql](../../../database/adb/43_agent_ords_probe_id_handler_patch.sql)을 순서대로 실행한다.
|
||||
3. 새 권한 결과 확인을 실행한다. 이전 요청에는 `CLIENT_ID`가 없으므로 소급해 매칭하지 않는다.
|
||||
4. 백오피스 실행 계정이 Autonomous의 `UNIFIED_AUDIT_TRAIL`을 조회할 수 있어야 한다. 전통 FGA 환경은 `DBA_FGA_AUDIT_TRAIL`을 fallback으로 사용한다. 일반 계정이면 감사 조회 권한을 가진 전용 observer 계정을 사용한다.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 함수 설계서: `addLocalSqlTrace` (#567)
|
||||
|
||||
> **부모 설계서**: ./README.md · **상태**: Approved
|
||||
> **작성**: [AI] Architect · **구현**: `src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:addLocalSqlTrace` · **테스트**: `ProbeResultTest`, `mvn test`
|
||||
> **작성**: [AI] Architect · **구현**: `vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:addLocalSqlTrace` · **테스트**: `ProbeResultTest`, `mvn test`
|
||||
|
||||
## 1. 시그니처
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 함수 설계서: `findVpdPredicate` (#567)
|
||||
|
||||
> **부모 설계서**: ./README.md · **상태**: Approved
|
||||
> **작성**: [AI] Architect · **구현**: `src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:findVpdPredicate` · **테스트**: `mvn test`, 운영 smoke
|
||||
> **작성**: [AI] Architect · **구현**: `vpd-backoffice/src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:findVpdPredicate` · **테스트**: `mvn test`, 운영 smoke
|
||||
|
||||
## 1. 시그니처
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
> **최종수정**: 2026-07-19
|
||||
> **추적성** — Redmine: #617 · 관련 ADR: [ADR-0001](../../adr/0001-dds-mcp-service-identity.md), [ADR-0002](../../adr/0002-dds-runtime-permission-source.md)
|
||||
> · 현재 구현: `DdsMcpBearerAuthenticator`, `DdsMcpEndUserResolver`, `DdsMcpContextExecutor`, `DdsMcpSseController`
|
||||
> · 기존 PoC 게시: `sql/adb/44_dds_mcp_local_end_user_setup.sql`
|
||||
> · 검증: `sql/adb/45_dds_mcp_local_end_user_test.sql`, SSE `tools/call`
|
||||
> · 기존 PoC 게시: `database/adb/44_dds_mcp_local_end_user_setup.sql`
|
||||
> · 검증: `database/adb/45_dds_mcp_local_end_user_test.sql`, SSE `tools/call`
|
||||
|
||||
## 1. 결정과 목적
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
> **상태**: Implemented snapshot documented · follow-up contract pending
|
||||
> **작성**: [AI] Architect · **최종수정**: 2026-07-14
|
||||
> **추적성** — Redmine: #654 · 관련 ADR: 없음 · 구현 커밋: `5bdd242`, `33399f9`, `1f6d974`
|
||||
> · 스냅샷: `poc4_active_source_20260714/` · 원본 archive: `poc4_active_source_20260714/poc4_active_source_20260714.tar.gz` · 현행 구현 파일: `apps/poc4/mcp_discovery_ui.py`, `src/mcp_tool_router.py`, `src/oci_genai_sdk.py`, `src/poc3/model_registry.py`, `config/mcp_servers.json` · 테스트: Python 3.11 `py_compile`, 기존 백오피스 `mvn -q test`
|
||||
> · 현재 소스: `ai-web-agent-console/` · 현행 구현 파일: `ai-web-agent-console/app.py`, `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py`, `ai-web-agent-console/ai_web_agent_console/oci_genai_sdk.py`, `ai-web-agent-console/ai_web_agent_console/model_registry.py`, `ai-web-agent-console/config/mcp_servers.json` · 테스트: Python 3.11 `compileall`/`unittest`, `mvn -f vpd-backoffice/pom.xml test`
|
||||
>
|
||||
> 이 문서의 PoC4 명칭과 원격 archive 경로는 2026-07-14 당시의 이력이다. 현재 저장소 구조는 #742 설계서를 기준으로 한다.
|
||||
|
||||
## 1. 목적 (Why)
|
||||
|
||||
@@ -17,17 +19,17 @@ PoC4 MCP AI Console이 KB VPD MCP를 사용자별 Bearer 토큰으로 안전하
|
||||
|
||||
| 영역 | 현행 구현 |
|
||||
|---|---|
|
||||
| 저장소 위치 | `poc4_active_source_20260714/` 단일 폴더에 격리 |
|
||||
| 실행 진입점 | 직접 실행은 `streamlit run apps/poc4/mcp_discovery_ui.py --server.address 0.0.0.0 --server.port 8622` |
|
||||
| 저장소 위치 | `ai-web-agent-console/` 단일 폴더에 격리 |
|
||||
| 실행 진입점 | 직접 실행은 `streamlit run ai-web-agent-console/app.py --server.address 0.0.0.0 --server.port 8622` |
|
||||
| Python 런타임 | Python 3.11 이상. 배포 서버 검증 런타임은 `/home/opc/poc_4/.python-runtime/cpython-3.11.15+20260610/bin/python3.11` |
|
||||
| Streamlit 화면 | `apps/poc4/mcp_discovery_ui.py` 단일 대형 UI. KB 테마, 포털 로그인, 대화 이력, MCP discovery/call, evidence 수집, 답변 합성을 포함 |
|
||||
| MCP registry | `config/mcp_servers.json`. `kb_mcp`와 `kb_vector_mcp` 두 서버를 선언 |
|
||||
| Streamlit 화면 | `ai-web-agent-console/app.py` 단일 대형 UI. KB 테마, 포털 로그인, 대화 이력, MCP discovery/call, evidence 수집, 답변 합성을 포함 |
|
||||
| MCP registry | `ai-web-agent-console/config/mcp_servers.json` |
|
||||
| KB 정형 MCP | `https://kb.cloud-handson.com/mcp`, 기본 tool `ords.query.kb_select_ai_vpd` |
|
||||
| KB 벡터 MCP | `http://127.0.0.1:9978/mcp`, allowlist `hybrid_rerank_search` |
|
||||
| 토큰 preset | `config/vpd_token_presets.json`. 실제 토큰 원문은 포함하지 않고 placeholder만 둠 |
|
||||
| 토큰 preset | `ai-web-agent-console/config/vpd_token_presets.json`. 실제 토큰 원문은 포함하지 않고 placeholder만 둠 |
|
||||
| 대화 저장소 | 기본 `data/poc4_mcp_chat.sqlite3`, 환경변수 `POC4_CHAT_DB_PATH`로 변경 가능 |
|
||||
| DB evidence 연결 | 기본 env file `/home/opc/kbmcp/.env`, wallet fallback `/home/opc/wallet/kbaipoc` |
|
||||
| OCI GenAI | `OCI_AUTH_TYPE=config_file`, `~/.oci/config`, `DEFAULT` profile 기반. model profile은 `config/poc3_model_profiles.json`에서 로드 |
|
||||
| OCI GenAI | `OCI_AUTH_TYPE=config_file`, `~/.oci/config`, `DEFAULT` profile 기반. model profile은 `ai-web-agent-console/config/model_profiles.json`에서 로드 |
|
||||
| 보안 원칙 | wallet, DB password, wallet password, 실제 VPD token, 대화 DB는 저장소에 포함하지 않음 |
|
||||
|
||||
현행 데이터 흐름은 다음과 같다.
|
||||
@@ -60,25 +62,24 @@ SQLite 대화 이력 저장
|
||||
|
||||
| 파일 | 책임 |
|
||||
|---|---|
|
||||
| `apps/poc4/mcp_discovery_ui.py` | Streamlit 화면, 포털 로그인, MCP discovery/call, agent loop, evidence 수집, 답변 합성, 대화 이력 저장 |
|
||||
| `apps/poc4/ui_theme.py` | UI theme 보조 코드 |
|
||||
| `src/mcp_tool_router.py` | 발견된 MCP tool descriptor를 기반으로 LLM router가 server/tool을 선택하고 tool arguments를 구성 |
|
||||
| `src/oci_genai_sdk.py` | OCI Generative AI 호출 경계. MCP/VPD token을 알지 않는 최소 completion client |
|
||||
| `src/poc3/model_registry.py` | 모델 profile registry 로드, region/endpoint 해석, 환경 override 처리 |
|
||||
| `src/poc3/questions.py` | 데모 질문 목록 |
|
||||
| `config/mcp_servers.json` | MCP 서버 registry. 현재는 `endpoint_url`이 있으면 이를 우선 사용 |
|
||||
| `config/poc3_model_profiles.json` | `gpt55_oci`, `gpt54_mini_oci`, `grok43`, `llama4_maverick`, `llama33_70b` profile |
|
||||
| `config/vpd_token_presets.json` | 데모 사용자 token preset 구조. 실제 토큰은 배포 환경에서 교체 |
|
||||
| `scripts/poc4/start_8622_langgraph_tc_ui_nohup.sh` | 원본 PoC4 런처 wrapper. 현재 스냅샷의 직접 entrypoint와는 다르게 `/home/opc/poc_4/scripts/poc4/run_8622_langgraph_tc_ui.sh` 및 `apps/poc4/langgraph_tc_ui.py`를 참조 |
|
||||
| `ai-web-agent-console/app.py` | Streamlit 화면, 포털 로그인, MCP discovery/call, agent loop, evidence 수집, 답변 합성, 대화 이력 저장 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/presentation.py` | 공통 UI theme와 화면 표현 보조 코드 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py` | 발견된 MCP tool descriptor를 기반으로 LLM router가 server/tool을 선택하고 tool arguments를 구성 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/oci_genai_sdk.py` | OCI Generative AI 호출 경계. MCP/VPD token을 알지 않는 최소 completion client |
|
||||
| `ai-web-agent-console/ai_web_agent_console/model_registry.py` | 모델 profile registry 로드, region/endpoint 해석, 환경 override 처리 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/questions.py` | 데모 질문 목록 |
|
||||
| `ai-web-agent-console/config/mcp_servers.json` | MCP 서버 registry |
|
||||
| `ai-web-agent-console/config/model_profiles.json` | OCI GenAI model profile registry |
|
||||
| `ai-web-agent-console/config/vpd_token_presets.json` | 데모 사용자 token preset 구조. 실제 토큰은 배포 환경에서 교체 |
|
||||
|
||||
런처 주의사항: 스냅샷에는 `mcp_discovery_ui.py` 직접 실행에 필요한 소스가 들어 있지만, 포함된 `start_8622...` script는 원본 서버의 공용 runtime wrapper에 의존한다. 이 저장소에서 독립 실행하려면 `SOURCE_README.md`의 직접 `streamlit run` 명령을 사용하거나, 별도 wrapper를 작성해야 한다.
|
||||
현재 저장소에서는 `cd ai-web-agent-console && streamlit run app.py`를 독립 실행 진입점으로 사용한다.
|
||||
|
||||
## 1.3 현행 보안/비밀정보 경계
|
||||
|
||||
- `VpdTokenPreset.token`은 dataclass에서 `repr=False`이며, UI는 token을 정규화한 뒤 Authorization header에만 넣는다.
|
||||
- `_NoRedirectHandler`는 redirect 시 Authorization header가 다른 endpoint로 전달되는 것을 막는다.
|
||||
- `src/mcp_tool_router.py`의 router는 질문과 tool descriptor만 받으며 bearer token 또는 provider credential을 받지 않는다.
|
||||
- `src/oci_genai_sdk.py`는 `.env`에서 `OCI_AUTH_TYPE`, `OCI_CONFIG_FILE`, `OCI_GENAI_COMPARTMENT_ID`, `OCI_PROFILE`만 읽는다.
|
||||
- `ai_web_agent_console.mcp_tool_router`의 router는 질문과 tool descriptor만 받으며 bearer token 또는 provider credential을 받지 않는다.
|
||||
- `ai_web_agent_console.oci_genai_sdk`는 `.env`에서 `OCI_AUTH_TYPE`, `OCI_CONFIG_FILE`, `OCI_GENAI_COMPARTMENT_ID`, `OCI_PROFILE`만 읽는다.
|
||||
- Oracle audit/business evidence 조회는 `/home/opc/kbmcp/.env`에서 `ORACLE_DB_USER`, `ORACLE_DB_PASSWORD`, `ORACLE_DSN`, `ORACLE_WALLET_PASSWORD`, `ORACLE_WALLET_DIR`를 읽는다.
|
||||
- wallet 기본 fallback은 `/home/opc/wallet/kbaipoc`이다.
|
||||
- 저장소에는 실제 `.env`, wallet, SQLite 대화 DB, 실제 VPD bearer token 원문을 포함하지 않는다.
|
||||
@@ -97,7 +98,7 @@ SQLite 대화 이력 저장
|
||||
## 2. 범위 (Scope)
|
||||
|
||||
- **포함**:
|
||||
- `apps/poc4/mcp_discovery_ui.py`의 KB MCP endpoint, 인증 헤더, JSON-RPC, 오류 처리 정비
|
||||
- `ai-web-agent-console/app.py`의 KB MCP endpoint, 인증 헤더, JSON-RPC, 오류 처리 정비
|
||||
- `config/mcp_servers.json` 및 sample의 KB MCP 선언 정비
|
||||
- KB MCP의 단일 도구 `ords.query.kb_select_ai_vpd` 호출 계약 문서화
|
||||
- VPD Backoffice `/mcp`과의 HTTP 상태·프로토콜 버전 호환성 점검 및 필요한 최소 보완
|
||||
@@ -300,8 +301,8 @@ Authorization: Bearer <current-user-vpd-token>
|
||||
배포 서버의 PoC4 활성 화면 소스를 현재 저장소에 별도 폴더로 반입했다.
|
||||
|
||||
- 원격 실제 위치: `/home/opc/poc_4/poc4_active_source_20260714.tar.gz`
|
||||
- 사용자 제시 경로 `/home/opc/poc_4/poc4_active_source_20260714/poc4_active_source_20260714.tar.gz`에는 파일이 없었고, 실제 archive는 `/home/opc/poc_4/` 바로 아래에 있었다.
|
||||
- 저장소 위치: `poc4_active_source_20260714/`
|
||||
- 사용자 제시 경로 `/home/opc/poc_4/ai-web-agent-console/poc4_active_source_20260714.tar.gz`에는 파일이 없었고, 실제 archive는 `/home/opc/poc_4/` 바로 아래에 있었다.
|
||||
- 저장소 위치: `ai-web-agent-console/`
|
||||
- 포함 파일: Streamlit UI, MCP router, OCI GenAI client, 모델 profile, token preset sample, 기동/status script, requirements
|
||||
- 보안 확인: 실제 `.env`, 실제 VPD token 원문, 대화 SQLite DB는 포함하지 않았다. `vpd_token_presets.json`에는 placeholder만 있다.
|
||||
- DB 참조 경로: VPD 개발본 배포 서버에서는 `/home/opc/kbmcp/.env`의 접속 정보를 사용하고, wallet directory는 `/home/opc/wallet/kbaipoc`를 사용한다. 두 경로의 파일 내용은 저장소에 포함하지 않는다.
|
||||
@@ -380,7 +381,7 @@ ENABLED_COUNT = 4
|
||||
SELECT_POLICY_COUNT = 4
|
||||
```
|
||||
|
||||
현재 DB의 정책명 계열은 모두 `KB_FGA_*`다. 저장소의 범용 적용 스크립트 `sql/adb/42_agent_ords_fga_execution_audit.sql`은 `CB_VPD_EXEC_AUDIT_<object_id>` 형태의 정책을 만들도록 작성되어 있으나, 현행 ADB에는 이 계열이 아니라 `KB_FGA_*` 정책이 적용되어 있다. 따라서 운영 확인 시에는 “스크립트 파일명/예상명”보다 `DBA_AUDIT_POLICIES`의 실제 정책명을 기준으로 봐야 한다.
|
||||
현재 DB의 정책명 계열은 모두 `KB_FGA_*`다. 저장소의 범용 적용 스크립트 `database/adb/42_agent_ords_fga_execution_audit.sql`은 `CB_VPD_EXEC_AUDIT_<object_id>` 형태의 정책을 만들도록 작성되어 있으나, 현행 ADB에는 이 계열이 아니라 `KB_FGA_*` 정책이 적용되어 있다. 따라서 운영 확인 시에는 “스크립트 파일명/예상명”보다 `DBA_AUDIT_POLICIES`의 실제 정책명을 기준으로 봐야 한다.
|
||||
|
||||
### 15.4 감사 이벤트 저장 위치
|
||||
|
||||
@@ -437,7 +438,7 @@ DBA_FGA_AUDIT_TRAIL event_count_7d = 0
|
||||
|
||||
### 15.6 소스 구현과 화면 연결
|
||||
|
||||
PoC4 스냅샷의 `apps/poc4/mcp_discovery_ui.py`는 감사로그 탭에서 다음 두 쿼리를 사용한다.
|
||||
PoC4 스냅샷의 `ai-web-agent-console/app.py`는 감사로그 탭에서 다음 두 쿼리를 사용한다.
|
||||
|
||||
| 함수 | 조회 대상 | 역할 |
|
||||
|---|---|---|
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
## 프로젝트 개요
|
||||
|
||||
`poc4_active_source_20260714`는 레거시 스냅샷 경로이며, 정식 서비스명은 HMM AI 업무 에이전트다. HMM MCP를 통해 HR 데이터, 표준 용어, 규정 문서를 조회하고 대화 이력과 보안 관리 화면을 제공한다.
|
||||
정식 서비스명은 HMM AI 업무 에이전트이며 현재 소스 경계는 `ai-web-agent-console/`이다.
|
||||
과거 `poc4_active_source_20260714` 스냅샷 경로는 #742에서 제거했다. HMM MCP를 통해 HR 데이터,
|
||||
표준 용어, 규정 문서를 조회하고 대화 이력과 보안 관리 화면을 제공한다.
|
||||
|
||||
## 목표
|
||||
|
||||
@@ -10,7 +12,7 @@
|
||||
|
||||
## 현재 문제
|
||||
|
||||
- `apps/poc4/mcp_discovery_ui.py`가 화면, 설정, 인증, SQLite 대화 이력, MCP JSON-RPC, Agent 실행을 함께 관리한다.
|
||||
- `ai-web-agent-console/app.py`가 화면, 설정, 인증, SQLite 대화 이력, MCP JSON-RPC, Agent 실행을 함께 관리한다.
|
||||
- MCP 설정과 인증 토큰 규칙을 수정할 때 화면 코드까지 함께 읽어야 한다.
|
||||
- MCP 프로토콜 처리의 단위 검증 지점이 없다.
|
||||
|
||||
@@ -18,14 +20,15 @@
|
||||
|
||||
| 모듈 | 책임 | Streamlit 의존 |
|
||||
| --- | --- | --- |
|
||||
| `src/poc4/runtime_config.py` | `.env`, MCP 서버 JSON, VPD preset 로드와 검증 | 없음 |
|
||||
| `src/poc4/mcp_client.py` | endpoint 검증, JSON-RPC, 세션 fallback, tool discovery/call | 없음 |
|
||||
| `src/poc4/chat_store.py` | SQLite 대화 이력 CRUD | 없음 |
|
||||
| `apps/poc4/mcp_discovery_ui.py` | 사용자 입력, 상태, 화면 렌더링, 업무 Agent orchestration | 있음 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/profile.py` | 제품 프로필과 환경 override 로드 | 없음 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/mcp_tool_router.py` | MCP 도구 discovery 결과의 route와 arguments 구성 | 없음 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/auth_gateway.py` | 로그인·쿠키·세션 경계 | 없음 |
|
||||
| `ai-web-agent-console/ai_web_agent_console/audit.py` | 감사·증적 조회 경계 | 없음 |
|
||||
| `ai-web-agent-console/app.py` | 사용자 입력, 상태, 화면 렌더링, 업무 Agent orchestration | 있음 |
|
||||
|
||||
### 재사용 UI Shell과 제품 프로필
|
||||
|
||||
공통 화면 shell은 `src/agent_console/`에서 제공하고, 특정 고객·PoC의 표현은
|
||||
공통 화면 shell은 `ai-web-agent-console/ai_web_agent_console/`에서 제공하고, 특정 고객·PoC의 표현은
|
||||
`config/app_profile.json`에 둔다. 다른 프로젝트는 앱 코드를 복사·수정하지 않고 profile JSON을
|
||||
교체할 수 있다. 실제 배포에서는 `AGENT_CONSOLE_NAME`, `AGENT_CONSOLE_HEADER_DESCRIPTION`,
|
||||
`AGENT_CONSOLE_PRIMARY_COLOR` 등 `AGENT_CONSOLE_*` 환경변수가 JSON 기본값보다 우선한다.
|
||||
@@ -48,7 +51,7 @@
|
||||
2. 변경은 Redmine 이슈에 설계·검증 결과와 Git commit SHA를 함께 기록한다.
|
||||
3. Git commit message에는 Redmine 번호를 `refs #<번호>:` 형식으로 포함한다.
|
||||
4. 환경별 값과 비밀값은 profile JSON에 넣지 않고 `.env` 또는 secret store에만 둔다.
|
||||
5. UI CSS는 `src/agent_console/presentation.py` 한 곳에서 관리한다. 제품별 색상과 문구는 Python/CSS를 수정하지 않고 `app_profile.json`으로 조정한다.
|
||||
5. UI CSS는 `ai-web-agent-console/ai_web_agent_console/presentation.py` 한 곳에서 관리한다. 제품별 색상과 문구는 Python/CSS를 수정하지 않고 `app_profile.json`으로 조정한다.
|
||||
|
||||
도메인 로직의 공개 오류는 `PublicMcpError`로 통일한다. UI는 이 오류를 사람이 이해할 수 있는 메시지로 표시하되 토큰과 HTTP 원문을 출력하지 않는다.
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ HMM_KNOWLEDGE_DOCUMENTS ──< HMM_KNOWLEDGE_CHUNKS ──< HMM_KNOWLEDGE_TAGS
|
||||
|
||||
- `/structured-data`와 `/schema-metadata`의 데이터 원본명, Oracle owner, 안내 문구, 최대 조회 건수,
|
||||
허용 테이블 목록은 Java·HTML에 하드코딩하지 않는다.
|
||||
- 기본 HMM 정의는 `src/main/resources/config/structured-data-catalog.json`에 둔다. 배포 환경에서는
|
||||
- 기본 HMM 정의는 `vpd-backoffice/src/main/resources/config/structured-data-catalog.json`에 둔다. 배포 환경에서는
|
||||
`BACKOFFICE_STRUCTURED_DATA_CATALOG_LOCATION=file:/.../structured-data-catalog.json`으로 외부
|
||||
JSON을 지정할 수 있어 다른 회사 PoC에서 애플리케이션 코드를 수정하지 않고 재사용할 수 있다.
|
||||
- 각 테이블 정의는 `key`, `tableName`, `businessName`, `description`을 기본으로 하고 필요하면
|
||||
|
||||
@@ -73,7 +73,7 @@ E1001에는 `HMM_HR_MANAGER`, E1002~E1007에는 `HMM_HR_VIEWER`를 부여한다.
|
||||
## 배포 순서
|
||||
|
||||
1. 애플리케이션 테스트와 SQL 구문 검사를 수행한다.
|
||||
2. 멱등 SQL `sql/adb/72_hmm_leave_team_vpd.sql`을 `ADMIN`으로 실행한다.
|
||||
2. 멱등 SQL `database/adb/72_hmm_leave_team_vpd.sql`을 `ADMIN`으로 실행한다.
|
||||
3. VPD 정책·컴파일 상태·백오피스 화면을 확인한다.
|
||||
4. 백오피스와 같은 SHA-256 저장 규칙으로 E1001과 E1002 임시 검증 토큰을 만든다.
|
||||
5. 비면제 검증 사용자에서 토큰별 조회 결과를 확인하고 검증 토큰과 사용자를 제거한다.
|
||||
|
||||
@@ -182,7 +182,7 @@ HMM 운영 MCP는 현재 세 개의 Agent Tool을 사용하므로 Select AI 접
|
||||
BACKOFFICE_SECURITY_SQL_SCRIPTS
|
||||
```
|
||||
|
||||
번들된 `sql/adb` 경로 안의 파일만 허용하며 요청값을 resource path로 사용하지 않는다.
|
||||
번들된 `database/adb` 경로 안의 파일만 허용하며 요청값을 resource path로 사용하지 않는다.
|
||||
HMM 운영에서는 `72_hmm_leave_team_vpd.sql` 등 HMM 관련 SQL만 노출한다.
|
||||
|
||||
## 5. 코드 구조
|
||||
|
||||
@@ -110,8 +110,8 @@ CHECK 제약으로 보장한다. 월별 조회와 위험 선사 조회에 각각
|
||||
## 7. 적재 순서
|
||||
|
||||
1. RDS TLS와 현재 계정의 CREATE 권한을 확인한다.
|
||||
2. `sql/source/postgres_hmm_carrier_performance.sql`을 실행한다.
|
||||
3. `sql/source/postgres_hmm_carrier_performance_verify.sql`을 실행한다.
|
||||
2. `database/source/postgres_hmm_carrier_performance.sql`을 실행한다.
|
||||
3. `database/source/postgres_hmm_carrier_performance_verify.sql`을 실행한다.
|
||||
4. 재실행 후에도 동일한 선사 8개와 실적 144행인지 확인한다.
|
||||
5. 후속 작업에서 ADB credential과 PostgreSQL database link를 만든다.
|
||||
|
||||
|
||||
112
docs/design/742-application-oriented-repository-layout/README.md
Normal file
112
docs/design/742-application-oriented-repository-layout/README.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# #742 애플리케이션 단위 저장소 구조 개편
|
||||
|
||||
## 문제
|
||||
|
||||
현재 저장소 루트의 `pom.xml`, `src/main`, `src/test`는 실제로 하나의 Spring Boot
|
||||
백오피스지만 제품 폴더 없이 저장소 전체 애플리케이션처럼 보인다. Streamlit 앱은
|
||||
`poc4_active_source_20260714`라는 날짜 스냅샷 폴더에 있고 내부에서도 `poc3`, `poc4`,
|
||||
`agent_console`, 단독 Python 모듈이 서로 참조한다.
|
||||
|
||||
이 구조에서는 다음 내용을 파일 경로만 보고 알 수 없다.
|
||||
|
||||
- 어떤 파일이 실제 배포 애플리케이션인지
|
||||
- Spring Boot와 Streamlit의 빌드·테스트 경계가 어디인지
|
||||
- `poc3`, `poc4`가 제품명인지 과거 실험 번호인지
|
||||
- DB 스크립트와 특정 애플리케이션의 관계가 무엇인지
|
||||
|
||||
## 목표 구조
|
||||
|
||||
```text
|
||||
vpd-permission-poc/
|
||||
├── vpd-backoffice/ Spring Boot VPD·권한 관리 백오피스
|
||||
│ ├── pom.xml
|
||||
│ ├── src/main/
|
||||
│ └── src/test/
|
||||
├── ai-web-agent-console/ Streamlit AI 업무 에이전트
|
||||
│ ├── app.py
|
||||
│ ├── ai_web_agent_console/ 단일 Python 패키지
|
||||
│ ├── config/
|
||||
│ ├── tests/
|
||||
│ └── requirements.txt
|
||||
├── dds-backoffice/ 별도 DDS 백오피스
|
||||
├── database/
|
||||
│ ├── adb/
|
||||
│ └── source/
|
||||
├── deploy/ 제품별 배포 설정
|
||||
├── docs/ 설계·운영·검증 문서
|
||||
├── scripts/ 저장소 공통 자동화
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 이동 매핑
|
||||
|
||||
| 기존 | 변경 | 처리 |
|
||||
|---|---|---|
|
||||
| `pom.xml` | `vpd-backoffice/pom.xml` | Maven 프로젝트 경계 명시 |
|
||||
| `src/main` | `vpd-backoffice/src/main` | Spring 애플리케이션 소스 |
|
||||
| `src/test` | `vpd-backoffice/src/test` | Spring 단위·통합 테스트 |
|
||||
| `sql/adb` | `database/adb` | Oracle/ADB 스크립트 |
|
||||
| `sql/source` | `database/source` | 외부 원천 DB 스크립트 |
|
||||
| `poc4_active_source_20260714` | `ai-web-agent-console` | 날짜·PoC 번호 제거 |
|
||||
| `apps/poc4/mcp_discovery_ui.py` | `ai-web-agent-console/app.py` | 명확한 Streamlit 진입점 |
|
||||
| `src/agent_console/*` | `ai-web-agent-console/ai_web_agent_console/*` | 단일 제품 패키지 |
|
||||
| `src/poc3/model_registry.py` | `ai-web-agent-console/ai_web_agent_console/model_registry.py` | 실험 번호 제거 |
|
||||
| `src/poc3/questions.py` | `ai-web-agent-console/ai_web_agent_console/questions.py` | 실험 번호 제거 |
|
||||
| `src/poc4/scenarios.py` | `ai-web-agent-console/ai_web_agent_console/scenarios.py` | 실험 번호 제거 |
|
||||
| `src/poc4/query_contracts.py` | `ai-web-agent-console/ai_web_agent_console/query_contracts.py` | 실험 번호 제거 |
|
||||
| `src/mcp_*.py`, `src/oci_genai_sdk.py` | `ai-web-agent-console/ai_web_agent_console/` | 앱 전용 공용 모듈 통합 |
|
||||
| `config/poc3_model_profiles.json` | `ai-web-agent-console/config/model_profiles.json` | 실험 번호 제거 |
|
||||
|
||||
## 경로 규칙
|
||||
|
||||
1. 저장소 루트에는 애플리케이션 프레임워크의 `src`나 `pom.xml`을 두지 않는다.
|
||||
2. 각 애플리케이션은 자신의 소스, 의존성 선언, 테스트 진입점을 가진다.
|
||||
3. DB 스크립트는 `database`를 Git 원본으로 사용하고 Spring JAR는 해당 경로를
|
||||
리소스로 포함한다.
|
||||
4. 배포 설정은 `deploy/<application>`에서 새 소스 경로를 참조한다.
|
||||
5. 과거 경로를 유지하는 심볼릭 링크나 복제본은 만들지 않는다. 잘못된 경로가 다시
|
||||
사용되면 테스트가 실패하도록 한다.
|
||||
6. 운영 중인 환경변수와 SQLite 테이블명은 데이터 호환을 위해 이번 변경에서 유지한다.
|
||||
폴더·패키지·실행 경로에서만 PoC 명칭을 제거한다.
|
||||
|
||||
## Maven 변경
|
||||
|
||||
`vpd-backoffice/pom.xml`의 SQL 리소스 경로는 `../database/adb`를 사용한다. 루트 자동화는
|
||||
`mvn -f vpd-backoffice/pom.xml`을 사용하며 앱 디렉토리 안에서는 기존처럼 `mvn test`가
|
||||
동작해야 한다.
|
||||
|
||||
Java 테스트에서 파일을 직접 여는 경로는 앱 디렉토리를 기준으로 유지한다. 따라서
|
||||
`vpd-backoffice`에서 실행한 테스트와 루트에서 `-f`로 실행한 테스트를 모두 확인한다.
|
||||
|
||||
## Python 변경
|
||||
|
||||
`ai-web-agent-console/app.py`는 자신의 부모 폴더를 애플리케이션 루트로 사용한다.
|
||||
모든 import는 `ai_web_agent_console.<module>` 형식으로 통일한다. 테스트도 같은 공개
|
||||
패키지 경로만 사용한다.
|
||||
|
||||
`model_profiles.json` 안의 `default_for_poc3` 속성은 `default_for_console`로 바꾸고
|
||||
로더·검증 코드도 함께 변경한다. 배포된 비밀정보 파일과 대화 DB는 Git 이동 대상이
|
||||
아니다.
|
||||
|
||||
## 배포 변경
|
||||
|
||||
- Spring 배포 빌드는 `vpd-backoffice/pom.xml`과 `vpd-backoffice/target`을 사용한다.
|
||||
- Streamlit 실행은 `streamlit run app.py`를 사용한다.
|
||||
- 인증 게이트웨이는 `python -m ai_web_agent_console.auth_gateway`를 사용한다.
|
||||
- 기존 운영 디렉토리 `/opt/hmm-poc4`는 무중단 전환을 위해 물리 경로로 유지할 수 있지만,
|
||||
서비스의 Git 소스 경로와 Python 모듈명은 새 구조를 사용한다.
|
||||
|
||||
## 검증
|
||||
|
||||
1. `git status --short`에서 기존 #741 변경이 새 경로에 남아 있는지 확인한다.
|
||||
2. `mvn -f vpd-backoffice/pom.xml test`를 실행한다.
|
||||
3. Python 전체 소스에 `compileall`을 실행한다.
|
||||
4. `unittest discover -s ai-web-agent-console/tests`를 실행한다.
|
||||
5. `rg`로 운영 코드의 `src.poc3`, `src.poc4`, `src.agent_console`,
|
||||
`poc4_active_source_20260714`, `apps/poc4` 참조가 0건인지 확인한다.
|
||||
6. 배포 스크립트의 dry-run 또는 정적 경로 검증을 수행한다.
|
||||
|
||||
## 롤백
|
||||
|
||||
모든 이동은 한 Git 커밋으로 추적한다. 문제가 생기면 해당 커밋을 revert하여 이전 경로와
|
||||
import를 함께 복구한다. DB 스키마와 운영 데이터는 이 구조 변경에서 수정하지 않는다.
|
||||
Reference in New Issue
Block a user