openapi: 3.1.0
info:
  title: AI News Platform Public API
  version: 1.0.0
  summary: AI News Platform 匿名只读公开 API
  description: |
    提供已处理 AI 资讯、网页信息流和每日日报。匿名访问，无需 token。
servers:
  - url: https://news.ajaiclub.com
    description: Current server
paths:
  /api/public/items:
    get:
      summary: 获取公开资讯
      parameters:
        - $ref: '#/components/parameters/Mode'
        - $ref: '#/components/parameters/Category'
        - name: since
          in: query
          schema:
            type: string
            format: date-time
        - $ref: '#/components/parameters/Take'
        - name: cursor
          in: query
          schema:
            type: string
        - name: q
          in: query
          schema:
            type: string
            maxLength: 120
          description: 标题与摘要搜索；少于 2 个字符时不应用搜索。
      responses:
        '200':
          description: 资讯列表
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicItemsResponse'
        '400':
          $ref: '#/components/responses/InvalidQuery'
  /api/public/feed:
    get:
      summary: 获取网页信息流
      parameters:
        - $ref: '#/components/parameters/Mode'
        - name: channel
          in: query
          schema:
            type: string
            enum: [all, firstParty, news, x]
            default: all
        - $ref: '#/components/parameters/Category'
        - name: q
          in: query
          schema:
            type: string
            maxLength: 120
        - name: tag
          in: query
          schema:
            type: string
            maxLength: 80
        - name: cursorAt
          in: query
          schema:
            type: string
            format: date-time
        - name: cursorId
          in: query
          schema:
            type: string
        - $ref: '#/components/parameters/Take'
      responses:
        '200':
          description: 网页信息流
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '400':
          $ref: '#/components/responses/InvalidQuery'
  /api/public/daily:
    get:
      summary: 获取最新日报
      responses:
        '200':
          description: 最新日报或 null
          content:
            application/json:
              schema:
                type: object
                properties:
                  report:
                    oneOf:
                      - $ref: '#/components/schemas/DailyReport'
                      - type: 'null'
  /api/public/daily/{date}:
    get:
      summary: 获取指定日期日报
      parameters:
        - name: date
          in: path
          required: true
          schema:
            type: string
            format: date
      responses:
        '200':
          description: 指定日期日报
          content:
            application/json:
              schema:
                type: object
                properties:
                  report:
                    $ref: '#/components/schemas/DailyReport'
        '400':
          $ref: '#/components/responses/InvalidQuery'
        '404':
          description: 日报不存在
  /api/public/dailies:
    get:
      summary: 获取日报归档
      parameters:
        - $ref: '#/components/parameters/Take'
      responses:
        '200':
          description: 日报列表
          content:
            application/json:
              schema:
                type: object
                required: [count, reports]
                properties:
                  count:
                    type: integer
                  reports:
                    type: array
                    items:
                      $ref: '#/components/schemas/DailyReport'
        '400':
          $ref: '#/components/responses/InvalidQuery'
components:
  parameters:
    Mode:
      name: mode
      in: query
      schema:
        type: string
        enum: [selected, all]
        default: selected
    Category:
      name: category
      in: query
      schema:
        type: string
        enum: [ai-models, ai-products, industry, paper, tip]
    Take:
      name: take
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
  responses:
    InvalidQuery:
      description: 查询参数无效
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      required: [error, message]
      properties:
        error:
          type: string
        message:
          type: string
    PublicItem:
      type: object
      required: [id, title, url, source, selected]
      properties:
        id:
          type: string
        title:
          type: string
        title_en:
          type: [string, 'null']
        url:
          type: string
          format: uri
        source:
          type: string
        publishedAt:
          type: [string, 'null']
          format: date-time
        summary:
          type: [string, 'null']
        category:
          type: [string, 'null']
          enum: [ai-models, ai-products, industry, paper, tip, null]
        score:
          type: [integer, 'null']
        selected:
          type: boolean
    PublicItemsResponse:
      type: object
      required: [count, hasNext, nextCursor, items]
      properties:
        count:
          type: integer
        hasNext:
          type: boolean
        nextCursor:
          type: [string, 'null']
        items:
          type: array
          items:
            $ref: '#/components/schemas/PublicItem'
    DailyReport:
      type: object
      required:
        [date, generatedAt, windowStart, windowEnd, leadTitle, leadParagraph, sections, flashes]
      properties:
        date:
          type: string
          format: date
        generatedAt:
          type: string
          format: date-time
        windowStart:
          type: string
          format: date-time
        windowEnd:
          type: string
          format: date-time
        leadTitle:
          type: string
        leadParagraph:
          type: string
        sections:
          type: array
          items: {}
        flashes:
          type: array
          items: {}
