{
  "schemaVersion": "1.0.0",
  "title": "AI完登計画 入出力仕様",
  "description": "未登頂の日本百名山をもとに、縦走・近接セット・適期・希望期間から完登ロードマップを生成する。天気詳細は晴れ山サーチへリンク。",
  "weatherPolicy": {
    "provider": "hareyama",
    "behavior": "deep_link_only",
    "baseUrl": "https://www.hareyama.app/",
    "note": "天気エンジンは自前実装しない。各山・各日から晴れ山へ誘導する。"
  },
  "input": {
    "$id": "HyakuPlanRequest",
    "required": ["horizon", "constraints"],
    "properties": {
      "horizon": {
        "description": "完登を目指す期間の枠",
        "type": "object",
        "required": ["mode"],
        "properties": {
          "mode": {
            "enum": ["season", "one_year", "three_years", "custom"],
            "description": "今シーズン / 1年 / 3年 / カスタム"
          },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" }
        }
      },
      "capacity": {
        "description": "遠征できる頻度・日数",
        "type": "object",
        "properties": {
          "trips_per_month": { "type": "number", "minimum": 0, "maximum": 8 },
          "max_days_per_trip": { "type": "integer", "enum": [1, 2, 3, 4] },
          "prefer_weekends": { "type": "boolean", "default": true },
          "prefer_long_holidays": { "type": "boolean", "default": true }
        }
      },
      "constraints": {
        "type": "object",
        "required": ["home", "transport"],
        "properties": {
          "home": {
            "type": "object",
            "properties": {
              "label": { "type": "string", "examples": ["横浜駅"] },
              "lat": { "type": "number" },
              "lng": { "type": "number" }
            }
          },
          "transport": { "enum": ["car", "transit", "both"] },
          "max_one_way_hours": { "type": "number", "description": "片道移動の上限目安" },
          "snow_ok": { "type": "boolean", "default": false },
          "max_physical_level": { "type": "integer", "minimum": 1, "maximum": 5 },
          "max_difficulty_level": { "type": "integer", "minimum": 1, "maximum": 5 },
          "avoid_regions": { "type": "array", "items": { "type": "string" } },
          "priority_regions": { "type": "array", "items": { "type": "string" } },
          "must_include_mountain_ids": {
            "type": "array",
            "items": { "type": "string", "format": "uuid" }
          },
          "exclude_mountain_ids": {
            "type": "array",
            "items": { "type": "string", "format": "uuid" }
          }
        }
      },
      "unclimbed_mountain_ids": {
        "description": "省略時はサーバーが user_climbing_records から未登頂百名山を算出",
        "type": "array",
        "items": { "type": "string", "format": "uuid" }
      },
      "preferences": {
        "type": "object",
        "properties": {
          "prefer_traverse": {
            "type": "boolean",
            "default": true,
            "description": "可能な限り縦走・近接2座を優先"
          },
          "prefer_efficiency": {
            "type": "boolean",
            "default": true,
            "description": "移動コスト最小化を優先"
          },
          "notes": { "type": "string", "description": "自由記述の希望" }
        }
      }
    }
  },
  "output": {
    "$id": "HyakuPlanResponse",
    "required": ["plan_id", "summary", "timeline", "expeditions", "leftover", "assumptions"],
    "properties": {
      "plan_id": { "type": "string", "format": "uuid" },
      "generated_at": { "type": "string", "format": "date-time" },
      "summary": {
        "type": "object",
        "required": ["unclimbed_count", "planned_count", "estimated_trips", "horizon_label"],
        "properties": {
          "horizon_label": { "type": "string" },
          "unclimbed_count": { "type": "integer" },
          "planned_count": { "type": "integer" },
          "estimated_trips": { "type": "integer" },
          "completion_estimate": {
            "type": "string",
            "description": "例: 2027年秋ごろ完登見込み（残りは要延長）"
          },
          "headline": { "type": "string" }
        }
      },
      "timeline": {
        "description": "四半期または月単位の概観",
        "type": "array",
        "items": {
          "type": "object",
          "required": ["period_label", "mountain_count", "focus"],
          "properties": {
            "period_start": { "type": "string", "format": "date" },
            "period_end": { "type": "string", "format": "date" },
            "period_label": { "type": "string", "examples": ["2026年10–12月"] },
            "mountain_count": { "type": "integer" },
            "focus": { "type": "string", "description": "この期の狙い（例: 関東近郊でペース作り）" },
            "best_months": { "type": "array", "items": { "type": "integer" } }
          }
        }
      },
      "expeditions": {
        "description": "実際の遠征単位（1座 or 縦走/近接セット）",
        "type": "array",
        "items": {
          "$ref": "#/$defs/Expedition"
        }
      },
      "leftover": {
        "description": "期間内に入りきらない未登頂",
        "type": "object",
        "properties": {
          "count": { "type": "integer" },
          "mountain_ids": { "type": "array", "items": { "type": "string" } },
          "reason": { "type": "string" },
          "suggested_extension": { "type": "string" }
        }
      },
      "assumptions": {
        "type": "array",
        "items": { "type": "string" },
        "description": "AIが置いた前提（説明責任）"
      },
      "warnings": {
        "type": "array",
        "items": { "type": "string" }
      }
    }
  },
  "$defs": {
    "Expedition": {
      "type": "object",
      "required": ["expedition_id", "kind", "suggested_window", "mountains", "rationale", "weather_links"],
      "properties": {
        "expedition_id": { "type": "string" },
        "kind": {
          "enum": ["single", "nearby_pair", "traverse"],
          "description": "単独 / 近接2座（別登山口可） / 縦走"
        },
        "title": { "type": "string", "examples": ["谷川岳×武尊山（近接週末）"] },
        "priority": { "type": "integer", "minimum": 1 },
        "suggested_window": {
          "type": "object",
          "required": ["earliest", "latest", "best_months"],
          "properties": {
            "earliest": { "type": "string", "format": "date" },
            "latest": { "type": "string", "format": "date" },
            "best_months": { "type": "array", "items": { "type": "integer" } },
            "avoid_months": { "type": "array", "items": { "type": "integer" } },
            "season_note": { "type": "string" }
          }
        },
        "estimated_days": { "type": "integer" },
        "drive_hours_est": { "type": "number" },
        "physical_peak": { "type": "integer", "minimum": 1, "maximum": 5 },
        "mountains": {
          "type": "array",
          "minItems": 1,
          "maxItems": 3,
          "items": {
            "type": "object",
            "required": ["mountain_id", "name", "order"],
            "properties": {
              "mountain_id": { "type": "string" },
              "name": { "type": "string" },
              "order": { "type": "integer" },
              "role": { "enum": ["main", "pair", "traverse_leg"] },
              "hyaku_number": { "type": "integer" },
              "elevation_m": { "type": "integer" },
              "prefecture": { "type": "string" }
            }
          }
        },
        "traverse": {
          "description": "kind=traverse のとき",
          "type": "object",
          "properties": {
            "feasible": { "type": "boolean" },
            "route_sketch": { "type": "string" },
            "overnight_needed": { "type": "boolean" },
            "caveats": { "type": "array", "items": { "type": "string" } }
          }
        },
        "rationale": {
          "type": "array",
          "items": { "type": "string" },
          "description": "なぜこの組み合わせ・時期か"
        },
        "weather_links": {
          "type": "array",
          "items": {
            "type": "object",
            "required": ["label", "url"],
            "properties": {
              "label": { "type": "string" },
              "url": { "type": "string", "format": "uri" },
              "mountain_name": { "type": "string" }
            }
          },
          "description": "晴れ山サーチへのディープリンクのみ"
        },
        "access_hints": {
          "type": "object",
          "properties": {
            "trailhead_summary": { "type": "string" },
            "stay_summary": { "type": "string" }
          }
        }
      }
    }
  },
  "api": {
    "endpoints": [
      {
        "method": "POST",
        "path": "/v1/hyaku/plans/generate",
        "auth": "required",
        "body": "HyakuPlanRequest",
        "response": "HyakuPlanResponse"
      },
      {
        "method": "POST",
        "path": "/v1/hyaku/plans/{plan_id}/regenerate",
        "auth": "required",
        "description": "登頂反映後や条件変更後の組み直し"
      },
      {
        "method": "GET",
        "path": "/v1/hyaku/plans/active",
        "auth": "required",
        "description": "進行中の完登計画"
      }
    ]
  }
}
