refs #732: scope report titles to selected user

This commit is contained in:
devmrko
2026-08-10 18:02:49 +09:00
parent 84029ed633
commit cbd49b6b05
6 changed files with 225 additions and 6 deletions

View File

@@ -14,6 +14,7 @@ DB를 다시 조회하거나 자연어를 해석하지 않는다.
- 선사 실적 조회 MCP가 VPD를 적용한 데이터 접근 경계이고, 리포트 MCP는 표현 경계다.
- 승인된 HTML 템플릿은 DB CLOB으로 버전 관리하고, 생성 HTML은 MCP 응답의 `html` 속성으로만 반환한다.
- 제목은 질문 전체 문장을 복사하지 않는다. 포털의 제목 생성 지침이 요청 대상과 업무 범위만 남긴 짧은 보고서 제목을 만들고 renderer에 전달한다.
- 같은 대화에서 데모 사용자를 전환해도 현재 선택 사용자 ID가 질문의 `내`와 제목 범위를 결정한다. 다른 사용자의 이전 대화는 현재 사용자의 문맥으로 사용하지 않는다.
- HTML artifact가 반환되면 일반 답변은 HTML 표나 코드를 반복하지 않고 생성 완료와 조회 건수만 안내한다. 실제 표현은 `생성된 리포트` 영역 하나에서 담당한다.
- 포털은 사용자 질문을 그대로 두 Tool에 재사용하지 않는다. 첫 조회에는 데이터 조건만 남긴 질문을 전달하고, `HTML로 보여줘` 같은 표현 요청은 renderer 선택과 제목 생성에만 사용한다.
@@ -42,3 +43,6 @@ Oracle DB의 custom Agent Tool과 템플릿 CLOB은 적용됐다. 포털은 리
8건, HTML 18,670자를 연속 호출해 확인했다. 조회 응답은 `response.result` 안의 JSON 배열 문자열로
반환되므로 포털이 이를 범용적으로 구조화한다. HTML 템플릿에는 업무 샘플 행을 저장하지 않으며,
호출 시 전달된 `report``rows`만 표시한다.
2026-08-10 사용자 전환 회귀 검증에서는 E1001 제목이 팀장·팀원 범위를 유지하고, 같은 대화에서
E1002로 전환한 `내 담당 선사` 제목은 E1002 범위로 생성되며 E1001 식별자가 섞이지 않음을 확인했다.

View File

@@ -65,6 +65,23 @@ Tool 이름, 사용자 코드나 예상 행 수를 조건으로 사용하지 않
제목 생성이 실패하면 전체 질문을 제목으로 사용하지 않고 짧은 일반 업무 제목으로 안전하게
대체한다. 이 규칙은 특정 사용자 코드나 조회 행 수를 조건으로 사용하지 않는다.
### 현재 선택 사용자와 대화 문맥
포털의 데모 사용자 선택값은 Bearer token 선택뿐 아니라 질문 해석과 제목 범위의 기준이다.
`내`, `나`, `우리` 같은 1인칭 표현은 현재 선택 사용자 ID를 기준으로 독립 질문으로 바꾼다.
대화 이력은 같은 `selected_user_id`로 저장된 turn만 불러오며, 제목 생성 모델에도 현재 선택 사용자
ID를 별도 입력으로 전달한다. 이전 사용자의 질문에 명시된 팀장·팀 범위가 현재 사용자의 제목으로
전파되어서는 안 된다.
```text
현재 사용자 E1001 + "E1001 팀장의 팀원별 ..." → E1001 팀 범위 제목 → VPD 결과 8건
현재 사용자 E1002 + "내 담당 선사 ..." → E1002 개인 범위 제목 → VPD 결과 2건
```
제목 문자열이나 예상 행 수를 사용자별로 하드코딩하지 않는다. 사용자 ID, 독립 질문, 실제 선행 조회
결과를 모델 입력으로 제공하고 공통 제목 지침으로 생성한다. `report.requestedBy`는 질문에서 추측하지
않고 현재 선택 사용자 ID를 사용한다.
## 포털 표시 계약
renderer 응답에 유효한 `html` 또는 `rendered_html`이 있으면 HTML artifact가 최종 표현물이다.

View File

@@ -40,6 +40,9 @@
6. 리포트 머리글이 질문 전체 문장이 아니라 출력 형식 문구를 제거한 짧은 업무 제목인지 확인한다.
7. `reportJson.rows`의 각 행이 `employeeCode`, `carrierCode`, KPI처럼 업무 필드를 가지며,
`htmlRow``<tr>` 문자열을 포함하지 않는지 확인한다.
8. 같은 대화에서 사용자를 E1001에서 E1002로 전환한 뒤 `내 담당 선사 ... 리포트로 보여줘`
요청한다. E1002의 독립 질문·제목·`report.requestedBy`에 E1001이 없어야 하며, E1002 권한 범위의
행만 표시되어야 한다.
대표 E1001 팀장 질의의 운영 회귀 기준은 현재 8건이다. 이 숫자는 검증 기준일 뿐 코드나 Tool
인수에 고정하지 않는다. 첫 단계 원본에 행이 있는데 `reportJson.rows`가 0건이면 순차 실행 성공이

View File

@@ -60,6 +60,27 @@
**재발 방지**: 제목과 원문 질문이 역할상 분리되고 제목 길이 제한이 적용되는지 검증한다.
## 사용자를 바꿨는데 이전 사용자의 이름·팀이 제목에 남음
**증상**: E1001로 리포트를 만든 뒤 같은 대화에서 E1002를 선택하고 `내 담당 선사`를 요청했는데,
데이터는 E1002의 2건이면서 제목은 `E1001 팀장 ...`으로 표시된다.
**원인**: 질문 독립화 단계가 사용자 구분 없이 이전 대화 turn을 불러와 `내`를 이전 사용자인
E1001로 치환했다. VPD는 현재 Bearer token으로 정상 적용되므로 데이터와 제목 범위가 어긋난다.
**확인**:
1. 저장된 turn의 `selected_user_id`, `question`, `standalone_question`을 비교한다.
2. E1002 turn의 `standalone_question` 또는 renderer `report.title`에 E1001이 남아 있는지 확인한다.
3. 선행 조회 행은 E1002 담당 선사만 반환되는지 별도로 확인한다.
**해결**: 대화 문맥을 현재 `selected_user_id`로 필터링하고, 질문 독립화와 제목 생성에 현재 사용자
ID를 명시적으로 전달한다. 1인칭은 현재 사용자만 가리키며 이전 사용자의 관리자·팀 범위를 재사용하지
않도록 공통 지침을 적용한다. `report.requestedBy`도 현재 선택 사용자 ID를 사용한다.
**재발 방지**: 한 대화에서 E1001→E1002로 연속 전환하는 회귀 테스트를 유지한다. 제목과 행 수를
사용자별로 고정하지 말고 E1002 결과에 E1001 식별자가 포함되지 않는지를 검사한다.
## `reportJson.rows`가 `htmlRow`와 `<tr>`만 포함함
**원인**: 포털이 `HTML로 보여줘`가 포함된 원문을 첫 Select AI 데이터 조회에 그대로 전달해,