root 176316378b
Deploy EG-BIM QA Gateway / deploy (push) Successful in 56s
상세페이지 UI 개선
2026-09-22 17:05:12 +09:00
2026-09-22 17:05:12 +09:00
2026-09-22 15:23:00 +09:00
2026-09-22 17:05:12 +09:00
2026-09-22 14:38:59 +09:00
2026-09-22 14:38:59 +09:00

EG-BIM Q&A static pages

egbim/ 아래의 index.html, write.html, detail.html 세 페이지로 구성한 EG-BIM Q&A UI입니다. 원본 egbim_homepage의 Q&A 화면 구성과 패키지 S/W 메뉴 방향을 참고해, PHP/그누보드/DB 의존성 없이 정적 호스팅에서 동작하도록 분리했습니다.

로그인부터 글 저장까지의 화면·처리 전이맵은 docs/qa-login-to-save-transition.md에 정리했습니다.

로컬 확인

정적 파일 서버에서 루트를 열면 됩니다.

python3 -m http.server 4173

그 다음 http://localhost:4173/egbim/에 접속합니다. 브라우저 보안 정책 때문에 file:// 직접 열기보다 정적 서버를 사용하는 편이 안전합니다.

feedback.hmac.kr DB 기준 연동

덤프의 EG-BIM 운영 대상은 다음 값으로 고정했습니다.

  • workspaces.id = 6, workspace_code = EGBIM
  • channels.name = Q&A, channels.id = 01a0ae40-51c2-7647-a93c-0249b3759777
  • 카테고리: ERROR_QNA, IMPROVEMENT_QNA, GENERAL_QNA
  • 신규 상태: support_tickets.status_code = RECEIVED, feedback_status = NEW
  • 첨부 저장소: storage_bucket = qa_cdn

작성 시 브라우저가 UUID를 하나 생성합니다. 같은 UUID를 feedback.id, feedback.source_record_id, support_tickets.idempotency_key에 사용하므로 중복 제출을 판별할 수 있습니다. API 서버는 envelope를 받아 다음 DB 레코드를 하나의 트랜잭션으로 생성해야 합니다.

  • feedbacks: id, channel_id, source_namespace, source_record_id, data
  • support_tickets: 작성자/테넌트/제목/내용/분류/상태/idempotency_key
  • feedback_comment_attachments: 답변 댓글 이미지가 생길 때 comment_idqa_cdn 메타데이터
  • support_attachments: 운영 호환 레이어가 필요할 때 동일 파일의 티켓 첨부 메타데이터

상세 페이지에는 공개 댓글 입력 UI가 있으며, 댓글은 같은 Worker를 통해 ABC의 feedback_comments에 저장하고 is_internal=false인 공개 댓글만 조회합니다. 댓글 이미지가 있으면 attachments multipart 필드로 Worker가 ABC에 전달하며, 응답으로 받은 이미지 URL을 썸네일로 표시합니다. 목록·상세 진입 시에는 ABC의 feedback_status를 다시 조회해 관리페이지에서 변경된 상태를 반영합니다.

연동 지점

  • SSO: Q&A는 홈페이지 로그인 정보를 전달받지 않고, https://sso.hmac.kr/oidc에 등록된 독립적인 PKCE Public Client로 직접 인증합니다. callback은 https://qa-test.baroncs.co.kr/auth/callback이며, Worker가 검증한 claim을 버전이 지정된 HttpOnly 세션 쿠키에 저장합니다. 브라우저의 GET /auth/session은 Q&A 세션에 저장된 작성자 정보를 반환합니다. feedback 서버는 반드시 SSO 세션 또는 토큰을 서버 측에서 검증해야 합니다.
  • 작성자 식별자: ssoSubject/requesterId, userUuid, tenantId/requesterTenantId, tenantIds, scope, roles, 이메일·이름·부서·전화번호를 payload에 넣습니다. requester_idrequester_tenant_id가 없으면 제출을 차단합니다.
  • API: 작성페이지는 같은 Worker의 POST /api/feedbacks를 호출합니다. Worker가 Q&A 세션 쿠키를 검증하고, SSO requester 정보와 ABC_API_KEY Secret을 추가한 뒤 POST https://feedback.hmac.kr/api/projects/{projectId}/channels/{channelId}/feedbacks로 전달합니다. API Key와 내부 ABC 주소는 브라우저에 노출하지 않습니다.
  • 첨부파일: 작성페이지가 multipart/form-data의 반복 images 필드로 파일을 Worker에 전달하고, Worker가 검증된 requester 정보와 API Key를 추가해 ABC API로 전달합니다. ABC API가 qa_cdn 저장소에 파일을 저장하므로 R2 access key/secret은 정적 페이지에 넣지 않습니다.
  • 텍스트만 등록할 때는 기존 JSON 요청을 사용하고, 파일이 있을 때만 multipart 요청을 사용합니다.

Cloudflare R2

wrangler.tomlsrc/index.js를 추가해 Worker가 R2 정적 파일을 제공하도록 구성했습니다. 루트(/)와 /index.html/egbim/으로 이동하고, /egbim/ 아래의 EG-BIM Q&A 페이지는 로그인 보호 경로입니다. EG-BIM 전용 페이지 파일은 egbim/에 두고, 스타일과 폰트는 여러 S/W가 공유할 수 있도록 assets/에 유지합니다.

npm install
npm run check
npm run r2:upload
npm run deploy

wrangler deploy는 Worker와 R2 binding을 배포하고, npm run r2:uploadegbim/ 페이지와 공통 assets/를 R2 bucket에 올립니다. npx wrangler r2 object put은 각 파일을 개별 업로드하므로 업로드 결과를 확인하기 쉽습니다.

Wrangler secret 등록

실제 secret은 저장소에 만들지 않습니다. qa-secrets.json.example을 복사해 qa-secrets.json을 만들고 값을 채운 뒤 등록합니다.

cp qa-secrets.json.example qa-secrets.json
openssl rand -hex 32
npx wrangler secret bulk qa-secrets.json --name baron-qa-gateway-test

ABC_API_KEY에는 프로젝트 전용 ABC API Key를 등록합니다. API Key는 작성페이지 코드나 egbim/config.js에 넣지 않습니다.

AUTH_CLIENT_ID, AUTH_AUTHORIZE_URL, AUTH_TOKEN_URL, 선택적인 AUTH_USERINFO_URLwrangler.toml에 실제 SSO 값으로 설정해야 합니다. 현재 Q&A RP는 https://sso.hmac.kr/oidc를 사용합니다. 이 RP는 PKCE Public Client이므로 AUTH_CLIENT_SECRET은 사용하지 않으며, SESSION_SECRET만 secret으로 등록합니다.

Worker는 OAuth Authorization Code + PKCE를 사용하고, callback에서 검증한 사용자 claim을 서명된 HttpOnly 세션 쿠키에 저장합니다. 브라우저의 GET /auth/session은 정규화된 작성자 정보만 반환합니다.

Gitea Actions 등록값

저장소 Settings → Actions → Secrets에 아래 2개를 등록합니다.

이름 종류
CLOUDFLARE_API_TOKEN Secret Workers Scripts Edit + Workers R2 Storage Edit 권한의 Cloudflare API Token
SESSION_SECRET Secret openssl rand -hex 32로 생성한 세션 서명키
ABC_API_KEY Secret 프로젝트 전용 ABC UserFeedback API Key

CLOUDFLARE_ACCOUNT_ID는 secret으로 등록할 필요가 없습니다. wrangler.toml81fa2d48964d31dd0da9558f9ce601d1로 설정되어 있습니다.

Cloudflare API Token에는 최소한 다음 권한이 필요합니다.

  • Account → Workers Scripts → Edit
  • Account → Workers R2 Storage → Edit
  • Account → Account Settings → Read
  • Custom Domain route를 Actions에서 변경할 경우 Zone → Workers Routes → Edit

.gitea/workflows/deploy.ymlmain push 또는 수동 실행 시 세션 secret을 Worker에 등록하고 R2 업로드 후 baron-qa-gateway-test를 배포합니다. 실제 secret 값은 로그에 출력하지 않습니다.

현재 화면은 API 설정 전에도 QA 흐름을 확인할 수 있도록 샘플 글과 로컬 테스트 저장을 포함합니다. 운영 배포 시에는 Gitea Secret ABC_API_KEY가 Worker에 등록되어야 하며, 작성페이지는 Worker 프록시를 통해 ABC API를 호출합니다.

S
Description
No description provided
Readme
743 KiB
Languages
JavaScript 64.3%
CSS 25.1%
HTML 9.6%
Shell 1%