swagger: "2.0"
info:
  title: HY Activity Service API
  version: "1.0.0"
  description: |
    activity-service 当前只暴露内部 gRPC + protobuf 同步查询接口，没有 HTTP JSON router。
    房间事件消费通过 consumer 边界接入，不伪装成同步 RPC。
    本文件用 OpenAPI 2.0 记录 gRPC 合约，`paths` 使用 gRPC full method 作为文档路径，不代表真实 HTTP endpoint。
host: localhost:13006
basePath: /
schemes:
  - http
consumes:
  - application/grpc+proto
produces:
  - application/grpc+proto
tags:
  - name: activity
    description: ActivityService，活动服务同步查询接口。
  - name: messages
    description: MessageInboxService，App system/activity 个人 inbox 内部接口。
  - name: health
    description: 标准 grpc.health.v1.Health。
responses:
  GRPCError:
    description: gRPC status error；稳定业务原因放在 google.rpc.ErrorInfo.reason。
    schema:
      $ref: "#/definitions/GRPCError"
paths:
  /hyapp.activity.v1.ActivityService/PingActivity:
    post:
      tags:
        - activity
      summary: 活动服务连通性探测
      operationId: activityPingActivity
      x-grpc-full-method: /hyapp.activity.v1.ActivityService/PingActivity
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/PingActivityRequest"
      responses:
        "200":
          description: 服务当前可接受同步 RPC。
          schema:
            $ref: "#/definitions/PingActivityResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.ActivityService/GetActivityStatus:
    post:
      tags:
        - activity
      summary: 查询活动状态
      operationId: activityGetActivityStatus
      x-grpc-full-method: /hyapp.activity.v1.ActivityService/GetActivityStatus
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/GetActivityStatusRequest"
      responses:
        "200":
          description: 查询成功。
          schema:
            $ref: "#/definitions/GetActivityStatusResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/ListMessageTabs:
    post:
      tags:
        - messages
      summary: 查询 App 消息 tab 摘要
      operationId: activityListMessageTabs
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/ListMessageTabs
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ListMessageTabsRequest"
      responses:
        "200":
          description: 固定返回 user/system/activity 三个分区。
          schema:
            $ref: "#/definitions/ListMessageTabsResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/ListInboxMessages:
    post:
      tags:
        - messages
      summary: 分页查询 system/activity inbox
      operationId: activityListInboxMessages
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/ListInboxMessages
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/ListInboxMessagesRequest"
      responses:
        "200":
          description: 返回当前页消息和下一页游标。
          schema:
            $ref: "#/definitions/ListInboxMessagesResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/MarkInboxMessageRead:
    post:
      tags:
        - messages
      summary: 标记单条 inbox 消息已读
      operationId: activityMarkInboxMessageRead
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/MarkInboxMessageRead
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MarkInboxMessageReadRequest"
      responses:
        "200":
          description: 重复标记成功且不覆盖首次 read_at_ms。
          schema:
            $ref: "#/definitions/MarkInboxMessageReadResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/MarkInboxSectionRead:
    post:
      tags:
        - messages
      summary: 标记一个消息分区全部已读
      operationId: activityMarkInboxSectionRead
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/MarkInboxSectionRead
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/MarkInboxSectionReadRequest"
      responses:
        "200":
          description: 返回本次实际更新的消息数。
          schema:
            $ref: "#/definitions/MarkInboxSectionReadResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/DeleteInboxMessage:
    post:
      tags:
        - messages
      summary: 删除当前用户可见 inbox 消息
      operationId: activityDeleteInboxMessage
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/DeleteInboxMessage
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/DeleteInboxMessageRequest"
      responses:
        "200":
          description: 删除是用户侧隐藏，不物理删除事实行。
          schema:
            $ref: "#/definitions/DeleteInboxMessageResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/CreateInboxMessage:
    post:
      tags:
        - messages
      summary: 生产者创建单用户 inbox 消息
      operationId: activityCreateInboxMessage
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/CreateInboxMessage
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/CreateInboxMessageRequest"
      responses:
        "200":
          description: 同 producer_event_id 重试返回原 message_id。
          schema:
            $ref: "#/definitions/CreateInboxMessageResponse"
        default:
          $ref: "#/responses/GRPCError"
  /hyapp.activity.v1.MessageInboxService/CreateFanoutJob:
    post:
      tags:
        - messages
      summary: 创建后台 fanout 任务
      operationId: activityCreateFanoutJob
      x-grpc-full-method: /hyapp.activity.v1.MessageInboxService/CreateFanoutJob
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/CreateFanoutJobRequest"
      responses:
        "200":
          description: 同 command_id 重试返回原 job_id。
          schema:
            $ref: "#/definitions/CreateFanoutJobResponse"
        default:
          $ref: "#/responses/GRPCError"
  /grpc.health.v1.Health/Check:
    post:
      tags:
        - health
      summary: 标准 gRPC health check
      operationId: activityHealthCheck
      x-grpc-full-method: /grpc.health.v1.Health/Check
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/HealthCheckRequest"
      responses:
        "200":
          description: 标准 health check 响应。
          schema:
            $ref: "#/definitions/HealthCheckResponse"
        default:
          $ref: "#/responses/GRPCError"
  /grpc.health.v1.Health/Watch:
    post:
      tags:
        - health
      summary: 标准 gRPC health watch
      operationId: activityHealthWatch
      x-grpc-full-method: /grpc.health.v1.Health/Watch
      parameters:
        - name: body
          in: body
          required: true
          schema:
            $ref: "#/definitions/HealthCheckRequest"
      responses:
        "200":
          description: 标准 health watch 流式响应；OpenAPI 只记录单条消息结构。
          schema:
            $ref: "#/definitions/HealthCheckResponse"
        default:
          $ref: "#/responses/GRPCError"
definitions:
  RequestMeta:
    type: object
    properties:
      request_id:
        type: string
        description: 链路追踪 ID，不作为幂等键。
      caller:
        type: string
      gateway_node_id:
        type: string
      sent_at_ms:
        type: integer
        format: int64
      app_code:
        type: string
        description: 调用方解析出的 App 租户键，所有 inbox 事实必须按该字段隔离。
  PingActivityRequest:
    type: object
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
  PingActivityResponse:
    type: object
    properties:
      ok:
        type: boolean
      node_id:
        type: string
  GetActivityStatusRequest:
    type: object
    required:
      - activity_id
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      activity_id:
        type: string
  GetActivityStatusResponse:
    type: object
    properties:
      activity_id:
        type: string
      status:
        type: string
        description: 当前活动状态；具体业务活动会扩展自己的状态枚举。
  MessageTabSection:
    type: object
    properties:
      section:
        type: string
        enum:
          - user
          - system
          - activity
      title:
        type: string
      unread_count:
        type: integer
        format: int64
      source:
        type: string
        enum:
          - tencent_im_sdk
          - backend
  ListMessageTabsRequest:
    type: object
    required:
      - user_id
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      user_id:
        type: integer
        format: int64
  ListMessageTabsResponse:
    type: object
    properties:
      sections:
        type: array
        items:
          $ref: "#/definitions/MessageTabSection"
  InboxMessage:
    type: object
    properties:
      message_id:
        type: string
      section:
        type: string
        enum:
          - system
          - activity
      title:
        type: string
      summary:
        type: string
      body:
        type: string
      icon_url:
        type: string
      image_url:
        type: string
      action_type:
        type: string
      action_param:
        type: string
      read:
        type: boolean
      sent_at_ms:
        type: integer
        format: int64
  ListInboxMessagesRequest:
    type: object
    required:
      - user_id
      - section
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      user_id:
        type: integer
        format: int64
      section:
        type: string
        enum:
          - system
          - activity
      page_size:
        type: integer
        format: int32
      page_token:
        type: string
  ListInboxMessagesResponse:
    type: object
    properties:
      section:
        type: string
      items:
        type: array
        items:
          $ref: "#/definitions/InboxMessage"
      next_page_token:
        type: string
  MarkInboxMessageReadRequest:
    type: object
    required:
      - user_id
      - message_id
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      user_id:
        type: integer
        format: int64
      message_id:
        type: string
  MarkInboxMessageReadResponse:
    type: object
    properties:
      message_id:
        type: string
      read:
        type: boolean
      read_at_ms:
        type: integer
        format: int64
  MarkInboxSectionReadRequest:
    type: object
    required:
      - user_id
      - section
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      user_id:
        type: integer
        format: int64
      section:
        type: string
        enum:
          - system
          - activity
  MarkInboxSectionReadResponse:
    type: object
    properties:
      section:
        type: string
      read_count:
        type: integer
        format: int64
  DeleteInboxMessageRequest:
    type: object
    required:
      - user_id
      - message_id
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      user_id:
        type: integer
        format: int64
      message_id:
        type: string
  DeleteInboxMessageResponse:
    type: object
    properties:
      message_id:
        type: string
      deleted:
        type: boolean
  CreateInboxMessageRequest:
    type: object
    required:
      - target_user_id
      - producer
      - producer_event_id
      - message_type
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      target_user_id:
        type: integer
        format: int64
      producer:
        type: string
      producer_event_id:
        type: string
      producer_event_type:
        type: string
      message_type:
        type: string
        enum:
          - system
          - activity
      aggregate_type:
        type: string
      aggregate_id:
        type: string
      template_id:
        type: string
      template_version:
        type: string
      title:
        type: string
      summary:
        type: string
      body:
        type: string
      icon_url:
        type: string
      image_url:
        type: string
      action_type:
        type: string
      action_param:
        type: string
      priority:
        type: integer
        format: int32
      sent_at_ms:
        type: integer
        format: int64
      expire_at_ms:
        type: integer
        format: int64
      metadata_json:
        type: string
        description: 低敏业务快照 JSON 字符串。
  CreateInboxMessageResponse:
    type: object
    properties:
      message_id:
        type: string
      created:
        type: boolean
  CreateFanoutJobRequest:
    type: object
    required:
      - command_id
      - message_type
      - target_scope
      - target_filter_json
      - template_snapshot_json
      - created_by
    properties:
      meta:
        $ref: "#/definitions/RequestMeta"
      command_id:
        type: string
        description: 客户端或操作端前端按单次写动作生成的幂等命令 ID，同一动作重试必须复用。
      message_type:
        type: string
        enum:
          - system
          - activity
      target_scope:
        type: string
        enum:
          - single_user
          - user_ids
          - region
          - country
          - all_active_users
      target_filter_json:
        type: string
      template_snapshot_json:
        type: string
      batch_size:
        type: integer
        format: int32
      created_by:
        type: string
  CreateFanoutJobResponse:
    type: object
    properties:
      job_id:
        type: string
      status:
        type: string
      created:
        type: boolean
  HealthCheckRequest:
    type: object
    properties:
      service:
        type: string
        description: gRPC health service name；activity-service 使用 `activity-service`。
  HealthCheckResponse:
    type: object
    properties:
      status:
        type: string
        enum:
          - UNKNOWN
          - SERVING
          - NOT_SERVING
          - SERVICE_UNKNOWN
  GRPCError:
    type: object
    properties:
      code:
        type: string
        description: gRPC status code，例如 INVALID_ARGUMENT、NOT_FOUND、UNAVAILABLE。
      message:
        type: string
      error_info_reason:
        type: string
        description: google.rpc.ErrorInfo.reason；活动常见值包括 RULE_NOT_ACTIVE、EVENT_ALREADY_CONSUMED、REWARD_PENDING。
