openapi: 3.0.3
info:
  title: 369 Spiritual API
  version: 0.1.0
  description: Детерминированный движок трактовок и синтеза эзотерических систем (v1, без LLM).
servers:
  - url: https://369-spiritual-api.pages.dev
  - url: http://localhost:8789
paths:
  /api/meta:
    get:
      summary: Сводка по системам и Knowledge Base
      operationId: getMeta
      responses:
        '200':
          description: Системы и число блоков по каждой kind
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Meta'
  /api/kb/{system}:
    get:
      summary: Число блоков по системе
      operationId: getKb
      parameters:
        - name: system
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/System'
      responses:
        '200':
          description: Система и её kinds
        '404':
          $ref: '#/components/responses/NotFound'
  /api/interpret:
    post:
      summary: Интерпретация переданного набора фич (evidence)
      operationId: interpret
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [features]
              properties:
features:
                   type: array
                   items:
                     $ref: '#/components/schemas/Feature'
                 sphere:
                   type: string
                   description: Запросить текст конкретной сферы жизни (love | money | work | growth), если у блока есть domains
       responses:
        '200':
          description: Интерпретации и пропущенные фичи
          content:
            application/json:
              schema:
                type: object
                properties:
                  count: { type: integer }
                  resolved: { type: integer }
                  items: { type: array, items: { $ref: '#/components/schemas/Interpretation' } }
                  missing:
                    type: array
                    items: { type: object }
        '400':
          $ref: '#/components/responses/BadRequest'
  /api/synthesize:
    post:
      summary: Полный синтез по evidence или дате рождения
      operationId: synthesize
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              oneOf:
                - required: [features]
                - required: [dateStr]
              properties:
                features:
                  type: array
                  items:
                    $ref: '#/components/schemas/Feature'
                dateStr:
                  type: string
                  description: Дата рождения в формате YYYY-MM-DD
                systems:
                  type: array
                  items:
                    $ref: '#/components/schemas/System'
                bio:
                  type: object
                  description: Метаданные рождения (контекст, не влияет на алгоритм синтеза)
                  properties:
                    dateStr:
                      type: string
                      description: Дата рождения в формате YYYY-MM-DD
                    time:
                      type: string
                      description: Время рождения HH:MM
                    timeKnown:
                      type: boolean
                      description: Известно ли точное время
                    place:
                      type: string
                      description: Место рождения
                    lat:
                      type: number
                    lon:
                      type: number
                    compatDate:
                      type: string
                      description: Дата партнёра для совместимости YYYY-MM-DD
responses:
        '200':
          description: Интерпретации по системам, метрики, аркан Таро и сводка
          content:
            application/json:
              schema:
                type: object
                properties:
                  requested:
                    type: array
                    items: { $ref: '#/components/schemas/System' }
                  bio:
                    type: object
                    description: Метаданные рождения (эхо входного bio)
                    properties:
                      dateStr: { type: string }
                      time: { type: string }
                      timeKnown: { type: boolean }
                      place: { type: string }
                      lat: { type: number }
                      lon: { type: number }
                  count: { type: integer }
                  resolved: { type: integer }
                  metrics:
                    type: object
                    properties:
                      resolved: { type: integer }
                      missing: { type: integer }
                      rate: { type: integer, format: int32, description: 'Процент покрытия (0-100)' }
                      strong: { type: integer, description: Число сильных (strong) фич }
                      bySystem:
                        type: object
                        additionalProperties: { type: integer }
                  missing:
                    type: array
                    items:
                      type: object
                      properties:
                        feature: { type: string }
                        label: { type: string }
                        matched: { type: boolean, enum: [false] }
                        reason: { type: string }
                  systems:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        $ref: '#/components/schemas/Interpretation'
                  tarot:
                    type: object
                    nullable: true
                    properties:
                      arcane: { type: integer }
                      name: { type: string }
                  compat:
                    type: object
                    nullable: true
                    description: Совместимость по двум датам (bio.compatDate)
                    properties:
                      score:
                        type: integer
                        description: Средний балл совместимости 0-100
                      features:
                        type: array
                        items: { $ref: '#/components/schemas/Feature' }
                      pairs:
                        type: array
                        items:
                          type: object
                          properties:
                            key: { type: string }
                            v1: { type: integer }
                            v2: { type: integer }
                            score: { type: integer }
                            name: { type: string }
                            cls: { type: string }
                  synthesis:
                    type: object
                    properties:
                      label: { type: string }
                      lead: { type: string, nullable: true }
                      leadSystem: { type: string, nullable: true }
                      themes: { type: array, items: { type: string } }
                      portrait: { type: string }
                      bySystem: { type: array, items: { type: string } }
                      summary: { type: array, items: { type: string } }
        '400':
          $ref: '#/components/responses/BadRequest'
components:
  schemas:
    System:
      type: string
      enum: [jyotish, astrology, matrix, syutsay, tarot, numerology]
    Feature:
      type: object
      required: [system, key, label, meta]
      properties:
        system: { type: string }
        category: { type: string }
        key:
          type: string
          example: matrix_center
        label: { type: string }
        strong: { type: boolean, default: false }
        meta:
          description: Числовое значение фичи, указывающее на блок KB
    Interpretation:
      type: object
      properties:
        feature: { type: string }
        label: { type: string }
        strong: { type: boolean }
        matched: { type: boolean }
        system: { $ref: '#/components/schemas/System' }
        kind: { type: string }
        blockKey: { type: string, description: Ключ атомарного блока KB }
        name: { type: string }
        essence: { type: string }
        text: { type: string }
        domains:
          description: Тексты по сферам жизни (love/money/work/growth), если у блока есть
          type: object
        ref:
          type: object
          properties:
            sources: { type: array, items: { type: string } }
            dictionary: { type: array, items: { type: string } }
    Meta:
      type: object
      properties:
        version: { type: string }
        systems:
          type: array
          items: { $ref: '#/components/schemas/System' }
        knowledge:
          type: object
  responses:
    BadRequest:
      description: Невалидный запрос
      content:
        application/json:
          schema:
            type: object
            properties:
              error: { type: string }
              message: { type: string }
    NotFound:
      description: Ресурс не найден
      content:
        application/json:
          schema:
            type: object
            properties:
              error: { type: string }
              message: { type: string }