API 엔드포인트¶
모든 API는 /procedure-hub prefix.
응답 유지 원칙¶
기존 endpoint의 최상위 키·필드명·조건부 생략은 소비자 계약이다. 공통
{data, code, meta} envelope를 덧씌우지 않는다. Pydantic은 기존 형태를 검증하는 데
사용하며 alias가 있는 응답은 원래 JSON 키로 직렬화한다. null과 키 생략은 구분하고
exclude_none은 해당 endpoint의 계약에 맞게 적용한다. taxonomy·products·extracted처럼
동적 구조인 응답을 형식 통일을 위해 고정 DTO로 바꾸지 않는다.
합병증 조회의 indication이 없으면 공통 항목과 비-indication 항목을 반환한다.
지정하면 공통 항목과 해당 indication 항목만 반환한다. 다른 부위의 항목을 섞지 않는다.
Swagger / OpenAPI¶
- 로컬 Swagger UI:
http://localhost:8005/procedure-hub/api-docs - 로컬 OpenAPI JSON:
http://localhost:8005/procedure-hub/openapi.json - STG Swagger UI:
https://api-stg-csp.medisolveai.com/procedure-hub/api-docs(다음 Backend 배포 후 노출 확인)
Swagger 설명은 BAY/SAY와 같은 방식으로 backend/app/swagger_docs/에 분리하고 router
decorator에서 연결한다. 각 operation의 실제 request/response schema는 Pydantic model,
공개 구조 불변 여부는 backend/tests/test_public_api_contract.py가 소유한다.
공개 계약 기준선 (2026-09-03)¶
등록된 FastAPI 공개 operation 42개를 현재 계약으로 동결한다. URL, method, parameter,
request body, status와 response schema는 승인 없이 변경하지 않는다. 구조적 기준선은
backend/tests/test_public_api_contract.py의 단일 table-driven gate가 소유하고, 실제 대표
응답 값은 기존 router snapshot test가 소유한다.
| Surface | Operation 수 | Semantic 분류 | 현재 확인된 소비자 |
|---|---|---|---|
/health, /health/config |
2 | read | 배포·운영 probe |
/api/v1/{taxonomy,...,treatment-sequence} |
23 | read | CHARTY 4개, Linky 4개, Procedure Hub 임상 조회 |
/api/v1/terminology/* GET |
2 | read | 저장소 내부 호출자 없음 |
/api/v1/glossary* GET |
4 | read | Procedure Hub glossary 화면·BFF |
/api/v1/knowledge/retrieve POST |
1 | read | Procedure Hub 범용 지식 검색 소비자 |
/api/v1/terminology/* PUT·DELETE |
8 | write | 저장소 내부 호출자 없음; legacy admin surface 유지 |
/api/v1/glossary/upload POST |
1 | preview=read, apply=write | Procedure Hub upload dialog·BFF |
/api/v1/glossary/versions/{id}/rollback POST |
1 | write | Procedure Hub version panel·BFF |
HTTP method와 semantic write 여부는 같지 않다. Knowledge Retrieval POST와 glossary upload preview는 상태를 바꾸지 않는다. Glossary upload apply, rollback과 terminology PUT·DELETE만 DB 상태를 변경한다.
Write 보호 책임¶
- 기존 FastAPI admin write의 인증·인가는 Gateway가 소유하고 BE router는 직접 인증하지 않는 현재 저장소 규칙을 유지한다.
- 실제 Gateway 차단 동작은 저장소 코드만으로 증명할 수 없으므로 STG 배포 gate에서 허용·거부 요청으로 검증한다.
- 현재 glossary Next BFF는 payload와
content-type만 전달하며X-Uploader감사 헤더는 전달하지 않는다. 인증 주체와 actor 전달은 Gateway 검증과 함께 보완한다. - terminology write는 저장소 정적 검색상 실제 FE caller가 없다. 계약은 보존하되 새 화면이 사용하기 전 admin caller와 actor 전달 방식을 먼저 확정한다.
- Next
PUT /api/taxonomy는 FastAPI operation에 포함되지 않던 무보호 legacy 경로였고 checkpoint C2에서 화면 caller와 함께 제거했다. 분류 화면은 read-only이며, 향후 편집은 DB의 초안·검토·게시·감사를 소유하는 Backend Application Service 없이 재도입하지 않는다.
현재 소비자 근거와 전환 상태는 Canonical 데이터·API 호환·RAG 전달이 소유한다.
Procedure Hub 화면용 Next BFF¶
화면은 같은 origin의 /api/{endpoint}를 호출하고, Next route는
PROCEDURE_API_BASE의 FastAPI /procedure-hub/api/v1/{endpoint} 응답 상태와 JSON 본문을
그대로 전달한다. 로컬 기본 Backend 주소는 http://localhost:8005다.
C3에서 기존 DB endpoint 11개를, C4에서 anatomy-danger-zones, consent-checklist,
market-pricing, patient-education, pih-risk, post-procedure-timeline, procedure-comparison,
treatment-optimization, treatment-sequence 9개를 DB-backed compatibility proxy로 전환했다.
Backend 연결 실패는 502 {"error":"Procedure API 연결에 실패했습니다."}로 반환한다. 두 단계
모두 기존 Next URL과 응답 본문을 유지하며, 잔여 runtime file route는 extracted와 UI i18n이다.
Health¶
GET /procedure-hub/health
응답:
{
"status": "ok",
"timestamp": "2026-04-15T05:00:00.000000+00:00"
}
핵심 API (CHARTY 사용)¶
이 4개 엔드포인트는 공통으로 optional lang query param 을 지원한다 (PHUB-WP-005, commit feb3d2f). 자세한 동작은 아래 다국어(lang) 응답 섹션 참조.
GET /procedure-hub/api/v1/taxonomy¶
시술 분류 체계. 키워드 감지, 시술 상세 정보에 사용.
Query Parameters¶
| param | type | default | required | 비고 |
|---|---|---|---|---|
lang |
string | ko |
optional | 응답 다국어 — ko / en / ja / zh / yue / th / vi 중 택1. 미지정 또는 미지원 값 = ko fallback. i18n 미적재 도메인은 ko fallback (COALESCE 자연 처리). |
GET /procedure-hub/api/v1/taxonomy→ ko 응답GET /procedure-hub/api/v1/taxonomy?lang=zh→ 중국어 응답 (modality 17×7 / problem 14×7 / subcategory 3×7 적재 완료)
products[].id (PLAN-009, CHARTY glossary 조인 키)¶
modality[].products[] 각 항목에 결정적 공개 id 노출 (additive — 기존 키 불변).
- 형식:
{modality_id}-P-{n}(예:M1-P-0).n은 modality 내 product 위치(sort_order). - 결정적: modality_id + 위치에서 산출 → 재시드/환경(stg·prod) 무관하게 동일. DB autoincrement PK 는 노출하지 않음 (재시드 시 변동 가능).
- lang 무관 동일:
?lang=ja와?lang=ko응답에서 동일 product 는 동일 id → CHARTY 가{ja_name: ko_name}용어집을 id 로 조인 가능. - item id(
M1-2-1)와-P-인픽스로 네임스페이스 분리 (flat{node_id: name}충돌 방지). - ⚠️ 이 id 는 CHARTY glossary 조인 전용. i18n CRUD(PUT/DELETE)는 terminology 엔드포인트의
products[].id(DB int) 사용 — 별개 키.
GET /procedure-hub/api/v1/combo-recipes¶
원장 검증 시술 조합 프리셋. AI 추천 컨텍스트에 사용.
Query Parameters¶
| param | type | default | required | 비고 |
|---|---|---|---|---|
lang |
string | ko |
optional | taxonomy 와 동일. 현재 i18n row 0 → 모든 lang 에서 ko fallback. |
GET /procedure-hub/api/v1/synergy¶
시술 간 시너지 관계 (116개 링크). AI 추천 컨텍스트에 사용.
Query Parameters¶
| param | type | default | required | 비고 |
|---|---|---|---|---|
lang |
string | ko |
optional | taxonomy 와 동일. 현재 i18n row 0 → 모든 lang 에서 ko fallback. |
GET /procedure-hub/api/v1/problem-combos¶
고민별 시술 패키지 (tier별).
Query Parameters¶
| param | type | default | required | 비고 |
|---|---|---|---|---|
lang |
string | ko |
optional | taxonomy 와 동일. i18n 테이블 신설(alembic 0034)되었으나 row 0 → 현재 ko fallback. |
다국어(lang) 응답 (CHARTY 사용 4 endpoint)¶
위 4개 엔드포인트(taxonomy / combo-recipes / synergy / problem-combos)는 optional lang query param 으로 다국어 응답을 지원한다. additive 변경 — 응답 스키마/키 불변, 기존 호출 영향 0 (CHARTY breaking 0).
지원 언어¶
ko(기본) / en / ja / zh / yue / th / vi — 7종.
폴백 정책¶
- 미지정:
lang생략 =ko→ 기존 응답과 byte-identical. - 미지원 값: 예
?lang=xx=kofallback. - i18n miss: i18n 미적재 도메인/row 는
ko원문 유지 (DB LEFT JOIN + COALESCE 로 자연 처리). - 응답 스키마/키 불변: 적재된 도메인만 해당 언어 값으로 치환, 미적재는 ko 그대로.
Accept-Language헤더 미지원 — query param 만 지원 (PHUB-SPEC-052 결정).
도메인별 i18n 적재 현황 (2026-06-05 기준)¶
| endpoint | i18n 적재 상태 | ?lang=zh 응답 |
|---|---|---|
/procedure-hub/api/v1/taxonomy |
✅ 적재 완료 (modality 17×7 / problem 14×7 / subcategory 3×7) | 다국어 응답 활성 |
/procedure-hub/api/v1/synergy |
❌ i18n row 0 (번역 원천 부재, 게이트 2 후속) | ko fallback |
/procedure-hub/api/v1/combo-recipes |
❌ i18n row 0 (동상) | ko fallback |
/procedure-hub/api/v1/problem-combos |
❌ i18n 테이블 신설(alembic 0034)만, row 0 | ko fallback |
참조 (정책 SoT)¶
- PHUB-SPEC-052 — i18n 정책 (R5: query param 단일 방식, ko fallback).
- PHUB-SPEC-050 — charty-consumer-contract (draft, 본 lang 정책 환류 예정).
- CHARTY-DEC-039 — CHARTY consumer 활용 정책.
추가 API¶
GET /procedure-hub/api/v1/products¶
제품-제조사 매핑 (60개).
GET /procedure-hub/api/v1/problem-packages¶
고민별 상담 패키지 (CC 레벨).
GET /procedure-hub/api/v1/complications¶
합병증 정보.
GET /procedure-hub/api/v1/contraindications¶
금기사항.
DB-backed 임상 reference read¶
다음 endpoint는 C4에서 normalized DB projection으로 전환했으며, 전환 전 JSON의 최상위·중첩 응답 형태와 조건부 키를 그대로 유지한다.
GET /procedure-hub/api/v1/anatomy-danger-zonesGET /procedure-hub/api/v1/consent-checklistGET /procedure-hub/api/v1/market-pricingGET /procedure-hub/api/v1/patient-educationGET /procedure-hub/api/v1/pih-riskGET /procedure-hub/api/v1/post-procedure-timelineGET /procedure-hub/api/v1/procedure-comparisonGET /procedure-hub/api/v1/treatment-optimizationGET /procedure-hub/api/v1/treatment-sequence
Knowledge Retrieval API¶
POST /procedure-hub/api/v1/knowledge/retrieve¶
현재 published canonical content release만 조회해 질의와 관련된 전체 PHub 지식 항목을 반환하는 API다. 호출자가 미리 분야나 화면 section을 선택할 필요가 없다.
요청:
{
"query": "보톡스와 필러를 같이 해도 돼?",
"lang": "ko",
"max_results": 40,
"cursor": null
}
query만 필수이며 1~500자다.- 공개 request에 domain·section filter를 두지 않고 전체 게시 domain을 검색한다.
max_results는 1~200이며, 잘린 결과는 같은 query·release에 묶인cursor로 이어서 조회한다.- 안전·합병증 질의의 구조화 규칙은 검색 점수와 무관하게 강제로 합류한다.
응답 status:
| 값 | 의미 |
|---|---|
ok |
같은 release에서 관련 지식을 정상 조회함 |
no_match |
게시 지식에서 관련 항목을 찾지 못함 |
needs_clarification |
alias 후보가 복수여서 임의 확정하지 않음 |
partial |
관련 항목은 있으나 필수 안전 규칙 또는 언어 특화가 일부 부족함 |
unavailable |
published canonical release가 없어 draft를 노출하지 않음 |
error |
요청을 평가하지 못함 |
응답에는 interpretation, 공통 items, sources, safety, 전체 domain의
coverage, retrieval, limitations, data_revision이 포함된다.
data_revision은 release_id, release version, published_at으로 구성되며, 서로 다른 release의
row를 한 응답에 섞지 않는다. evidence는 approved claim과 현재 statement version의 verified
verification, 검증된 identifier를 모두 요구한다.
로컬 조회 화면은 http://localhost:3001/knowledge-retrieval이며, Next BFF
POST /api/v1/knowledge/retrieve가 위 FastAPI 응답을 상태와 본문 변경 없이 전달한다.
Linky WP-010 prefill API (신규)¶
GET /procedure-hub/api/v1/extracted¶
17 modality별 최신 immutable legacy ContentRevision.snapshot을
{"M1": {...}, "M2": {...}, ...} dict로 반환한다. Linky CatalogResource.EXTRACTED
계약을 유지하며 runtime 파일을 읽지 않는다. Procedure Hub의 Next /api/extracted는 기존 화면
계약인 17개 배열로만 변환한다.
GET /procedure-hub/api/v1/procedure-profiles¶
시술별 소요시간, 전처치, 사후관리 프로파일. DB compatibility projection.
Linky CatalogResource.PROCEDURE_PROFILES 출처.
GET /procedure-hub/api/v1/pre-procedure-checklist¶
시술 전 공통·카테고리별 체크리스트. DB compatibility projection.
Linky CatalogResource.PRE_PROCEDURE_CHECKLIST 출처. universal_checks 12항목.
용어 사전 (terminology) API — 편집기 전용 (PHUB-WP-008)¶
원장 편집기의 용어 사전 탭 전용. 계층 번역 매트릭스 GET + 레벨별 번역 CRUD.
- 데이터 소스 = DB (PHUB-SPEC-054 / PHUB-DEC-003). overlay JSON 폐기.
- CHARTY
/taxonomy와 동일 i18n 테이블 = 단일 소스 — 용어 편집 결과가 곧 CHARTY 다국어 응답에 반영. - 라우터는 write 권한을 직접 검증하지 않는다. Gateway 설정에 따른 노출 범위와 운영 조치는 배포 가이드를 따른다.
- 지원 lang =
ko / en / ja / zh / yue / th / vi(7종,taxonomy와 동일).
셀(cell) 구조¶
매트릭스의 각 언어 셀 = { name, source, editable }.
| source | 의미 | editable |
|---|---|---|
column |
원천 컬럼값 | ko = false (편집 거부) / en = true (편집 시 i18n 오버레이 생성) |
i18n |
i18n 테이블 적재 번역 | true |
missing |
미적재 (name: null) |
true |
GET /procedure-hub/api/v1/terminology/matrix¶
modality + subcategory + product + 용도별 item 계층 번역 매트릭스 (DB 단일 소스).
응답:
{
"langs": ["ko", "en", "ja", "zh", "yue", "th", "vi"],
"modalities": [
{
"id": "M1",
"name": "보톡스",
"name_en": "Botulinum Toxin",
"cells": { "ko": { "name": "보톡스", "source": "column", "editable": false }, "zh": { "name": null, "source": "missing", "editable": true } },
"subcategories": [
{ "id": "M1-2", "slug": "by-purpose", "label": "용도별", "cells": { "...": "..." } }
],
"products": [
{ "id": 12, "name": "보툴렉스", "name_en": "Botulax", "cells": { "...": "..." } }
],
"items": [
{ "id": "M1-3-1", "name": "...", "cells": { "...": "..." } }
]
}
]
}
- subcategory 는 같은 ko 라벨끼리 번역을 공유 (slug·ko텍스트 매칭).
products[].id= DB int (CRUD path 에 그대로 사용).
GET /procedure-hub/api/v1/terminology/modality¶
modality × 언어 시술명 매트릭스 (하위호환, PLAN-006). 계층 없는 modality-only. 신규 사용은 matrix 권장.
레벨별 번역 CRUD (DB write)¶
| Method · Path | 테이블 | id 타입 |
|---|---|---|
PUT · DELETE /api/v1/terminology/modality/{modality_id}/{lang} |
modality_i18n |
str (예: M1) |
PUT · DELETE /api/v1/terminology/subcategory/{subcategory_id}/{lang} |
subcategory_label_i18n |
str (예: M1-2) |
PUT · DELETE /api/v1/terminology/product/{product_id}/{lang} |
modality_product_i18n |
int (GET 응답 products[].id) |
PUT · DELETE /api/v1/terminology/item/{item_id}/{lang} |
modality_item_i18n |
str (예: M1-3-1) |
PUTbody ={ "name": "..." }, 응답 ={ "level", "id", "lang", "cell" }.DELETE응답 ={ "level", "id", "lang", "deleted": true }.
검증 / 에러¶
| 상황 | status |
|---|---|
| ko(원천) 편집·삭제 | 400 |
| 미지원 lang | 400 |
| 없는 id | 404 |
| 이미 없는 번역 재DELETE | 404 |
| product id non-int | 422 |
빈 name (min_length=1) |
422 |
엔드포인트 요약¶
| 엔드포인트 | 설명 | CHARTY 사용 | Linky 사용 | ?lang= |
|---|---|---|---|---|
GET /procedure-hub/health |
헬스 체크 | - | - | - |
GET /procedure-hub/api/v1/taxonomy |
시술 분류 체계 (modality.name 필드 포함) | ✅ | ✅ | ✅ 적재 완료 |
GET /procedure-hub/api/v1/combo-recipes |
시술 조합 레시피 | ✅ | - | ⚠️ param 지원 / row 0 (ko fallback) |
GET /procedure-hub/api/v1/synergy |
시너지 관계 | ✅ | - | ⚠️ param 지원 / row 0 (ko fallback) |
GET /procedure-hub/api/v1/problem-combos |
고민별 조합 | ✅ | - | ⚠️ param 지원 / row 0 (ko fallback) |
GET /procedure-hub/api/v1/products |
제품 매핑 | - | - | - |
GET /procedure-hub/api/v1/problem-packages |
고민별 패키지 | - | - | - |
GET /procedure-hub/api/v1/complications |
합병증 | - | - | - |
GET /procedure-hub/api/v1/contraindications |
금기사항 | - | - | - |
POST /procedure-hub/api/v1/knowledge/retrieve |
published canonical 범용 지식 검색 | - | - | body lang |
GET /procedure-hub/api/v1/extracted |
17 modality extracted dict | - | ✅ | - |
GET /procedure-hub/api/v1/procedure-profiles |
시술 프로파일 | - | ✅ | - |
GET /procedure-hub/api/v1/pre-procedure-checklist |
시술 전 체크리스트 | - | ✅ | - |
GET /procedure-hub/api/v1/terminology/matrix |
용어 사전 계층 번역 매트릭스 (편집기 전용, +레벨별 CRUD) | - | - | 7종 |