{
  "openapi": "3.1.0",
  "info": {
    "title": "Parky API (Mobile App)",
    "version": "0.1.0",
    "description": "Parky API — Flutter モバイルアプリ専用エンドポイント (/v1/mobile/*)。views / actions / telemetry で構成。"
  },
  "servers": [
    {
      "url": "https://api.parky.co.jp",
      "description": "Production"
    },
    {
      "url": "https://stg-api.parky.co.jp",
      "description": "Staging"
    },
    {
      "url": "https://dev-api.parky.co.jp",
      "description": "Development"
    },
    {
      "url": "http://localhost:8787",
      "description": "Local"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Supabase Auth が発行した JWT（HS256 / SUPABASE_JWT_SECRET 署名）"
      }
    },
    "schemas": {
      "AppleAppSiteAssociation": {
        "type": "object",
        "properties": {
          "applinks": {
            "type": "object",
            "properties": {
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "appIDs": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "components": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "/": {
                            "type": "string"
                          },
                          "comment": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "/"
                        ]
                      }
                    }
                  },
                  "required": [
                    "appIDs",
                    "components"
                  ]
                }
              }
            },
            "required": [
              "details"
            ]
          },
          "webcredentials": {
            "type": "object",
            "properties": {
              "apps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "apps"
            ]
          }
        },
        "required": [
          "applinks",
          "webcredentials"
        ]
      },
      "AssetLinksEntry": {
        "type": "object",
        "properties": {
          "relation": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "target": {
            "type": "object",
            "properties": {
              "namespace": {
                "type": "string"
              },
              "package_name": {
                "type": "string"
              },
              "sha256_cert_fingerprints": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "required": [
              "namespace",
              "package_name",
              "sha256_cert_fingerprints"
            ]
          }
        },
        "required": [
          "relation",
          "target"
        ]
      },
      "AssetLinksResponse": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/AssetLinksEntry"
        }
      },
      "BootAppUser": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "display_name",
          "status",
          "created_at"
        ]
      },
      "BootCodesSummary": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string",
            "description": "codes 全行 (lang=ja) の md5 hash。client の cache invalidation key",
            "examples": [
              "a1b2c3d4e5f6..."
            ]
          }
        },
        "required": [
          "version"
        ]
      },
      "BootAppConfig": {
        "type": [
          "object",
          "null"
        ],
        "additionalProperties": {}
      },
      "BootI18n": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string",
            "description": "bundle が属する言語コード (BCP47 primary subtag)",
            "examples": [
              "ja"
            ]
          },
          "version": {
            "type": "string",
            "description": "i18n_messages 全 row の md5 hash。client の cache invalidation key",
            "examples": [
              "d41d8cd98f00b204e9800998ecf8427e"
            ]
          }
        },
        "required": [
          "lang",
          "version"
        ]
      },
      "MobileNavigationTab": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "icon": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "label_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "id",
          "icon",
          "label_code"
        ]
      },
      "MobileNavigationScreen": {
        "type": "object",
        "properties": {
          "route": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "requires_auth": {
            "type": "boolean",
            "default": true
          }
        },
        "required": [
          "route"
        ]
      },
      "MobileNavigationShell": {
        "type": "object",
        "properties": {
          "tabs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileNavigationTab"
            }
          },
          "screens": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/MobileNavigationScreen"
            }
          }
        },
        "required": [
          "tabs",
          "screens"
        ]
      },
      "ValidationRule": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "rule": {
            "type": "string",
            "enum": [
              "required",
              "min_length",
              "max_length",
              "regex",
              "numeric_range"
            ]
          },
          "param": {},
          "message_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "required": [
          "field",
          "rule",
          "message_code"
        ]
      },
      "ErrorState": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "message_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "retryable": {
            "type": "boolean"
          },
          "fallback": {
            "type": "string",
            "enum": [
              "cached",
              "empty",
              "block"
            ]
          }
        },
        "required": [
          "code",
          "message_code",
          "retryable",
          "fallback"
        ]
      },
      "EmptyState": {
        "type": "object",
        "properties": {
          "illustration": {
            "type": [
              "string",
              "null"
            ]
          },
          "title_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "body_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "cta": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "label_code": {
                "type": "string",
                "minLength": 1,
                "maxLength": 128
              },
              "action": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64
              }
            },
            "required": [
              "label_code",
              "action"
            ]
          }
        },
        "required": [
          "illustration",
          "title_code",
          "body_code",
          "cta"
        ]
      },
      "SkeletonHint": {
        "type": "object",
        "properties": {
          "layout": {
            "type": "string",
            "enum": [
              "list",
              "detail",
              "map",
              "grid",
              "splash"
            ]
          },
          "item_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 50
          }
        },
        "required": [
          "layout"
        ]
      },
      "ViewStates": {
        "type": "object",
        "properties": {
          "error": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ErrorState"
            }
          },
          "empty": {
            "$ref": "#/components/schemas/EmptyState"
          },
          "skeleton": {
            "$ref": "#/components/schemas/SkeletonHint"
          }
        }
      },
      "FallbackBehavior": {
        "type": "object",
        "properties": {
          "on_network_error": {
            "type": "string",
            "enum": [
              "show_cached",
              "show_empty",
              "show_error"
            ]
          },
          "on_auth_error": {
            "type": "string",
            "enum": [
              "redirect_login",
              "show_error"
            ]
          },
          "on_version_mismatch": {
            "type": "string",
            "enum": [
              "force_update",
              "degrade",
              "ignore"
            ]
          },
          "cache_ttl_seconds": {
            "type": "integer",
            "minimum": 0,
            "maximum": 86400
          }
        },
        "required": [
          "on_network_error",
          "on_auth_error",
          "on_version_mismatch",
          "cache_ttl_seconds"
        ]
      },
      "MobileViewSpec": {
        "type": "object",
        "properties": {
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          }
        },
        "required": [
          "fallback_behavior"
        ]
      },
      "MobileUiLayer": {
        "type": "object",
        "properties": {
          "ui_version": {
            "type": "string",
            "description": "L0 (navigation_shell) + L1 (view_specs) 全体の hash。クライアント cache の世代管理 key、ETag 値としても流用",
            "examples": [
              "ui_a1b2c3d4e5f6"
            ]
          },
          "navigation_shell": {
            "$ref": "#/components/schemas/MobileNavigationShell"
          },
          "view_specs": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/MobileViewSpec"
            }
          }
        },
        "required": [
          "ui_version",
          "navigation_shell",
          "view_specs"
        ]
      },
      "MobileBootData": {
        "type": "object",
        "properties": {
          "me": {
            "type": "object",
            "properties": {
              "user_id": {
                "type": "string",
                "format": "uuid"
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "app_user": {
                "$ref": "#/components/schemas/BootAppUser"
              }
            },
            "required": [
              "user_id",
              "email",
              "app_user"
            ]
          },
          "codes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "category_id": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "display_label": {
                  "type": "string"
                },
                "sort_order": {
                  "type": "integer"
                }
              },
              "required": [
                "category_id",
                "code",
                "display_label",
                "sort_order"
              ]
            }
          },
          "codes_summary": {
            "$ref": "#/components/schemas/BootCodesSummary"
          },
          "app_config": {
            "$ref": "#/components/schemas/BootAppConfig"
          },
          "i18n": {
            "$ref": "#/components/schemas/BootI18n"
          },
          "ui_layer": {
            "$ref": "#/components/schemas/MobileUiLayer"
          }
        },
        "required": [
          "me",
          "codes",
          "codes_summary",
          "app_config",
          "i18n",
          "ui_layer"
        ]
      },
      "UiConfig": {
        "type": "object",
        "properties": {
          "messages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "feature_flags": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            }
          },
          "experiment_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "theme_hint": {
            "type": "string",
            "enum": [
              "light",
              "dark",
              "auto"
            ],
            "default": "auto"
          },
          "highlighted_fields": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "NavigationHint": {
        "type": "object",
        "properties": {
          "target": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "params": {
            "type": "object",
            "additionalProperties": {}
          },
          "strategy": {
            "type": "string",
            "enum": [
              "push",
              "replace",
              "pop_to_root"
            ],
            "default": "push"
          }
        },
        "required": [
          "target"
        ]
      },
      "RealtimeHint": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "event_types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "INSERT",
                "UPDATE",
                "DELETE"
              ]
            },
            "minItems": 1
          },
          "rls_precondition": {
            "type": "string",
            "maxLength": 256
          },
          "fallback_poll_seconds": {
            "type": "integer",
            "minimum": 0,
            "maximum": 3600,
            "default": 0
          }
        },
        "required": [
          "channel",
          "event_types"
        ]
      },
      "ViewMeta": {
        "type": "object",
        "properties": {
          "server_time": {
            "type": "string",
            "format": "date-time"
          },
          "cache_key": {
            "type": [
              "string",
              "null"
            ]
          },
          "min_app_version": {
            "type": "string",
            "pattern": "^\\d+\\.\\d+\\.\\d+$"
          },
          "sunset_date": {
            "type": [
              "string",
              "null"
            ]
          },
          "realtime": {
            "$ref": "#/components/schemas/RealtimeHint"
          },
          "expected_ui_version": {
            "type": [
              "string",
              "null"
            ],
            "description": "UI バージョン鮮度トークン。`/boot` レスポンスに含まれる `ui_layer.ui_version` と突合し、不一致ならクライアントは背景で再 fetch する。null は UI レイヤー情報を返さないエンドポイント。",
            "examples": [
              "ui_2026_04_26_1547"
            ]
          },
          "view_spec_ref": {
            "type": [
              "string",
              "null"
            ],
            "description": "/boot の ui_layer.view_specs[id] への参照 key。client は spec を cache resolve して validation/states/fallback_behavior を取得。null = spec 未カタログ化 endpoint",
            "examples": [
              "parking_lot_detail_v1"
            ]
          }
        },
        "required": [
          "server_time",
          "cache_key",
          "min_app_version",
          "sunset_date"
        ]
      },
      "MobileBootResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileBootData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "examples": [
                  "not_found"
                ]
              },
              "message": {
                "type": "string",
                "examples": [
                  "Not Found"
                ]
              },
              "message_key": {
                "type": "string",
                "examples": [
                  "common.error.not_found"
                ]
              },
              "request_id": {
                "type": "string",
                "examples": [
                  "7d4e5…-…"
                ]
              },
              "param": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "リクエスト上のエラー対象フィールド名（zod path[0] 等）。root レベルエラーは null。",
                "examples": [
                  "email"
                ]
              },
              "doc_url": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "エラーコードに対応するドキュメント URL。未整備時は null。",
                "examples": [
                  null
                ]
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "HomeBanner": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slot_key": {
            "type": "string",
            "enum": [
              "home_top",
              "home_middle",
              "home_bottom"
            ]
          },
          "title": {
            "type": "string"
          },
          "subtitle": {
            "type": [
              "string",
              "null"
            ]
          },
          "image_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "link_type": {
            "type": "string",
            "enum": [
              "external",
              "deep",
              "none"
            ]
          },
          "link_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "display_order": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "slot_key",
          "title",
          "subtitle",
          "image_url",
          "link_type",
          "link_url",
          "display_order"
        ]
      },
      "HomeGamificationSlot": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "slot_type": {
                "type": "string",
                "enum": [
                  "tutorial_mission"
                ]
              },
              "missions": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "badge_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "icon": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "progress_percent": {
                      "type": "integer"
                    },
                    "threshold": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "badge_id",
                    "name",
                    "icon",
                    "description",
                    "progress_percent",
                    "threshold"
                  ]
                }
              },
              "earned_count": {
                "type": "integer"
              },
              "total_tutorial_count": {
                "type": "integer"
              }
            },
            "required": [
              "slot_type",
              "missions",
              "earned_count",
              "total_tutorial_count"
            ]
          },
          {
            "type": "object",
            "properties": {
              "slot_type": {
                "type": "string",
                "enum": [
                  "general_progress"
                ]
              },
              "earned_count": {
                "type": "integer"
              },
              "total_count": {
                "type": "integer"
              }
            },
            "required": [
              "slot_type",
              "earned_count",
              "total_count"
            ]
          },
          {
            "type": "object",
            "properties": {
              "slot_type": {
                "type": "string",
                "enum": [
                  "hidden"
                ]
              }
            },
            "required": [
              "slot_type"
            ]
          }
        ]
      },
      "MobileHomeFeedData": {
        "type": "object",
        "properties": {
          "lots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "lat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "lng": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "distance_m": {
                  "type": "number"
                },
                "status": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "lat",
                "lng",
                "distance_m",
                "status"
              ]
            }
          },
          "sponsors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "lat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "lng": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "distance_m": {
                  "type": "number"
                }
              },
              "required": [
                "id",
                "name",
                "lat",
                "lng",
                "distance_m"
              ]
            }
          },
          "active_session": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "parking_lot_id": {
                "type": "string",
                "format": "uuid"
              },
              "started_at": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "parking_lot_id",
              "started_at",
              "status"
            ]
          },
          "banners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HomeBanner"
            }
          },
          "gamification": {
            "$ref": "#/components/schemas/HomeGamificationSlot"
          }
        },
        "required": [
          "lots",
          "sponsors",
          "active_session",
          "banners",
          "gamification"
        ]
      },
      "MobileHomeFeed": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileHomeFeedData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileLotReviewsData": {
        "type": "object",
        "properties": {
          "lotId": {
            "type": "string",
            "format": "uuid"
          },
          "summary": {
            "type": "object",
            "properties": {
              "avgRating": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "ratingCount": {
                "type": "integer"
              },
              "distribution": {
                "type": "object",
                "properties": {
                  "r1": {
                    "type": "integer"
                  },
                  "r2": {
                    "type": "integer"
                  },
                  "r3": {
                    "type": "integer"
                  },
                  "r4": {
                    "type": "integer"
                  },
                  "r5": {
                    "type": "integer"
                  }
                },
                "required": [
                  "r1",
                  "r2",
                  "r3",
                  "r4",
                  "r5"
                ]
              }
            },
            "required": [
              "avgRating",
              "ratingCount",
              "distribution"
            ]
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "userId": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid"
                },
                "userName": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "rating": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 5
                },
                "comment": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "createdAt": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "userId",
                "userName",
                "rating",
                "comment",
                "createdAt"
              ]
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "lotId",
          "summary",
          "items",
          "nextCursor"
        ]
      },
      "MobileLotReviewsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileLotReviewsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileLotSpot": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "vehicle_type_max": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_ev_charger": {
            "type": "boolean"
          },
          "ev_connector_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "accessibility": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_reservable": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "code",
          "vehicle_type_max",
          "is_ev_charger",
          "ev_connector_type",
          "accessibility",
          "is_reservable"
        ]
      },
      "MobileLotPricingGroup": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "code": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "is_default": {
            "type": "boolean"
          },
          "display_order": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "code",
          "name",
          "is_default",
          "display_order"
        ]
      },
      "MobileLotDetailData": {
        "type": "object",
        "properties": {
          "lot": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "address": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "lat": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "lng": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "status": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "total_spaces": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "operating_hours": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "updated_at": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "name",
              "address",
              "lat",
              "lng",
              "status",
              "total_spaces",
              "operating_hours",
              "updated_at"
            ]
          },
          "reviews": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "user_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "user_name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "rating": {
                  "type": "integer"
                },
                "comment": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "created_at": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "user_id",
                "user_name",
                "rating",
                "comment",
                "created_at"
              ]
            }
          },
          "pricing_rules": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "category": {
                  "type": "string"
                },
                "price_minor": {
                  "type": "integer"
                },
                "rule_order": {
                  "type": "integer"
                }
              },
              "required": [
                "id",
                "category",
                "price_minor",
                "rule_order"
              ]
            }
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "image_url": {
                  "type": "string",
                  "format": "uri"
                },
                "is_main": {
                  "type": "boolean"
                },
                "sort_order": {
                  "type": "integer"
                }
              },
              "required": [
                "id",
                "image_url",
                "is_main",
                "sort_order"
              ]
            }
          },
          "spots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileLotSpot"
            }
          },
          "pricing_groups": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileLotPricingGroup"
            }
          },
          "nearby": {
            "type": "object",
            "properties": {
              "lots": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "distance_m": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "distance_m"
                  ]
                }
              },
              "sponsors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "distance_m": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "distance_m"
                  ]
                }
              }
            },
            "required": [
              "lots",
              "sponsors"
            ]
          },
          "is_open_now": {
            "type": [
              "boolean",
              "null"
            ]
          }
        },
        "required": [
          "lot",
          "reviews",
          "pricing_rules",
          "images",
          "spots",
          "pricing_groups",
          "nearby",
          "is_open_now"
        ]
      },
      "MobileLotDetail": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileLotDetailData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "SubscriptionPlanFeatures": {
        "anyOf": [
          {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          {
            "type": "object",
            "additionalProperties": {}
          }
        ]
      },
      "MobilePremiumViewData": {
        "type": "object",
        "properties": {
          "current_subscription": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "plan_code": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "current_period_end": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "trial_ends_at": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "cancel_at_period_end": {
                "type": "boolean"
              },
              "trial_days_remaining": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            },
            "required": [
              "id",
              "plan_code",
              "status",
              "current_period_end",
              "trial_ends_at",
              "cancel_at_period_end",
              "trial_days_remaining"
            ]
          },
          "plans": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "code": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "description": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "price_minor": {
                  "type": "integer"
                },
                "currency": {
                  "type": "string"
                },
                "billing_period": {
                  "type": "string"
                },
                "features": {
                  "$ref": "#/components/schemas/SubscriptionPlanFeatures"
                },
                "sort_order": {
                  "type": "integer"
                },
                "plan_group": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "variant_label": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "trial_days": {
                  "type": "integer"
                },
                "discount_percent": {
                  "type": "integer"
                },
                "effective_price_minor": {
                  "type": "integer"
                },
                "discount_amount_minor": {
                  "type": "integer"
                },
                "applied_campaign": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "properties": {
                    "code": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "ends_at": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "name",
                    "ends_at"
                  ]
                }
              },
              "required": [
                "id",
                "code",
                "name",
                "description",
                "price_minor",
                "currency",
                "billing_period",
                "features",
                "sort_order",
                "plan_group",
                "variant_label",
                "trial_days",
                "discount_percent",
                "effective_price_minor",
                "discount_amount_minor",
                "applied_campaign"
              ]
            }
          },
          "pricing_variant": {
            "type": [
              "string",
              "null"
            ]
          },
          "has_used_trial": {
            "type": "boolean"
          }
        },
        "required": [
          "current_subscription",
          "plans",
          "pricing_variant",
          "has_used_trial"
        ]
      },
      "MobilePremiumView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobilePremiumViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionNearbyPlace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "banner_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "link_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "is_sponsored": {
            "type": "boolean",
            "description": "true=リアスポンサー (強調表示)、false=一般 POI"
          },
          "discount_title": {
            "type": [
              "string",
              "null"
            ],
            "description": "該当駐車場との提携優待のタイトル（無ければ null）"
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "logo_url",
          "banner_url",
          "link_url",
          "lat",
          "lng",
          "is_sponsored",
          "discount_title"
        ]
      },
      "ParkingSessionView": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "parking_lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "lot_name": {
            "type": "string"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "planned_end_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "退庁見込み時刻（駐車開始時または編集で設定された任意項目）"
          },
          "memo": {
            "type": [
              "string",
              "null"
            ],
            "description": "ユーザーメモ（1 件・任意）"
          },
          "elapsed_minutes": {
            "type": "integer",
            "minimum": 0
          },
          "current_fee": {
            "type": "integer",
            "minimum": 0
          },
          "completion_rate": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 1,
            "description": "planned_end_at が設定されている場合の進捗率 (0〜1)。未設定または超過で null。"
          },
          "can_finalize": {
            "type": "boolean"
          },
          "can_cancel": {
            "type": "boolean"
          },
          "sponsors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionNearbyPlace"
            },
            "description": "近隣リアスポンサー一覧 (最大 5 件、is_sponsored=true)"
          },
          "nearby_places": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionNearbyPlace"
            },
            "description": "近隣周辺施設一覧 (最大 5 件、優待提携があれば discount_title 同梱)"
          }
        },
        "required": [
          "session_id",
          "parking_lot_id",
          "lot_name",
          "started_at",
          "planned_end_at",
          "memo",
          "elapsed_minutes",
          "current_fee",
          "completion_rate",
          "can_finalize",
          "can_cancel",
          "sponsors",
          "nearby_places"
        ]
      },
      "ParkingSessionViewResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ParkingSessionView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "ParkingSessionItem": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "parking_lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "lot_name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "parking",
              "completed",
              "cancelled"
            ]
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "total_fee_minor": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "session_id",
          "parking_lot_id",
          "lot_name",
          "status",
          "started_at",
          "ended_at",
          "total_fee_minor"
        ]
      },
      "ParkingSessionsListView": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParkingSessionItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "items",
          "next_cursor"
        ]
      },
      "ParkingSessionsListViewResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ParkingSessionsListView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileAuthConfigData": {
        "type": "object",
        "properties": {
          "providers": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "email",
                "google",
                "apple"
              ]
            },
            "examples": [
              [
                "email",
                "google",
                "apple"
              ]
            ]
          },
          "termsUrl": {
            "type": "string",
            "format": "uri",
            "examples": [
              "https://parky.co.jp/terms"
            ]
          },
          "privacyPolicyUrl": {
            "type": "string",
            "format": "uri",
            "examples": [
              "https://parky.co.jp/privacy"
            ]
          },
          "welcome_message_code": {
            "type": "string",
            "examples": [
              "auth.welcome_message"
            ]
          }
        },
        "required": [
          "providers",
          "termsUrl",
          "privacyPolicyUrl",
          "welcome_message_code"
        ]
      },
      "MobileAuthConfigView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileAuthConfigData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "SearchResultItem": {
        "type": "object",
        "properties": {
          "lotId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "東京都渋谷区神宮前1-1-1"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ],
            "examples": [
              35.658
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ],
            "examples": [
              139.7016
            ]
          },
          "distanceMeters": {
            "type": "number",
            "examples": [
              350
            ]
          },
          "hourlyFeeMinor": {
            "type": [
              "integer",
              "null"
            ],
            "description": "最安の時間料金 (円 × 1000 minor unit)",
            "examples": [
              30000
            ]
          },
          "dailyFeeMinor": {
            "type": [
              "integer",
              "null"
            ],
            "description": "日額最安料金 (24h 以上の cap)",
            "examples": [
              1500000
            ]
          },
          "rating": {
            "type": [
              "number",
              "null"
            ],
            "examples": [
              4.2
            ]
          },
          "ratingCount": {
            "type": "integer",
            "examples": [
              23
            ]
          },
          "totalSpaces": {
            "type": [
              "integer",
              "null"
            ],
            "examples": [
              30
            ]
          },
          "operatorCode": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "times24"
            ]
          },
          "operatorName": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "タイムズ24"
            ]
          },
          "isOpen": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "isSaved": {
            "type": "boolean",
            "description": "ログインユーザーが保存済みか",
            "examples": [
              false
            ]
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "required": [
          "lotId",
          "name",
          "address",
          "lat",
          "lng",
          "distanceMeters",
          "hourlyFeeMinor",
          "dailyFeeMinor",
          "rating",
          "ratingCount",
          "totalSpaces",
          "operatorCode",
          "operatorName",
          "isOpen",
          "isSaved",
          "thumbnailUrl"
        ]
      },
      "MobileSearchResultsData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResultItem"
            }
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "totalCount": {
            "type": "integer"
          },
          "appliedSort": {
            "type": "string",
            "enum": [
              "distance",
              "price_asc",
              "price_desc",
              "rating",
              "availability",
              "recommended"
            ],
            "examples": [
              "distance"
            ]
          }
        },
        "required": [
          "items",
          "nextCursor",
          "totalCount",
          "appliedSort"
        ]
      },
      "MobileSearchResultsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchResultsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSearchNearbyLotItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "distance_m": {
            "type": "number",
            "examples": [
              350
            ]
          },
          "shape_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "area_geojson": {}
        },
        "required": [
          "id",
          "name",
          "address",
          "lat",
          "lng",
          "distance_m",
          "shape_type"
        ]
      },
      "MobileSearchNearbyLotsData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileSearchNearbyLotItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "MobileSearchNearbyLotsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchNearbyLotsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSearchNearbyPlaceItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "banner_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "link_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "radius_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "is_sponsored": {
            "type": "boolean"
          },
          "source": {
            "type": [
              "string",
              "null"
            ]
          },
          "rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "user_ratings_total": {
            "type": [
              "number",
              "null"
            ]
          },
          "distance_m": {
            "type": "number"
          },
          "score": {
            "type": "number"
          },
          "discount": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "description",
          "logo_url",
          "banner_url",
          "thumbnail_url",
          "link_url",
          "phone",
          "address",
          "lat",
          "lng",
          "radius_m",
          "is_sponsored",
          "source",
          "rating",
          "user_ratings_total",
          "distance_m",
          "score",
          "discount"
        ]
      },
      "MobileSearchNearbyPlacesData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileSearchNearbyPlaceItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "MobileSearchNearbyPlacesView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchNearbyPlacesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSearchMapPlaceInBboxItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": "number"
          },
          "lng": {
            "type": "number"
          },
          "is_sponsored": {
            "type": "boolean"
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "place_types": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "lat",
          "lng",
          "is_sponsored",
          "thumbnail_url",
          "place_types"
        ]
      },
      "MobileSearchPlacesInBboxData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileSearchMapPlaceInBboxItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "MobileSearchPlacesInBboxView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchPlacesInBboxData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSearchNearbySponsorItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "banner_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "link_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "radius_m": {
            "type": [
              "number",
              "null"
            ]
          },
          "distance_m": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "name",
          "category",
          "description",
          "logo_url",
          "banner_url",
          "link_url",
          "phone",
          "address",
          "lat",
          "lng",
          "radius_m",
          "distance_m"
        ]
      },
      "MobileSearchNearbySponsorsData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileSearchNearbySponsorItem"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "MobileSearchNearbySponsorsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchNearbySponsorsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileDestinationsData": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "recentItems": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "address": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "lat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "lng": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "placeId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "history",
                    "lot",
                    "external"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "address",
                "lat",
                "lng",
                "placeId",
                "source"
              ]
            }
          },
          "autocompleteItems": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "address": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "lat": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "lng": {
                  "type": [
                    "number",
                    "null"
                  ]
                },
                "placeId": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "source": {
                  "type": "string",
                  "enum": [
                    "history",
                    "lot",
                    "external"
                  ]
                }
              },
              "required": [
                "id",
                "name",
                "address",
                "lat",
                "lng",
                "placeId",
                "source"
              ]
            }
          },
          "externalSource": {
            "type": "string",
            "enum": [
              "mapbox",
              "lots_only"
            ]
          },
          "sessionToken": {
            "type": "string"
          }
        },
        "required": [
          "query",
          "recentItems",
          "autocompleteItems",
          "externalSource",
          "sessionToken"
        ]
      },
      "MobileDestinationsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileDestinationsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileAiSearchViewData": {
        "type": "object",
        "properties": {
          "aiEnabled": {
            "type": "boolean",
            "examples": [
              true
            ]
          },
          "recentQueries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "渋谷 屋根あり",
                "1時間500円以下"
              ]
            ]
          },
          "suggested_query_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "ai_search.suggested_query.shibuya_5min",
                "ai_search.suggested_query.roofed_24h",
                "ai_search.suggested_query.under_500_per_hour"
              ]
            ]
          },
          "disclaimer_message_code": {
            "type": "string",
            "examples": [
              "ai_search.disclaimer_message"
            ]
          }
        },
        "required": [
          "aiEnabled",
          "recentQueries",
          "suggested_query_codes",
          "disclaimer_message_code"
        ]
      },
      "MobileAiSearchView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileAiSearchViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "ExistingReviewForCompose": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "rating": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "body": {
            "type": [
              "string",
              "null"
            ]
          },
          "photos": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              []
            ]
          }
        },
        "required": [
          "id",
          "rating",
          "title",
          "body",
          "photos"
        ]
      },
      "ReviewTagOption": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "examples": [
              "clean"
            ]
          },
          "label_code": {
            "type": "string",
            "examples": [
              "review_tag.clean"
            ]
          }
        },
        "required": [
          "code",
          "label_code"
        ]
      },
      "MobileReviewComposeData": {
        "type": "object",
        "properties": {
          "lotId": {
            "type": "string",
            "format": "uuid"
          },
          "lotName": {
            "type": "string"
          },
          "existingReview": {
            "$ref": "#/components/schemas/ExistingReviewForCompose"
          },
          "tagOptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReviewTagOption"
            }
          },
          "prohibitedWords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "広告",
                "宣伝"
              ]
            ]
          }
        },
        "required": [
          "lotId",
          "lotName",
          "existingReview",
          "tagOptions",
          "prohibitedWords"
        ]
      },
      "MobileReviewComposeView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileReviewComposeData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffVehicleViewItem": {
        "type": "object",
        "properties": {
          "vehicle_id": {
            "type": "string",
            "format": "uuid"
          },
          "nickname": {
            "type": [
              "string",
              "null"
            ]
          },
          "plate_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "vehicle_type": {
            "type": "string"
          },
          "is_default": {
            "type": "boolean"
          }
        },
        "required": [
          "vehicle_id",
          "nickname",
          "plate_number",
          "vehicle_type",
          "is_default"
        ]
      },
      "BffProfileVehiclesData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BffVehicleViewItem"
            }
          },
          "can_add_more": {
            "type": "boolean"
          }
        },
        "required": [
          "items",
          "can_add_more"
        ]
      },
      "BffMobileProfileVehiclesView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileVehiclesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffProfileReferralsData": {
        "type": "object",
        "properties": {
          "my_code": {
            "type": "string"
          },
          "success_count": {
            "type": "integer"
          },
          "pending_count": {
            "type": "integer"
          },
          "reward_total": {
            "type": "integer"
          },
          "share_message": {
            "type": "string"
          },
          "terms_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "my_code",
          "success_count",
          "pending_count",
          "reward_total",
          "share_message",
          "terms_url"
        ]
      },
      "BffMobileProfileReferralsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileReferralsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffEarnedBadgeView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "badge_id": {
            "type": "string",
            "format": "uuid"
          },
          "icon": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "earned_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "badge_id",
          "icon",
          "name",
          "description",
          "category",
          "earned_at"
        ]
      },
      "BffPendingBadgeView": {
        "type": "object",
        "properties": {
          "badge_id": {
            "type": "string",
            "format": "uuid"
          },
          "icon": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "current_count": {
            "type": "integer"
          },
          "threshold": {
            "type": "integer"
          },
          "progress_percent": {
            "type": "integer"
          }
        },
        "required": [
          "badge_id",
          "icon",
          "name",
          "description",
          "category",
          "current_count",
          "threshold",
          "progress_percent"
        ]
      },
      "BffExpEventView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "amount": {
            "type": "integer"
          },
          "reason": {
            "type": "string"
          },
          "earned_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "amount",
          "reason",
          "earned_at"
        ]
      },
      "BffProfileGamificationData": {
        "type": "object",
        "properties": {
          "current_level": {
            "type": "integer"
          },
          "current_exp": {
            "type": "integer"
          },
          "next_level_exp": {
            "type": [
              "integer",
              "null"
            ]
          },
          "progress": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "earned_badges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BffEarnedBadgeView"
            }
          },
          "pending_badges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BffPendingBadgeView"
            }
          },
          "recent_exp_events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BffExpEventView"
            }
          },
          "leaderboard_rank": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "current_level",
          "current_exp",
          "next_level_exp",
          "progress",
          "earned_badges",
          "pending_badges",
          "recent_exp_events"
        ]
      },
      "BffMobileProfileGamificationView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileGamificationData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffProfileSettingsData": {
        "type": "object",
        "properties": {
          "theme": {
            "type": [
              "string",
              "null"
            ]
          },
          "notifications_enabled": {
            "type": "boolean"
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "marketing_opt_in": {
            "type": "boolean"
          },
          "data_export_available": {
            "type": "boolean"
          },
          "delete_account_eligible": {
            "type": "boolean"
          }
        },
        "required": [
          "theme",
          "notifications_enabled",
          "language",
          "marketing_opt_in",
          "data_export_available",
          "delete_account_eligible"
        ]
      },
      "BffMobileProfileSettingsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileSettingsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffBadgePreview": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "icon": {
            "type": "string"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "icon",
          "name"
        ]
      },
      "BffProfileMainData": {
        "type": "object",
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid"
          },
          "display_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "member_since": {
            "type": "string",
            "format": "date-time"
          },
          "total_parking_count": {
            "type": "integer"
          },
          "total_spent_minor": {
            "type": "integer"
          },
          "level": {
            "type": "integer"
          },
          "exp": {
            "type": "integer"
          },
          "next_level_exp": {
            "type": [
              "integer",
              "null"
            ]
          },
          "badge_count": {
            "type": "integer"
          },
          "saved_count": {
            "type": "integer"
          },
          "review_count": {
            "type": "integer"
          },
          "unlocked_badge_preview": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BffBadgePreview"
            }
          }
        },
        "required": [
          "user_id",
          "display_name",
          "email",
          "avatar_url",
          "member_since",
          "total_parking_count",
          "total_spent_minor",
          "level",
          "exp",
          "next_level_exp",
          "badge_count",
          "saved_count",
          "review_count",
          "unlocked_badge_preview"
        ]
      },
      "BffMobileProfileView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileMainData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "SavedLotItem": {
        "type": "object",
        "properties": {
          "lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "hourly_fee_minor": {
            "type": [
              "integer",
              "null"
            ]
          },
          "rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "distance_meters": {
            "type": [
              "number",
              "null"
            ]
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "saved_at": {
            "type": "string",
            "format": "date-time"
          },
          "is_open": {
            "type": "boolean"
          }
        },
        "required": [
          "lot_id",
          "name",
          "address",
          "lat",
          "lng",
          "hourly_fee_minor",
          "rating",
          "distance_meters",
          "thumbnail_url",
          "saved_at",
          "is_open"
        ]
      },
      "SavedViewData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedLotItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "total_count": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "next_cursor",
          "total_count"
        ]
      },
      "MobileSavedView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SavedViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "NotificationCategoryItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "label": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          }
        },
        "required": [
          "code",
          "label",
          "enabled"
        ]
      },
      "NotificationsPreferencesViewData": {
        "type": "object",
        "properties": {
          "email_enabled": {
            "type": "boolean"
          },
          "push_enabled": {
            "type": "boolean"
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NotificationCategoryItem"
            }
          }
        },
        "required": [
          "email_enabled",
          "push_enabled",
          "categories"
        ]
      },
      "MobileNotificationsPreferencesView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationsPreferencesViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "NotificationItem": {
        "type": "object",
        "properties": {
          "notification_id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "deep_link": {
            "type": [
              "string",
              "null"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "read_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "required": [
          "notification_id",
          "type",
          "category",
          "title",
          "body",
          "deep_link",
          "created_at",
          "read_at",
          "thumbnail_url"
        ]
      },
      "NotificationsViewData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/NotificationItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "unread_count": {
            "type": "integer",
            "minimum": 0
          },
          "total_count": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "next_cursor",
          "unread_count",
          "total_count"
        ]
      },
      "MobileNotificationsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationsViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "ParkingHistoryItem": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "parking_lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "lot_name": {
            "type": "string"
          },
          "started_at": {
            "type": "string",
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "total_fee_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "user_entered_fee_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "finalize 時にユーザーが入力した料金（分単位、未入力は null）"
          },
          "fee_mismatch_flag": {
            "type": "boolean",
            "description": "自動計算料金と user_entered_fee_minor が不一致なら true"
          },
          "status": {
            "type": "string",
            "enum": [
              "completed"
            ]
          },
          "review_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "can_review": {
            "type": "boolean"
          }
        },
        "required": [
          "session_id",
          "parking_lot_id",
          "lot_name",
          "started_at",
          "ended_at",
          "duration_minutes",
          "total_fee_minor",
          "user_entered_fee_minor",
          "fee_mismatch_flag",
          "status",
          "review_id",
          "can_review"
        ]
      },
      "ParkingHistoryViewData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ParkingHistoryItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "total_spent_minor": {
            "type": "integer",
            "minimum": 0
          },
          "total_duration_minutes": {
            "type": "integer",
            "minimum": 0
          },
          "session_count": {
            "type": "integer",
            "minimum": 0
          }
        },
        "required": [
          "items",
          "next_cursor",
          "total_spent_minor",
          "total_duration_minutes",
          "session_count"
        ]
      },
      "MobileParkingHistoryView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ParkingHistoryViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSearchPresetsData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "preset_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": "string"
                },
                "radius_m": {
                  "type": "integer"
                },
                "fee_max_minor": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "features": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "code": {
                        "type": "string"
                      },
                      "label_code": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "code",
                      "label_code"
                    ]
                  }
                },
                "is_default": {
                  "type": "boolean"
                },
                "created_at": {
                  "type": "string",
                  "format": "date-time"
                }
              },
              "required": [
                "preset_id",
                "name",
                "radius_m",
                "fee_max_minor",
                "features",
                "is_default",
                "created_at"
              ]
            }
          },
          "can_add_more": {
            "type": "boolean"
          }
        },
        "required": [
          "items",
          "can_add_more"
        ]
      },
      "MobileSearchPresetsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSearchPresetsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileLotRegistrationData": {
        "type": "object",
        "properties": {
          "form_config": {
            "type": "object",
            "properties": {
              "required_fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "label_code": {
                      "type": "string"
                    },
                    "input_type": {
                      "type": "string",
                      "enum": [
                        "text",
                        "number",
                        "email",
                        "phone",
                        "location",
                        "image"
                      ]
                    },
                    "hint_code": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "field",
                    "label_code",
                    "input_type"
                  ]
                }
              },
              "optional_fields": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "label_code": {
                      "type": "string"
                    },
                    "input_type": {
                      "type": "string",
                      "enum": [
                        "text",
                        "number",
                        "email",
                        "phone",
                        "location",
                        "image"
                      ]
                    },
                    "hint_code": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "field",
                    "label_code",
                    "input_type"
                  ]
                }
              }
            },
            "required": [
              "required_fields",
              "optional_fields"
            ]
          },
          "example_lots": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "address": {
                  "type": "string"
                },
                "capacity": {
                  "type": "integer"
                },
                "hourly_fee_minor": {
                  "type": "integer"
                }
              },
              "required": [
                "name",
                "address",
                "capacity",
                "hourly_fee_minor"
              ]
            }
          },
          "faq_url": {
            "type": "string",
            "format": "uri"
          },
          "terms_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "form_config",
          "example_lots",
          "faq_url",
          "terms_url"
        ]
      },
      "MobileLotRegistrationView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileLotRegistrationData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "MediaArticleItem": {
        "type": "object",
        "properties": {
          "article_id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "cover_image_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "author": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "category_code": {
            "type": "string"
          },
          "category_label": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "article_id",
          "slug",
          "title",
          "summary",
          "cover_image_url",
          "author",
          "published_at",
          "category_code",
          "category_label",
          "tags"
        ]
      },
      "ArticleCategoryItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "label"
        ]
      },
      "MediaListData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MediaArticleItem"
            }
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ArticleCategoryItem"
            }
          }
        },
        "required": [
          "items",
          "next_cursor",
          "categories"
        ]
      },
      "MobileMediaListView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MediaListData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "RelatedArticle": {
        "type": "object",
        "properties": {
          "article_id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "cover_image_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "article_id",
          "slug",
          "title",
          "cover_image_url",
          "published_at"
        ]
      },
      "ArticleDetailData": {
        "type": "object",
        "properties": {
          "article_id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": [
              "string",
              "null"
            ]
          },
          "author": {
            "type": [
              "string",
              "null"
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "cover_image_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "category_code": {
            "type": "string"
          },
          "category_label": {
            "type": "string"
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "related_articles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RelatedArticle"
            }
          }
        },
        "required": [
          "article_id",
          "slug",
          "title",
          "body",
          "author",
          "published_at",
          "cover_image_url",
          "category_code",
          "category_label",
          "tags",
          "related_articles"
        ]
      },
      "MobileArticleDetailView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ArticleDetailData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "FaqItem": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string"
          },
          "answer": {
            "type": "string"
          },
          "category_code": {
            "type": "string"
          }
        },
        "required": [
          "question",
          "answer",
          "category_code"
        ]
      },
      "RecentTicket": {
        "type": "object",
        "properties": {
          "ticket_id": {
            "type": "string",
            "format": "uuid"
          },
          "subject": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "ticket_id",
          "subject",
          "status",
          "created_at"
        ]
      },
      "SupportData": {
        "type": "object",
        "properties": {
          "faq_items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FaqItem"
            }
          },
          "recent_tickets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecentTicket"
            }
          },
          "contact_email": {
            "type": "string"
          },
          "can_submit_new_ticket": {
            "type": "boolean"
          }
        },
        "required": [
          "faq_items",
          "recent_tickets",
          "contact_email",
          "can_submit_new_ticket"
        ]
      },
      "MobileSupportView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SupportData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "PolicyItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "terms",
              "privacy",
              "cookies",
              "licenses"
            ]
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "title",
          "body",
          "version",
          "updated_at"
        ]
      },
      "PoliciesData": {
        "type": "object",
        "properties": {
          "policies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PolicyItem"
            }
          }
        },
        "required": [
          "policies"
        ]
      },
      "MobilePoliciesView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PoliciesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "RecentSearch": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "searched_at": {
            "type": "string"
          }
        },
        "required": [
          "query",
          "location",
          "searched_at"
        ]
      },
      "SearchHistoryData": {
        "type": "object",
        "properties": {
          "recent_searches": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecentSearch"
            }
          },
          "can_clear": {
            "type": "boolean"
          }
        },
        "required": [
          "recent_searches",
          "can_clear"
        ]
      },
      "MobileSearchHistoryView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SearchHistoryData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "PermissionItem": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "location",
              "notification",
              "camera",
              "gallery"
            ]
          },
          "label": {
            "type": "string"
          },
          "status_label": {
            "type": "string"
          },
          "deep_link": {
            "type": "string"
          },
          "required": {
            "type": "boolean"
          },
          "reason_text": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "label",
          "status_label",
          "deep_link",
          "required",
          "reason_text"
        ]
      },
      "PermissionsData": {
        "type": "object",
        "properties": {
          "permissions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PermissionItem"
            }
          }
        },
        "required": [
          "permissions"
        ]
      },
      "MobilePermissionsView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PermissionsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "RetryableAction": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string"
          },
          "target": {
            "type": "string"
          },
          "params": {
            "type": "object",
            "additionalProperties": {}
          }
        },
        "required": [
          "label",
          "target"
        ]
      },
      "AppVersionInfo": {
        "type": "object",
        "properties": {
          "app_version": {
            "type": "string"
          },
          "build_number": {
            "type": "string"
          },
          "api_version": {
            "type": "string"
          }
        },
        "required": [
          "app_version",
          "build_number",
          "api_version"
        ]
      },
      "ErrorFallbackData": {
        "type": "object",
        "properties": {
          "retryable_actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RetryableAction"
            }
          },
          "diagnostics_support_url": {
            "type": "string"
          },
          "version": {
            "$ref": "#/components/schemas/AppVersionInfo"
          },
          "troubleshooting_steps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "retryable_actions",
          "diagnostics_support_url",
          "version",
          "troubleshooting_steps"
        ]
      },
      "MobileErrorFallbackView": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ErrorFallbackData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "AppReviewStatusView": {
        "type": "object",
        "properties": {
          "can_prompt": {
            "type": "boolean",
            "description": "いまアプリ内レビューポップアップを出して良いか"
          },
          "reason": {
            "type": "string",
            "enum": [
              "already_submitted",
              "in_cooldown",
              "ok"
            ],
            "description": "can_prompt の理由: already_submitted (submit 済) / in_cooldown (cooldown 中) / ok"
          },
          "cooldown_days": {
            "type": "integer",
            "minimum": 0,
            "description": "適用された cooldown 日数（デフォルト 90 日）"
          },
          "last_dispatched_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "直近で promote ダイアログを出した時刻（無ければ null）"
          },
          "submitted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "ユーザーが submit 自己申告した時刻（無ければ null）"
          }
        },
        "required": [
          "can_prompt",
          "reason",
          "cooldown_days",
          "last_dispatched_at",
          "submitted_at"
        ]
      },
      "AppReviewStatusViewResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AppReviewStatusView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "ActionMeta": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ViewMeta"
          },
          {
            "type": "object",
            "properties": {
              "mutation_id": {
                "type": "string",
                "format": "uuid"
              }
            },
            "required": [
              "mutation_id"
            ]
          }
        ]
      },
      "StartSessionActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ParkingSessionView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionCelebrationExp": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "exp_gained": {
            "type": "integer",
            "minimum": 0,
            "description": "今回付与された EXP"
          },
          "total_exp_before": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "total_exp_after": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "level_before": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "level_after": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "level_up": {
            "type": "boolean",
            "description": "今回のセッションでレベルアップしたか"
          },
          "daily_cap_hit": {
            "type": "boolean",
            "description": "1 日 EXP 上限に到達して以降の付与が抑止されたか"
          }
        },
        "required": [
          "exp_gained",
          "total_exp_before",
          "total_exp_after",
          "level_before",
          "level_after",
          "level_up",
          "daily_cap_hit"
        ]
      },
      "SessionCelebrationBadge": {
        "type": "object",
        "properties": {
          "badge_id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "icon": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "badge_id",
          "name",
          "description",
          "icon",
          "category"
        ]
      },
      "SessionCelebration": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "false なら client は celebration UI を出さず即 history に遷移してよい"
          },
          "exp": {
            "$ref": "#/components/schemas/SessionCelebrationExp"
          },
          "badges_earned": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionCelebrationBadge"
            },
            "description": "今回新たに獲得したバッジ。0 件もありえる。"
          },
          "sequence": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "badge",
                "level_up",
                "exp"
              ]
            },
            "description": "再生順。badge があれば badge → level_up → exp の順を推奨"
          }
        },
        "required": [
          "enabled",
          "exp",
          "badges_earned",
          "sequence"
        ]
      },
      "FinalizeSessionResultV2": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "celebration": {
            "$ref": "#/components/schemas/SessionCelebration"
          }
        },
        "required": [
          "session_id",
          "celebration"
        ]
      },
      "FinalizeSessionActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/FinalizeSessionResultV2"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "CancelSessionResult": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "sessionId"
        ]
      },
      "CancelSessionActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/CancelSessionResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "UpdateSessionActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ParkingSessionView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionFeedbackBadReason": {
        "type": [
          "string",
          "null"
        ],
        "enum": [
          "parking_info",
          "dislike",
          "other"
        ]
      },
      "SessionPostFlow": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "ask_app_review",
              "ask_lot_review",
              "info_correction",
              "support_contact",
              "done"
            ],
            "description": "ask_app_review (Apple/Google レビュー UI 表示) / ask_lot_review (駐車場 ★ レビュー) / info_correction (情報訂正) / support_contact (サポート) / done (終了)"
          },
          "params": {
            "type": "object",
            "additionalProperties": {},
            "description": "target 画面に渡す params。parking_lot_id / session_id / prefilled_rating 等。"
          }
        },
        "required": [
          "kind",
          "params"
        ]
      },
      "SessionFeedbackResult": {
        "type": "object",
        "properties": {
          "session_id": {
            "type": "string",
            "format": "uuid"
          },
          "rating": {
            "type": "string",
            "enum": [
              "good",
              "bad",
              "skip"
            ]
          },
          "bad_reason": {
            "$ref": "#/components/schemas/SessionFeedbackBadReason"
          },
          "next_flow": {
            "$ref": "#/components/schemas/SessionPostFlow"
          }
        },
        "required": [
          "session_id",
          "rating",
          "bad_reason",
          "next_flow"
        ]
      },
      "SessionFeedbackActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionFeedbackResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionNotificationView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "parkingSessionId": {
            "type": "string",
            "format": "uuid"
          },
          "triggerType": {
            "type": "string",
            "enum": [
              "price_reached",
              "max_price_reached",
              "time_reached",
              "planned_end_minus"
            ]
          },
          "thresholdAmountMinor": {
            "type": [
              "integer",
              "null"
            ]
          },
          "thresholdAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "offsetMinutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "delivery": {
            "type": "string",
            "enum": [
              "push",
              "in_app",
              "both"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "firedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancelledAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "parkingSessionId",
          "triggerType",
          "thresholdAmountMinor",
          "thresholdAt",
          "offsetMinutes",
          "delivery",
          "label",
          "firedAt",
          "cancelledAt",
          "createdAt",
          "updatedAt"
        ]
      },
      "SessionNotificationListView": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SessionNotificationView"
            }
          }
        },
        "required": [
          "items"
        ]
      },
      "SessionNotificationListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionNotificationListView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "validation": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ValidationRule"
            }
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ViewMeta"
          }
        },
        "required": [
          "data",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionNotificationCreateResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionNotificationView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionNotificationCreateBody": {
        "type": "object",
        "properties": {
          "trigger_type": {
            "type": "string",
            "enum": [
              "price_reached",
              "max_price_reached",
              "time_reached",
              "planned_end_minus"
            ]
          },
          "threshold_amount_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "threshold_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "offset_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "delivery": {
            "type": "string",
            "enum": [
              "push",
              "in_app",
              "both"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          }
        },
        "required": [
          "trigger_type"
        ]
      },
      "SessionNotificationUpdateResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionNotificationView"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SessionNotificationUpdateBody": {
        "type": "object",
        "properties": {
          "trigger_type": {
            "type": "string",
            "enum": [
              "price_reached",
              "max_price_reached",
              "time_reached",
              "planned_end_minus"
            ]
          },
          "threshold_amount_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "threshold_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "offset_minutes": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "delivery": {
            "type": "string",
            "enum": [
              "push",
              "in_app",
              "both"
            ]
          },
          "label": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 200
          }
        }
      },
      "SessionNotificationDeleteResult": {
        "type": "object",
        "properties": {
          "deleted": {
            "type": "boolean"
          }
        },
        "required": [
          "deleted"
        ]
      },
      "SessionNotificationDeleteResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SessionNotificationDeleteResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ToggleSaveResult": {
        "type": "object",
        "properties": {
          "lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "is_saved": {
            "type": "boolean"
          }
        },
        "required": [
          "lot_id",
          "is_saved"
        ]
      },
      "LotSaveActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ToggleSaveResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ToggleSaveActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ToggleSaveResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ReportIncorrectResult": {
        "type": "object",
        "properties": {
          "report_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "report_id"
        ]
      },
      "ReportIncorrectActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ReportIncorrectResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "NavigateLotResult": {
        "type": "object",
        "properties": {
          "lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "lot_name": {
            "type": "string"
          },
          "destination_lat": {
            "type": "number"
          },
          "destination_lng": {
            "type": "number"
          },
          "google_maps_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "lot_id",
          "lot_name",
          "destination_lat",
          "destination_lng",
          "google_maps_url"
        ]
      },
      "NavigateLotActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NavigateLotResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ShareLotResult": {
        "type": "object",
        "properties": {
          "lot_id": {
            "type": "string",
            "format": "uuid"
          },
          "share_url": {
            "type": "string",
            "format": "uri"
          },
          "share_text": {
            "type": "string"
          }
        },
        "required": [
          "lot_id",
          "share_url",
          "share_text"
        ]
      },
      "ShareLotActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ShareLotResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileRequestOtpData": {
        "type": "object",
        "properties": {
          "otpRequested": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "expiresInSeconds": {
            "type": "integer",
            "examples": [
              600
            ]
          }
        },
        "required": [
          "otpRequested",
          "email",
          "expiresInSeconds"
        ]
      },
      "MobileRequestOtpResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileRequestOtpData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileRequestOtpBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "maxLength": 254,
            "format": "email"
          }
        },
        "required": [
          "email"
        ]
      },
      "MobileVerifyOtpData": {
        "type": "object",
        "properties": {
          "authUserId": {
            "type": "string",
            "format": "uuid"
          },
          "appUserId": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "accessToken": {
            "type": "string"
          },
          "refreshToken": {
            "type": "string"
          }
        },
        "required": [
          "authUserId",
          "appUserId",
          "accessToken",
          "refreshToken"
        ]
      },
      "MobileVerifyOtpResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileVerifyOtpData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileVerifyOtpBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "maxLength": 254,
            "format": "email"
          },
          "otp": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          }
        },
        "required": [
          "email",
          "otp"
        ]
      },
      "MobileSignUpData": {
        "type": "object",
        "properties": {
          "authUserId": {
            "type": "string",
            "format": "uuid"
          },
          "appUserId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "authUserId",
          "appUserId"
        ]
      },
      "MobileSignUpResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSignUpData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSignUpBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "maxLength": 254,
            "format": "email"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          },
          "displayName": {
            "type": "string",
            "maxLength": 64
          },
          "referralCode": {
            "type": "string",
            "maxLength": 32
          }
        },
        "required": [
          "email",
          "password"
        ]
      },
      "MobileSignOutData": {
        "type": "object",
        "properties": {
          "signedOut": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "signedOut"
        ]
      },
      "MobileSignOutResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSignOutData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSignOutBodyInner": {
        "type": "object",
        "properties": {
          "revoke_refresh_token": {
            "type": "boolean"
          }
        }
      },
      "MobileSaveHistoryData": {
        "type": "object",
        "properties": {
          "saved": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "saved"
        ]
      },
      "MobileSaveHistoryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSaveHistoryData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSaveHistoryBody": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 200,
            "examples": [
              "渋谷 屋根あり"
            ]
          },
          "lat": {
            "type": "number",
            "examples": [
              35.658
            ]
          },
          "lng": {
            "type": "number",
            "examples": [
              139.7016
            ]
          }
        }
      },
      "AiSearchResultItem": {
        "type": "object",
        "properties": {
          "lotId": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "distanceMeters": {
            "type": [
              "number",
              "null"
            ]
          },
          "hourlyFeeMinor": {
            "type": [
              "integer",
              "null"
            ]
          },
          "dailyFeeMinor": {
            "type": [
              "integer",
              "null"
            ]
          },
          "rating": {
            "type": [
              "number",
              "null"
            ]
          },
          "ratingCount": {
            "type": "integer"
          },
          "isOpen": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "isSaved": {
            "type": "boolean"
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "required": [
          "lotId",
          "name",
          "address",
          "distanceMeters",
          "hourlyFeeMinor",
          "dailyFeeMinor",
          "rating",
          "ratingCount",
          "isOpen",
          "isSaved",
          "thumbnailUrl"
        ]
      },
      "AiSearchExtractedFilters": {
        "type": [
          "object",
          "null"
        ],
        "properties": {
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "渋谷",
                "屋根付き"
              ]
            ]
          },
          "maxPricePerHour": {
            "type": [
              "integer",
              "null"
            ],
            "examples": [
              50000
            ]
          },
          "roof": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "open24h": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "vehicleType": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "sedan",
              "kei",
              "minivan",
              "suv",
              "truck"
            ],
            "examples": [
              "sedan"
            ]
          },
          "radiusM": {
            "type": [
              "integer",
              "null"
            ],
            "examples": [
              1000
            ]
          },
          "sort": {
            "type": "string",
            "enum": [
              "distance",
              "price_asc",
              "price_desc",
              "rating",
              "availability",
              "recommended"
            ],
            "examples": [
              "distance"
            ]
          }
        },
        "required": [
          "keywords",
          "maxPricePerHour",
          "roof",
          "open24h",
          "vehicleType",
          "radiusM",
          "sort"
        ]
      },
      "MobileAiSearchQueryData": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiSearchResultItem"
            }
          },
          "interpretation": {
            "type": "string",
            "examples": [
              "渋谷駅周辺の屋根付き駐車場を検索しています"
            ]
          },
          "queryId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "parsed",
              "need_info",
              "error"
            ]
          },
          "replyMessage": {
            "type": "string",
            "description": "status が need_info / error の場合の返答メッセージ",
            "examples": [
              "どのエリアで探しますか？"
            ]
          },
          "extractedFilters": {
            "$ref": "#/components/schemas/AiSearchExtractedFilters"
          }
        },
        "required": [
          "items",
          "interpretation",
          "queryId",
          "status",
          "extractedFilters"
        ]
      },
      "MobileAiSearchQueryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileAiSearchQueryData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileAiSearchQueryBody": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "examples": [
              "渋谷駅から徒歩5分以内の屋根付き駐車場"
            ]
          },
          "lat": {
            "type": "number",
            "examples": [
              35.658
            ]
          },
          "lng": {
            "type": "number",
            "examples": [
              139.7016
            ]
          },
          "radius_m": {
            "type": "integer",
            "examples": [
              1500
            ]
          }
        },
        "required": [
          "query"
        ]
      },
      "FieldSuggestionSubmitResponse": {
        "type": "object",
        "properties": {
          "suggestion_id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "00000000-0000-0000-0000-000000000000"
            ]
          },
          "confirms_n": {
            "type": "integer"
          },
          "promoted": {
            "type": "boolean"
          }
        },
        "required": [
          "suggestion_id",
          "confirms_n",
          "promoted"
        ]
      },
      "FieldSuggestionSubmitBody": {
        "type": "object",
        "properties": {
          "parking_lot_id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "00000000-0000-0000-0000-000000000000"
            ]
          },
          "field_name": {
            "type": "string",
            "enum": [
              "name",
              "address",
              "total_spaces",
              "structure",
              "entry_method",
              "receipt_available",
              "pricing_notes",
              "vehicle_type_max",
              "contact_phone",
              "contact_email",
              "contact_url",
              "capacity_disabled",
              "capacity_kei",
              "capacity_regular",
              "capacity_oversized",
              "capacity_motorcycle",
              "capacity_ev",
              "entry_difficulty",
              "entry_exit_locations"
            ]
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "null"
              },
              {
                "type": "null"
              }
            ]
          },
          "note": {
            "type": "string",
            "maxLength": 500
          }
        },
        "required": [
          "parking_lot_id",
          "field_name",
          "value"
        ]
      },
      "FieldSuggestionConfirmResponse": {
        "type": "object",
        "properties": {
          "suggestion_id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "00000000-0000-0000-0000-000000000000"
            ]
          },
          "confirms_n": {
            "type": "integer"
          },
          "inserted": {
            "type": "boolean"
          }
        },
        "required": [
          "suggestion_id",
          "confirms_n",
          "inserted"
        ]
      },
      "MobileReviewCreateData": {
        "type": "object",
        "properties": {
          "lotId": {
            "type": "string",
            "format": "uuid"
          },
          "newAverageRating": {
            "type": [
              "number",
              "null"
            ],
            "examples": [
              4.2
            ]
          },
          "reviewCount": {
            "type": "integer",
            "examples": [
              42
            ]
          },
          "userReviewId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "lotId",
          "newAverageRating",
          "reviewCount",
          "userReviewId"
        ]
      },
      "MobileReviewCreateResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileReviewCreateData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileReviewCreateBody": {
        "type": "object",
        "properties": {
          "parking_lot_id": {
            "type": "string",
            "format": "uuid",
            "examples": [
              "00000000-0000-0000-0000-000000000000"
            ]
          },
          "rating": {
            "type": "integer",
            "minimum": 1,
            "maximum": 5
          },
          "title": {
            "type": "string",
            "maxLength": 100,
            "examples": [
              "清潔で使いやすい"
            ]
          },
          "body": {
            "type": "string",
            "minLength": 10,
            "maxLength": 2000
          },
          "tag_codes": {
            "type": "array",
            "items": {
              "type": "string",
              "maxLength": 64
            }
          },
          "photo_asset_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "required": [
          "parking_lot_id",
          "rating",
          "body"
        ]
      },
      "DestinationRecordResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "lat": {
            "type": [
              "number",
              "null"
            ]
          },
          "lng": {
            "type": [
              "number",
              "null"
            ]
          },
          "placeId": {
            "type": [
              "string",
              "null"
            ]
          },
          "useCount": {
            "type": "integer"
          },
          "lastUsedAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "address",
          "lat",
          "lng",
          "placeId",
          "useCount",
          "lastUsedAt"
        ]
      },
      "DestinationRecordResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/DestinationRecordResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffVehiclesAddAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileVehiclesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffVehiclesUpdateAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileVehiclesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffVehiclesDeleteAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileVehiclesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffVehiclesSetDefaultAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileVehiclesData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffProfileUpdateAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffProfileMainData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffAvatarUploadData": {
        "type": "object",
        "properties": {
          "avatar_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          }
        },
        "required": [
          "avatar_url"
        ]
      },
      "BffAvatarUploadAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffAvatarUploadData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffDataExportRequestData": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "format": "uuid"
          },
          "estimated_minutes": {
            "type": "integer"
          }
        },
        "required": [
          "request_id",
          "estimated_minutes"
        ]
      },
      "BffRequestDataExportAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffDataExportRequestData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "BffDeleteAccountData": {
        "type": "object",
        "properties": {
          "scheduled_deletion_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "scheduled_deletion_at"
        ]
      },
      "BffDeleteAccountAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/BffDeleteAccountData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSavedRemoveAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SavedViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileNotificationsPreferencesUpdateAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationsPreferencesViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileNotificationsMarkReadAction": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationsViewData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "CreateSearchPresetResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "preset_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "radius_m": {
                      "type": "integer"
                    },
                    "fee_max_minor": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "label"
                        ]
                      }
                    },
                    "is_default": {
                      "type": "boolean"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "preset_id",
                    "name",
                    "radius_m",
                    "fee_max_minor",
                    "features",
                    "is_default",
                    "created_at"
                  ]
                }
              },
              "can_add_more": {
                "type": "boolean"
              }
            },
            "required": [
              "items",
              "can_add_more"
            ]
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "CreateSearchPresetBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "プリセット名"
          },
          "radius_m": {
            "type": "integer",
            "minimum": 100,
            "maximum": 50000,
            "description": "検索半径（メートル）"
          },
          "fee_max_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "最大料金（最小通貨単位）。null で上限なし"
          },
          "required_feature_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 10,
            "default": [],
            "description": "必須設備コード一覧"
          },
          "is_default": {
            "type": "boolean",
            "default": false,
            "description": "デフォルトプリセットにするか"
          }
        },
        "required": [
          "name",
          "radius_m"
        ]
      },
      "UpdateSearchPresetResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "preset_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "radius_m": {
                      "type": "integer"
                    },
                    "fee_max_minor": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "label"
                        ]
                      }
                    },
                    "is_default": {
                      "type": "boolean"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "preset_id",
                    "name",
                    "radius_m",
                    "fee_max_minor",
                    "features",
                    "is_default",
                    "created_at"
                  ]
                }
              },
              "can_add_more": {
                "type": "boolean"
              }
            },
            "required": [
              "items",
              "can_add_more"
            ]
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "UpdateSearchPresetBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50,
            "description": "プリセット名"
          },
          "radius_m": {
            "type": "integer",
            "minimum": 100,
            "maximum": 50000,
            "description": "検索半径（メートル）"
          },
          "fee_max_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "最大料金（最小通貨単位）"
          },
          "required_feature_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 10,
            "description": "必須設備コード一覧"
          }
        }
      },
      "DeleteSearchPresetResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "preset_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "radius_m": {
                      "type": "integer"
                    },
                    "fee_max_minor": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "label"
                        ]
                      }
                    },
                    "is_default": {
                      "type": "boolean"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "preset_id",
                    "name",
                    "radius_m",
                    "fee_max_minor",
                    "features",
                    "is_default",
                    "created_at"
                  ]
                }
              },
              "can_add_more": {
                "type": "boolean"
              }
            },
            "required": [
              "items",
              "can_add_more"
            ]
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SetDefaultSearchPresetResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "preset_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "name": {
                      "type": "string"
                    },
                    "radius_m": {
                      "type": "integer"
                    },
                    "fee_max_minor": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "features": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "code",
                          "label"
                        ]
                      }
                    },
                    "is_default": {
                      "type": "boolean"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "preset_id",
                    "name",
                    "radius_m",
                    "fee_max_minor",
                    "features",
                    "is_default",
                    "created_at"
                  ]
                }
              },
              "can_add_more": {
                "type": "boolean"
              }
            },
            "required": [
              "items",
              "can_add_more"
            ]
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "PremiumVerifyIapData": {
        "type": "object",
        "properties": {
          "subscription_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan": {
            "type": "string",
            "description": "プランコード"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "subscription_id",
          "plan",
          "expires_at",
          "is_active"
        ]
      },
      "VerifyIapActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PremiumVerifyIapData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "VerifyIapActionBody": {
        "type": "object",
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "ios",
              "android"
            ],
            "description": "購入プラットフォーム"
          },
          "receipt": {
            "type": "string",
            "minLength": 1,
            "description": "ios: StoreKit2 の JWS (signedTransactionInfo)、android: purchaseToken"
          },
          "product_id": {
            "type": "string",
            "minLength": 1,
            "description": "subscription_plans.code に対応する productId / subscriptionId"
          },
          "transaction_id": {
            "type": "string",
            "description": "ios のみ。StoreKit2 の transactionId（省略時は receipt から抽出）"
          }
        },
        "required": [
          "platform",
          "receipt",
          "product_id"
        ]
      },
      "PremiumCancelData": {
        "type": "object",
        "properties": {
          "subscription_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan": {
            "type": [
              "string",
              "null"
            ]
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "is_active": {
            "type": "boolean"
          }
        },
        "required": [
          "subscription_id",
          "plan",
          "expires_at",
          "is_active"
        ]
      },
      "CancelSubscriptionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PremiumCancelData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ApplyCouponData": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "discount_amount": {
            "type": [
              "integer",
              "null"
            ],
            "description": "割引額（%）。fixed_days の場合は null。"
          },
          "new_expires_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "fixed_days の場合は延長後の期限。percentage の場合は null。"
          }
        },
        "required": [
          "success",
          "discount_amount",
          "new_expires_at"
        ]
      },
      "ApplyCouponResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ApplyCouponData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "ApplyCouponBody": {
        "type": "object",
        "properties": {
          "coupon_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 32,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "クーポンコード（大文字英数字 / ハイフン / アンダースコア）"
          }
        },
        "required": [
          "coupon_code"
        ]
      },
      "PremiumStartTrialData": {
        "type": "object",
        "properties": {
          "subscription_id": {
            "type": "string",
            "format": "uuid"
          },
          "plan_code": {
            "type": "string"
          },
          "plan_name": {
            "type": "string"
          },
          "trial_ends_at": {
            "type": "string"
          },
          "trial_days": {
            "type": "integer"
          }
        },
        "required": [
          "subscription_id",
          "plan_code",
          "plan_name",
          "trial_ends_at",
          "trial_days"
        ]
      },
      "StartTrialActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PremiumStartTrialData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "StartTrialActionBody": {
        "type": "object",
        "properties": {
          "plan_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80,
            "description": "明示指定するプランコード。省略時は app_users.pricing_variant + monthly から自動解決"
          },
          "billing_period": {
            "type": "string",
            "enum": [
              "monthly",
              "yearly"
            ],
            "default": "monthly",
            "description": "プラン billing_period。plan_code 指定時は無視。デフォルト monthly"
          }
        }
      },
      "LotRegistrationResultData": {
        "type": "object",
        "properties": {
          "application_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "submitted"
            ]
          },
          "next_steps": {
            "type": "string",
            "description": "審査後の流れの説明文（クライアントがそのまま表示）"
          }
        },
        "required": [
          "application_id",
          "status",
          "next_steps"
        ]
      },
      "SubmitLotRegistrationResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LotRegistrationResultData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "SubmitLotRegistrationBody": {
        "type": "object",
        "properties": {
          "lot_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "駐車場名"
          },
          "address": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "住所"
          },
          "lat": {
            "type": "number",
            "minimum": -90,
            "maximum": 90,
            "description": "緯度"
          },
          "lng": {
            "type": "number",
            "minimum": -180,
            "maximum": 180,
            "description": "経度"
          },
          "capacity": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1,
            "maximum": 9999,
            "description": "収容台数（任意）"
          },
          "hourly_fee_minor": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "description": "1 時間料金（最小通貨単位、任意）"
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "maxItems": 20,
            "default": [],
            "description": "設備コード一覧（任意）"
          },
          "photos": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "maxItems": 5,
            "default": [],
            "description": "写真アセット UUID 一覧（最大 5 枚、任意）"
          },
          "owner_contact_email": {
            "type": "string",
            "maxLength": 255,
            "format": "email",
            "description": "オーナー連絡先メール"
          },
          "owner_contact_phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 20,
            "description": "オーナー連絡先電話番号（任意）"
          }
        },
        "required": [
          "lot_name",
          "address",
          "lat",
          "lng",
          "owner_contact_email"
        ]
      },
      "MobileSubmitTicketData": {
        "type": "object",
        "properties": {
          "ticketId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "open"
            ]
          }
        },
        "required": [
          "ticketId",
          "status"
        ]
      },
      "MobileSubmitTicketResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileSubmitTicketData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileSubmitTicketBody": {
        "type": "object",
        "properties": {
          "category_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "examples": [
              "billing"
            ]
          },
          "subject": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "examples": [
              "支払いについて"
            ]
          },
          "body": {
            "type": "string",
            "minLength": 1,
            "maxLength": 5000,
            "examples": [
              "支払い処理に問題が発生しました。"
            ]
          },
          "related_session_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "related_lot_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          }
        },
        "required": [
          "category_code",
          "subject",
          "body"
        ]
      },
      "MobileClearSearchHistoryData": {
        "type": "object",
        "properties": {
          "cleared": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "cleared"
        ]
      },
      "MobileClearSearchHistoryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileClearSearchHistoryData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileClearSearchHistoryBody": {
        "type": "object",
        "properties": {}
      },
      "MobileRecordPermissionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/PermissionsData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileRecordPermissionBody": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "location",
              "notification",
              "camera",
              "gallery"
            ],
            "examples": [
              "location"
            ]
          },
          "granted": {
            "type": "boolean",
            "examples": [
              true
            ]
          },
          "recorded_at": {
            "type": "string",
            "format": "date-time",
            "description": "クライアント側の記録日時（省略時はサーバー時刻）"
          }
        },
        "required": [
          "code",
          "granted"
        ]
      },
      "MobileReportErrorData": {
        "type": "object",
        "properties": {
          "reportId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "reportId"
        ]
      },
      "MobileReportErrorResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobileReportErrorData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileReportErrorBody": {
        "type": "object",
        "properties": {
          "error_code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "examples": [
              "render_error"
            ]
          },
          "message": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 2000,
            "examples": [
              "Widget build failed"
            ]
          },
          "stack": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 10000,
            "description": "スタックトレース"
          },
          "context": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {},
            "description": "追加コンテキスト（route / screen / device 情報等）"
          }
        },
        "required": [
          "error_code"
        ]
      },
      "MobilePushTokenRegisterData": {
        "type": "object",
        "properties": {
          "registered": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "常に true（受理を表す）"
          },
          "token_id": {
            "type": "string",
            "format": "uuid",
            "description": "user_push_tokens.id"
          }
        },
        "required": [
          "registered",
          "token_id"
        ]
      },
      "MobilePushTokenRegisterResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/MobilePushTokenRegisterData"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobilePushTokenRegisterBody": {
        "type": "object",
        "properties": {
          "device_token": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096,
            "description": "FCM token (Android) または APNs device token (iOS)",
            "examples": [
              "fcm-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            ]
          },
          "platform": {
            "type": "string",
            "enum": [
              "ios",
              "android",
              "web"
            ],
            "description": "デバイス種別",
            "examples": [
              "android"
            ]
          },
          "app_version": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 32,
            "description": "クライアント側のアプリバージョン (semver)。X-App-Version ヘッダでも取得可。",
            "examples": [
              "1.2.3"
            ]
          },
          "locale": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 32,
            "description": "BCP47 ロケールタグ。push 通知の i18n に利用予定。",
            "examples": [
              "ja"
            ]
          },
          "device_id": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 128,
            "description": "端末固有 ID（Android: ANDROID_ID / iOS: identifierForVendor 等）"
          }
        },
        "required": [
          "device_token",
          "platform"
        ]
      },
      "AppReviewDispatchedResult": {
        "type": "object",
        "properties": {
          "prompt_id": {
            "type": "string",
            "format": "uuid"
          },
          "dispatched_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "prompt_id",
          "dispatched_at"
        ]
      },
      "AppReviewDispatchedActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AppReviewDispatchedResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "AppReviewSubmittedResult": {
        "type": "object",
        "properties": {
          "prompt_id": {
            "type": "string",
            "format": "uuid"
          },
          "submitted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "prompt_id",
          "submitted_at"
        ]
      },
      "AppReviewSubmittedActionResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AppReviewSubmittedResult"
          },
          "ui_config": {
            "$ref": "#/components/schemas/UiConfig"
          },
          "navigation": {
            "$ref": "#/components/schemas/NavigationHint"
          },
          "states": {
            "$ref": "#/components/schemas/ViewStates"
          },
          "fallback_behavior": {
            "$ref": "#/components/schemas/FallbackBehavior"
          },
          "meta": {
            "$ref": "#/components/schemas/ActionMeta"
          }
        },
        "required": [
          "data",
          "navigation",
          "fallback_behavior",
          "meta"
        ]
      },
      "MobileI18nBundle": {
        "type": "object",
        "properties": {
          "lang": {
            "type": "string",
            "examples": [
              "ja"
            ]
          },
          "version": {
            "type": "string",
            "description": "全 row の md5 hash。ETag と一致させる",
            "examples": [
              "9c7f1a3d..."
            ]
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "examples": [
              "2026-04-23T12:34:56.789Z"
            ]
          },
          "messages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "key → value の辞書。Flutter 側 resolver がこれを引く",
            "examples": [
              {
                "common.retry": "再試行",
                "common.cancel": "キャンセル"
              }
            ]
          }
        },
        "required": [
          "lang",
          "version",
          "updated_at",
          "messages"
        ]
      },
      "TelemetryAck": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          },
          "received_at": {
            "type": "string",
            "format": "date-time"
          },
          "event_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "ok",
          "received_at",
          "event_id"
        ]
      },
      "MobileTelemetryEventInput": {
        "type": "object",
        "properties": {
          "event": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "props": {
            "type": "object",
            "additionalProperties": {}
          },
          "ts": {
            "type": "string",
            "format": "date-time"
          },
          "session_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        "required": [
          "event",
          "ts",
          "session_id"
        ]
      },
      "MobileTelemetryEventsBody": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MobileTelemetryEventInput"
            },
            "minItems": 1,
            "maxItems": 50
          }
        },
        "required": [
          "events"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/.well-known/apple-app-site-association": {
      "get": {
        "tags": [
          "well-known"
        ],
        "summary": "iOS Universal Links 設定 / iOS Universal Links Config",
        "description": "Apple が Universal Links 検証時に取得する JSON。\n\n- 認証不要・公開エンドポイント。\n- Content-Type は application/json 固定。\n- Cache-Control: public, max-age=86400（24 時間）。\n- `appIDs` は環境変数 `IOS_APP_ID`（形式: TEAMID.co.jp.parky.app）から取得。\n  または `IOS_APP_TEAM_ID` + `IOS_APP_BUNDLE_ID` を個別に指定（優先）。\n  すべて未設定時は `details` と `webcredentials.apps` を空配列にして返す。\n- 対応パス: /parking-lots/*, /parking-sessions/*, /share/parking/*, /articles/*, /auth/*",
        "responses": {
          "200": {
            "description": "Apple App Site Association",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppleAppSiteAssociation"
                }
              }
            }
          }
        },
        "operationId": "webWellKnownAppleAppSiteAssociationList"
      }
    },
    "/.well-known/assetlinks.json": {
      "get": {
        "tags": [
          "well-known"
        ],
        "summary": "Android App Links 設定 / Android App Links Config",
        "description": "Android が App Links 検証時に取得する JSON。\n\n- 認証不要・公開エンドポイント。\n- Content-Type は application/json 固定。\n- Cache-Control: public, max-age=86400（24 時間）。\n- `package_name` は環境変数 `ANDROID_PACKAGE_NAME` から取得。\n- `sha256_cert_fingerprints` は環境変数 `ANDROID_APP_CERT_FINGERPRINTS`（カンマ区切り）から取得。\n  未設定時は空配列 `[]`（Android 側は App Links 検出しないだけで 200）。",
        "responses": {
          "200": {
            "description": "Digital Asset Links",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetLinksResponse"
                }
              }
            }
          }
        },
        "operationId": "webWellKnownAssetlinksList"
      }
    },
    "/v1/mobile/views/boot": {
      "get": {
        "tags": [
          "スプラッシュ画面 / Splash Screen"
        ],
        "summary": "スプラッシュ画面開始 / Start Splash Screen",
        "description": "Splash 画面でこの 1 本を叩くだけでアプリの初期化に必要なデータが揃う。\n- `data.me`: ログインユーザーの基本情報\n- `data.codes`: コードマスター全件\n- `data.app_config`: アプリ設定 JSON\n- `data.i18n`: i18n bundle の lang + version（client はこの version を手元キャッシュと突合し、一致すれば bundle 再取得不要）\n\n### Splash での並列取得戦略\nclient は Splash で本 endpoint と `/v1/mobile/i18n/bundle` を `Future.wait` で並列に叩く想定。\nbundle 側は If-None-Match (ETag) で 304 を返すので、変更なしなら実質ゼロコスト。\n`data.i18n.version` が手元キャッシュと一致する場合は bundle endpoint 自体をスキップしても良い。\n詳細は `docs/mobile-app/bootstrap-flow.html` を参照。\n\n### envelope\nレスポンスは `{ data, fallback_behavior, meta, ... }` 形式。\n- `meta.min_app_version`: この endpoint が要求する最小 client version\n- `fallback_behavior`: 到達不能時 / version mismatch 時の client 挙動規約\n- `X-App-Version` ヘッダを付けると server 側で version check を行う",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Client app semver",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "クライアントが保持している composite ETag。サーバ側 (ui_layer + codes + i18n の hash) と一致すれば 304 を返却",
              "examples": [
                "\"boot.ui_abc.codes_def.i18n_ghi\""
              ]
            },
            "required": false,
            "name": "if-none-match",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "起動データ (静的 catalog または me 系のいずれかが更新)",
            "headers": {
              "ETag": {
                "description": "composite ETag: boot.<ui_version>.<codes_version>.<i18n_version>。クライアントは次回 If-None-Match に渡す",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "private, max-age=0, must-revalidate (per-user response のため private)",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileBootResponse"
                }
              }
            }
          },
          "304": {
            "description": "If-None-Match が現在の composite ETag と一致 (静的 catalog 変更なし、body なし)",
            "headers": {
              "ETag": {
                "description": "現在の composite ETag (一致確認用に再送)",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsBootList"
      }
    },
    "/v1/mobile/views/home-feed": {
      "get": {
        "tags": [
          "ホーム画面 / Home Screen"
        ],
        "summary": "ホーム画面開始 / Start Home Screen",
        "description": "ホームマップ画面で必要なデータを 1 本で返す。\n- `data.lots`: 近隣駐車場（`nearby_parking_lots` RPC）\n- `data.sponsors`: 近隣スポンサー施設（`nearby_sponsors` RPC、地理的ピン）\n- `data.active_session`: アクティブな駐車セッション（なければ null）\n- `data.banners`: ホーム画面上部に表示するバナー（`home_banners` テーブル）\n- `data.gamification`: ゲーミフィケーションスロット（チュートリアルミッション or 一般進捗 or hidden）\n\n### キャッシュ\nlots / sponsors / banners は KV 60s SWR。active_session / gamification はユーザー固有のためキャッシュなし。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "クライアントが保持している composite ETag。サーバ側 (ui_layer + codes + i18n + banners + nearby feed の hash) と一致すれば 304 を返却",
              "examples": [
                "\"home.banners_a1b2c3d4.codes_def.feed_ef01.i18n_ghi.ui_jkl\""
              ]
            },
            "required": false,
            "name": "if-none-match",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "ホームフィード (静的 catalog または近隣 lots / banners が更新)",
            "headers": {
              "ETag": {
                "description": "composite ETag: home.<banners_hash>.<codes_version>.<feed_hash>.<i18n_version>.<ui_version>。次回 If-None-Match に渡す",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileHomeFeed"
                }
              }
            }
          },
          "304": {
            "description": "If-None-Match が現在の composite ETag と一致 (静的 catalog + 地理バケット + banners 全て変更なし、body なし)",
            "headers": {
              "ETag": {
                "description": "現在の composite ETag (一致確認用に再送)",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsHomeFeedList"
      }
    },
    "/v1/mobile/views/lot-detail/{id}/reviews": {
      "get": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場詳細画面開始 / Start Lot Detail Screen",
        "description": "駐車場詳細レビュータブ用。`status='approved'` のレビューのみ返す。\n`cursor`: 前ページ最終レビューの created_at（ISO 8601）。初回は省略。\n`limit`: 最大 50、デフォルト 20。\n`summary.distribution` はレーティング別件数（r1..r5）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "レビュー一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileLotReviewsView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsLotDetailReviewsList"
      }
    },
    "/v1/mobile/views/lot-detail/{id}": {
      "get": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場詳細画面開始 / Start Lot Detail Screen",
        "description": "lot + reviews + pricing_rules + nearby + is_open_now を 1 往復で返す。\nKV 300s SWR + composite ETag（ui_layer + codes + i18n + lot.id + lot.updated_at の hash）。\n\n`states.empty` は reviews が 0 件の時だけ `illustration: \"empty_reviews\"` を返す hint。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "highlight_max_price",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "highlight_roof_only",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "highlight_open_24h",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "highlight_tags",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "highlight_vehicle_type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "クライアントが保持している composite ETag。サーバ側 (ui_layer + codes + i18n + lot.id + lot.updated_at) と一致すれば 304 を返却",
              "examples": [
                "\"lot.codes_def.i18n_ghi.lot_a1b2c3d4.ts_1729900000.ui_jkl\""
              ]
            },
            "required": false,
            "name": "if-none-match",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "駐車場詳細 (静的 catalog または lot 自身が更新)",
            "headers": {
              "ETag": {
                "description": "composite ETag: lot.<codes_version>.<i18n_version>.<lot_id_short>.<updated_at_epoch>.<ui_version>。次回 If-None-Match に渡す",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileLotDetail"
                }
              }
            }
          },
          "304": {
            "description": "If-None-Match が現在の composite ETag と一致 (静的 catalog + lot.updated_at 全て変更なし、body なし)",
            "headers": {
              "ETag": {
                "description": "現在の composite ETag (一致確認用に再送)",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsLotDetailGet"
      }
    },
    "/v1/mobile/views/premium": {
      "get": {
        "tags": [
          "プレミアム画面 / Premium Screen"
        ],
        "summary": "プレミアム画面開始 / Start Premium Screen",
        "description": "プレミアム画面に必要なデータを 1 往復で返す。\n\n`data.current_subscription` が null なら未加入、navigation で plan 選択 CTA を示す。\n`validation` にクーポンコード入力用の rule を載せる（フォーム post は別 endpoint）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "プレミアムデータ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobilePremiumView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsPremiumList"
      }
    },
    "/v1/mobile/views/parking-session/{id}": {
      "get": {
        "tags": [
          "駐車中詳細画面 / Parking Session Detail Screen"
        ],
        "summary": "駐車中詳細画面開始 / Start Parking Session Detail Screen",
        "description": "駐車中セッションのリアルタイム情報を返す。\nmeta.realtime に Supabase Realtime 購読契約を含む（Flutter 側が直接購読）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "駐車中詳細 View",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParkingSessionViewResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsParkingSessionGet"
      }
    },
    "/v1/mobile/views/parking-sessions": {
      "get": {
        "tags": [
          "駐車セッション一覧画面 / Parking Sessions Screen"
        ],
        "summary": "駐車セッション一覧画面開始 / Start Parking Sessions Screen",
        "description": "自分の駐車セッション一覧を cursor-based ページングで返す。\n?status=active|completed|cancelled|all / ?cursor=xxx / ?limit=20",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "completed",
                "cancelled",
                "all"
              ]
            },
            "required": false,
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d+$"
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "駐車セッション一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ParkingSessionsListViewResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsParkingSessionsList"
      }
    },
    "/v1/mobile/views/auth-config": {
      "get": {
        "tags": [
          "ログイン画面 / Login Screen"
        ],
        "summary": "ログイン画面開始 / Start Login Screen",
        "description": "ログイン画面を表示する前に呼ぶ preflight API。\n- `data.providers`: 有効な認証プロバイダ一覧（Flutter はこのリストでボタンを出す）\n- `data.termsUrl` / `data.privacyPolicyUrl`: 利用規約・プライバシーポリシーの URL\n- `data.welcome_message_code`: ウェルカムメッセージの i18n キー（Flutter が i18n bundle で解決）\n\n### 認証\n不要。アプリ起動直後でも呼べる。\n\nFALLBACK_BOOT: ネットワークエラー時はエラー画面表示。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "Auth 設定",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileAuthConfigView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsAuthConfigList"
      }
    },
    "/v1/mobile/views/search-results": {
      "get": {
        "tags": [
          "検索結果画面 / Search Results Screen"
        ],
        "summary": "検索結果画面開始 / Start Search Results Screen",
        "description": "現在地（lat/lng）から radius_m 以内の駐車場を指定ソートで返す。\n\n### 基本\n- `q`: キーワード（名称・住所の部分一致）\n- `lat` / `lng`: 現在地（必須）\n- `radius_m`: 検索半径（デフォルト 1000m、最大 50000m）\n- `sort`: `distance` / `price_asc` / `price_desc` / `rating` / `availability` / `recommended`\n- `cursor` / `limit`: ページング（offset ベース、limit 最大 50）\n\n### フィルタ\n- `tags`: カンマ区切りのタグ slug（例: `roof,indoor,ev_charger`）\n- `operator_codes`: カンマ区切りの operator_code（例: `times24,repark`）\n- `vehicle_type`: `sedan` / `kei` / `minivan` / `suv` / `truck`\n- `max_price_per_hour`: 時間単価の最大値（minor 単位）\n- `roof_only`: `true` で屋根あり駐車場のみ\n- `open_24h`: `true` で 24 時間営業のみ\n\n### 返却値\n各 item にはカード表示に必要な数値（rating / ratingCount / hourlyFeeMinor /\ndailyFeeMinor / distanceMeters / totalSpaces）とクライアントサイドソート用の\n正規化値が揃っている。`isSaved` でお気に入り判定。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "maxLength": 200,
              "examples": [
                "渋谷"
              ]
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "緯度（文字列）",
              "examples": [
                "35.6580"
              ]
            },
            "required": true,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "経度（文字列）",
              "examples": [
                "139.7016"
              ]
            },
            "required": true,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1000"
              ]
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "distance",
                "price_asc",
                "price_desc",
                "rating",
                "availability",
                "recommended"
              ],
              "examples": [
                "distance"
              ]
            },
            "required": false,
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "offset を文字列で保持"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "20"
              ]
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "roof,indoor"
              ]
            },
            "required": false,
            "name": "tags",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "times24,repark"
              ]
            },
            "required": false,
            "name": "operator_codes",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "sedan",
                "kei",
                "minivan",
                "suv",
                "truck"
              ]
            },
            "required": false,
            "name": "vehicle_type",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "50000"
              ]
            },
            "required": false,
            "name": "max_price_per_hour",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "true"
              ]
            },
            "required": false,
            "name": "roof_only",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "true"
              ]
            },
            "required": false,
            "name": "open_24h",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "検索結果",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchResultsView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchResultsList"
      }
    },
    "/v1/mobile/views/search/nearby-lots": {
      "get": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "検索画面開始 / Start Search Screen",
        "description": "PostGIS RPC `nearby_parking_lots` の戻り値をそのまま返す。\n\n- `lat` / `lng`: 中心座標（必須）\n- `radius_m`: 検索半径（デフォルト 1000m、最大 50000m）\n\n応答は集計・正規化を行わない thin wrapper。後続 Phase でランキングや\nisSaved など enrichment を加える可能性がある。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "35.6580"
              ]
            },
            "required": true,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "139.7016"
              ]
            },
            "required": true,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1000"
              ]
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "周辺駐車場（thin wrapper）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchNearbyLotsView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchNearbyLotsList"
      }
    },
    "/v1/mobile/views/search/nearby-places": {
      "get": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "検索画面開始 / Start Search Screen",
        "description": "PostGIS RPC `nearby_places` の戻り値をそのまま返す。\n\n- `lat` / `lng`: 中心座標（必須）\n- `lot_id`: 対象駐車場 UUID（place_discounts 提携情報を同梱するため必須）\n- `radius_m`: 検索半径（デフォルト 500m、最大 50000m）\n\n戻り順は RPC 規定（is_sponsored DESC → score DESC → distance_m ASC）。\nthin wrapper なので集計・正規化はしない。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "35.6580"
              ]
            },
            "required": true,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "139.7016"
              ]
            },
            "required": true,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "lot_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "500"
              ]
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "周辺施設（thin wrapper）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchNearbyPlacesView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchNearbyPlacesList"
      }
    },
    "/v1/mobile/views/search/places-in-bbox": {
      "get": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "検索画面開始 / Start Search Screen",
        "description": "PostGIS RPC `map_places_in_bbox` の戻り値をそのまま返す。\n\n- `min_lat` / `min_lng`: 南西角の座標（必須）\n- `max_lat` / `max_lng`: 北東角の座標（必須）\n\nthin wrapper なので集計・正規化はしない。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "35.6500"
              ]
            },
            "required": true,
            "name": "min_lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "139.7000"
              ]
            },
            "required": true,
            "name": "min_lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "35.6700"
              ]
            },
            "required": true,
            "name": "max_lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "139.7100"
              ]
            },
            "required": true,
            "name": "max_lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "bbox 内のマップピン（thin wrapper）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchPlacesInBboxView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchPlacesInBboxList"
      }
    },
    "/v1/mobile/views/search/nearby-sponsors": {
      "get": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "検索画面開始 / Start Search Screen",
        "description": "PostGIS RPC `nearby_sponsors` の戻り値をそのまま返す。\n\n- `lat` / `lng`: 中心座標（必須）\n- `radius_m`: 検索半径（デフォルト 1000m、最大 50000m）\n\nthin wrapper なので集計・正規化はしない。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "35.6580"
              ]
            },
            "required": true,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "139.7016"
              ]
            },
            "required": true,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1000"
              ]
            },
            "required": false,
            "name": "radius_m",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "周辺スポンサー（thin wrapper）",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchNearbySponsorsView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchNearbySponsorsList"
      }
    },
    "/v1/mobile/views/destinations": {
      "get": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "検索画面開始 / Start Search Screen",
        "description": "Wherto の目的地入力欄で使うオートコンプリート候補。\n- `q` 空: ユーザーの最近使用した目的地履歴のみ返す\n- `q` 指定: 履歴 + Mapbox Search Box suggest + parking_lots 名称/住所マッチを merge\n- `lat`/`lng` 指定時は Mapbox proximity バイアス + parking_lots 候補を距離順でソート\n- `session_token`: Mapbox billing session 管理用。クライアントが UUID を生成し、\n  その後の `POST /v1/mobile/actions/destinations` でも同じ値を使う\n\n`data.externalSource` が `mapbox` なら Mapbox 契約済、`lots_only` なら未契約 fallback。\n`data.sessionToken` はクライアントが `session_token` 未指定時にサーバー側で発行した値のエコーバック。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "required": false,
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 80
            },
            "required": false,
            "name": "session_token",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "目的地候補",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileDestinationsView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsDestinationsList"
      }
    },
    "/v1/mobile/views/ai-search": {
      "get": {
        "tags": [
          "AI 検索画面 / AI Search Screen"
        ],
        "summary": "AI検索画面開始 / Start AI Search Screen",
        "description": "AI 検索画面を表示する前に呼ぶ初期化 API。\n- `data.aiEnabled`: AI 検索機能が有効かどうか（Feature Flag）\n- `data.recentQueries`: ユーザーの最近の検索クエリ（最大 5 件）\n- `data.suggested_query_codes`: サジェストクエリの i18n キー一覧（Flutter が bundle で解決）\n- `data.disclaimer_message_code`: AI 結果の免責事項メッセージの i18n キー\n\n### 認証\nBearer JWT 任意。未ログイン時は recentQueries が空配列で返る。\n\nFALLBACK_DETAIL: ネットワークエラー時はキャッシュ表示。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "AI 検索画面初期データ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileAiSearchView"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsAiSearchList"
      }
    },
    "/v1/mobile/views/review-compose/{lot_id}": {
      "get": {
        "tags": [
          "レビュー投稿画面 / Review Compose Screen"
        ],
        "summary": "レビュー投稿画面開始 / Start Review Compose Screen",
        "description": "レビュー投稿画面を表示するための初期データを返す。\n- `data.lotId` / `data.lotName`: 対象駐車場\n- `data.existingReview`: 既にレビュー済みの場合は編集対象データ（なければ null）\n- `data.tagOptions`: タグ選択肢（code + label_code。label_code は `review_tag.{code}` 形式の i18n キー）\n- `data.prohibitedWords`: 禁止ワード一覧（クライアント側リアルタイムチェック用）\n- `validation`: rating(required) / body(min_length=10, max_length=2000) のフォームルール\n\n### 認証\nBearer JWT 必須。\n\nFALLBACK_DETAIL: ネットワークエラー時はキャッシュ表示。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "lot_id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "レビュー投稿画面データ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileReviewComposeView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsReviewComposeGet"
      }
    },
    "/v1/mobile/views/profile/vehicles": {
      "get": {
        "tags": [
          "車両管理画面 / Vehicles Screen"
        ],
        "summary": "車両管理画面開始 / Start Vehicles Screen",
        "description": "ユーザーの登録車両一覧と追加可否を返す。\n\n### canAddMore\n1ユーザーあたりの最大登録台数（10台）に達していると false を返す。\nFlutter 側はこのフラグで「+追加」ボタンの有効/無効を制御する。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "車両管理データ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffMobileProfileVehiclesView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsProfileVehiclesList"
      }
    },
    "/v1/mobile/views/profile/referrals": {
      "get": {
        "tags": [
          "紹介コード画面 / Referrals Screen"
        ],
        "summary": "紹介コード画面開始 / Start Referrals Screen",
        "description": "自分の紹介コード・成功/保留中件数・報酬合計・シェア文言を返す。\n\n### myCode\n未生成の場合はサーバーで自動生成してから返す（generate_user_referral_code RPC）。\n\n### shareMessage\nSNS / LINE 等へのシェア用に整形済みの文言。Flutter はそのままシェアシートに渡せる。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "紹介コードデータ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffMobileProfileReferralsView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsProfileReferralsList"
      }
    },
    "/v1/mobile/views/profile/gamification": {
      "get": {
        "tags": [
          "ゲーミフィケーション画面 / Gamification Screen"
        ],
        "summary": "ゲーミフィケーション画面開始 / Start Gamification Screen",
        "description": "現在レベル・EXP・進捗・獲得バッジ・進捗中バッジ・直近 EXP イベントを返す。\n\n### progress\n現在レベルから次レベルへの達成率（0〜100 の整数）。最大レベル到達時は 100。\n\n### recentExpEvents\n直近 10 件の EXP 獲得履歴。user_exp_events テーブルが未作成の場合は空配列。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "ゲーミフィケーションデータ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffMobileProfileGamificationView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsProfileGamificationList"
      }
    },
    "/v1/mobile/views/profile/settings": {
      "get": {
        "tags": [
          "設定画面 / Settings Screen"
        ],
        "summary": "設定画面開始 / Start Settings Screen",
        "description": "テーマ・通知・言語・マーケティング同意・データエクスポート可否・アカウント削除可否を返す。\n\n### deleteAccountEligible\nソフト削除済みでないユーザーは true。既に削除申請済みのユーザーは false。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "設定データ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffMobileProfileSettingsView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsProfileSettingsList"
      }
    },
    "/v1/mobile/views/profile": {
      "get": {
        "tags": [
          "プロフィール画面 / Profile Screen"
        ],
        "summary": "プロフィール画面開始 / Start Profile Screen",
        "description": "ユーザー基本情報・ゲーミフィケーション要約・統計を 1 往復で返す。\n\n### Realtime\n`meta.realtime` に app_users テーブルの Supabase Realtime 購読情報を含む。\nFlutter 側は Supabase Realtime で表示名・アバターのリアルタイム更新を受け取れる。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "プロフィールデータ",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffMobileProfileView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsProfileList"
      }
    },
    "/v1/mobile/views/saved": {
      "get": {
        "tags": [
          "保存済み駐車場画面 / Saved Lots Screen"
        ],
        "summary": "保存済み駐車場画面開始 / Start Saved Lots Screen",
        "description": "### 用途\nログイン中ユーザーが保存した駐車場一覧を返す。\n\n### ソート\n- `recent`（デフォルト）: 保存日時の降順\n- `name`: 駐車場名の昇順（カーソルは名前文字列）\n- `distance`: 現在地からの距離昇順（lat/lng 必須。未指定時は recent にフォールバック）\n\n### カーソルページング\ncursor は前ページ最後のレコードの sort 基準値（ISO datetime / 名前文字列 / 距離メートル）。\nnextCursor が null のとき最終ページ。\n\n### Realtime\nsave/remove action 後はクライアント側で NAVIGATION_REFRESH_CURRENT で再取得する。\nRealtime 購読は設けていない（保存操作は比較的少ない）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "recent",
                "name",
                "distance"
              ],
              "default": "recent"
            },
            "required": false,
            "name": "sort",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "number",
                "null"
              ],
              "minimum": -90,
              "maximum": 90
            },
            "required": false,
            "name": "lat",
            "in": "query"
          },
          {
            "schema": {
              "type": [
                "number",
                "null"
              ],
              "minimum": -180,
              "maximum": 180
            },
            "required": false,
            "name": "lng",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "保存済み駐車場一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSavedView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSavedList"
      }
    },
    "/v1/mobile/views/notifications/preferences": {
      "get": {
        "tags": [
          "通知設定画面 / Notifications Preferences Screen"
        ],
        "summary": "通知設定画面開始 / Start Notification Preferences Screen",
        "description": "### 用途\nログイン中ユーザーの通知設定（email / push / カテゴリ別）を返す。\n\n### カテゴリ\ncategories は codes テーブルの notif_type を全件返す。\n各カテゴリの enabled は user_notification_prefs.push_enabled\n(notif_type ごとに 1 行) で管理し、行が無い category は true (オプトアウト方式)。\n\n### 更新\n設定の更新は `PATCH /v1/mobile/actions/notifications/preferences/update` で行う。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "通知設定",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileNotificationsPreferencesView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsNotificationsPreferencesList"
      }
    },
    "/v1/mobile/views/notifications": {
      "get": {
        "tags": [
          "通知画面 / Notifications Screen"
        ],
        "summary": "通知画面開始 / Start Notifications Screen",
        "description": "### 用途\nログイン中ユーザーの通知一覧を返す。\n\n### タブフィルタ\n- `all`（デフォルト）: 全通知\n- `unread`: 未読のみ\n- `system`: システム通知のみ（category_code = 'system'）\n- `promo`: プロモーション通知のみ（category_code = 'promo'）\n\n### unreadCount\nunreadCount は tab フィルタに関わらず全未読件数を返す（バッジ表示用）。\n\n### Realtime\nmeta.realtime フィールドに Supabase Realtime の購読設定を返す。\nFlutter は Supabase client で user_notifications チャンネルを購読して\nINSERT/UPDATE を即時受信し、必要に応じて再取得する。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "unread",
                "system",
                "promo"
              ],
              "default": "all"
            },
            "required": false,
            "name": "tab",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "通知一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileNotificationsView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsNotificationsList"
      }
    },
    "/v1/mobile/views/parking-history": {
      "get": {
        "tags": [
          "駐車履歴画面 / Parking History Screen"
        ],
        "summary": "駐車履歴画面開始 / Start Parking History Screen",
        "description": "### 用途\nログイン中ユーザーの完了済み駐車セッション一覧を返す。\n\n### フィルタ\n- `from` / `to`: YYYY-MM-DD 形式（JST）。started_at で絞り込む。\n  両方省略した場合は全期間。\n\n### 集計値\n- `totalSpentMinor`: フィルタ期間内の総支払額（最小通貨単位）\n- `totalDurationMinutes`: フィルタ期間内の総駐車時間（分）\n- `sessionCount`: フィルタ期間内のセッション件数\n集計値はページングに関わらず全件を集計した値を返す。\n\n### canReview\n同ユーザーが同じ駐車場にまだレビューを書いていない場合 true を返す。\nレビュー投稿は `/v1/me/reviews` (POST) を使う（Wave 2 実装済み）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "required": false,
            "name": "from",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
            },
            "required": false,
            "name": "to",
            "in": "query"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "駐車履歴",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileParkingHistoryView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsParkingHistoryList"
      }
    },
    "/v1/mobile/views/search-presets": {
      "get": {
        "tags": [
          "検索プリセット画面 / Search Presets Screen"
        ],
        "summary": "検索プリセット画面開始 / Start Search Presets Screen",
        "description": "ユーザーが保存した検索プリセット一覧を返す。\n\n### data\n- `items`: プリセット配列（is_default 降順 → created_at 昇順）\n- `can_add_more`: 上限（10 件）に達していなければ true\n\n### validation\n作成フォームの field rule（name 必須 / radius_m 数値範囲）を含む。\nクライアントは validation を見てローカルバリデーションを実装する。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "検索プリセット View",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchPresetsView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchPresetsList"
      }
    },
    "/v1/mobile/views/lot-registration": {
      "get": {
        "tags": [
          "駐車場登録申請画面 / Lot Registration Screen"
        ],
        "summary": "駐車場登録申請画面開始 / Start Lot Registration Screen",
        "description": "駐車場登録申請フォームの設定を返す。\n\n### data\n- `form_config`: 必須フィールド / 任意フィールドの定義\n- `example_lots`: 入力例（ユーザーガイド用）\n- `faq_url` / `terms_url`: FAQ と利用規約 URL\n\n### validation\nフォームの field バリデーション rule を含む。\nクライアントは validation を見てサブミット前にローカルバリデーションを実施する。\n\n### 申請送信\n`POST /v1/mobile/actions/lot-registration/submit` で送信。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "駐車場登録申請フォーム View",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileLotRegistrationView"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsLotRegistrationList"
      }
    },
    "/v1/mobile/views/media-list": {
      "get": {
        "tags": [
          "メディア一覧画面 / Media List Screen"
        ],
        "summary": "メディア一覧画面開始 / Start Media List Screen",
        "description": "公開記事一覧を cursor-based ページングで返す。\n- `data.items`: 記事リスト（article_id / slug / title / summary / cover_image_url 等）\n- `data.next_cursor`: 次ページ取得用カーソル（null で最終ページ）\n- `data.categories`: 利用可能なカテゴリ一覧\n\n### 認証\n不要。匿名でも呼べる。\n\n### ページング\n`cursor` に前回レスポンスの `nextCursor` を渡して次ページを取得する。\ncursor が null の場合は先頭から取得。\n\nFALLBACK_FEED: ネットワークエラー時は cached 表示（60s）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "カテゴリコードで絞り込み"
            },
            "required": false,
            "name": "category",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "カーソル（published_at ISO 文字列）"
            },
            "required": false,
            "name": "cursor",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "1〜100（デフォルト 20）",
              "examples": [
                "20"
              ]
            },
            "required": false,
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "メディア一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileMediaListView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsMediaListList"
      }
    },
    "/v1/mobile/views/article-detail/{slug}": {
      "get": {
        "tags": [
          "記事詳細画面 / Article Detail Screen"
        ],
        "summary": "記事詳細画面開始 / Start Article Detail Screen",
        "description": "slug をキーに公開記事 1 件を本文付きで返す。\n- `data.body`: 記事本文（HTML or Markdown）\n- `data.relatedArticles`: 同カテゴリの関連記事（最大 5 件）\n\n### 認証\n不要。匿名でも呼べる。\n\n### エラー\n- 404: 記事が存在しない、または非公開\n\nFALLBACK_DETAIL: ネットワークエラー時は cached 表示（300s）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "tokyo-parking-guide-2026"
              ]
            },
            "required": true,
            "name": "slug",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "記事詳細",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileArticleDetailView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "記事が存在しない",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsArticleDetailGet"
      }
    },
    "/v1/mobile/views/support": {
      "get": {
        "tags": [
          "サポート画面 / Support Screen"
        ],
        "summary": "サポート画面開始 / Start Support Screen",
        "description": "FAQ・最近のサポートチケット・問い合わせ先を返す。\n- `data.faqItems`: FAQ 一覧（カテゴリ付き）\n- `data.recentTickets`: 最近のチケット（認証済みのみ・最大 5 件）\n- `data.contactEmail`: 問い合わせ先メールアドレス\n- `data.canSubmitNewTicket`: 送信フォーム開放フラグ\n\n### 認証\n任意。未認証でも呼べるが、`recentTickets` は空になる。\n\n### validation\nチケット送信フォームのバリデーションルールを `validation` で返す。\n\nFALLBACK_PERSONAL: auth エラー時は redirect_login。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "authorization",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "サポート画面",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSupportView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSupportList"
      }
    },
    "/v1/mobile/views/policies": {
      "get": {
        "tags": [
          "ポリシー画面 / Policies Screen"
        ],
        "summary": "ポリシー画面開始 / Start Policies Screen",
        "description": "アプリで提示するポリシー文書の一覧を返す。\n- `data.policies`: code / title / body / version / updatedAt の配列\n- code: `terms` / `privacy` / `cookies` / `licenses`\n\n### 認証\n不要。匿名でも呼べる。\n\n### データソース\npublic.policies テーブルが存在する場合はそこから取得。\n存在しない場合は静的定義にフォールバックする。\n\nFALLBACK_DETAIL: ネットワークエラー時は cached 表示（300s）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "ポリシー一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobilePoliciesView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsPoliciesList"
      }
    },
    "/v1/mobile/views/search-history": {
      "get": {
        "tags": [
          "検索履歴画面 / Search History Screen"
        ],
        "summary": "検索履歴画面開始 / Start Search History Screen",
        "description": "認証済みユーザーの最近の検索履歴を返す。\n- `data.recentSearches`: 検索クエリ・位置・日時の配列（最大 20 件）\n- `data.canClear`: 履歴がある場合 true\n\n### 認証\n任意。未認証の場合は空配列を返す。\n\nFALLBACK_PERSONAL: auth エラー時は redirect_login。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "authorization",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "検索履歴",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSearchHistoryView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsSearchHistoryList"
      }
    },
    "/v1/mobile/views/permissions": {
      "get": {
        "tags": [
          "パーミッション画面 / Permissions Screen"
        ],
        "summary": "パーミッション画面開始 / Start Permissions Screen",
        "description": "位置情報・通知・カメラ・フォトライブラリの OS パーミッション状態を返す。\n- `data.permissions`: code / label / statusLabel / deepLink / required / reasonText\n- `deepLink`: OS 設定画面への遷移 URL\n- `required`: アプリ動作に必須かどうか\n\n### 認証\n必須。Bearer JWT。\n\n### データソース\nuser_device_permissions テーブルの最新レコード。\n未記録の場合は「未確認」ステータスを返す。\n\nFALLBACK_PERSONAL: auth エラー時は redirect_login。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Bearer JWT"
            },
            "required": true,
            "name": "authorization",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "パーミッション一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobilePermissionsView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsPermissionsList"
      }
    },
    "/v1/mobile/views/error-fallback": {
      "get": {
        "tags": [
          "エラー画面 / Error Screen"
        ],
        "summary": "エラー画面開始 / Start Error Screen",
        "description": "アプリがエラー状態に陥った時に表示する復旧画面のデータを返す。\n- `data.retryableActions`: 再試行・ホームへ戻る等のアクション一覧\n- `data.diagnosticsSupportUrl`: サポートページ URL\n- `data.version`: アプリバージョン情報\n- `data.troubleshootingSteps`: トラブルシューティング手順\n\n### 認証\n不要。エラー状態でも送信できるよう認証不要にしている。\n\nFALLBACK_BOOT: 最も保守的な設定。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "エラーフォールバック画面",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileErrorFallbackView"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsErrorFallbackList"
      }
    },
    "/v1/mobile/views/app-review-status": {
      "get": {
        "tags": [
          "設定画面 / Settings Screen"
        ],
        "summary": "設定画面開始 / Start Settings Screen",
        "description": "「いまアプリレビューポップアップを出して良いか」をサーバーが判定して返す。\n\n- can_prompt=true   → クライアントは SKStoreReview / InAppReview を呼んで良い\n- already_submitted → 既に submit 済（永続的に false）\n- in_cooldown       → 直近の dispatch から cooldown_days (デフォルト 90 日) 経過していない\n\nクライアントは promote ダイアログを開いた直後に\nPOST /v1/mobile/actions/app-review/dispatched を必ず叩いて記録すること。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "アプリレビュー促進ステータス",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppReviewStatusViewResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileViewsAppReviewStatusList"
      }
    },
    "/v1/mobile/actions/sessions/start": {
      "post": {
        "tags": [
          "駐車開始画面 / Park Start Screen"
        ],
        "summary": "駐車セッション開始 / Start Parking Session",
        "description": "駐車セッションを開始する。Idempotency-Key 必須。\n成功時は parking_session 画面へ replace ナビゲーション。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "parking_lot_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "parking_spot_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "vehicle_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "vehicle_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 50
                  },
                  "start_lat": {
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90
                  },
                  "start_lng": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180
                  },
                  "started_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "planned_end_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "memo": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "required": [
                  "parking_lot_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "セッション開始成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartSessionActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsStart"
      }
    },
    "/v1/mobile/actions/sessions/{id}/finalize": {
      "post": {
        "tags": [
          "駐車終了画面 / Park End Screen"
        ],
        "summary": "駐車セッション完了 / Finalize Parking Session",
        "description": "駐車セッションを完了状態に移行する。Idempotency-Key 必須。\n\n- data.celebration: ゲーミフィケーションのお祝い payload。\n  enabled=true なら Flutter 側で badge / level_up / exp gauge の演出を順に再生する。\n  reward が無いセッション (旧 RPC, 既に finalize 済 等) では enabled=false。\n- 成功時の navigation は parking_history への pop_to_root。\n  Flutter は celebration を表示 → 閉じる → セッション feedback ダイアログ \n  (POST /v1/mobile/actions/sessions/{id}/feedback) → next_flow に従い遷移、の流れ。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ended_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "started_at": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "user_entered_fee_minor": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "end_lat": {
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90
                  },
                  "end_lng": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "セッション完了成功 (ActionEnvelope, data に celebration 同梱)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinalizeSessionActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsFinalizeCreate"
      }
    },
    "/v1/mobile/actions/sessions/{id}/cancel": {
      "post": {
        "tags": [
          "駐車終了画面 / Park End Screen"
        ],
        "summary": "駐車セッションキャンセル / Cancel Parking Session",
        "description": "駐車セッションをキャンセルする。開始から 5 分以内のみ許可。Idempotency-Key 必須。\n成功時は home 画面へ pop_to_root ナビゲーション。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "キャンセル成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelSessionActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsCancel"
      }
    },
    "/v1/mobile/actions/sessions/{id}": {
      "patch": {
        "tags": [
          "駐車中画面 / Parking Session Screen"
        ],
        "summary": "駐車セッション部分更新",
        "description": "進行中セッションの planned_end_at / memo を部分更新する。\nnull 明示で列を NULL 化。省略された field は変更しない。\nstatus='parking' のセッションのみ更新可能。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "planned_end_at": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "退庁見込み時刻。null 指定で clear、省略で非更新。"
                  },
                  "memo": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000,
                    "description": "メモ。null 指定で clear、省略で非更新。"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateSessionActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsUpdate"
      }
    },
    "/v1/mobile/actions/sessions/{id}/feedback": {
      "post": {
        "tags": [
          "駐車終了画面 / Park End Screen"
        ],
        "summary": "セッション完了後フィードバック / Session Completion Feedback",
        "description": "駐車セッション完了直後にユーザーが付けた good / bad / skip 評価を記録し、\n**次にどの画面へ遷移するかを `data.next_flow.kind` で返す**。\n\nクライアントはレスポンスの `next_flow.kind` だけを見て遷移先を判定する:\n- `ask_app_review`     : Apple SKStoreReview / Google InAppReview を呼ぶ\n- `ask_lot_review`     : 駐車場 ★ レビュー画面（params.prefilled_rating で初期値）\n- `info_correction`    : 駐車場情報の訂正フォーム\n- `support_contact`    : サポート問合せフォーム（params.source 同梱）\n- `done`               : これ以上の促しなし。閉じてよい\n\nDB には `parking_sessions.personal_rating` と `parking_sessions.bad_reason` を\n更新する。Idempotency-Key 必須（再送で評価が複数件にならない）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "rating": {
                    "type": "string",
                    "enum": [
                      "good",
                      "bad",
                      "skip"
                    ]
                  },
                  "bad_reason": {
                    "type": "string",
                    "enum": [
                      "parking_info",
                      "dislike",
                      "other"
                    ]
                  }
                },
                "required": [
                  "rating"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "フィードバック受理 + next_flow 同梱 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionFeedbackActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsFeedbackCreate"
      }
    },
    "/v1/mobile/actions/sessions/{id}/notifications": {
      "get": {
        "tags": [
          "駐車中画面 / Parking Session Screen"
        ],
        "summary": "セッション通知一覧",
        "description": "対象セッションに紐付く通知設定を全件返す。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "セッション通知一覧",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionNotificationListResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsNotificationsList"
      },
      "post": {
        "tags": [
          "駐車中画面 / Parking Session Screen"
        ],
        "summary": "セッション通知作成",
        "description": "対象セッションに通知設定を作成する。Idempotency-Key 必須。\ntrigger_type 別の必須フィールド:\n  - price_reached: threshold_amount_minor\n  - time_reached:  threshold_at\n  - planned_end_minus: offset_minutes, session.planned_end_at が事前設定済みであること\n  - max_price_reached: 追加必須なし",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionNotificationCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "通知作成成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionNotificationCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionsNotificationsCreate"
      }
    },
    "/v1/mobile/actions/session-notifications/{id}": {
      "patch": {
        "tags": [
          "駐車中画面 / Parking Session Screen"
        ],
        "summary": "セッション通知更新",
        "description": "通知設定を部分更新。fired_at が立っている通知は編集不可。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SessionNotificationUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionNotificationUpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionNotificationsUpdate"
      },
      "delete": {
        "tags": [
          "駐車中画面 / Parking Session Screen"
        ],
        "summary": "セッション通知削除",
        "description": "通知設定を物理削除する。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "削除成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SessionNotificationDeleteResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSessionNotificationsDelete"
      }
    },
    "/v1/mobile/actions/lots/{id}/save": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場を保存（冪等）",
        "description": "指定した駐車場をユーザーの保存リストに追加する。\n\n- **冪等**: すでに保存済みでも 200 を返す（追加せず現状を返す）\n- **Idempotency-Key 必須**: 同じキーでの再送は副作用なし\n- **後継**: 旧 `POST /v1/mobile/actions/lots/{id}/toggle-save` のうち `save: true` 相当",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "保存成功 (ActionEnvelope)。既保存でも 200 を返す。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LotSaveActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsSaveCreate"
      }
    },
    "/v1/mobile/actions/lots/{id}/unsave": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場の保存を解除（冪等）",
        "description": "指定した駐車場をユーザーの保存リストから外す。\n\n- **冪等**: 未保存でも 200 を返す（削除対象がなくても成功扱い）\n- **Idempotency-Key 必須**: 同じキーでの再送は副作用なし\n- **後継**: 旧 `POST /v1/mobile/actions/lots/{id}/toggle-save` のうち `save: false` 相当\n- 旧 `POST /v1/mobile/actions/saved/{lot_id}/remove` の代替",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "解除成功 (ActionEnvelope)。未保存でも 200 を返す。",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LotSaveActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsUnsaveCreate"
      }
    },
    "/v1/mobile/actions/lots/{id}/toggle-save": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場の保存・解除 / Toggle Save Parking Lot",
        "deprecated": true,
        "description": "**Deprecated**: Use `POST /v1/mobile/actions/lots/{id}/save` or `POST /v1/mobile/actions/lots/{id}/unsave` instead. Will be removed 2026-07-31.\n\n{ save: true } で保存追加、{ save: false } で保存解除。べき等。Idempotency-Key 必須。\n成功時は現在画面をリフレッシュ（NAVIGATION_REFRESH_CURRENT）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "save": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "save"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "保存トグル成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToggleSaveActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsToggleSaveCreate"
      }
    },
    "/v1/mobile/actions/lots/{id}/report-incorrect": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場の誤情報を報告 / Report Incorrect Lot Info",
        "description": "field で誤りの種別を指定し、message で詳細メッセージを添える。Idempotency-Key 必須。\n成功時は現在画面をリフレッシュ（NAVIGATION_REFRESH_CURRENT）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "field": {
                    "type": "string",
                    "enum": [
                      "location",
                      "hours",
                      "price",
                      "closed",
                      "other"
                    ]
                  },
                  "message": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "required": [
                  "field"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "誤情報報告成功 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportIncorrectActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsReportIncorrectCreate"
      }
    },
    "/v1/mobile/actions/lots/{id}/navigate": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場へのナビ起動 / Record Navigate To Lot",
        "description": "ナビボタン押下を計測対象として記録し、外部地図アプリを開くための URL を返す。\nIdempotency-Key 必須。activity_type=navigated_to_spot を best-effort で emit。\ndestination_app / origin_lat / origin_lng は計測精度向上のための任意項目。\nクライアントは応答 googleMapsUrl を fallback として、プラットフォームに応じた地図アプリ URL を優先構築してよい。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "destination_app": {
                    "type": "string",
                    "enum": [
                      "google_maps",
                      "apple_maps",
                      "yahoo_car_navi",
                      "native",
                      "other"
                    ]
                  },
                  "origin_lat": {
                    "type": "number",
                    "minimum": -90,
                    "maximum": 90
                  },
                  "origin_lng": {
                    "type": "number",
                    "minimum": -180,
                    "maximum": 180
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ナビ URL 発行 + activity 記録 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NavigateLotActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsNavigateCreate"
      }
    },
    "/v1/mobile/actions/lots/{id}/share": {
      "post": {
        "tags": [
          "駐車場詳細画面 / Lot Detail Screen"
        ],
        "summary": "駐車場を共有 / Record Share Lot",
        "description": "共有ボタン押下を計測対象として記録し、共有用 URL とデフォルトテキストを返す。\nIdempotency-Key 必須。activity_type=share を best-effort で emit。\nchannel は計測精度向上のための任意項目（native / copy_link / twitter / line / other）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "native",
                      "copy_link",
                      "twitter",
                      "line",
                      "other"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "共有 URL 発行 + activity 記録 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLotActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotsShareCreate"
      }
    },
    "/v1/mobile/actions/auth/request-otp": {
      "post": {
        "tags": [
          "ログイン画面 / Login Screen"
        ],
        "summary": "OTP・Magic linkを送信 / Send OTP / Magic Link",
        "description": "Supabase Auth の signInWithOtp をサーバー経由で呼び出す。\n- `email` に 6 桁 OTP をメール送信する\n- 冪等: 同一 email への再送は再度呼ぶこと（Idempotency-Key で重複排除）\n- Rate limit: login scope\n\n### Idempotency-Key\n必須ではないが付けると 1 分以内の再送をサーバー側でキャッシュする。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileRequestOtpBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OTP 送信受理",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRequestOtpResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAuthRequestOtp"
      }
    },
    "/v1/mobile/actions/auth/verify-otp": {
      "post": {
        "tags": [
          "ログイン画面 / Login Screen"
        ],
        "summary": "OTP・Magic linkを検証 / Verify OTP / Magic Link",
        "description": "Supabase Auth の verifyOtp をサーバー経由で呼び出す。\n- 成功時: `data.accessToken` / `data.refreshToken` を返す\n- 成功後のナビゲーション: `home` へ pop_to_root\n\n### Idempotency-Key\n必須。ネットワーク断→再送で二重検証しないために付けること。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileVerifyOtpBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OTP 検証成功 + トークン",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileVerifyOtpResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAuthVerifyOtp"
      }
    },
    "/v1/mobile/actions/auth/sign-up": {
      "post": {
        "tags": [
          "ログイン画面 / Login Screen"
        ],
        "summary": "新規登録 / Sign Up",
        "description": "Supabase Auth signUp + `public.app_users` の INSERT を実施する。\n- 成功時のナビゲーション: `onboarding` へ replace\n- `email_already_exists`: 同一 email が既に登録済みの場合は 409\n- referralCode は app_users.referral_code_used に保存\n\n### Idempotency-Key\n必須。ネットワーク断→再送で二重登録しないために付けること。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileSignUpBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "登録成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSignUpResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAuthSignUp"
      }
    },
    "/v1/mobile/actions/auth/sign-out": {
      "post": {
        "tags": [
          "ログイン画面 / Login Screen"
        ],
        "summary": "サインアウト / Sign Out",
        "description": "Supabase Auth の signOut をサーバー経由で呼び出す。\n- クライアントのローカルトークンを削除する前にこの API を呼ぶ\n- 成功後のナビゲーション: `auth` へ pop_to_root\n\n### 認証\nBearer JWT 必須。",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileSignOutBodyInner"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "サインアウト完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSignOutResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAuthSignOut"
      }
    },
    "/v1/mobile/actions/search/save-history": {
      "post": {
        "tags": [
          "検索結果画面 / Search Results Screen"
        ],
        "summary": "検索履歴を記録 / Record Search History",
        "description": "検索キーワードまたは位置情報を検索履歴として記録する。\n- `query`: 検索キーワード（オプション）\n- `lat` / `lng`: 検索時の位置（オプション）\n- 保存先: `user_search_preferences.recent_queries` JSON 配列に先頭追加\n- 最大 20 件を保持（超過分は末尾から削除）\n\n### 認証\nBearer JWT 必須。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileSaveHistoryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "検索履歴保存完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSaveHistoryResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchSaveHistoryCreate"
      }
    },
    "/v1/mobile/actions/ai-search/query": {
      "post": {
        "tags": [
          "AI 検索画面 / AI Search Screen"
        ],
        "summary": "AI検索を実行 / Execute AI Search",
        "description": "自然言語クエリを構造化フィルタに変換し、同時に検索結果も返す。\n- `query`: 自然言語での検索クエリ（必須）\n- `lat` / `lng`: 現在地（任意。無い場合は extractedFilters のみ返し items は空）\n- `radius_m`: 検索半径（任意、省略時 1500m）\n\n### レスポンス\n- `data.status`: `parsed` / `need_info` / `error`\n- `data.items`: 検索結果（status=parsed & lat/lng 指定時のみ非空）\n- `data.extractedFilters`: parsed 時に UI にセットすべき構造化フィルタ\n- `data.interpretation`: AI の解釈メッセージ（画面表示用）\n\n### 認証\nBearer JWT 必須。rate limit あり（1 分間の上限は security.search_rate_limit_max_hits）。\n\n### Idempotency-Key\n付けることを推奨（ネットワーク再送防止）。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileAiSearchQueryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "AI 検索結果",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileAiSearchQueryResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAiSearchQueryCreate"
      }
    },
    "/v1/mobile/actions/field-suggestions/submit": {
      "post": {
        "tags": [
          "field-suggestions"
        ],
        "summary": "駐車場 field 値の修正提案を投稿 (UGC)",
        "description": "### 用途\nユーザーが駐車場詳細画面で「この情報を訂正」した時に呼ぶ。\n`parking_field_values` に source='ugc' / approved_at=NULL / is_primary=false で蓄積。\n\n### 認証・認可\n`requireUser` 必須。app_users.id を contributor_id に記録。\n\n### Rate Limit\n`ugc_submission` scope: 同一ユーザー / 1 時間 10 件。\n\n### 関連\n- `POST /v1/mobile/actions/field-suggestions/{id}/confirm` — 別ユーザーの confirmation\n- confirm UPDATE → trigger (trg_pfv_set_priority_score_upd → trg_pfv_recompute_primary_aiu) で即時 is_primary 再判定",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldSuggestionSubmitBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "投稿成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldSuggestionSubmitResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsFieldSuggestionsSubmit"
      }
    },
    "/v1/mobile/actions/field-suggestions/{id}/confirm": {
      "post": {
        "tags": [
          "field-suggestions"
        ],
        "summary": "他人の field 提案に「これで合ってる」を投じる",
        "description": "### 用途\n親ユーザーが自分の confirmation を 1 票投じる。confirms_n が +1 され、\nBEFORE UPDATE trigger が priority_score を即時再計算 → AFTER UPDATE trigger\nが is_primary を再判定し、UGC が閾値を超えた瞬間に primary 昇格される。\n\n### 制約\n- `requireUser` 必須。\n- (field_value_id, user_id) UNIQUE — 同じ user は同じ提案に 1 回だけ投票可。\n- 自分の投稿には confirm できない (投稿者自身は contributor_id でカウント済み)。\n\n### Rate Limit\n`ugc_confirmation` scope: 同一ユーザー / 1 時間 60 件。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "投票成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FieldSuggestionConfirmResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsFieldSuggestionsConfirmCreate"
      }
    },
    "/v1/mobile/actions/field-suggestions/{id}/confirmations": {
      "get": {
        "tags": [
          "field-suggestions"
        ],
        "summary": "提案への confirmation を投じた user 一覧",
        "description": "admin moderation 補助。本人の app_user_id は隠さず返す。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "確認者一覧",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "user_id": {
                            "type": "string",
                            "format": "uuid",
                            "examples": [
                              "00000000-0000-0000-0000-000000000000"
                            ]
                          },
                          "confirmed_at": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "user_id",
                          "confirmed_at"
                        ]
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "items",
                    "total"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsFieldSuggestionsConfirmationsList"
      }
    },
    "/v1/mobile/actions/reviews/create": {
      "post": {
        "tags": [
          "レビュー投稿画面 / Review Compose Screen"
        ],
        "summary": "レビューを投稿 / Post Review",
        "description": "駐車場にレビューを投稿する。\n- `status=pending` で作成 → 管理者が承認 / 却下する\n- 禁止ワードが含まれていれば 422 `prohibited_words_detected` を返す\n- 同一ユーザーが同一駐車場に既にレビュー済みの場合 409 `review_already_exists`\n- 成功後のナビゲーション: `parking_detail` へ pop_to_root（該当 lot に戻る）\n\n### 認証\nBearer JWT 必須。\n\n### Idempotency-Key\n必須（ネットワーク再送で二重投稿しないために付けること）。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileReviewCreateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "レビュー投稿完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileReviewCreateResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsReviewsCreateCreate"
      }
    },
    "/v1/mobile/actions/destinations": {
      "post": {
        "tags": [
          "検索画面 / Search Screen"
        ],
        "summary": "目的地を記録 / Record Destination",
        "description": "ユーザーがオートコンプリート候補から目的地を選んだ時に呼ぶ。\nplace_id 重複時は use_count++ + last_used_at 更新（べき等）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "address": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 500
                  },
                  "lat": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": -90,
                    "maximum": 90
                  },
                  "lng": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "minimum": -180,
                    "maximum": 180
                  },
                  "place_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 200
                  },
                  "session_token": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 80
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "目的地履歴を更新",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DestinationRecordResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsDestinationsCreate"
      }
    },
    "/v1/mobile/actions/profile/vehicles/add": {
      "post": {
        "tags": [
          "車両管理画面 / Vehicles Screen"
        ],
        "summary": "車両を登録 / Register Vehicle",
        "description": "車両を登録し、更新後の vehicles View データを ActionEnvelope で返す。\n\n### 上限チェック\n1ユーザー最大 10 台。上限到達時は 409 vehicle_limit_exceeded。\n\n### Idempotency-Key\nPOST ミューテーションなので Idempotency-Key ヘッダを付けること（二重登録防止）。",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nickname": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "plate_number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20
                  },
                  "vehicle_type_code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  }
                },
                "required": [
                  "vehicle_type_code"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "登録後の vehicles View データ (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffVehiclesAddAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileVehiclesAddCreate"
      }
    },
    "/v1/mobile/actions/profile/vehicles/{id}/update": {
      "patch": {
        "tags": [
          "車両管理画面 / Vehicles Screen"
        ],
        "summary": "車両情報を更新 / Update Vehicle",
        "description": "指定した車両のフィールドを部分更新し、更新後の vehicles View データを返す。\n\n### 空ボディ\nフィールド未指定の場合は no-op（現行値を返す）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "nickname": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 50
                  },
                  "plate_number": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 20
                  },
                  "vehicle_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 32
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後の vehicles View データ (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffVehiclesUpdateAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileVehiclesUpdateUpdate"
      }
    },
    "/v1/mobile/actions/profile/vehicles/{id}/delete": {
      "post": {
        "tags": [
          "車両管理画面 / Vehicles Screen"
        ],
        "summary": "車両をソフト削除 / Soft Delete Vehicle",
        "description": "指定した車両を論理削除（deleted_at = NOW()）し、削除後の vehicles View データを返す。\n\n### 冪等性\n既に削除済みの vehicle_id を指定してもエラーにならない（冪等）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "削除後の vehicles View データ (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffVehiclesDeleteAction"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileVehiclesDeleteCreate"
      }
    },
    "/v1/mobile/actions/profile/vehicles/{id}/set-default": {
      "post": {
        "tags": [
          "車両管理画面 / Vehicles Screen"
        ],
        "summary": "車両をデフォルトに設定 / Set Default Vehicle",
        "description": "指定した車両を is_default = true にし、他の車両を false にする。\n設定後の vehicles View データを ActionEnvelope で返す。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "examples": [
                "00000000-0000-0000-0000-000000000000"
              ]
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "設定後の vehicles View データ (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffVehiclesSetDefaultAction"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileVehiclesSetDefaultCreate"
      }
    },
    "/v1/mobile/actions/profile/update": {
      "patch": {
        "tags": [
          "プロフィール画面 / Profile Screen"
        ],
        "summary": "プロフィールを更新 / Update Profile",
        "description": "表示名・テーマ・言語・通知設定・マーケティング同意を部分更新し、\n更新後のプロフィールメイン View データを ActionEnvelope で返す。\n\n### Idempotency-Key\nroutes-manifest で idempotent: true が設定されているため、ヘッダ必須。\n同一 Idempotency-Key で再 PATCH しても安全（二重更新防止）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "display_name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 40
                  },
                  "theme_code": {
                    "type": "string",
                    "maxLength": 32
                  },
                  "language_code": {
                    "type": "string",
                    "maxLength": 10
                  },
                  "notifications_enabled": {
                    "type": "boolean"
                  },
                  "marketing_opt_in": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後のプロフィール View データ (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffProfileUpdateAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileUpdateUpdate"
      }
    },
    "/v1/mobile/actions/profile/avatar-upload": {
      "post": {
        "tags": [
          "プロフィール画面 / Profile Screen"
        ],
        "summary": "アバター更新",
        "description": "R2 に upload 済みの asset_id を指定して avatar_asset_id を更新する。\nレスポンスは更新後の avatarUrl のみ含む軽量 ActionEnvelope。\n\n### フロー\n1. Flutter が /v1/storage などで R2 に画像 upload → asset_id 取得\n2. 本 endpoint に asset_id を POST → app_users.avatar_asset_id を UPDATE\n3. 返却 avatarUrl を Flutter が即時表示\n\n### Idempotency-Key\nroutes-manifest で idempotent: true が設定されているため、ヘッダ必須。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "asset_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "asset_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後の avatarUrl (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffAvatarUploadAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileAvatarUploadCreate"
      }
    },
    "/v1/mobile/actions/profile/request-data-export": {
      "post": {
        "tags": [
          "プロフィール画面 / Profile Screen"
        ],
        "summary": "個人データエクスポートをリクエスト",
        "description": "GDPR 第20条（データポータビリティ権）への対応。\nエクスポートを非同期でリクエストし、requestId と推定完了時間を返す。\n\n### 既存 /v1/me/data-export との違い\n既存 endpoint は同期で全データを返す。この Action は非同期（push 通知 or メール配信予定）。\n\n### Idempotency-Key\nroutes-manifest で idempotent: true が設定されているため、ヘッダ必須。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "エクスポートリクエスト受理 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffRequestDataExportAction"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "too_many_requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileRequestDataExportCreate"
      }
    },
    "/v1/mobile/actions/profile/delete-account": {
      "post": {
        "tags": [
          "プロフィール画面 / Profile Screen"
        ],
        "summary": "アカウントを削除 / Delete Account",
        "description": "アカウントをソフト削除する（deleted_at = NOW()）。\n30日後に物理削除バッチが実行される。猶予期間中はサポートへ復旧申請可能。\n\n### confirmation\n`\"DELETE\"` という文字列を body に含める必要がある（誤タップ防止）。\n一致しない場合は 422 invalid_delete_confirmation を返す。\n\n### navigation\n削除成功時は `{ target: \"auth\", strategy: \"pop_to_root\" }` を返す。\nFlutter はルートまで pop してログイン画面を表示する。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": false,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirmation": {
                    "type": "string"
                  }
                },
                "required": [
                  "confirmation"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "削除受理 + scheduled_deletion_at (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BffDeleteAccountAction"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsProfileDeleteAccountCreate"
      }
    },
    "/v1/mobile/actions/saved/{lot_id}/remove": {
      "post": {
        "tags": [
          "保存済み駐車場画面 / Saved Lots Screen"
        ],
        "summary": "保存済み駐車場を削除 / Remove Saved Lot",
        "deprecated": true,
        "description": "**Deprecated**: Use `POST /v1/mobile/actions/lots/{id}/unsave` instead. Will be removed 2026-07-31.\n\n### 用途\n指定した駐車場をユーザーの保存リストから削除する。\n\n### 冪等性\nIdempotency-Key ヘッダが必須。\nすでに削除済みの lotId を指定しても 200 を返す（removedCount = 0）。\n\n### レスポンス\ndata には削除後の保存一覧（先頭 20 件）を返す。\nFlutter は navigation.strategy = 'replace' を受けてその場で画面を再描画する。\n\n### 注意\n保存の追加（toggle-save）は Wave 1+3 が実装する `/v1/mobile/actions/lots/{id}/toggle-save`\nを使うこと。本エンドポイントは remove のみ。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "lot_id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "削除後の保存一覧 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSavedRemoveAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSavedRemoveCreate"
      }
    },
    "/v1/mobile/actions/notifications/preferences/update": {
      "patch": {
        "tags": [
          "通知設定画面 / Notifications Preferences Screen"
        ],
        "summary": "通知設定を更新 / Update Notification Preferences",
        "description": "### 用途\nログイン中ユーザーの通知設定を部分更新する。\n\n### リクエスト\n- `email_enabled`: メール通知の有効/無効\n- `push_enabled`: プッシュ通知の有効/無効\n- `categories`: { [category_code]: boolean } 形式の差分パッチ\n  未指定フィールドは既存値を維持する。\n\n### 冪等性\nIdempotency-Key ヘッダが必須。\n同じ値を何度送っても同一結果を返す。\n\n### レスポンス\ndata には更新後の通知設定 View データを返す。\nFlutter は navigation.strategy = 'replace' でその場で画面を再描画する。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email_enabled": {
                    "type": "boolean"
                  },
                  "push_enabled": {
                    "type": "boolean"
                  },
                  "categories": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新後の通知設定 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileNotificationsPreferencesUpdateAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsNotificationsPreferencesUpdateUpdate"
      }
    },
    "/v1/mobile/actions/notifications/mark-read": {
      "post": {
        "tags": [
          "通知画面 / Notifications Screen"
        ],
        "summary": "通知を既読 / Mark Notifications as Read",
        "description": "### 用途\n指定した通知（または全通知）を既読にし、最新の通知一覧 snapshot を返す。\n\n### リクエスト形式\n- `{ notification_ids: uuid[] }`: 指定した通知のみ既読\n- `{ mark_all: true }`: ユーザーの全通知を既読\nどちらも指定しない場合は 422 を返す。\n\n### 冪等性\nIdempotency-Key ヘッダが必須。\n既読済みの通知 ID を渡しても updatedCount = 0 で 200 を返す。\n\n### レスポンス\ndata には既読処理後の通知一覧（先頭 20 件、tab = all）を返す。\nunreadCount が 0 または減少していることを Flutter 側で確認できる。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "notification_ids": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "mark_all": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "既読処理後の通知一覧 (ActionEnvelope)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileNotificationsMarkReadAction"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsNotificationsMarkRead"
      }
    },
    "/v1/mobile/actions/search-presets": {
      "post": {
        "tags": [
          "検索プリセット画面 / Search Presets Screen"
        ],
        "summary": "検索プリセットを作成 / Create Search Preset",
        "description": "検索プリセットを新規作成する。\n\n### ActionEnvelope\n`data` は作成後の SearchPresets View 全体。クライアントは再 fetch 不要。\n`navigation = NAVIGATION_REFRESH_CURRENT`（同画面再描画）。\n\n### 上限\n1 ユーザー 10 件まで。超過は `preset_limit_exceeded`（409）。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSearchPresetBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "作成成功。更新後の search-presets View を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateSearchPresetResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchPresetsCreate"
      }
    },
    "/v1/mobile/actions/search-presets/{id}/update": {
      "patch": {
        "tags": [
          "検索プリセット画面 / Search Presets Screen"
        ],
        "summary": "検索プリセットを更新 / Update Search Preset",
        "description": "検索プリセットを部分更新する。指定フィールドのみ上書きし、他は現行値を維持。\n\n### ActionEnvelope\n`data` は更新後の SearchPresets View 全体。`navigation = NAVIGATION_REFRESH_CURRENT`。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSearchPresetBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "更新成功。更新後の search-presets View を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateSearchPresetResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchPresetsUpdateUpdate"
      }
    },
    "/v1/mobile/actions/search-presets/{id}/delete": {
      "post": {
        "tags": [
          "検索プリセット画面 / Search Presets Screen"
        ],
        "summary": "検索プリセットを削除 / Delete Search Preset",
        "description": "検索プリセットをソフト削除する。\n\n### 冪等性\n存在しない ID / 他ユーザーの ID への削除は 200 を返す（エラーにしない）。\n\n### ActionEnvelope\n`data` は削除後の SearchPresets View 全体。`navigation = NAVIGATION_REFRESH_CURRENT`。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "削除成功（冪等）。削除後の search-presets View を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteSearchPresetResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchPresetsDeleteCreate"
      }
    },
    "/v1/mobile/actions/search-presets/{id}/set-default": {
      "post": {
        "tags": [
          "検索プリセット画面 / Search Presets Screen"
        ],
        "summary": "検索プリセットをデフォルトに設定 / Set Default Search Preset",
        "description": "指定プリセットをデフォルトに設定し、他のプリセットのデフォルトを解除する。\nアトミック（1 TX で完結）。既にデフォルトのプリセットに呼んでも 200 を返す（冪等）。\n\n### ActionEnvelope\n`data` は更新後の SearchPresets View 全体。`navigation = NAVIGATION_REFRESH_CURRENT`。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "デフォルト切替成功。更新後の search-presets View を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetDefaultSearchPresetResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchPresetsSetDefaultCreate"
      }
    },
    "/v1/mobile/actions/premium/verify-iap": {
      "post": {
        "tags": [
          "プレミアム画面 / Premium Screen"
        ],
        "summary": "IAP 購入レシート検証",
        "description": "Apple App Store / Google Play の IAP レシートをサーバーで検証し、\n`user_subscriptions` を最新状態に更新して ActionEnvelope で返す。\n\n### ActionEnvelope\n`data`: `{ subscription_id, plan, expires_at, is_active }` の抜粋。\n`navigation = NAVIGATION_REFRESH_CURRENT`（premium 画面を再描画）。\n\n### 既存との関係\n`POST /v1/me/subscription/verify-iap` の Mobile 版。同じ検証ロジックを共有する。\n旧 endpoint は 2026-07-31 に 410 Gone 予定。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerifyIapActionBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "検証成功。premium 抜粋を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VerifyIapActionResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPremiumVerifyIapCreate"
      }
    },
    "/v1/mobile/actions/premium/cancel": {
      "post": {
        "tags": [
          "プレミアム画面 / Premium Screen"
        ],
        "summary": "サブスクリプション解約",
        "description": "アクティブなサブスクリプションを解約（`status = cancelled`）する。\n\n### ActionEnvelope\n`data`: キャンセル後の subscription 抜粋。`is_active = false`。\n`navigation = NAVIGATION_REFRESH_CURRENT`（premium 画面を再描画）。\n\n### エラー\n- 404 `subscription_not_found` — アクティブな契約が存在しない\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "解約成功。更新後の subscription 抜粋を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CancelSubscriptionResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPremiumCancel"
      }
    },
    "/v1/mobile/actions/premium/apply-coupon": {
      "post": {
        "tags": [
          "プレミアム画面 / Premium Screen"
        ],
        "summary": "クーポンコードを適用 / Apply Coupon Code",
        "description": "クーポンコードを適用してサブスクリプション期限を延長、または割引額を返す。\n\n### クーポン種別\n- `fixed_days`: `new_expires_at` に延長後の期限を返す\n- `percentage`: `discount_amount` に割引率（%）を返す（外部課金プロバイダ側で適用）\n\n### ActionEnvelope\n`data`: `{ success, discount_amount?, new_expires_at? }`。\n`navigation = NAVIGATION_REFRESH_CURRENT`（premium 画面を再描画）。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyCouponBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "適用成功。割引情報を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplyCouponResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPremiumApplyCouponCreate"
      }
    },
    "/v1/mobile/actions/premium/start-trial": {
      "post": {
        "tags": [
          "プレミアム画面 / Premium Screen"
        ],
        "summary": "7日無料トライアル開始",
        "description": "Free 会員が Premium 体験を 7 日間無料で試す。IAP 課金不要。\n\n### 挙動\n1. すでに Premium active / trial / past_due → 409 conflict\n2. trial 履歴あり (再利用) → 409 trial_already_used\n3. 上記以外 → user_subscriptions に status='trial' + trial_ends_at=NOW+plan.trial_days で INSERT\n\n### プラン解決\n- `plan_code` 明示時はそのプランで trial\n- 省略時は `app_users.pricing_variant` + `billing_period` (default monthly) で variant 解決\n\n### 後続フロー\n- 7 日後に cron が `status='trial_expired'` へ遷移し Free に戻す\n- ユーザーがトライアル中に IAP 課金完了 → verify-iap が status='active' に上書き",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartTrialActionBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "トライアル開始成功",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StartTrialActionResponse"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPremiumStartTrialCreate"
      }
    },
    "/v1/mobile/actions/lot-registration/submit": {
      "post": {
        "tags": [
          "駐車場登録申請画面 / Lot Registration Screen"
        ],
        "summary": "駐車場登録申請を送信 / Submit Lot Registration",
        "description": "駐車場登録申請を送信する。申請後、管理者が審査して承認するとオーナー招待メールが届く。\n\n### ActionEnvelope\n`data`: `{ application_id, status: 'submitted', next_steps }`。\n`navigation = { target: 'home', strategy: 'pop_to_root' }`（ホーム画面へ戻る）。\n\n### べき等性\n同一ユーザーの同一 lot_name + address の重複申請は既存行の application_id を返す（冪等）。\n\n### Idempotency-Key\n必須（routes-manifest の `idempotent: true` で middleware 強制）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitLotRegistrationBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "申請受付成功。application_id を ActionEnvelope で返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitLotRegistrationResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsLotRegistrationSubmit"
      }
    },
    "/v1/mobile/actions/support/submit-ticket": {
      "post": {
        "tags": [
          "サポート画面 / Support Screen"
        ],
        "summary": "サポートチケットを送信 / Submit Support Ticket",
        "description": "サポートチケットを新規作成する。\n- `data.ticketId`: 作成されたチケットの UUID\n- `data.status`: 初期ステータス `open`\n\n### 認証\n必須。Bearer JWT。\n\n### Idempotency-Key\n必須。ネットワーク断→再送で二重チケットを防ぐ。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "必須。二重送信防止キー"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Bearer JWT"
            },
            "required": true,
            "name": "authorization",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileSubmitTicketBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "チケット作成完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileSubmitTicketResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSupportSubmitTicketCreate"
      }
    },
    "/v1/mobile/actions/search-history/clear": {
      "post": {
        "tags": [
          "検索履歴画面 / Search History Screen"
        ],
        "summary": "検索履歴をクリア / Clear Search History",
        "description": "ログイン中ユーザーの検索履歴を全件削除する。べき等。\n削除後は `navigation = NAVIGATION_REFRESH_CURRENT` で同画面を更新。\n\n### 認証\n必須。Bearer JWT。\n\n### Idempotency-Key\n必須。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "必須。二重実行防止キー"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Bearer JWT"
            },
            "required": true,
            "name": "authorization",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileClearSearchHistoryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "検索履歴クリア完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileClearSearchHistoryResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsSearchHistoryClearCreate"
      }
    },
    "/v1/mobile/actions/permissions/record": {
      "post": {
        "tags": [
          "パーミッション画面 / Permissions Screen"
        ],
        "summary": "OSパーミッションを記録 / Record OS Permissions",
        "description": "OS のネイティブパーミッション状態をサーバーに記録する。\n- `data`: 更新後の PermissionsData（permissions 全件）\n- `navigation = NAVIGATION_REFRESH_CURRENT` で同画面をリフレッシュ\n\n### 認証\n必須。Bearer JWT。\n\n### Idempotency-Key\n必須。同一パーミッション変更の重複記録を防ぐ。\n\n### code\n- `location`: 位置情報\n- `notification`: プッシュ通知\n- `camera`: カメラ\n- `gallery`: フォトライブラリ",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "必須。重複記録防止キー"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "description": "Bearer JWT"
            },
            "required": true,
            "name": "authorization",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileRecordPermissionBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "パーミッション記録完了・更新後の View を返す",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileRecordPermissionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPermissionsRecordCreate"
      }
    },
    "/v1/mobile/actions/error/report": {
      "post": {
        "tags": [
          "エラー画面 / Error Screen"
        ],
        "summary": "エラーレポートを送信 / Send Error Report",
        "description": "アプリのクラッシュ・エラー情報をサーバーに記録する。\n- `data.reportId`: 採番されたレポート UUID\n\n### 認証\n不要。エラー状態でも送信できるよう認証不要にしている。\nJWT があれば user_id が記録される（optionalUser）。\n\n### Idempotency-Key\n推奨。同一エラーの重複記録を防ぐ。\n\n### 注意\n本 endpoint は誤情報報告（`/v1/error-reports`）とは別。\nこちらはアプリのクラッシュ・例外レポート専用。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "authorization",
            "in": "header"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileReportErrorBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "エラーレポート受理",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileReportErrorResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsErrorReport"
      }
    },
    "/v1/mobile/actions/push-tokens/register": {
      "post": {
        "tags": [
          "サポート系（画面横断） / Support (cross-screen)"
        ],
        "summary": "FCM/APNs デバイストークンを登録",
        "description": "プッシュ通知配信用のデバイストークンをサーバに登録する。\n\n### 呼び出しタイミング\n- サインイン直後\n- FCM/APNs から token を取得できた時\n- token rotation（onTokenRefresh）が発生した時\n- アプリ起動時のヘルスチェック\n\n### 冪等性\nDB の UNIQUE 制約 `(user_id, fcm_token)` で重複は吸収される。\n同じ token を何度送っても同じ `token_id` が返る。\nIdempotency-Key を併用すれば二重実行防止が二重防御になる。\n\n### サインアウト時\n本 endpoint では deregister しない。サインアウト時はクライアント側で\ntoken を破棄し、別途 `/v1/me/push-tokens` の DELETE 系を叩くか、\n次回サインイン時に新しい token で上書きする運用。",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Bearer JWT"
            },
            "required": true,
            "name": "authorization",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "任意。同一登録の二重実行を防ぐ"
            },
            "required": false,
            "name": "idempotency-key",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobilePushTokenRegisterBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "登録 / 再登録完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobilePushTokenRegisterResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "unprocessable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "internal_error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsPushTokensRegisterCreate"
      }
    },
    "/v1/mobile/actions/app-review/dispatched": {
      "post": {
        "tags": [
          "設定画面 / Settings Screen"
        ],
        "summary": "アプリレビュー表示記録 / Record App Review Dispatched",
        "description": "クライアントが SKStoreReview / InAppReview の native UI を呼び出した直後に必ず叩く。\ncooldown 判定の起点になる。Idempotency-Key 必須（再送で行が増えない）。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "enum": [
                      "app_store",
                      "play_store",
                      "unknown"
                    ]
                  },
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "session_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "store"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "記録完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppReviewDispatchedActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAppReviewDispatchedCreate"
      }
    },
    "/v1/mobile/actions/app-review/submitted": {
      "post": {
        "tags": [
          "設定画面 / Settings Screen"
        ],
        "summary": "アプリレビュー submit 自己申告 / Record App Review Submitted",
        "description": "ユーザーが native レビュー UI で submit を押したと推測される時に叩く。\n1 件でも submit 済が記録されると、以降 GET /v1/mobile/views/app-review-status は\n永続的に can_prompt=false (reason='already_submitted') を返す。\nIdempotency-Key 必須。",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "idempotency-key",
            "in": "header"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "store": {
                    "type": "string",
                    "enum": [
                      "app_store",
                      "play_store",
                      "unknown"
                    ]
                  },
                  "source": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "session_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "store"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "記録完了",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppReviewSubmittedActionResponse"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileActionsAppReviewSubmittedCreate"
      }
    },
    "/v1/mobile/i18n/bundle": {
      "get": {
        "tags": [
          "i18n / Mobile Labels"
        ],
        "summary": "モバイル i18n 辞書 bundle (ETag/304 対応)",
        "description": "### 用途\nモバイルアプリの画面ラベル・エラーメッセージ・empty state 等を key → value の\n辞書として配信する。client は起動時 / foreground 復帰時にローカルキャッシュを\nread しつつ、並行で `If-None-Match` ヘッダ付きで本 endpoint を叩いて変更検知する。\n\n### 変更検知フロー\n1. client がローカルキャッシュの version (= ETag) を `If-None-Match` に載せて GET\n2. サーバ側で `(key, value, updated_at)` の md5 hash を計算\n3. 一致 → **304 Not Modified** (body 0 byte)\n4. 不一致 → **200 OK** + `data.version` / `data.messages` の全辞書\n\n### キャッシュ戦略\n- レスポンスには `ETag: \"<md5>\"` と `Cache-Control: public, max-age=0, must-revalidate` を付与\n- edge cache (Cloudflare) は ETag を尊重して保持 → admin が文言編集時は cache purge が必要\n\n### 認証\n不要。未ログイン画面 (splash / ログイン画面) でも辞書は必要なため。\n\n### lang\n`?lang=ja` (既定) / `?lang=en` など。未知 lang は `ja` にフォールバック。\n\n### 関連\n- `PATCH /v1/admin/i18n-messages/{id}` — 文言編集 (変更で version が変わる)\n- `POST /v1/admin/i18n-messages/purge-cache` — 手動 edge cache purge",
        "parameters": [
          {
            "schema": {
              "type": "string",
              "examples": [
                "ja"
              ]
            },
            "required": false,
            "name": "lang",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "\"9c7f1a3d...\""
              ]
            },
            "required": false,
            "name": "if-none-match",
            "in": "header"
          },
          {
            "schema": {
              "type": "string",
              "examples": [
                "1.2.3"
              ]
            },
            "required": false,
            "name": "x-app-version",
            "in": "header"
          }
        ],
        "responses": {
          "200": {
            "description": "i18n 辞書 bundle (変更あり)",
            "headers": {
              "ETag": {
                "description": "現在の bundle version の quoted md5",
                "schema": {
                  "type": "string"
                }
              },
              "Cache-Control": {
                "description": "public, max-age=0, must-revalidate",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MobileI18nBundle"
                }
              }
            }
          },
          "304": {
            "description": "If-None-Match がサーバ側 version と一致 (body なし)"
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileI18nBundleList"
      }
    },
    "/v1/mobile/telemetry/events": {
      "post": {
        "tags": [
          "Mobile / Telemetry"
        ],
        "summary": "汎用 telemetry events を batch 受信",
        "description": "Flutter から fire-and-forget で送信される画面・操作イベントをまとめて記録する。\n送信側 (TelemetryClient) は 5 秒間隔で flush するか、buffer が 50 件に達したら即時 flush する。\n全イベントは analytics.client_events に severity=info / message=null で append-only INSERT。\nprops は metadata カラム (jsonb) にそのまま積む。",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileTelemetryEventsBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "受理",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TelemetryAck"
                }
              }
            }
          },
          "400": {
            "description": "validation_error / bad_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "mobileTelemetryEventsCreate"
      }
    }
  },
  "webhooks": {}
}
