댓글, 첨부파일 구현
Deploy EG-BIM QA Gateway / deploy (push) Successful in 43s

This commit is contained in:
root
2026-09-21 20:01:57 +09:00
parent 1fb3a84608
commit 6639c148eb
8 changed files with 202 additions and 61 deletions
+3 -3
View File
@@ -31,15 +31,15 @@ python3 -m http.server 4173
- `feedback_comment_attachments`: 답변 댓글 이미지가 생길 때 `comment_id``qa_cdn` 메타데이터
- `support_attachments`: 운영 호환 레이어가 필요할 때 동일 파일의 티켓 첨부 메타데이터
현재 작성 페이지에는 댓글 입력 UI가 없으므로 `comments``commentAttachments`는 빈 배열로 보냅니다. 관리 페이지에서 댓글과 이미지를 작성할 때 같은 규칙으로 `feedback_comments`/`feedback_comment_attachments``ticket_comments`/`support_attachments`를 생성할 수 있도록 envelope를 열어 두었습니다.
상세 페이지에는 공개 댓글 입력 UI가 있으며, 댓글은 같은 Worker를 통해 ABC의 `feedback_comments`에 저장하고 `is_internal=false`인 공개 댓글만 조회합니다. 댓글 첨부파일은 별도 댓글 첨부 API 계약을 확인한 뒤 추가합니다.
## 연동 지점
- SSO: Q&A는 홈페이지 로그인 정보를 전달받지 않고, `https://app.brsw.kr/oidc`에 독립적인 PKCE Public Client로 직접 인증합니다. callback은 `https://qa-test.baroncs.co.kr/auth/callback`이며, Worker가 검증한 claim을 `baron_qa_session` HttpOnly 쿠키에 저장합니다. 브라우저의 `GET /auth/session`은 Q&A 세션에 저장된 작성자 정보를 반환합니다. feedback 서버는 반드시 SSO 세션 또는 토큰을 서버 측에서 검증해야 합니다.
- 작성자 식별자: `ssoSubject`/`requesterId`, `userUuid`, `tenantId`/`requesterTenantId`, `tenantIds`, `scope`, `roles`, 이메일·이름·부서·전화번호를 payload에 넣습니다. `requester_id``requester_tenant_id`가 없으면 제출을 차단합니다.
- API: 작성페이지는 같은 Worker의 `POST /api/feedbacks`를 호출합니다. Worker가 `baron_qa_session`을 검증하고, SSO requester 정보와 `ABC_API_KEY` Secret을 추가한 뒤 `POST https://feedback.hmac.kr/api/projects/{projectId}/channels/{channelId}/feedbacks`로 전달합니다. API Key와 내부 ABC 주소는 브라우저에 노출하지 않습니다.
- presign 응답: `{ "uploads": [{ "uploadUrl": "...", "storageKey": "...", "storageBucket": "qa_cdn", "headers": {} }] }` 형태를 기대합니다. R2 access key/secret은 정적 페이지에 넣지 않습니다.
- API 주소가 비어 있으면 테스트를 위해 브라우저 `localStorage`에만 저장하며, 첨부파일은 `local-preview/...` 메타데이터만 생성합니다.
- 첨부파일: 작성페이지가 `multipart/form-data`의 반복 `images` 필드로 파일을 Worker에 전달하고, Worker가 검증된 requester 정보와 API Key를 추가해 ABC API로 전달합니다. ABC API가 `qa_cdn` 저장소에 파일을 저장하므로 R2 access key/secret은 정적 페이지에 넣지 않습니다.
- 텍스트만 등록할 때는 기존 JSON 요청을 사용하고, 파일이 있을 때만 multipart 요청을 사용합니다.
## Cloudflare R2