# 함수 설계서: `findVpdPredicate` (#567)

> **부모 설계서**: ./README.md · **상태**: Approved
> **작성**: [AI] Architect · **구현**: `src/main/java/com/cloudhandson/vpdbackoffice/service/OrdsProbeService.java:findVpdPredicate` · **테스트**: `mvn test`, 운영 smoke

## 1. 시그니처

```java
private String findVpdPredicate(String bearerToken, ProtectedObject object)
```

## 2. 책임 (단일 책임, 1줄)

하나의 pooled DB connection에서 Bearer 기반 context를 설정하고 동일 VPD 함수의 predicate를 조회한 뒤 context를 제거한다.

## 3. 입력

| 파라미터 | 타입 | 제약/검증 | 설명 |
|----------|------|-----------|------|
| `bearerToken` | `String` | 상위 token 검증 통과 | `set_user_by_bearer` 입력 |
| `object` | `ProtectedObject` | 활성 object | predicate의 schema/object 입력 |

## 4. 출력

- **반환**: `ADMIN.CB_AGENT_DOC_VPD_FILTER(owner, object)`의 predicate 문자열 또는 조회 불가 시 null.
- **부수효과**: 같은 connection의 secure application context를 잠시 설정하고 반드시 clear한다. token 원문은 DB 함수 호출 이외의 출력으로 내보내지 않는다.

## 5. 동작 / 알고리즘

1. `JdbcTemplate.execute(ConnectionCallback)`으로 connection을 확보한다.
2. `BEGIN admin.cb_agent_ctx_pkg.set_user_by_bearer(?); END;`를 실행한다.
3. `SELECT admin.cb_agent_doc_vpd_filter(?, ?) FROM dual`을 실행한다.
4. `finally`에서 `BEGIN admin.cb_agent_ctx_pkg.clear_user; END;`를 실행한다.
5. Spring JDBC/DB runtime 오류는 trace optional 경로에서 null로 변환한다.

## 6. 에러 & 실패 모드

| 조건 | 처리 | 반환/예외 |
|------|------|-----------|
| DB 연결/권한 오류 | fallback 경계에서 처리 | null |
| Bearer 매핑 실패 | DB package 오류 | null, 원 ORDS 결과 유지 |
| predicate 함수 오류 | DB query 오류 | null, 원 ORDS 결과 유지 |
| cleanup 오류 | 별도 오류로 덮지 않음 | predicate 결과 또는 null |

## 7. 엣지케이스

- context setter가 실패해도 `finally` cleanup을 시도한다.
- connection pool에 context가 남지 않아야 한다.
- ORDS와 백오피스가 다른 DB/계정인 구성에서는 null이 정상 fallback 결과일 수 있다.
- `ADMIN` 이외 함수 owner는 이번 설계에서 지원하지 않는다.

## 8. 복잡도 / 성능

- trace가 없는 성공/0행 조회당 DB connection 1회, PL/SQL 1회, predicate SELECT 1회.
- 결과 행 수나 token 수에 비례하지 않는 `O(1)` DB 호출이며, Handler trace가 있으면 호출하지 않는다.

## 9. 의존성

- Spring `JdbcTemplate`/`ConnectionCallback`.
- `ADMIN.CB_AGENT_CTX_PKG`, `ADMIN.CB_AGENT_DOC_VPD_FILTER`.
- connection pool cleanup semantics.

## 10. 테스트 케이스

- [ ] context setter와 predicate query가 같은 connection에서 실행됨.
- [ ] query 성공 후 clear가 실행됨.
- [ ] setter/query 실패 후 clear가 시도됨.
- [ ] DB privilege 미설정 시 원 ORDS 결과가 유지됨.

## 11. 추적성

- 인수조건: #567의 “기존 Handler도 trace fallback 제공” 및 “trace 실패가 권한 결과를 실패로 만들지 않음”.
- 관련 ADR: 없음.
