{
  "openapi":"3.1.0",
  "info":{"title":"华谱 REST API","version":"1.0.0","description":"适合华人族谱资料交换的版本化 API。所有业务接口需要细粒度 Bearer 令牌，写入支持 Idempotency-Key。"},
  "servers":[{"url":"/"}],
  "security":[{"bearerAuth":[]}],
  "paths":{
    "/api/v1/clans":{"get":{"summary":"分页列出可访问族谱","x-required-scope":"CLAN_READ","parameters":[{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"族谱分页","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}}},
    "/api/v1/clans/{clanId}/persons":{"get":{"summary":"分页列出可见人物","x-required-scope":"PERSON_READ","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"人物分页","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Page"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"}}},"post":{"summary":"幂等创建人物","x-required-scope":"PERSON_WRITE","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePerson"}}}},"responses":{"201":{"description":"人物已创建","headers":{"Idempotency-Replayed":{"schema":{"type":"boolean"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Person"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"409":{"description":"幂等键请求体冲突"}}}},
    "/api/v1/clans/{clanId}/relations":{"get":{"summary":"分页列出亲子与伴侣关系","x-required-scope":"RELATION_READ","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"关系分页"}}}},
    "/api/v1/clans/{clanId}/sources":{"get":{"summary":"分页列出来源及可见引文","x-required-scope":"SOURCE_READ","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"来源分页"}}}},
    "/api/v1/clans/{clanId}/changes":{"get":{"summary":"分页列出对象版本变更","x-required-scope":"CHANGE_READ","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"变更分页"}}}},
    "/api/v1/clans/{clanId}/audit":{"get":{"summary":"分页列出族谱审计记录","description":"同时要求 ADMIN 账号。","x-required-scope":"AUDIT_READ","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/page"},{"$ref":"#/components/parameters/size"}],"responses":{"200":{"description":"审计分页"},"403":{"$ref":"#/components/responses/Forbidden"}}}},
    "/api/v1/clans/{clanId}/webhooks":{"get":{"summary":"列出 Webhook 订阅","x-required-scope":"WEBHOOK_MANAGE","parameters":[{"$ref":"#/components/parameters/clanId"}],"responses":{"200":{"description":"订阅列表"}}},"post":{"summary":"幂等创建 Webhook 订阅","description":"签名密钥仅在首次响应中返回。生产模式仅允许公共 HTTPS 地址。","x-required-scope":"WEBHOOK_MANAGE","parameters":[{"$ref":"#/components/parameters/clanId"},{"$ref":"#/components/parameters/idempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","endpointUrl","eventTypes"],"properties":{"name":{"type":"string"},"endpointUrl":{"type":"string","format":"uri"},"eventTypes":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"订阅及一次性签名密钥"}}}},
    "/api/v1/clans/{clanId}/webhooks/deliveries":{"get":{"summary":"列出最近 Webhook 投递","x-required-scope":"WEBHOOK_MANAGE","parameters":[{"$ref":"#/components/parameters/clanId"}],"responses":{"200":{"description":"投递记录"}}}}
  },
  "components":{
    "securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"HuapuToken"}},
    "parameters":{"clanId":{"name":"clanId","in":"path","required":true,"schema":{"type":"integer","format":"int64"}},"page":{"name":"page","in":"query","schema":{"type":"integer","minimum":0,"default":0}},"size":{"name":"size","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},"idempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":8,"maxLength":100}}},
    "schemas":{"Page":{"type":"object","required":["items","page","size","total","totalPages"],"properties":{"items":{"type":"array","items":{}},"page":{"type":"integer"},"size":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}},"Person":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"globalId":{"type":"string","format":"uuid"},"fullName":{"type":"string"},"gender":{"enum":["MALE","FEMALE","UNKNOWN"]},"generationNumber":{"type":["integer","null"]},"living":{"type":"boolean"},"birthDate":{"type":["string","null"]},"deathDate":{"type":["string","null"]}}},"CreatePerson":{"type":"object","required":["surname","givenName"],"properties":{"surname":{"type":"string"},"givenName":{"type":"string"},"gender":{"enum":["MALE","FEMALE","UNKNOWN"]},"generationNumber":{"type":["integer","null"]},"generationCharacter":{"type":["string","null"]},"rankInFamily":{"type":["integer","null"]},"living":{"type":"boolean","default":true},"privacyLevel":{"enum":["PRIVATE","CLAN","PUBLIC"]},"branchId":{"type":["integer","null"]},"occupation":{"type":["string","null"]},"biography":{"type":["string","null"]},"birthDate":{"$ref":"#/components/schemas/HistoricalDate"},"deathDate":{"$ref":"#/components/schemas/HistoricalDate"}}},"HistoricalDate":{"type":["object","null"],"properties":{"calendar":{"enum":["GREGORIAN","LUNAR","GANZHI"]},"precision":{"enum":["EXACT","YEAR","APPROXIMATE","RANGE"]},"originalText":{"type":["string","null"]},"normalizedStart":{"type":["string","null"],"format":"date"},"normalizedEnd":{"type":["string","null"],"format":"date"},"confirmed":{"type":"boolean"},"boundaryRule":{"enum":["LUNAR_NEW_YEAR","START_OF_SPRING","WINTER_SOLSTICE"]}}},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"}}}},
    "responses":{"Unauthorized":{"description":"令牌无效或过期","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"Forbidden":{"description":"令牌范围、族谱或账号权限不足","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"BadRequest":{"description":"请求参数错误","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}
  }
}
