{
  "openapi": "3.1.0",
  "info": {
    "title": "Japanese Calendar API",
    "version": "1.0.0",
    "description": "日本の祝日・販促イベント・六曜・暦注・営業日計算 API。\n祝日のデータソースは内閣府「国民の祝日について」CSV (Source of Truth)。"
  },
  "servers": [
    {
      "url": "/",
      "description": "Current origin"
    }
  ],
  "tags": [
    {
      "name": "Static assets",
      "description": "Workers Static Assets から配信する生成済み祝日データと OpenAPI ドキュメント。"
    },
    {
      "name": "Holidays",
      "description": "祝日判定、次の祝日、期間内の祝日一覧。"
    },
    {
      "name": "Events",
      "description": "販促活動で使いやすい一般イベント、季節行事、記念日、コマースイベント。"
    },
    {
      "name": "Rokuyo",
      "description": "六曜の判定と次の指定六曜の検索。"
    },
    {
      "name": "Almanac",
      "description": "旧暦、十干十二支、二十四節気などの暦注。"
    },
    {
      "name": "Utilities",
      "description": "営業日数など、祝日データを使ったユーティリティ。"
    }
  ],
  "paths": {
    "/v1/holidays.json": {
      "get": {
        "tags": [
          "Static assets"
        ],
        "summary": "全期間の祝日データ (マップ形式)",
        "description": "内閣府 CSV から生成した全期間の祝日データ。`YYYY-MM-DD` をキー、祝日名を値にする holidays-jp/api 互換のマップ形式。",
        "responses": {
          "200": {
            "description": "祝日マップ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayMap"
                }
              }
            }
          }
        }
      }
    },
    "/v1/holidays/{year}.json": {
      "get": {
        "tags": [
          "Static assets"
        ],
        "summary": "年別の祝日データ",
        "description": "生成済みの年別祝日データ。存在しない年は Static Assets 側で 404。",
        "parameters": [
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1955
            },
            "example": 2026,
            "description": "取得したい西暦年"
          }
        ],
        "responses": {
          "200": {
            "description": "年別祝日マップ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayMap"
                }
              }
            }
          }
        }
      }
    },
    "/v1/holidays.ics": {
      "get": {
        "tags": [
          "Static assets"
        ],
        "summary": "iCalendar 形式 (RFC 5545)",
        "description": "全期間の祝日データを Asia/Tokyo の終日予定として出力する iCalendar ファイル。",
        "responses": {
          "200": {
            "description": "iCalendar",
            "content": {
              "text/calendar": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/holidays.csv": {
      "get": {
        "tags": [
          "Static assets"
        ],
        "summary": "CSV 形式 (UTF-8 BOM)",
        "description": "全期間の祝日データを UTF-8 BOM 付き CSV として出力する。",
        "responses": {
          "200": {
            "description": "CSV",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v1/holidays/{date}": {
      "get": {
        "tags": [
          "Holidays"
        ],
        "summary": "指定日が祝日かどうか判定",
        "description": "指定日が祝日の場合は `is_holiday: true` と祝日名を返す。祝日でない場合は `name: null`。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "判定したい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "判定結果",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HolidayCheckResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/holidays/next": {
      "get": {
        "tags": [
          "Holidays"
        ],
        "summary": "基準日以降で最も近い祝日",
        "description": "`from` を含めて、対応データ範囲内で最も近い祝日を返す。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "基準日 (デフォルト: JST の今日)"
          }
        ],
        "responses": {
          "200": {
            "description": "次の祝日",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextHolidayResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "年別の一般イベント一覧",
        "description": "販促活動向けの一般イベント、季節行事、記念日、コマースイベントを年単位で返す。祝日データとは別系統のルールベースカレンダー。",
        "parameters": [
          {
            "name": "year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 9999
            },
            "example": 2026,
            "description": "取得したい西暦年"
          }
        ],
        "responses": {
          "200": {
            "description": "年別イベント一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsYearResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/events/{date}": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "指定日の一般イベント一覧",
        "description": "指定日に該当する販促向けイベントを返す。該当なしの場合は空配列。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "調べたい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "指定日のイベント",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventsDateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/events/between": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "期間内の一般イベント一覧",
        "description": "`from` と `to` の両端を含む期間内の販促向けイベントを、日付昇順の配列で返す。閉区間の長さは最大 4000 日（両端含む）まで。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "開始日 (YYYY-MM-DD)"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "終了日 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "イベント配列",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CalendarEvent"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/events/next": {
      "get": {
        "tags": [
          "Events"
        ],
        "summary": "基準日以降で最も近い一般イベント",
        "description": "`from` を含めて最も近い販促向けイベントを返す。`category` でイベント分類を絞り込める。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "基準日 (デフォルト: JST の今日)"
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "$ref": "#/components/schemas/EventCategory"
            },
            "description": "絞り込みたいイベント分類"
          }
        ],
        "responses": {
          "200": {
            "description": "次のイベント",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextEventResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/rokuyo/{date}": {
      "get": {
        "tags": [
          "Rokuyo"
        ],
        "summary": "指定日の六曜",
        "description": "旧暦の月日から算出した六曜（先勝・友引・先負・仏滅・大安・赤口）を返す。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "調べたい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "六曜",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RokuyoResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/rokuyo/next": {
      "get": {
        "tags": [
          "Rokuyo"
        ],
        "summary": "基準日以降で最も近い指定六曜",
        "description": "name で指定した六曜（先勝・友引・先負・仏滅・大安・赤口）のうち、基準日以降で最も近い日を返す。",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "$ref": "#/components/schemas/RokuyoName"
            },
            "description": "探したい六曜"
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "基準日 (デフォルト: JST の今日)"
          }
        ],
        "responses": {
          "200": {
            "description": "次の指定六曜",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NextRokuyoResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/v1/lunar/{date}": {
      "get": {
        "tags": [
          "Almanac"
        ],
        "summary": "指定日の旧暦",
        "description": "指定日に対応する旧暦の年月日と、閏月かどうかを返す。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "調べたい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "旧暦",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LunarDateResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/kanshi/{date}": {
      "get": {
        "tags": [
          "Almanac"
        ],
        "summary": "指定日の十干十二支",
        "description": "指定日の年・月・日に対応する十干十二支（干支）を返す。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "調べたい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "十干十二支",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KanshiResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/solar-terms/{date}": {
      "get": {
        "tags": [
          "Almanac"
        ],
        "summary": "指定日の二十四節気",
        "description": "指定日が二十四節気に当たるかどうかと、前後の二十四節気を返す。",
        "parameters": [
          {
            "name": "date",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "調べたい日付 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "二十四節気",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SolarTermsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/between": {
      "get": {
        "tags": [
          "Holidays"
        ],
        "summary": "期間内の祝日一覧",
        "description": "`from` と `to` の両端を含む期間内の祝日を、日付昇順の配列で返す。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "開始日 (YYYY-MM-DD)"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "終了日 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "祝日配列",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Holiday"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/business-days": {
      "get": {
        "tags": [
          "Utilities"
        ],
        "summary": "期間内の営業日数",
        "description": "from と to の両端を含むカレンダー日の閉区間における営業日数（土日・祝日除く）を返す。閉区間の長さは最大 4000 日（両端含む）まで。それを超えると 400 (code: RANGE_TOO_LARGE)。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "開始日 (YYYY-MM-DD)"
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "終了日 (YYYY-MM-DD)"
          }
        ],
        "responses": {
          "200": {
            "description": "営業日数",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BusinessDaysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/v1/business-days/add": {
      "get": {
        "tags": [
          "Utilities"
        ],
        "summary": "営業日加算",
        "description": "from の翌日から days 営業日を数え、休業日に当たる分だけ後ろへ繰り越した日付を返す。days=0 の場合は from 自体を候補日とし、休業日なら次の営業日へ繰り越す。exclude_weekends / exclude_holidays は省略時 true。closed の日付は常に休業日扱い。計算対象のカレンダー日数は最大 4000 日まで。それを超えると 400 (code: RANGE_TOO_LARGE)。",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "example": "2026-01-01"
            },
            "description": "基準日 (YYYY-MM-DD)"
          },
          {
            "name": "days",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "from の翌日から数える営業日数。0 の場合は from を候補日とする。"
          },
          {
            "name": "closed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "2026-04-28,2026-04-30"
            },
            "description": "追加で休業日扱いする YYYY-MM-DD のカンマ区切りリスト"
          },
          {
            "name": "exclude_weekends",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "true の場合、土日を休業日として扱い、日付を繰り越す"
          },
          {
            "name": "exclude_holidays",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true
            },
            "description": "true の場合、祝日を休業日として扱い、日付を繰り越す"
          }
        ],
        "responses": {
          "200": {
            "description": "営業日加算の結果",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddBusinessDaysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HolidayDate": {
        "type": "string",
        "format": "date",
        "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
        "example": "2026-01-01"
      },
      "Holiday": {
        "type": "object",
        "required": [
          "date",
          "name"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "example": "元日"
          }
        }
      },
      "HolidayMap": {
        "type": "object",
        "propertyNames": {
          "type": "string",
          "format": "date",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "example": "2026-01-01"
        },
        "additionalProperties": {
          "type": "string",
          "minLength": 1
        },
        "description": "YYYY-MM-DD をキー、祝日名を値とするマップ",
        "example": {
          "2026-01-01": "元日",
          "2026-01-12": "成人の日"
        }
      },
      "EventCategory": {
        "type": "string",
        "enum": [
          "retail",
          "gift",
          "family",
          "food",
          "seasonal",
          "traditional",
          "culture",
          "health",
          "sports",
          "travel",
          "international",
          "ceremony",
          "digital",
          "environment"
        ],
        "example": "gift"
      },
      "CalendarEvent": {
        "type": "object",
        "required": [
          "date",
          "id",
          "name",
          "category",
          "rule"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "id": {
            "type": "string",
            "minLength": 1,
            "example": "mothers-day"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "example": "母の日"
          },
          "category": {
            "$ref": "#/components/schemas/EventCategory"
          },
          "rule": {
            "type": "string",
            "minLength": 1,
            "example": "5月第2日曜日"
          }
        }
      },
      "EventsDateResponse": {
        "type": "object",
        "required": [
          "date",
          "events"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarEvent"
            }
          }
        }
      },
      "EventsYearResponse": {
        "type": "object",
        "required": [
          "year",
          "events"
        ],
        "properties": {
          "year": {
            "type": "integer",
            "minimum": 1,
            "maximum": 9999,
            "example": 2026
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CalendarEvent"
            }
          }
        }
      },
      "NextEventResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CalendarEvent"
          },
          {
            "type": "object",
            "required": [
              "days_until"
            ],
            "properties": {
              "days_until": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        ]
      },
      "HolidayCheckResponse": {
        "type": "object",
        "required": [
          "date",
          "is_holiday",
          "name"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "is_holiday": {
            "type": "boolean"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "RokuyoName": {
        "type": "string",
        "enum": [
          "先勝",
          "友引",
          "先負",
          "仏滅",
          "大安",
          "赤口"
        ],
        "example": "大安"
      },
      "RokuyoResponse": {
        "type": "object",
        "required": [
          "date",
          "rokuyo"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "rokuyo": {
            "$ref": "#/components/schemas/RokuyoName"
          }
        }
      },
      "NextRokuyoResponse": {
        "type": "object",
        "required": [
          "date",
          "rokuyo",
          "days_until"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "rokuyo": {
            "$ref": "#/components/schemas/RokuyoName"
          },
          "days_until": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "LunarDateResponse": {
        "type": "object",
        "required": [
          "date",
          "lunar"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "lunar": {
            "type": "object",
            "required": [
              "year",
              "month",
              "day",
              "is_leap_month",
              "month_name",
              "day_name"
            ],
            "properties": {
              "year": {
                "type": "integer",
                "example": 2026
              },
              "month": {
                "type": "integer",
                "minimum": 1,
                "maximum": 12,
                "example": 3
              },
              "day": {
                "type": "integer",
                "minimum": 1,
                "maximum": 30,
                "example": 9
              },
              "is_leap_month": {
                "type": "boolean",
                "example": false
              },
              "month_name": {
                "type": "string",
                "example": "三"
              },
              "day_name": {
                "type": "string",
                "example": "初九"
              }
            }
          }
        }
      },
      "KanshiPart": {
        "type": "object",
        "required": [
          "stem",
          "branch",
          "name"
        ],
        "properties": {
          "stem": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1,
            "example": "丙"
          },
          "branch": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1,
            "example": "午"
          },
          "name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "example": "丙午"
          }
        }
      },
      "KanshiResponse": {
        "type": "object",
        "required": [
          "date",
          "kanshi"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "kanshi": {
            "type": "object",
            "required": [
              "year",
              "month",
              "day"
            ],
            "properties": {
              "year": {
                "$ref": "#/components/schemas/KanshiPart"
              },
              "month": {
                "$ref": "#/components/schemas/KanshiPart"
              },
              "day": {
                "$ref": "#/components/schemas/KanshiPart"
              }
            }
          }
        }
      },
      "SolarTerm": {
        "type": "object",
        "required": [
          "date",
          "name",
          "kind",
          "kind_name"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "example": "春分"
          },
          "kind": {
            "type": "string",
            "enum": [
              "jie",
              "qi"
            ],
            "example": "qi"
          },
          "kind_name": {
            "type": "string",
            "enum": [
              "節",
              "中"
            ],
            "example": "中"
          }
        }
      },
      "SolarTermsResponse": {
        "type": "object",
        "required": [
          "date",
          "solar_term",
          "previous",
          "next"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "solar_term": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/SolarTerm"
              },
              {
                "type": "null"
              }
            ]
          },
          "previous": {
            "$ref": "#/components/schemas/SolarTerm"
          },
          "next": {
            "$ref": "#/components/schemas/SolarTerm"
          }
        }
      },
      "NextHolidayResponse": {
        "type": "object",
        "required": [
          "date",
          "name",
          "days_until"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "name": {
            "type": "string",
            "minLength": 1
          },
          "days_until": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "BusinessDaysResponse": {
        "type": "object",
        "required": [
          "from",
          "to",
          "business_days"
        ],
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "to": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "business_days": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "BusinessDaySkippedReason": {
        "type": "string",
        "enum": [
          "weekend",
          "holiday",
          "custom_closed"
        ]
      },
      "BusinessDaySkippedDate": {
        "type": "object",
        "required": [
          "date",
          "reason"
        ],
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "reason": {
            "$ref": "#/components/schemas/BusinessDaySkippedReason"
          },
          "name": {
            "type": "string",
            "minLength": 1
          }
        }
      },
      "AddBusinessDaysResponse": {
        "type": "object",
        "required": [
          "from",
          "days",
          "exclude_weekends",
          "exclude_holidays",
          "date",
          "calendar_days",
          "skipped_days"
        ],
        "properties": {
          "from": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "days": {
            "type": "integer",
            "minimum": 0
          },
          "exclude_weekends": {
            "type": "boolean"
          },
          "exclude_holidays": {
            "type": "boolean"
          },
          "date": {
            "type": "string",
            "format": "date",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
            "example": "2026-01-01"
          },
          "calendar_days": {
            "type": "integer",
            "minimum": 0
          },
          "skipped_days": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BusinessDaySkippedDate"
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "enum": [
              "INVALID_DATE_FORMAT",
              "INVALID_ROKUYO_NAME",
              "MISSING_PARAMETER",
              "INVALID_RANGE",
              "RANGE_TOO_LARGE",
              "NOT_FOUND",
              "INTERNAL_ERROR"
            ]
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad Request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not Found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }
}
