{"openapi":"3.0.0","paths":{"/api/v1/status/{slug}/{listId}":{"get":{"description":"OB 3.0 표준 폐지 목록 VC.\ncredentialStatus.statusListCredential URL에서 참조됩니다.\n\n인코딩: gzip + base64url (RFC 3986 §4.2)\n비트 0 = 유효, 비트 1 = 폐지","operationId":"StatusController_getStatusList","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}},{"name":"listId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"BitstringStatusListCredential JSON-LD"}},"summary":"BitstringStatusListCredential 조회","tags":["status"]}},"/api/v1/platform":{"post":{"operationId":"PlatformController_createPlatform","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlatformDto"}}}},"responses":{"201":{"description":""}},"security":[{"admin-key":[]}],"summary":"[어드민] Platform 파트너 생성 및 API Key 발급","tags":["platform"]},"get":{"operationId":"PlatformController_listPlatforms","parameters":[],"responses":{"200":{"description":""}},"security":[{"admin-key":[]}],"summary":"[어드민] Platform 파트너 목록","tags":["platform"]}},"/api/v1/platform/tenants":{"post":{"operationId":"PlatformController_createSubTenant","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubTenantDto"}}}},"responses":{"201":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 생성","tags":["platform"]},"get":{"operationId":"PlatformController_listSubTenants","parameters":[],"responses":{"200":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 목록","tags":["platform"]}},"/api/v1/platform/tenants/{tenantId}":{"get":{"operationId":"PlatformController_getSubTenant","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 상세 조회","tags":["platform"]}},"/api/v1/platform/tenants/{tenantId}/approve":{"post":{"operationId":"PlatformController_approveSubTenant","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 KYB 승인 (플랫폼 자체 검증 후)","tags":["platform"]}},"/api/v1/platform/tenants/{tenantId}/suspend":{"post":{"operationId":"PlatformController_suspendSubTenant","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 정지","tags":["platform"]}},"/api/v1/platform/tenants/{tenantId}/api-key/rotate":{"post":{"operationId":"PlatformController_rotateApiKey","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"platform-key":[]}],"summary":"[Platform] 서브 테넌트 API Key 교체","tags":["platform"]}},"/api/v1/auth/login":{"post":{"operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":""}},"summary":"테넌트 로그인 — email + API Key → JWT","tags":["auth"]}},"/api/v1/tenants/register":{"post":{"description":"테넌트를 생성하고 API Key를 발급합니다.\n\n> ⚠️ **주의:** 가입 직후에는 배지 클래스 생성 및 배지 발행이 **불가능**합니다.\n> KYB(사업자 인증) 제출 후 관리자 승인이 완료되어야 발행 기능이 활성화됩니다.\n>\n> **TrustFlow 연동의 경우** 이 엔드포인트를 사용하지 않고,\n> `POST /v1/platform/tenants` (X-Platform-Key 필요)를 통해 서브 테넌트를 자동 생성하세요.\n> Platform API로 생성된 테넌트는 `autoApprove: true` 옵션으로 즉시 발행 가능합니다.","operationId":"TenantsController_register","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"201":{"description":"테넌트 생성 및 API Key 발급 성공 — KYB 승인 후 발행 가능"},"409":{"description":"이미 사용 중인 slug 또는 이메일"}},"summary":"테넌트 가입 (TrustBadge 직접 가입)","tags":["tenants"]}},"/api/v1/tenants/activate":{"post":{"description":"일회성 토큰으로 API Key를 1회만 반환합니다. 토큰은 즉시 소비되며 48시간 후 만료됩니다.","operationId":"TenantsController_activate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateDto"}}}},"responses":{"201":{"description":"{ apiKey } — 1회만 표시"},"400":{"description":"이미 사용/만료된 링크"},"404":{"description":"유효하지 않은 토큰"}},"summary":"API Key 활성화 (승인 메일의 일회성 링크)","tags":["tenants"]}},"/api/v1/tenants/recover-key":{"post":{"description":"등록 이메일로 새 API Key의 일회성 활성화 링크를 보냅니다. 기존 키는 무효화됩니다. (이메일 존재 여부는 응답에 노출하지 않음)","operationId":"TenantsController_recoverKey","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecoverKeyDto"}}}},"responses":{"201":{"description":"{ ok: true } — 등록된 이메일이면 안내 발송"}},"summary":"API Key 재발급 (분실 시·이메일 기반)","tags":["tenants"]}},"/api/v1/tenants/me":{"get":{"operationId":"TenantsController_getMe","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"내 테넌트 정보 조회","tags":["tenants"]}},"/api/v1/tenants/me/kyb":{"post":{"operationId":"TenantsController_submitKyb","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitKybDto"}}}},"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"KYB 제출","tags":["tenants"]}},"/api/v1/tenants/me/api-keys":{"get":{"operationId":"TenantsController_listApiKeys","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"API 키 목록","tags":["tenants"]}},"/api/v1/tenants/me/api-keys/{keyId}/rotate":{"post":{"operationId":"TenantsController_rotateApiKey","parameters":[{"name":"keyId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"API 키 교체","tags":["tenants"]}},"/api/v1/tenants/me/public-profile":{"patch":{"description":"`publicEnabled` 토글 및 `publicProfile` 메타(로고/소개/링크 등) 업데이트. 공개 페이지는 verify.badge.retrust.world/issuer/{slug} 에서 노출됩니다.","operationId":"TenantsController_updatePublicProfile","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePublicProfileDto"}}}},"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"발급기관 공개 프로필 설정","tags":["tenants"]}},"/api/v1/tenants/me/ai-keys":{"get":{"operationId":"TenantsController_listAiKeys","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"테넌트 AI 키 목록 (마스킹)","tags":["tenants"]},"patch":{"description":"provider(anthropic/openai/gemini/deepseek) + apiKey. 평문 미저장, AES-GCM 암호화.","operationId":"TenantsController_setAiKey","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"AI 프로바이더 키 등록/교체 (암호화 저장)","tags":["tenants"]}},"/api/v1/tenants/me/ai-keys/{provider}":{"delete":{"operationId":"TenantsController_removeAiKey","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"AI 프로바이더 키 삭제","tags":["tenants"]}},"/api/v1/tenants/{slug}/did.json":{"get":{"operationId":"TenantsController_getDidDocument","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"W3C DID Document"},"404":{"description":"테넌트 미존재 또는 키 미생성"}},"summary":"DID Document 조회 (did:web)","tags":["tenants"]}},"/api/v1/tenants/admin/stats":{"get":{"operationId":"TenantsController_adminStats","parameters":[],"responses":{"200":{"description":""}},"summary":"[어드민] 플랫폼 통계","tags":["tenants"]}},"/api/v1/tenants/admin/list":{"get":{"operationId":"TenantsController_adminList","parameters":[],"responses":{"200":{"description":""}},"summary":"[어드민] 전체 테넌트 목록","tags":["tenants"]}},"/api/v1/tenants/admin/kyb":{"get":{"operationId":"TenantsController_adminKybQueue","parameters":[],"responses":{"200":{"description":""}},"summary":"[어드민] KYB 심사 대기 목록","tags":["tenants"]}},"/api/v1/tenants/{tenantId}/kyb/approve":{"patch":{"operationId":"TenantsController_approveKyb","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewKybDto"}}}},"responses":{"200":{"description":""}},"summary":"[어드민] KYB 승인","tags":["tenants"]}},"/api/v1/tenants/{tenantId}/kyb/reject":{"patch":{"operationId":"TenantsController_rejectKyb","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReviewKybDto"}}}},"responses":{"200":{"description":""}},"summary":"[어드민] KYB 거부","tags":["tenants"]}},"/api/v1/tenants/{tenantId}/rotate-key":{"post":{"description":"새 keyId(version+1)를 Vault에 생성해 ACTIVE로, 이전 ACTIVE 키는 RETIRED(검증전용)로 전환합니다. RETIRED 키 공개키는 영구 보존되어 기존 증서 검증이 유지됩니다.","operationId":"TenantsController_rotateSigningKey","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"[어드민] VC 서명키 로테이션 (ADR-004)","tags":["tenants"]}},"/api/v1/credits/balance":{"get":{"operationId":"CreditsController_balance","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"크레딧 잔액 조회","tags":["credits"]}},"/api/v1/credits/ledger":{"get":{"description":"KYB 지급·배지 발급·AI 사용 차감 내역 (최신순)","operationId":"CreditsController_ledger","parameters":[{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"크레딧 거래 내역","tags":["credits"]}},"/api/v1/credits/admin/{tenantId}/grant":{"post":{"description":"amount(+/-) 만큼 조정. reason 기본 ADMIN_ADJUST.","operationId":"CreditsController_adminGrant","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"[어드민] 크레딧 수동 지급/조정","tags":["credits"]}},"/api/v1/credits/admin/backfill-kyb":{"post":{"description":"지급 이력 없는 KYB_APPROVED 테넌트에만 1회 지급","operationId":"CreditsController_backfill","parameters":[],"responses":{"201":{"description":""}},"summary":"[어드민] 기존 KYB 승인 테넌트 100크레딧 일괄 백필","tags":["credits"]}},"/api/v1/badges/ai-assist":{"post":{"description":"배지명/카테고리를 입력하면 선택한 프로바이더(anthropic/openai/gemini/deepseek)·모델이 설명·기준·태그·프레임·티어·아이콘·색상을 자동 추천합니다. 테넌트가 자체 키(BYOK)를 등록했으면 그 키, 아니면 플랫폼 기본 키 사용.","operationId":"BadgesController_generateAiSuggestion","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAssistDto"}}}},"responses":{"200":{"description":"AI 추천 결과"},"503":{"description":"AI 어시스트가 활성화되지 않음 (프로바이더 키 필요)"}},"security":[{"api-key":[]}],"summary":"AI 디자인 어시스트","tags":["badges"]}},"/api/v1/badges/ai-assist/status":{"get":{"operationId":"BadgesController_getAiStatus","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"AI 어시스트 활성화 여부 + 사용 가능 프로바이더·모델 (테넌트 BYOK 반영)","tags":["badges"]}},"/api/v1/badges/ai-assist/layout":{"post":{"description":"프레임·요소(텍스트/로고/QR 등) 정보를 주면 공문서 디자인 원칙(시각 계층·중심축 정렬·여백·겹침 방지)에 따라 각 요소의 위치·크기(rect)를 제안합니다. 텍스트는 height=글자 크기. 테넌트 BYOK 키 사용 시 크레딧 무차감.","operationId":"BadgesController_suggestLayout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiLayoutDto"}}}},"responses":{"200":{"description":"{ [key]: {x,y,width,height} } 배치 맵"},"503":{"description":"AI 프로바이더 키 필요"}},"security":[{"api-key":[]}],"summary":"AI 자동 배치","tags":["badges"]}},"/api/v1/badges/ai-assist/translate":{"post":{"description":"저장 전 작성 중인 콘텐츠를 대상 언어들로 AI 번역하여 { [locale]: {name,description,criteria,tags} } 맵을 반환. 디자이너에서 저장 전 미리 번역하는 용도. 테넌트 BYOK 우선.","operationId":"BadgesController_translateContent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranslateContentDto"}}}},"responses":{"200":{"description":"번역 맵"},"503":{"description":"AI 프로바이더 키 필요"}},"security":[{"api-key":[]}],"summary":"DPP 다국어 번역 (저장 없이 결과만 반환)","tags":["badges"]}},"/api/v1/badges/{id}/translate":{"post":{"description":"배지 기본 언어(defaultLocale) 콘텐츠를 대상 언어들로 AI 번역하여 i18n 에 병합 저장합니다. 테넌트 BYOK 키 우선, 없으면 플랫폼 기본 키. 결과는 발급기관이 검수·수정 가능.","operationId":"BadgesController_translateBadge","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranslateBadgeDto"}}}},"responses":{"200":{"description":"번역 적용된 배지 클래스"},"503":{"description":"AI 프로바이더 키 필요"}},"security":[{"api-key":[]}],"summary":"DPP 다국어 번역","tags":["badges"]}},"/api/v1/badges":{"post":{"description":"새 배지 클래스를 생성합니다. **KYB 승인된 테넌트만 가능합니다.** 생성 후 `DRAFT` 상태이며, `/activate` 호출 후 발행에 사용할 수 있습니다.","operationId":"BadgesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBadgeClassDto"}}}},"responses":{"201":{"description":"배지 클래스 생성 성공 (DRAFT 상태)"},"403":{"description":"KYB 미승인 — 관리자 승인 후 생성 가능"}},"security":[{"api-key":[]}],"summary":"배지 클래스 생성","tags":["badges"]},"get":{"operationId":"BadgesController_findAll","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 클래스 목록 조회","tags":["badges"]}},"/api/v1/badges/{id}":{"get":{"operationId":"BadgesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 클래스 단건 조회","tags":["badges"]},"patch":{"operationId":"BadgesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBadgeClassDto"}}}},"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 클래스 수정","tags":["badges"]}},"/api/v1/badges/{id}/activate":{"post":{"description":"DRAFT 상태의 배지 클래스를 ACTIVE 상태로 전환합니다. 활성화 후 배지 발행에 사용할 수 있습니다.","operationId":"BadgesController_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 클래스 활성화","tags":["badges"]}},"/api/v1/badges/{id}/archive":{"post":{"operationId":"BadgesController_archive","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 클래스 보관 (비활성화)","tags":["badges"]}},"/api/v1/webhooks/events":{"get":{"operationId":"WebhooksController_listEvents","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"사용 가능한 webhook 이벤트 목록","tags":["webhooks"]}},"/api/v1/webhooks":{"get":{"operationId":"WebhooksController_findAll","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"Webhook 목록 조회","tags":["webhooks"]},"post":{"description":"새 webhook을 등록합니다. 응답에 포함된 `secret`은 다시 표시되지 않으니 안전한 곳에 보관하세요.","operationId":"WebhooksController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookBodyDto"}}}},"responses":{"201":{"description":"생성 성공 (secret 1회 노출)"}},"security":[{"api-key":[]}],"summary":"Webhook 등록","tags":["webhooks"]}},"/api/v1/webhooks/{id}":{"get":{"operationId":"WebhooksController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"Webhook 단건 조회","tags":["webhooks"]},"patch":{"operationId":"WebhooksController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookBodyDto"}}}},"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"Webhook 수정 (url/events/description)","tags":["webhooks"]},"delete":{"operationId":"WebhooksController_delete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"api-key":[]}],"summary":"Webhook 삭제","tags":["webhooks"]}},"/api/v1/webhooks/{id}/toggle":{"post":{"operationId":"WebhooksController_toggle","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ToggleWebhookBodyDto"}}}},"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"Webhook 활성/비활성 토글","tags":["webhooks"]}},"/api/v1/webhooks/{id}/deliveries":{"get":{"operationId":"WebhooksController_deliveries","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"최근 발송 기록 (기본 50건)","tags":["webhooks"]}},"/api/v1/assertions":{"post":{"description":"수신자에게 배지를 발행합니다. **KYB 승인된 테넌트만 가능합니다.** 발행 즉시 XDC 블록체인 앵커링 및 수신자 이메일 발송이 비동기로 처리됩니다.","operationId":"AssertionsController_issue","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueAssertionDto"}}}},"responses":{"201":{"description":"발행 성공"},"403":{"description":"KYB 미승인 — 관리자 승인 후 발행 가능"}},"security":[{"api-key":[]}],"summary":"배지 단건 발행","tags":["assertions"]},"get":{"operationId":"AssertionsController_findAll","parameters":[{"name":"status","required":false,"in":"query","schema":{"enum":["ISSUED","REVOKED","EXPIRED"],"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"발행 내역 목록 조회","tags":["assertions"]}},"/api/v1/assertions/batch":{"post":{"description":"여러 수신자에게 배지를 일괄 발행합니다. **KYB 승인된 테넌트만 가능합니다.**","operationId":"AssertionsController_issueMany","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchIssueDto"}}}},"responses":{"201":{"description":"일괄 발행 성공"},"403":{"description":"KYB 미승인 — 관리자 승인 후 발행 가능"}},"security":[{"api-key":[]}],"summary":"배지 일괄 발행","tags":["assertions"]}},"/api/v1/assertions/csv":{"post":{"description":"CSV 텍스트로 대량 배지를 발행합니다.\n\n헤더 형식: `email,name,badgeClassId,expiresAt`\n- `email`: 필수\n- `name`: 수신자 이름 (선택)\n- `badgeClassId`: 배지 ID (선택, 없으면 body의 badgeClassId 사용)\n- `expiresAt`: 만료일 ISO8601 (선택)\n\n실패한 행은 건너뛰고 계속 진행합니다. 결과 리포트를 반환합니다.","operationId":"AssertionsController_issueCsv","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CsvIssueDto"}}}},"responses":{"201":{"description":"일괄 발행 완료 (성공/실패 통계 포함)"},"403":{"description":"KYB 미승인"}},"security":[{"api-key":[]}],"summary":"CSV 일괄 발행","tags":["assertions"]}},"/api/v1/assertions/public/{id}":{"get":{"description":"OB 3.0 표준 Verifiable Credential JSON을 반환합니다. 인증 없이 공개 접근 가능합니다.","operationId":"AssertionsController_getPublicAssertion","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"공개 OB 3.0 VC JSON 조회 (인증 불필요)","tags":["assertions"]}},"/api/v1/assertions/{id}":{"get":{"operationId":"AssertionsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"발행 내역 단건 조회","tags":["assertions"]}},"/api/v1/assertions/{id}/revoke":{"post":{"operationId":"AssertionsController_revoke","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevokeAssertionDto"}}}},"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"배지 발행 취소 (Revoke)","tags":["assertions"]}},"/api/v1/assertions/admin/stats":{"get":{"operationId":"AdminAssertionsController_adminStats","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"어드민 어서션 통계","tags":["assertions-admin"]}},"/api/v1/assertions/admin/list":{"get":{"operationId":"AdminAssertionsController_adminList","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"어드민 어서션 목록 (필터/페이징)","tags":["assertions-admin"]}},"/api/v1/assertions/admin/export.csv":{"get":{"operationId":"AdminAssertionsController_adminExportCsv","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"어드민 어서션 CSV 내보내기","tags":["assertions-admin"]}},"/api/v1/assertions/admin/{id}":{"get":{"operationId":"AdminAssertionsController_adminGet","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"어드민 어서션 상세 (마스킹 없음)","tags":["assertions-admin"]}},"/api/v1/assertions/admin/{id}/force-revoke":{"post":{"operationId":"AdminAssertionsController_adminForceRevoke","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"어드민 강제 폐지","tags":["assertions-admin"]}},"/api/v1/assertions/admin/{id}/retry-anchor":{"post":{"operationId":"AdminAssertionsController_adminRetryAnchor","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"어드민 앵커 재시도","tags":["assertions-admin"]}},"/api/v1/verify":{"get":{"operationId":"VerificationController_verifyByUrl","parameters":[{"name":"url","required":true,"in":"query","description":"Public assertion URL","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Verify an assertion by public URL","tags":["verification"]}},"/api/v1/verify/wallet/badges":{"get":{"operationId":"VerificationController_walletBadges","parameters":[{"name":"email","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 이메일로 배지 조회 (발급기관 API Key — 본인 발행분만)","tags":["verification"]}},"/api/v1/verify/wallet/request":{"post":{"operationId":"VerificationController_walletRequest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimDto"}}}},"responses":{"201":{"description":"{ ok, email(마스킹) }"}},"summary":"내 지갑 열기 요청 (매직링크 메일 발송)","tags":["verification"]}},"/api/v1/verify/wallet/access":{"get":{"operationId":"VerificationController_walletAccess","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"월렛으로 리다이렉트 (?session=)"}},"summary":"지갑 접근 (메일 링크 → 세션)","tags":["verification"]}},"/api/v1/verify/wallet/my":{"get":{"operationId":"VerificationController_walletMy","parameters":[{"name":"authorization","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"내 배지 목록"}},"summary":"내 배지 (세션 인증)","tags":["verification"]}},"/api/v1/verify/wallet/transfer":{"post":{"operationId":"VerificationController_walletTransfer","parameters":[{"name":"authorization","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletTransferDto"}}}},"responses":{"201":{"description":"{ ok, newAssertionId } 또는 { ok:false, reason }"}},"summary":"소유권 이전 (디지털, 세션 인증)","tags":["verification"]}},"/api/v1/verify/{id}/provenance":{"get":{"operationId":"VerificationController_getProvenance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"[1대 → … → 현재] 소유자 목록 (이메일 마스킹)"}},"summary":"소유 이력 (provenance 체인)","tags":["verification"]}},"/api/v1/verify/{id}/share":{"get":{"description":"배지를 LinkedIn/카카오/SNS에 공유할 때 필요한 메타데이터를 반환합니다.\n\n반환 데이터:\n- `linkedin`: LinkedIn Add to Profile URL\n- `kakao`: 카카오 공유 파라미터\n- `og`: Open Graph 메타데이터 (title, description, image, url)","operationId":"VerificationController_getShareMeta","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"SNS 공유 메타데이터","tags":["verification"]}},"/api/v1/verify/{id}/claim":{"post":{"description":"입력된 이메일이 VC의 IdentityObject 와 일치하는지 확인합니다.\nVC 안의 salt + 입력 email 로 SHA-256 해시 재계산하여 `identityHash` 와 비교합니다.\n\n응답:\n- `{ verified: true }` — 일치 (본인 확인)\n- `{ verified: false, reason: 'MISMATCH' }` — 다른 이메일\n- `{ verified: false, reason: 'NO_IDENTIFIER' }` — 구버전 어선션 (IdentityObject 없음, 본인 증명 불가)\n- `{ verified: false, reason: 'REVOKED' | 'EXPIRED' | 'ASSERTION_NOT_FOUND' }` — 검증 불가 상태","operationId":"VerificationController_claim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"example":{"email":"user@example.com"}}}}},"responses":{"201":{"description":""}},"summary":"본인 증명 (claim) — 이메일로 배지 소유 확인","tags":["verification"]}},"/api/v1/verify/{id}":{"get":{"operationId":"VerificationController_verifyById","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Verify an assertion by ID","tags":["verification"]}},"/api/v1/recipients":{"post":{"description":"이메일을 키로 수령자를 등록합니다. 기존 수령자가 있으면 정보를 갱신합니다. 배지 발급 시 자동으로 호출되므로 직접 사용할 일은 적습니다.","operationId":"RecipientsController_upsert","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRecipientDto"}}}},"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 등록 또는 갱신 (upsert)","tags":["recipients"]},"get":{"operationId":"RecipientsController_findAll","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 목록 조회","tags":["recipients"]}},"/api/v1/recipients/{id}":{"get":{"operationId":"RecipientsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 단건 조회","tags":["recipients"]}},"/api/v1/payments/plans":{"get":{"operationId":"PaymentsController_getPlans","parameters":[],"responses":{"200":{"description":""}},"summary":"플랜 목록 및 가격 조회","tags":["payments"]}},"/api/v1/payments/my-plan":{"get":{"operationId":"PaymentsController_getMyPlan","parameters":[],"responses":{"200":{"description":""}},"summary":"현재 플랜 및 이번 달 사용량 조회","tags":["payments"]}},"/api/v1/payments/subscribe/{plan}":{"post":{"operationId":"PaymentsController_subscribe","parameters":[{"name":"plan","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"플랜 구독 (STARTER / PROFESSIONAL)","tags":["payments"]}},"/api/v1/payments/subscription":{"delete":{"operationId":"PaymentsController_cancel","parameters":[],"responses":{"200":{"description":""}},"summary":"구독 취소 (FREE 플랜으로 전환)","tags":["payments"]}},"/api/v1/payments/webhook/portone":{"post":{"operationId":"PaymentsController_portoneWebhook","parameters":[],"responses":{"201":{"description":""}},"summary":"PortOne 결제 웹훅 (내부용)","tags":["payments"]}},"/api/v1/payments/admin/platform-usage":{"get":{"operationId":"PaymentsController_adminPlatformUsage","parameters":[],"responses":{"200":{"description":""}},"summary":"플랫폼 파트너 사용량 전체 (어드민)","tags":["payments"]}},"/api/v1/payments/admin/platform-usage/{platformId}":{"get":{"operationId":"PaymentsController_adminPlatformDetail","parameters":[{"name":"platformId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"특정 플랫폼 사용량 상세 (어드민)","tags":["payments"]}},"/api/v1/pathways":{"post":{"description":"여러 배지를 묶어서 상위 메타 배지를 자동 발행하는 학습 경로를 설정합니다.\n\n**type: \"ALL\"** — 모든 하위 배지 취득 시 메타 배지 자동 발행\n**type: \"ANY_N\"** — requiredCount개 이상 취득 시 자동 발행 (예: 5개 중 3개)\n\n메타 배지는 조건 달성 즉시 자동으로 수신자에게 발행됩니다.","operationId":"PathwayController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePathwayDto"}}}},"responses":{"201":{"description":"Pathway 생성 성공"}},"security":[{"api-key":[]}],"summary":"Pathway 생성 (Milestone Badge)","tags":["pathways"]},"get":{"operationId":"PathwayController_findAll","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"Pathway 목록 조회","tags":["pathways"]}},"/api/v1/pathways/{pathwayId}/progress/{email}":{"get":{"operationId":"PathwayController_getProgress","parameters":[{"name":"pathwayId","required":true,"in":"path","schema":{"type":"string"}},{"name":"email","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수신자별 Pathway 진행 상황 조회","tags":["pathways"]}},"/api/v1/analytics/me":{"get":{"operationId":"AnalyticsController_getMyStats","parameters":[],"responses":{"200":{"description":""}},"summary":"내 테넌트 발급 통계 (대시보드용)","tags":["analytics"]}},"/api/v1/analytics/admin/overview":{"get":{"operationId":"AnalyticsController_getAdminOverview","parameters":[],"responses":{"200":{"description":""}},"summary":"전체 플랫폼 통계 (어드민 전용)","tags":["analytics"]}},"/api/v1/analytics/admin/platforms":{"get":{"operationId":"AnalyticsController_getPlatformSummary","parameters":[],"responses":{"200":{"description":""}},"summary":"플랫폼 파트너 사용량 전체 (어드민 전용)","tags":["analytics"]}},"/api/v1/analytics/admin/platforms/{platformId}":{"get":{"operationId":"AnalyticsController_getPlatformDetail","parameters":[{"name":"platformId","required":true,"in":"path","schema":{"type":"string"}},{"name":"months","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"특정 플랫폼 사용량 상세","tags":["analytics"]}},"/api/v1/analytics/forecast":{"get":{"operationId":"AnalyticsController_getForecast","parameters":[],"responses":{"200":{"description":""}},"summary":"다음 분기 발급 수 예측 (내 테넌트)","tags":["analytics"]}},"/api/v1/analytics/skill-trends":{"get":{"operationId":"AnalyticsController_getSkillTrends","parameters":[],"responses":{"200":{"description":""}},"summary":"카테고리별 스킬 트렌드 (내 테넌트)","tags":["analytics"]}},"/api/v1/analytics/trending-badges":{"get":{"operationId":"AnalyticsController_getTrendingBadges","parameters":[{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"이번 달 인기 배지 Top N","tags":["analytics"]}},"/api/v1/analytics/admin/forecast":{"get":{"operationId":"AnalyticsController_getAdminForecast","parameters":[],"responses":{"200":{"description":""}},"summary":"전체 플랫폼 분기 예측 (어드민)","tags":["analytics"]}},"/api/v1/analytics/admin/skill-trends":{"get":{"operationId":"AnalyticsController_getAdminSkillTrends","parameters":[],"responses":{"200":{"description":""}},"summary":"전체 플랫폼 스킬 트렌드 (어드민)","tags":["analytics"]}},"/api/v1/campaigns":{"post":{"description":"대규모 배지 발행 캠페인을 생성합니다. scheduledAt 미지정 시 DRAFT 상태로 저장됩니다. **KYB 승인된 테넌트만 실제 발송 가능.**","operationId":"CampaignsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignDto"}}}},"responses":{"201":{"description":"생성 성공"}},"security":[{"api-key":[]}],"summary":"캠페인 생성","tags":["campaigns"]},"get":{"operationId":"CampaignsController_findAll","parameters":[],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"캠페인 목록 조회","tags":["campaigns"]}},"/api/v1/campaigns/{id}":{"get":{"operationId":"CampaignsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"캠페인 단건 조회 (통계 포함)","tags":["campaigns"]}},"/api/v1/campaigns/{id}/recipients":{"get":{"operationId":"CampaignsController_getRecipients","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"캠페인 수령자 목록 조회","tags":["campaigns"]}},"/api/v1/campaigns/{id}/start":{"post":{"operationId":"CampaignsController_start","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"캠페인 즉시 시작","tags":["campaigns"]}},"/api/v1/campaigns/{id}/cancel":{"post":{"operationId":"CampaignsController_cancel","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"캠페인 취소 (SCHEDULED/DRAFT만)","tags":["campaigns"]}},"/api/v1/profiles/{slug}":{"get":{"description":"수령자의 공개 프로필과 발행된 배지 목록을 반환합니다.\n\n`publicEnabled`가 `true`이고 `publicSlug`가 설정된 수령자만 조회됩니다.","operationId":"ProfilesController_getPublicProfile","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"프로필 + 배지 목록"},"404":{"description":"프로필을 찾을 수 없음"}},"summary":"공개 프로필 조회","tags":["profiles"]}},"/api/v1/profiles/recipient/{email}":{"get":{"operationId":"ProfilesController_getRecipientProfile","parameters":[{"name":"email","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 프로필 조회 (발급기관용)","tags":["profiles"]},"patch":{"description":"발급기관이 자기 테넌트 내 수령자의 공개 프로필을 설정합니다.\n\n- `publicSlug`: 공개 페이지 슬러그 (영문/숫자/하이픈 3-30자, 전역 unique)\n- `publicEnabled`: 공개 여부 토글\n- `publicBio`: 자기소개 (최대 500자)\n- `publicLinks`: 외부 링크 배열 (최대 10개)","operationId":"ProfilesController_updateProfile","parameters":[{"name":"email","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProfileDto"}}}},"responses":{"200":{"description":""}},"security":[{"api-key":[]}],"summary":"수령자 공개 프로필 설정","tags":["profiles"]}},"/api/v1/og/assertion/{id}":{"get":{"description":"SNS 공유용 1200×630 PNG 이미지. 1시간 캐시.","operationId":"OgController_assertionOg","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"배지 발행건 OG 이미지 (PNG)","tags":["og"]}},"/api/v1/og/preview":{"post":{"description":"저장하지 않은 임시 입력값으로 1200×630 PNG 를 즉시 생성합니다. 디자인 선택·미리보기용. 발급 후 OG 와 동일 layout. 월간 발급 한도(quota) 에 카운트되지 않습니다 (preview only). Rate limit: 테넌트당 60초/100회 (ThrottlerModule 기본).","operationId":"OgController_previewOg","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OgPreviewDto"}}}},"responses":{"200":{"description":"1200×630 PNG (Content-Type: image/png)"},"400":{"description":"입력 검증 실패"},"401":{"description":"X-API-Key 누락 또는 무효"}},"security":[{"api-key":[]}],"summary":"배지 클래스 미리보기 OG 이미지 (PNG, 발행 전)","tags":["og"]}},"/api/v1/og/issuer/{slug}":{"get":{"description":"SNS 공유용 1200×630 PNG 이미지. 1시간 캐시.","operationId":"OgController_issuerOg","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"발급기관 공개 페이지 OG 이미지 (PNG)","tags":["og"]}},"/api/v1/og/profile/{slug}":{"get":{"description":"SNS 공유용 1200×630 PNG 이미지. 1시간 캐시.","operationId":"OgController_profileOg","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"공개 프로필 OG 이미지 (PNG)","tags":["og"]}},"/api/v1/share/assertion/{id}":{"get":{"operationId":"ShareController_assertionShare","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"배지 발행건 OG/공유 HTML (SNS 봇용)","tags":["share"]}},"/api/v1/share/issuer/{slug}":{"get":{"operationId":"ShareController_issuerShare","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"발급기관 공개 페이지 OG/공유 HTML (SNS 봇용)","tags":["share"]}},"/api/v1/share/profile/{slug}":{"get":{"operationId":"ShareController_profileShare","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"공개 프로필 OG/공유 HTML (SNS 봇용)","tags":["share"]}},"/api/v1/public/issuer/{slug}":{"get":{"description":"`publicEnabled=true` 로 설정된 발급기관(테넌트)의 공개 메타와 발급 통계, 활성 배지 클래스 목록을 반환합니다.","operationId":"IssuerPublicController_getIssuer","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"발급기관 공개 데이터"},"404":{"description":"존재하지 않거나 비공개"}},"summary":"발급기관 공개 프로필 조회","tags":["public"]}},"/api/v1/skills":{"get":{"operationId":"SkillsController_search","parameters":[{"name":"q","required":true,"in":"query","schema":{"type":"string"}},{"name":"category","required":true,"in":"query","schema":{"type":"string"}},{"name":"limit","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"스킬 검색 / 자동완성 (Public)","tags":["skills"]},"post":{"operationId":"SkillsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSkillDto"}}}},"responses":{"201":{"description":""}},"security":[{"api-key":[]}],"summary":"새 스킬 태그 생성 / 업서트 (어드민 또는 발행기관)","tags":["skills"]}},"/api/v1/skills/categories":{"get":{"operationId":"SkillsController_categories","parameters":[],"responses":{"200":{"description":""}},"summary":"사용 가능한 카테고리 목록 (Public)","tags":["skills"]}},"/api/v1/skills/recalculate":{"post":{"operationId":"SkillsController_recalculate","parameters":[],"responses":{"201":{"description":""}},"summary":"SkillTag.badgeCount 재계산 (어드민 전용, cron 권장)","tags":["skills"]}},"/api/v1/system/health":{"get":{"operationId":"SystemController_health","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"시스템 헬스 체크 (DB/Redis/Vault/Chain)","tags":["system"]}},"/api/v1/system/queues":{"get":{"operationId":"SystemController_queues","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"큐 통계 (waiting/active/completed/failed/delayed)","tags":["system"]}},"/api/v1/system/build":{"get":{"operationId":"SystemController_build","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"빌드 정보 (commit/env/uptime 등)","tags":["system"]}},"/api/v1/system/log":{"get":{"operationId":"SystemController_log","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"level","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"최근 로그 (메모리 버퍼)","tags":["system"]}},"/api/v1/system/log/stream":{"get":{"operationId":"SystemController_stream","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"로그 SSE 스트림","tags":["system"]}},"/api/v1/system/queues/{queue}/retry-failed":{"post":{"operationId":"SystemController_retryFailed","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}},{"name":"queue","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"큐의 실패 작업 일괄 재시도","tags":["system"]}},"/api/v1/system/cache/clear":{"post":{"operationId":"SystemController_clearCache","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"캐시 키 클리어 (analytics/cache prefix만)","tags":["system"]}},"/api/v1/system/stats/recompute":{"post":{"operationId":"SystemController_recompute","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"PlatformUsage 재계산","tags":["system"]}},"/api/v1/system/broadcast":{"post":{"operationId":"SystemController_broadcast","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"모든 KYB 승인 테넌트에 공지 이메일","tags":["system"]}},"/api/v1/system/skills/reseed":{"post":{"operationId":"SystemController_reseed","parameters":[{"name":"x-admin-key","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"기본 스킬 태그 리시드 (upsert)","tags":["system"]}},"/api/v1/uploads/image":{"post":{"description":"multipart/form-data 로 이미지 1개 업로드. Object Storage(public-read)에 저장 후 공개 URL 반환. PNG/JPEG/WebP/GIF/SVG, 8MB 이하.","operationId":"UploadsController_uploadImage","parameters":[],"responses":{"201":{"description":"{ url } 공개 이미지 URL"}},"security":[{"api-key":[]}],"summary":"이미지 업로드 (배경/로고/엠블럼 등)","tags":["uploads"]}},"/api/v1/renewals/direct":{"post":{"operationId":"RenewalsController_direct","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectRenewDto"}}}},"responses":{"201":{"description":"갱신 결과"}},"security":[{"api-key":[]}],"summary":"어드민 직접 갱신 (유효기간 연장 + 재서명)","tags":["renewals"]}},"/api/v1/renewals":{"get":{"operationId":"RenewalsController_list","parameters":[{"name":"status","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"갱신 요청 목록"}},"security":[{"api-key":[]}],"summary":"갱신 요청 큐 조회 (status 필터)","tags":["renewals"]}},"/api/v1/renewals/{id}":{"patch":{"operationId":"RenewalsController_decide","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecideRenewalDto"}}}},"responses":{"200":{"description":"처리 결과"}},"security":[{"api-key":[]}],"summary":"갱신 요청 승인/반려","tags":["renewals"]}},"/api/v1/public/renewal-request":{"post":{"operationId":"RenewalPublicController_request","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewalRequestDto"}}}},"responses":{"201":{"description":"{ ok: true }"}},"summary":"갱신 신청 (공개)","tags":["renewals"]}},"/api/v1/tags/scan":{"get":{"operationId":"TagsController_scan","parameters":[{"name":"k","required":true,"in":"query","schema":{"type":"string"}},{"name":"picc","required":true,"in":"query","schema":{"type":"string"}},{"name":"cmac","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"verify 페이지로 리다이렉트"}},"summary":"NFC 태그 스캔 검증 → verify 리다이렉트","tags":["tags"]}},"/api/v1/tags/attest":{"get":{"operationId":"TagsController_attest","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"검증 결과 (verified 및 태그 속성)"}},"summary":"정품 인증 토큰 재확인","tags":["tags"]}},"/api/v1/tags/activate":{"post":{"operationId":"TagsController_activate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateTagDto"}}}},"responses":{"201":{"description":"{ ok, status(activated|already), assertionId }"}},"summary":"구매 활성화 (즉시 발행 — 레거시/관리자용)","tags":["tags"]}},"/api/v1/tags/activate/request":{"post":{"operationId":"TagsController_activateRequest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateTagDto"}}}},"responses":{"201":{"description":"{ ok, status(email_sent|already), email(마스킹) }"}},"summary":"구매 활성화 요청 (확인 메일 발송)","tags":["tags"]}},"/api/v1/tags/activate/confirm":{"get":{"operationId":"TagsController_activateConfirm","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"verify 페이지로 리다이렉트"}},"summary":"구매 활성화 확인 (메일 링크)","tags":["tags"]}},"/api/v1/tags/transfer/request":{"post":{"operationId":"TagsController_transferRequest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateTagDto"}}}},"responses":{"201":{"description":"{ ok, status(requested), seller(마스킹) }"}},"summary":"실물 소유권 이전 요청 (판매자 승인 메일)","tags":["tags"]}},"/api/v1/tags/transfer/confirm":{"get":{"operationId":"TagsController_transferConfirm","parameters":[{"name":"token","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"302":{"description":"verify 페이지로 리다이렉트"}},"summary":"실물 소유권 이전 승인 (메일 링크)","tags":["tags"]}},"/api/v1/tags/badge-dpp":{"post":{"operationId":"TagsAdminController_setDpp","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetBadgeDppDto"}}}},"responses":{"201":{"description":"갱신된 DPP 설정"}},"security":[{"api-key":[]}],"summary":"배지 클래스 DPP 실물 설정 (dppLevel/gtin/editionTotal/tagKeyRef)","tags":["tags"]}},"/api/v1/tags/provision":{"post":{"operationId":"TagsAdminController_provision","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvisionTagDto"}}}},"responses":{"201":{"description":"등록된 태그 + 스캔 URL 템플릿"}},"security":[{"api-key":[]}],"summary":"실물 NFC 태그 등록 (uid ↔ 배지클래스/발행)","tags":["tags"]}},"/api/v1/tags":{"get":{"operationId":"TagsAdminController_list","parameters":[],"responses":{"200":{"description":"태그 목록 (스캔 통계 포함)"}},"security":[{"api-key":[]}],"summary":"발급기관 실물 태그 목록","tags":["tags"]}},"/api/v1/tags/perso-keys":{"post":{"operationId":"TagsAdminController_persoKeys","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersoKeysDto"}}}},"responses":{"201":{"description":"{ keyRef, zero, metaKey, fileKey }"}},"security":[{"api-key":[]}],"summary":"개인화 분산키 제공 (ChangeKey용, 마스터 미노출)","tags":["tags"]}}},"info":{"title":"TrustBadge API","description":"OB 3.0 디지털 자격증서 발행 플랫폼 API","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"api-key":{"type":"apiKey","in":"header","name":"X-API-Key"},"admin-key":{"type":"apiKey","in":"header","name":"X-Admin-Key"},"platform-key":{"type":"apiKey","in":"header","name":"X-Platform-Key"}},"schemas":{"CreatePlatformDto":{"type":"object","properties":{}},"CreateSubTenantDto":{"type":"object","properties":{}},"LoginDto":{"type":"object","properties":{}},"RegisterDto":{"type":"object","properties":{}},"ActivateDto":{"type":"object","properties":{}},"RecoverKeyDto":{"type":"object","properties":{}},"SubmitKybDto":{"type":"object","properties":{}},"UpdatePublicProfileDto":{"type":"object","properties":{}},"ReviewKybDto":{"type":"object","properties":{}},"AiAssistDto":{"type":"object","properties":{}},"AiLayoutDto":{"type":"object","properties":{}},"TranslateContentDto":{"type":"object","properties":{}},"TranslateBadgeDto":{"type":"object","properties":{}},"CreateBadgeClassDto":{"type":"object","properties":{}},"UpdateBadgeClassDto":{"type":"object","properties":{}},"CreateWebhookBodyDto":{"type":"object","properties":{}},"UpdateWebhookBodyDto":{"type":"object","properties":{}},"ToggleWebhookBodyDto":{"type":"object","properties":{}},"IssueAssertionDto":{"type":"object","properties":{}},"BatchIssueDto":{"type":"object","properties":{}},"CsvIssueDto":{"type":"object","properties":{}},"RevokeAssertionDto":{"type":"object","properties":{}},"ClaimDto":{"type":"object","properties":{}},"WalletTransferDto":{"type":"object","properties":{}},"CreateRecipientDto":{"type":"object","properties":{}},"CreatePathwayDto":{"type":"object","properties":{}},"CreateCampaignDto":{"type":"object","properties":{}},"UpdateProfileDto":{"type":"object","properties":{}},"OgPreviewDto":{"type":"object","properties":{}},"CreateSkillDto":{"type":"object","properties":{}},"DirectRenewDto":{"type":"object","properties":{}},"DecideRenewalDto":{"type":"object","properties":{}},"RenewalRequestDto":{"type":"object","properties":{}},"ActivateTagDto":{"type":"object","properties":{}},"SetBadgeDppDto":{"type":"object","properties":{}},"ProvisionTagDto":{"type":"object","properties":{}},"PersoKeysDto":{"type":"object","properties":{}}}}}