openapi: 3.1.0
info:
  title: RaiseLife API
  version: 1.0.0
  description: |
    徳を積むほど相棒が育つ habit tracker RaiseLife の公開 REST API。
    外部 AI (ChatGPT / Claude / Zapier / Siri Shortcuts / curl 等) からタスクを追加・完了できます。
    認証はユーザーごとに発行する API Key (`Authorization: Bearer rl_...`) で行います。
  contact:
    url: https://raise-life.pages.dev/api-docs
servers:
  - url: https://raise-life.pages.dev
    description: Production
paths:
  /api/state:
    get:
      operationId: getState
      summary: 相棒の現在の状態とタスク一覧を取得
      security: [{ bearerAuth: [] }]
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema: { $ref: "#/components/schemas/StateResponse" }
        "401": { $ref: "#/components/responses/Unauthorized" }
  /api/tasks:
    get:
      operationId: listTasks
      summary: タスク一覧を取得
      security: [{ bearerAuth: [] }]
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  tasks:
                    type: array
                    items: { $ref: "#/components/schemas/Task" }
        "401": { $ref: "#/components/responses/Unauthorized" }
    post:
      operationId: addTask
      summary: タスクを追加
      security: [{ bearerAuth: [] }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, category, hardness]
              properties:
                name:
                  type: string
                  description: タスク名 (例「3ヶ月放置の経費精算」)
                category:
                  type: string
                  enum: [habit, daily, todo]
                  description: habit(毎日の習慣) / daily(今日の日課) / todo(1 回限り)
                hardness:
                  type: integer
                  minimum: 1
                  maximum: 5
                  description: 嫌度 1(軽い)〜5(重い)。高いほど徳 pt が多い (1=1pt, 2=3pt, 3=6pt, 4=10pt, 5=15pt)
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  task: { $ref: "#/components/schemas/Task" }
                  state: { $ref: "#/components/schemas/GameState" }
        "400": { $ref: "#/components/responses/BadRequest" }
        "401": { $ref: "#/components/responses/Unauthorized" }
  /api/tasks/{id}/complete:
    post:
      operationId: completeTask
      summary: タスクを完了して徳 pt を加算 + 進化判定
      security: [{ bearerAuth: [] }]
      parameters:
        - name: id
          in: path
          required: true
          description: タスク ID (例 "t-1793250000-abcde")
          schema: { type: string }
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok: { type: boolean }
                  earned: { type: integer, description: 加算された徳 pt }
                  evolved: { type: boolean, description: 進化が発生したか }
                  previousStage: { type: integer, minimum: 1, maximum: 6 }
                  newStage: { type: integer, minimum: 1, maximum: 6 }
                  state: { $ref: "#/components/schemas/GameState" }
        "401": { $ref: "#/components/responses/Unauthorized" }
        "404": { $ref: "#/components/responses/NotFound" }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key (rl_...)
  schemas:
    Task:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        category:
          type: string
          enum: [habit, daily, todo]
        hardness: { type: integer, minimum: 1, maximum: 5 }
        completedAt:
          type: string
          format: date-time
          nullable: true
        createdAt: { type: string, format: date-time }
    GameState:
      type: object
      properties:
        eggKey:
          type: string
          enum: [kin, setsu, ken, chi, wa, sou]
          nullable: true
          description: 選んだ卵 (勤 / 節 / 健 / 智 / 和 / 創)
        buddyName: { type: string }
        tasks:
          type: array
          items: { $ref: "#/components/schemas/Task" }
        tokuPt: { type: integer, description: 累積徳 pt }
        currentStage:
          type: integer
          minimum: 1
          maximum: 6
          description: 現在の進化段階 (1 タマゴ / 2 幼年期 / 3 成長期 / 4 成熟期 / 5 完全体 / 6 究極体)
        branches:
          type: object
          properties:
            growth: { type: string, enum: [A, B], description: "A 剛毅 / B 柔和" }
            mature: { type: string, enum: [A1, A2, B1, B2] }
        equipment: { type: array, items: { type: string } }
        skills: { type: array, items: { type: string } }
        titles: { type: array, items: { type: string } }
        streak: { type: integer, description: 連続日数 }
    StateResponse:
      type: object
      properties:
        ok: { type: boolean }
        state: { $ref: "#/components/schemas/GameState" }
    Error:
      type: object
      properties:
        error: { type: string }
  responses:
    Unauthorized:
      description: API Key 未指定 or 無効
      content: { application/json: { schema: { $ref: "#/components/schemas/Error" } } }
    BadRequest:
      description: リクエスト不正 (必須フィールド欠落 / 型違反)
      content: { application/json: { schema: { $ref: "#/components/schemas/Error" } } }
    NotFound:
      description: リソースが見つからない
      content: { application/json: { schema: { $ref: "#/components/schemas/Error" } } }
