openapi: 3.0.3
info:
  title: 保险合同服务API
  version: 1.0.0
paths:
  /insurance/policies:
    post:
      tags: [保险]
      operationId: CreatePolicy
      summary: 创建保单（预出单）
      security:
        - tenantAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyCreateRequest"
      responses:
        "201":
          description: 保单创建成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PolicyCreateResponse"
                
        "400":
          $ref: "#/components/responses/BadRequest"

    get:
      tags: [保险]
      operationId: ListPolicies
      summary: 获取保单列表
      security:
        - tenantAuth: []
      parameters:
        - $ref: "#/components/parameters/page"
        - $ref: "#/components/parameters/pageSize"
        - $ref: "#/components/parameters/userInfo"
        - name: tenantId
          in: query
          schema:
            type: string
          description: 租户ID
        - name: orderNo
          in: query
          schema:
            type: string
          description: 外部订单号
        - name: policyNo
          in: query
          schema:
            type: string
          description: 保险公司保单号
        - name: status
          in: query
          schema:
            $ref: "#/components/schemas/policyStatus"
          description: 保单状态
        - name: channel
          in: query
          schema:
            $ref: "#/components/schemas/InsuranceChannel"
          description: 保险渠道
      responses:
        "200":
          description: 获取保单列表成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ListPoliciesResponseWrap"
        "400":
          $ref: "#/components/responses/BadRequest"

  /insurance/policies/{id}:
    get:
      tags: [保险]
      operationId: GetPolicy
      summary: 获取保单详情
      security:
        - tenantAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: 保单内部ID
      responses:
        "200":
          description: 获取保单成功
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/BaseResponse"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/Policy"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /insurance/policies/{id}/insure:
    post:
      tags: [保险]
      operationId: ConfirmInsure
      summary: 确认投保
      description: 在预出单后，确认进行实际投保操作，将与保险公司进行异步交互
      security:
        - tenantAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: 保单内部ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyInsureRequest"
      responses:
        "200":
          description: 投保请求已接受，进入异步处理
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/BaseResponse"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/Policy"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          description: 保单状态不允许执行投保操作
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /insurance/policies/{id}/status:
    patch:
      tags: [保险]
      operationId: UpdatePolicyStatus
      summary: 更新保单状态
      security:
        - tenantAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
          description: 保单内部ID
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PolicyStatusUpdateRequest"
      responses:
        "200":
          description: 状态更新成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BaseResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /insurance/claims:
    post:
      tags: [理赔]
      operationId: CreateClaim
      summary: 创建理赔申请
      security:
        - tenantAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClaimCreateRequest"
      responses:
        "201":
          description: 理赔申请创建成功
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/BaseResponse"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/ClaimCreateResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"

    get:
      tags: [理赔]
      operationId: ListClaims
      summary: 获取理赔申请列表
      security:
        - tenantAuth: []
      parameters:
        - $ref: "#/components/parameters/page"
        - $ref: "#/components/parameters/pageSize"
        - $ref: "#/components/parameters/userInfo"
        - name: policyId
          in: query
          schema:
            type: string
          description: 保单内部ID
        - name: policyNo
          in: query
          schema:
            type: string
          description: 保险公司保单号
        - name: claimNo
          in: query
          schema:
            type: string
          description: 保险公司理赔单号
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, processing, approved, rejected, completed]
          description: 理赔状态
      responses:
        "200":
          description: 获取理赔列表成功
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/BaseResponse"
                  - type: object
                    properties:
                      data:
                        type: object
                        properties:
                          total:
                            type: integer
                            description: 总记录数
                          items:
                            type: array
                            items:
                              $ref: "#/components/schemas/ClaimSummary"
        "400":
          $ref: "#/components/responses/BadRequest"

  /insurance/claims/{id}:
    get:
      tags: [理赔]
      operationId: GetClaim
      summary: 获取理赔申请详情
      security:
        - tenantAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: 理赔单内部ID
        - $ref: "#/components/parameters/userInfo"
      responses:
        "200":
          description: 获取理赔详情成功
          content:
            application/json:
              schema:
                allOf:
                  - $ref: "#/components/schemas/BaseResponse"
                  - type: object
                    properties:
                      data:
                        $ref: "#/components/schemas/ClaimDetail"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /insurance/webhooks/callback/zy:
    post:
      tags: [回调]
      operationId: InsuranceCallbackZy
      summary: 中元保险回调接口
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InsuranceCallbackZyRequest"
      responses:
        "200":
          description: 回调处理成功
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BaseResponse"
        "400":
          $ref: "#/components/responses/BadRequest"

components:
  schemas:
    BaseResponse:
      type: object
      properties:
        code:
          type: integer
          enum: [0]
          description: 响应代码（0表示成功）
        message:
          type: string
          description: 响应消息
        data:
          type: object
          description: 响应数据
      required: [code]

    # 保险渠道
    InsuranceChannel:
      type: string
      enum: [zy]
      description: 保险渠道

    PolicyCreateRequest:
      type: object
      properties:
        channel:
          $ref: "#/components/schemas/InsuranceChannel"
        tenantId:
          type: string
          description: 租户ID
        userInfo:
          $ref: "#/components/schemas/UserInfo"
        insurants:
          type: array
          description: 被保险人列表
          items:
            $ref: "#/components/schemas/Insurant"
        startTime:
          type: string
          format: date-time
          description: 起保时间
        orderNo:
          type: string
          description: 外部订单号
      required:
        - tenantId
        - userIdentifier
        - userType
        - insurants
        - startTime
        - orderNo

    PolicyCreateResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/Policy"

    Insurant:
      type: object
      allOf:
        - $ref: "#/components/schemas/UserInfo"
        - type: object
          properties:
            name:
              type: string
              description: 姓名
            cardNo:
              type: string
              description: 证件号码
            mobile:
              type: string
              description: 手机号
      required:
        - userIdentifier
        - userType
        - name
        - cardNo
        - mobile

    PolicyInsureRequest:
      type: object
      properties:
        effectiveTime:
          type: string
          format: date-time
          description: 实际生效时间（可选，默认使用创建时的startTime）
        additionalInfo:
          type: object
          description: 额外的投保信息（视具体保险公司要求）

    ListPoliciesResponseWrap:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
        - type: object
          properties:
            data:
              $ref: "#/components/schemas/ListPoliciesResponseData"
              
    ListPoliciesResponseData:
      type: object
      properties:
        total:
          type: integer
          description: 总记录数
        items:
          type: array
          items:
            $ref: "#/components/schemas/Policy"
    # PolicyInsureResponse:
    #   type: object
    #   properties:
    #     id:
    #       type: string
    #       description: 保单内部ID
    #     tenantId:
    #       type: string
    #       description: 租户ID
    #     userIdentifier:
    #       type: string
    #       description: 用户标识（业务系统中的用户ID）
    #     orderNo:
    #       type: string
    #       description: 外部订单号
    #     status:
    #       $ref: "#/components/schemas/policyStatus"
    #     payUrl:
    #       type: string
    #       description: 支付链接（如果需要支付）
    #     updateTime:
    #       type: string
    #       format: date-time
    #       description: 更新时间

    # PolicySummary:
    #   type: object
    #   properties:
    #     id:
    #       type: string
    #       description: 保单内部ID
    #     tenantId:
    #       type: string
    #       description: 租户ID
    #     userIdentifier:
    #       type: string
    #       description: 用户标识（业务系统中的用户ID）
    #     orderNo:
    #       type: string
    #       description: 外部订单号
    #     policyNo:
    #       type: string
    #       description: 保险公司保单号（成功投保后才有）
    #     insuredName:
    #       type: string
    #       description: 被保险人姓名
    #     startTime:
    #       type: string
    #       format: date-time
    #       description: 起保时间
    #     endTime:
    #       type: string
    #       format: date-time
    #       description: 终保时间
    #     status:
    #       $ref: "#/components/schemas/policyStatus"
    #     createTime:
    #       type: string
    #       format: date-time
    #       description: 创建时间

    Policy:
      type: object
      properties:
        id:
          type: integer
          description: 保单内部ID
        tenantId:
          type: string
          description: 租户ID
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        orderNo:
          type: string
          description: 外部订单号
        policyNo:
          type: string
          description: 保险公司保单号（成功投保后才有）
        proposalNo:
          type: string
          description: 投保单号
        insurants:
          type: array
          description: 被保险人列表
          items:
            $ref: "#/components/schemas/Insurant"
        startTime:
          type: string
          format: date-time
          description: 起保时间
        endTime:
          type: string
          format: date-time
          description: 终保时间
        status:
          $ref: "#/components/schemas/policyStatus"
        documentUrl:
          type: string
          description: 电子保单文档地址（投保成功后才有）

    PolicyStatusUpdateRequest:
      type: object
      properties:
        # 保单状态，但只支持：cancelled
        status:
          $ref: "#/components/schemas/policyStatus"
        reason:
          type: string
          description: 状态变更原因
      required:
        - status

    ClaimCreateRequest:
      type: object
      properties:
        tenantId:
          type: string
          description: 租户ID
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        userType:
          type: string
          enum: [customer, operator, admin]
          description: 用户类型，用于区分客户、操作员和管理员
        policyId:
          type: string
          description: 保单内部ID
        description:
          type: string
          description: 理赔描述
        eventTime:
          type: string
          format: date-time
          description: 事故发生时间
        attachments:
          type: array
          description: 附件列表
          items:
            $ref: "#/components/schemas/Attachment"
      required:
        - tenantId
        - userIdentifier
        - userType
        - policyId
        - description
        - eventTime

    Attachment:
      type: object
      properties:
        fileId:
          type: string
          description: 文件ID
        fileName:
          type: string
          description: 文件名称
        fileType:
          type: string
          description: 文件类型
        fileUrl:
          type: string
          description: 文件URL
      required:
        - fileId
        - fileName
        - fileType
        - fileUrl

    ClaimCreateResponse:
      type: object
      properties:
        id:
          type: string
          description: 理赔单内部ID
        tenantId:
          type: string
          description: 租户ID
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        policyId:
          type: string
          description: 保单内部ID
        policyNo:
          type: string
          description: 保险公司保单号
        status:
          type: string
          description: 理赔状态
          enum: [pending]
        createTime:
          type: string
          format: date-time
          description: 创建时间

    ClaimSummary:
      type: object
      properties:
        id:
          type: string
          description: 理赔单内部ID
        tenantId:
          type: string
          description: 租户ID
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        policyId:
          type: string
          description: 保单内部ID
        policyNo:
          type: string
          description: 保险公司保单号
        claimNo:
          type: string
          description: 保险公司理赔单号（处理中或完成后才有）
        insuredName:
          type: string
          description: 被保险人姓名
        eventTime:
          type: string
          description: 事故发生时间
        status:
          type: string
          description: 理赔状态
          enum: [pending, processing, approved, rejected, completed]
        createTime:
          type: string
          format: date-time
          description: 创建时间

    ClaimDetail:
      type: object
      properties:
        id:
          type: string
          description: 理赔单内部ID
        tenantId:
          type: string
          description: 租户ID
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        policyId:
          type: string
          description: 保单内部ID
        policyNo:
          type: string
          description: 保险公司保单号
        claimNo:
          type: string
          description: 保险公司理赔单号（处理中或完成后才有）
        description:
          type: string
          description: 理赔描述
        eventTime:
          type: string
          description: 事故发生时间
        attachments:
          type: array
          description: 附件列表
          items:
            $ref: "#/components/schemas/Attachment"
        status:
          type: string
          description: 理赔状态
          enum: [pending, processing, approved, rejected, completed]
        amount:
          type: number
          format: double
          description: 理赔金额
        remark:
          type: string
          description: 备注
        createTime:
          type: string
          format: date-time
          description: 创建时间
        updateTime:
          type: string
          format: date-time
          description: 更新时间

    InsuranceCallbackZyRequest:
      type: object
      properties:
        head:
          $ref: "#/components/schemas/CallbackHeadZy"
        body:
          $ref: "#/components/schemas/CallbackBodyZy"

    CallbackHeadZy:
      type: object
      properties:
        transactionNo:
          type: string
          description: 交易流水号
        operator:
          type: string
          description: 操作员
        aiBaoTransactionNo:
          type: string
          description: 保险交易流水号
        timeStamp:
          type: string
          description: 时间戳
        errorCode:
          type: string
          description: 错误编码
        errorMsg:
          type: string
          description: 错误描述

    CallbackBodyZy:
      type: object
      properties:
        tenantId:
          type: string
          description: 租户ID
        policyInfo:
          type: array
          items:
            $ref: "#/components/schemas/CallbackPolicyInfo"

    CallbackPolicyInfo:
      type: object
      properties:
        localOrderNo:
          type: string
          description: 内部订单号
        policyNo:
          type: string
          description: 保单号
        policyDownUrl:
          type: string
          description: 电子保单地址
        orderNo:
          type: string
          description: 渠道订单号
        insurerKey:
          type: string
          description: 被保人唯一ID
        proposalNo:
          type: string
          description: 投保单号
        proposalTime:
          type: string
          description: 投保单生成时间
        policyTime:
          type: string
          description: 保单生成时间
        payType:
          type: string
          description: 支付方式

    policyStatus:
      type: string
      description: 保单状态
      enum: [pre_insuring, insuring, insured, insure_failed, cancelled, claimed]

    ErrorResponse:
      allOf:
        - $ref: "#/components/schemas/BaseResponse"
     
    UserInfo:
      type: object
      properties:
        userIdentifier:
          type: string
          description: 用户标识（业务系统中的用户ID）
        userType:
          type: string
          enum: [customer, operator, admin]
          description: 用户类型，用于区分客户、操作员和管理员

  securitySchemes:
    tenantAuth:
      type: apiKey
      in: header
      name: X-Tenant-Token
      description: 租户鉴权令牌，用于识别和授权不同的业务系统

  parameters:
    page:
      name: page
      in: query
      schema:
        type: integer
        default: 1
      description: 页码
    pageSize:
      name: pageSize
      in: query
      schema:
        type: integer
        default: 20
      description: 每页数量
    
    # 用户基础信息
    userInfo:
      name: userInfo
      in: query
      schema:
        $ref: "#/components/schemas/UserInfo"
      description: 用户信息

    # userIdentifier:
    #   name: userIdentifier
    #   in: query
    #   schema:
    #     type: string
    #     description: 用户标识（业务系统中的用户ID）
    # userType:
    #   name: userType
    #   in: query
    #   schema:
    #     type: string
    #     enum: [customer, operator, admin]
    #     description: 用户类型，用于区分客户、操作员和管理员

      
  # WARNING: ErrorResponse is no longer defined here!
  responses:
    BadRequest:
      description: 非法请求参数
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    NotFound:
      description: 资源未找到
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    ServerError:
      description: 服务器内部错误
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
    Unauthorized:
      description: 未授权
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ErrorResponse"
