{
  "openapi": "3.1.0",
  "info": {
    "title": "FastAPI",
    "version": "0.1.0"
  },
  "paths": {
    "/guilds/search/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Search Guilds",
        "description": "Search Comlink for guilds whose name matches ``name`` (substring).\n\nRead-only against Comlink \u2014 does *not* persist results into ``db.guilds``.\nPublic; the actual \"add this guild to our store\" step is the\ndrill-in (``GET /guilds/{guild_id}/``) which upserts on cache miss\nand is officer-gated. Non-officers searching can browse results and\ndrill into already-tracked guilds; untracked guilds 404 for them.\n\nThe minimum query length is 2 characters; shorter queries are rejected\nwith a 400 to avoid hammering Comlink with overly-broad searches.",
        "operationId": "search_guilds_guilds_search__get",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Name"
            }
          },
          {
            "name": "start_index",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Start Index"
            }
          },
          {
            "name": "count",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 20,
              "title": "Count"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response Search Guilds Guilds Search  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/history/counts/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get History Counts",
        "description": "Return ``{guild_id: snapshot_count}`` across ``db.guilds_history``.\n\nIndexed ``$group`` aggregation \u2014 finishes in milliseconds even as\nthe history collection grows. Frontend-friendly dict shape so\ncallers can do ``counts[guild_id]`` directly.",
        "operationId": "get_history_counts_guilds_history_counts__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "integer"
                  },
                  "type": "object",
                  "title": "Response Get History Counts Guilds History Counts  Get"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/history/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild History",
        "operationId": "get_guild_history_guilds__guild_id__history__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Limit"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Days"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild",
        "description": "Resolve a guild by id.\n\nDiscovery (cache miss \u2192 Comlink) requires role ``officer`` or\nhigher \u2014 that's the \"add a new guild\" gate. Refreshing an\n*existing* guild is open to everyone, whether implicit (the 24h\nstaleness auto-refresh) or explicit (``?refresh=true``): Comlink\ncall frequency per guild stays bounded either way and a fresh\nview is the right page-load behavior for any viewer.\n\nSide effect on first-time discovery: schedules a background\nrefresh of every member's roster. Without it, derived views\n(unit ownership, GL counts, team readiness) would show zero\nuntil the daily cron runs. The task is wrapped via\n``run_and_record`` so admins can track progress + errors.",
        "operationId": "get_guild_guilds__guild_id___get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/refresh-players/": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Refresh Guild Players",
        "description": "Manually trigger a refresh of every member's roster.\n\nOfficer-gated. Returns 202 + a brief acknowledgement; the\nactual work runs as a background task (per-member refreshes\ntake a few seconds each, so a serial sweep across a 50-member\nguild is multi-minute \u2014 too long to hold the request).\n\nThe data layer's ``max_age_seconds`` skip threshold (default\n6 h) prevents thrashing when officers click the button\nrepeatedly. Track progress in ``/admin/tasks``.",
        "operationId": "refresh_guild_players_guilds__guild_id__refresh_players__post",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Refresh Guild Players Guilds  Guild Id  Refresh Players  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guilds",
        "operationId": "get_guilds_guilds__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/mods/summary/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Mods Summary",
        "description": "Guild-wide mod headline: ML+15 totals, speed-mod totals, per-member rows.\n\nAggregates every member's parsed mods into a single rollup\nsuitable for the GuildDetail / GuildStatistics surfaces. Each\nmember row carries their total_speed / ml15_count / gold_count /\nspeed_arrow_count so the UI can render a leaderboard inline.\n\nPublic \u2014 same as the other guild rollups.",
        "operationId": "get_guild_mods_summary_guilds__guild_id__mods_summary__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/scoreboard/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Scoreboard",
        "description": "Per-member officer triage scoreboard (Theme E).\n\nCombined ranked roster for \"who's pulling weight\" / \"who needs\ncoaching\" / \"who would we recruit out\". Returns:\n\n* ``members`` \u2014 per-member row with GP, league/division/skill,\n  activity, roster depth, mod-farming progress\n* ``medians`` and ``percentiles`` (p25/p75) for each ranked metric\n* ``coaching_highlights`` \u2014 pre-sorted list of (member, metric)\n  pairs below the guild's p25, capped at 30 for readability\n\nOfficer-gated \u2014 the audit framed this surface as \"officer\ntriage\". Per-member raw data is otherwise available via the\nindividual player pages; the value-add here is the cross-member\nranking + coaching pass.",
        "operationId": "get_guild_scoreboard_guilds__guild_id__scoreboard__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/territory-battle/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Territory Battle",
        "description": "Per-member breakdown of the guild's most recent Territory Battle.\n\nRead straight from the cached guild envelope \u2014 Comlink ships\n``recentTerritoryBattleResult`` on every ``include_activity=True``\nfetch, so this costs one Mongo read and no upstream call.\n\nOpen like the rest of the guild read surface: it is aggregate\nparticipation over data the game shows every member of that guild\nanyway, and it carries no roster detail the guild page doesn't.\n\n``null`` result when the guild has no finished TB in its cached\nenvelope, which is normal between battles rather than an error \u2014\nhence 200 with an empty body rather than a 404.\n\nThe scoring rule is deliberately narrow; see\n:mod:`app.swgoh.guild_territory_battle` for why summing every\n``playerStat.score`` inflates the total ~5x AND reorders the\nleaderboard.",
        "operationId": "get_guild_territory_battle_guilds__guild_id__territory_battle__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "instance_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Instance Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/territory-wars/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Territory Wars",
        "description": "Every Territory War we have ever captured for this guild.\n\nComlink only ever shows the last eight; this is the archive built from\nevery observation since capture began, so it grows past that window\ninstead of rolling over.",
        "operationId": "get_guild_territory_wars_guilds__guild_id__territory_wars__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/engagement/activity/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Activity",
        "description": "Activity heatmap + AFK roll-up for a guild.\n\nReads ``member[].lastActivityTime`` from the cached guild doc \u2014\nno new Comlink calls, no schema-specific parsing (the field has\nbeen there since the project's first ingest). Returns per-member\nrows sorted newest-active first, bucket counts (today / 1-3d /\n4-7d / 8-14d / 15-29d / 30+d), and a top-level ``afk_count``\nusing a 7-day threshold.\n\nPublic \u2014 same gating as the other guild rollups. The info is no\nmore sensitive than what the per-player ``lastActivityTime``\nalready exposes individually.",
        "operationId": "get_guild_activity_guilds__guild_id__engagement_activity__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/engagement/contributions/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Contributions",
        "description": "Raid + daily-activity + ticket contribution rollup.\n\nDerived from each member's ``memberContribution[]`` array (now\npreserved after the Theme C un-pop). The parser classifies each\nentry into a normalised bucket (raid / territory / daily_activity\n/ guild_currency / ticket / challenge / other) via keyword\nmatching on the contribution type id \u2014 see\n:data:`app.swgoh.guild_engagement._BUCKET_KEYWORDS` for the\nrules.\n\nReturns ``totals`` per bucket, the per-member parsed rows, plus\npre-sorted ``raid_leaderboard`` / ``ticket_leaderboard`` /\n``territory_leaderboard`` slices (top 50 each) so the UI can\nrender leaderboard tables without re-sorting.\n\nPublic \u2014 same policy as the activity endpoint.",
        "operationId": "get_guild_contributions_guilds__guild_id__engagement_contributions__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/speed-sweep/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Guild Speed Sweep",
        "description": "Every member's speed on one specific unit, sorted desc.\n\nRequires login (any role) per the design decision \u2014 speed-sweep\nis an arena-scouting tool useful enough that anonymous users can\npick it up off a Google scrape; logged-in friction is the right\ncompromise. Per-player mod data is otherwise public, so the gate\nis UX-level, not a hard privacy line.\n\nReturns rows sorted by ``total_speed`` desc. Members missing the\nunit drop out (the question is \"who has the fastest X\", not \"who\nneeds to farm X\").",
        "operationId": "get_guild_speed_sweep_guilds__guild_id__speed_sweep__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "base_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          },
          {
            "name": "min_speed",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Min Speed"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/guild/{guild_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Players From Guild",
        "operationId": "get_players_from_guild_players_guild__guild_id___get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/history/counts/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player History Counts",
        "description": "Return ``{player_id: snapshot_count}`` across ``db.players_history``.\n\nIndexed ``$group`` aggregation \u2014 bounded by index size, finishes in\nmilliseconds even as the history collection grows. Frontend-friendly\ndict shape so the player picker can do ``counts[player_id]`` lookups.",
        "operationId": "get_player_history_counts_players_history_counts__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "integer"
                  },
                  "type": "object",
                  "title": "Response Get Player History Counts Players History Counts  Get"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/history/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player History",
        "description": "Return per-player slim headline snapshots, newest first.\n\nSee :meth:`Players.get_player_history` for the schema and write\nsemantics. Sync handler \u2014 only Mongo I/O, but matches the broader\npattern of using sync routes for blocking work so anyio can\nthread-pool the call.",
        "operationId": "get_player_history_players__player_id__history__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/activity/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Activity",
        "description": "Return narrative events for a player, newest first.\n\n``types`` is an optional CSV filter (e.g. ``unit_geared,unit_relic_promoted``)\n\u2014 unknown types are dropped silently rather than rejected. Empty\nor missing ``types`` returns all event types.\nSee :meth:`Players.get_player_activity` for the row shape.",
        "operationId": "get_player_activity_players__player_id__activity__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "types",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Types"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/seasons/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Seasons",
        "description": "Per-season GAC summaries for the Season History card.\n\nPublic \u2014 same gating as ``/history/`` and ``/activity/``. Returns\na paginated list of ``{season_id, league_id, division_id, rank,\npoints, wins, losses, join_time, end_time}``. Sorted newest-first\nby ``join_time`` so the most recent season is row zero.\n\nEmpty list if the player isn't tracked yet, or hasn't been\nrefreshed since the Phase 1 ingest helpers landed \u2014 the upsert\nruns on the next ``get_player`` call, so a quick refresh fills\nthe collection.",
        "operationId": "get_player_gac_seasons_players__player_id__gac_seasons__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/current/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Current",
        "description": "Live snapshot of the player's current GAC season.\n\nRead straight from the cached ``db.players`` envelope \u2014 no\nComlink call. Useful for the PlayerGac header (league/division/\nskill-rating pill, current W-L, points) without a separate\nrequest to the full player endpoint. 404 if the player isn't\ntracked at all.",
        "operationId": "get_player_gac_current_players__player_id__gac_current__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/bracket/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Bracket",
        "description": "Latest captured GAC bracket for a player, plus per-row diffs.\n\nReads the most recent ``db.gac_brackets`` snapshot and diffs it\nagainst the previous same-season snapshot \u2014 each row in the\nreturned ``players`` array carries ``points_delta`` and\n``rank_delta`` (positive ``rank_delta`` = climbed; smaller rank\nnumbers are better).\n\nPublic \u2014 same gating as ``/gac/seasons/`` and ``/gac/current/``.\nThe bracket itself doesn't expose anything more sensitive than\nthe per-player headline (opponent names + bracket points), and\nthe cadence is already bounded by the scheduled capture's TTL.\n\nReturns 404 when no bracket has ever been captured for this\nplayer. That's distinct from \"captured but empty\" \u2014 an empty\n``players`` array would surface on a snapshot CG returned with\nno entries (rare, mid-season-end edge case).",
        "operationId": "get_player_gac_bracket_players__player_id__gac_bracket__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/bracket/refresh/": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Refresh Player Gac Bracket",
        "description": "Manually capture this player's current GAC bracket.\n\nOfficer-gated. Honors the per-player 5h TTL inside\n:meth:`Gac.capture_player_bracket` \u2014 clicking twice in quick\nsuccession is a safe no-op. Wrapped via ``run_and_record`` so\nthe click shows up in the admin task-history view.\n\nReturns the capture result envelope (status / season_id /\nobserved_at / reason) verbatim so the UI can decide whether to\nshow \"captured\" toast vs \"TTL \u2014 try again later\" hint.",
        "operationId": "refresh_player_gac_bracket_players__player_id__gac_bracket_refresh__post",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/timeline/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Timeline",
        "description": "Most-recent-season snapshot timeline.\n\nConvenience shortcut for the default PlayerGac view \u2014 saves a\nround-trip discovering the latest season id. Returns the same\nenvelope as the explicit ``/timeline/{season_id}/`` route.\n\n404 when the player has zero bracket captures (i.e. Phase 2 hasn't\ningested anything for them yet).",
        "operationId": "get_player_gac_timeline_players__player_id__gac_timeline__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/seasons/{season_id}/timeline/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Season Timeline",
        "description": "Snapshot timeline for one specific captured season.\n\nDrives the per-season tab in the PlayerGac timeline UI. Returns\nevery snapshot for the (player, season) pair, each carrying the\nself deltas + the bracket \"top gainer\" for the interval ending\nat that snapshot.\n\n404 if the (player, season) pair has no captures.",
        "operationId": "get_player_gac_season_timeline_players__player_id__gac_seasons__season_id__timeline__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "season_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Season Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/seasons-with-brackets/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Seasons With Brackets",
        "description": "Distinct seasons we have at least one bracket snapshot for.\n\nPowers the season picker in the timeline UI. Returns a flat list\nof season_id strings \u2014 newest-first ordering is left to the\nclient because season_id has no canonical lex order (CG embeds\nthe season number inside a longer template id).",
        "operationId": "get_player_gac_seasons_with_brackets_players__player_id__gac_seasons_with_brackets__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/gac/opponents/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Gac Opponents",
        "description": "Head-to-head roll-up \u2014 recurring bracket-mates across all seasons.\n\nEach row carries ``appearances`` (total snapshots this opponent\nhas appeared in *our* brackets), ``season_count`` /\n``most_recent_season``, and the opponent's most-recently-observed\n``name`` + ``guild_name`` so renames / guild transfers don't\ndesync the H2H card.\n\nFrequency-only \u2014 we don't claim wins/losses here because per-round\nopponent identification isn't reliable yet (see the Phase 3\nscope notes in ``app/swgoh/gac.py``).",
        "operationId": "get_player_gac_opponents_players__player_id__gac_opponents__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 30,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/units/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Units",
        "operationId": "get_player_units_players__player_id__units__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/titles/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Titles Route",
        "description": "Player title achievements (Theme G).\n\nResolves the cached ``unlockedPlayerTitle[]`` + ``selectedPlayerTitle``\nfields against the title catalog (``db.player_title``). Returns\nthe full unlocked list with friendly names + descriptions, plus\nthe currently-displayed title for the player.\n\nPublic \u2014 same gating as the other per-player reads. No Comlink\ncall; pure derivation over the cached envelope.",
        "operationId": "get_player_titles_route_players__player_id__titles__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/compare/{left_id}/{right_id}/titles/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Diff Player Titles Route",
        "description": "Title comparison between two players for PlayerCompare.\n\nReturns left-only / right-only / shared lists (each with friendly\ntitle names) plus per-side and shared counts. Useful as a\n\"completionism\" diff \u2014 see exactly what titles one player has\nthat the other doesn't.",
        "operationId": "diff_player_titles_route_players_compare__left_id___right_id__titles__get",
        "parameters": [
          {
            "name": "left_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Left Id"
            }
          },
          {
            "name": "right_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Right Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/arena-defense/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Arena Defense",
        "description": "Squad + fleet arena defensive lineups for a player.\n\nReturns ``{squad: {rank, lineup}, fleet: {rank, lineup}}`` where\n``lineup`` is an ordered list of base_ids (leader first for squad,\ncapital ship first for fleet). Empty ``lineup`` arrays mean the\nplayer hasn't placed a defense or the cached envelope predates\nthe field \u2014 UI renders that as \"no defense placed\".\n\nRead straight from the cached ``db.players`` envelope \u2014 no Comlink\ncall. Public, same gating as the rest of the per-player reads.",
        "operationId": "get_player_arena_defense_players__player_id__arena_defense__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/units/{unit_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Unit",
        "operationId": "get_player_unit_players__player_id__units__unit_id___get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "unit_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Unit Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/mods/summary/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Mods Summary",
        "description": "Whole-roster mod analytics: headline counts + top fastest + breakdowns.\n\nWalks every unit envelope in ``db.units`` for this player, parses\neach unit's ``equippedStatMod[]`` against the ``db.stat_mods``\ntemplate cache, and rolls up to:\n\n* **headline** \u2014 speed_mod_count, gold_count, ml15_count, six_pip_count,\n  speed_arrow_count, total_roster_speed, fastest_unit\n* **all_units** \u2014 full sortable list of every modded unit, with\n  per-unit total_speed / ml15_count / has_speed_arrow etc.\n* **slot_distribution** \u2014 per-slot count + avg speed\n* **set_distribution** \u2014 per-set equipped count\n\nPublic \u2014 same gating as the rest of the per-player read paths. No\nnew Comlink calls; all derivation is over the cached unit\nenvelopes we already store.",
        "operationId": "get_player_mods_summary_players__player_id__mods_summary__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/units/{base_id}/mods/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player Unit Mods",
        "description": "Per-unit mod detail: the 6 mods + their per-mod quality / speed.\n\nUsed by the per-unit drawer in PlayerMods and as the data source\nfor an inline mod display on UnitDetail. Returns the parsed mods\n+ a per-unit summary so callers don't have to re-compute.\n\n404 if the player doesn't own the unit. Returns an empty mods\nlist (not a 404) when they own it but haven't equipped any \u2014\nthat's \"they own a freshly-unlocked unit\", not an error state.",
        "operationId": "get_player_unit_mods_players__player_id__units__base_id__mods__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{code}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Player",
        "description": "Resolve a player by ally code or player_id.\n\nDiscovery (cache miss \u2192 Comlink) requires role ``officer`` or\nhigher \u2014 that's the \"add a new player\" gate. Refreshing an\n*existing* player is open to everyone, whether implicit (the\n~28h staleness auto-refresh) or explicit (``?refresh=true``):\nComlink call frequency per player stays bounded either way and\na fresh view is the right page-load behavior for any viewer.",
        "operationId": "get_player_players__code___get",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Code"
            }
          },
          {
            "name": "refresh",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Refresh"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Players",
        "description": "Return a slim projection of every tracked player.\n\nIntentionally omits roster, stats, and profileStat[] \u2014 only the fields\na list view needs are projected server-side. See\n:meth:`Players.get_players` for the projection details.",
        "operationId": "get_players_players__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "type": "array",
                  "title": "Response Get Players Players  Get"
                }
              }
            }
          }
        }
      }
    },
    "/comlink/version": {
      "get": {
        "tags": [
          "comlink"
        ],
        "summary": "Get Version",
        "operationId": "get_version_comlink_version_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/comlink/enums": {
      "get": {
        "tags": [
          "comlink"
        ],
        "summary": "Get Enums",
        "operationId": "get_enums_comlink_enums_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/comlink/guild/{guild_id}": {
      "get": {
        "tags": [
          "comlink"
        ],
        "summary": "Get Guild",
        "operationId": "get_guild_comlink_guild__guild_id__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/comlink/player/{player_id}": {
      "get": {
        "tags": [
          "comlink"
        ],
        "summary": "Get Player",
        "operationId": "get_player_comlink_player__player_id__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "stats",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Stats"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/comlink/game/data": {
      "get": {
        "tags": [
          "comlink"
        ],
        "summary": "Get Game Data",
        "operationId": "get_game_data_comlink_game_data_get",
        "parameters": [
          {
            "name": "segment",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Segment"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Key"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/update/game-data": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Update Game Data",
        "description": "Refresh game data from Comlink into MongoDB.\n\nOptional ``segment`` (0\u20134) restricts the refresh to a single\n``getGameData`` segment. Segment 0 contains keys that aren't returned\nby 1\u20134 (notably ``unitGuideDefinition``). Optional ``key`` further\nrestricts it to a single Comlink type within that segment\n(e.g. ``key=units``).\n\n``refresh_loc`` (default ``True``) folds the localization bundle fetch\ninto the same run so each item's ``data.localized.*`` is stamped at\nwrite time. Pass ``refresh_loc=false`` when you only want to refresh a\nspecific segment without re-fetching the (large) localization payload.\n\nReturns 502 with the upstream message if Comlink is unhealthy (typically\nan APK-version mismatch on the Comlink server itself).",
        "operationId": "update_game_data_tasks_update_game_data_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "segment",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Segment"
            }
          },
          {
            "name": "key",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Key"
            }
          },
          {
            "name": "refresh_loc",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Refresh Loc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/backfill/meta-created": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Backfill Meta Created",
        "description": "One-shot: stamp ``meta.created`` on legacy docs missing it.\n\nApproximates ``meta.created`` / ``meta.created_timestamp`` from the\nexisting ``meta.updated`` / ``meta.timestamp`` values on docs where\n``meta.created`` doesn't yet exist. Idempotent \u2014 re-running after the\nfirst successful run is a no-op. Optional ``type_`` query param scopes\nthe backfill to one game-data collection (e.g. ``?type_=characters``);\nomitted, runs across every game-data collection.",
        "operationId": "backfill_meta_created_tasks_backfill_meta_created_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "type_",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Type "
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/update/guilds": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Update Guilds",
        "description": "Force-refresh every guild known to ``db.guilds`` from Comlink.\n\nIterates every doc in ``db.guilds`` and calls\n:meth:`Guilds.get_guild` with ``force=True`` per guild_id, bypassing\nthe staleness gate. One guild's failure doesn't abort the run.\nReturns per-guild outcome counts plus a capped error list.\n\nThis is the same path the scheduled ``refresh_guilds`` job runs \u2014\nhandy for manual triggers or verifying the bulk path before the\nschedule fires.",
        "operationId": "update_guilds_tasks_update_guilds_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/tasks/update/players": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Update Players",
        "description": "Force-refresh every player known via any guild in ``db.guilds``.\n\nWalks every guild doc, collects unique ``guild.member[].playerId``\nvalues, then calls :meth:`Players.get_player` with ``refresh=True``\nper id. One player's failure doesn't abort the run. Returns per-player\noutcome counts plus a capped error list.\n\nThis is the same path the scheduled ``refresh_players`` job runs.\nPlayers that exist in ``db.players`` but aren't currently in any\ntracked guild are *not* refreshed by this endpoint \u2014 by design.",
        "operationId": "update_players_tasks_update_players_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/tasks/scan/guilds": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Scan New Guilds",
        "description": "Discover guilds we don't track yet by scanning ``db.players``.\n\nWalks every player record, finds ``player.guildId`` values we don't\nalready have in ``db.guilds``, fetches each via\n:meth:`Guilds.get_guild`, and pulls any newly seen guild's members\ninto ``db.players``.\n\nSame path the scheduled ``scan_new_guilds`` job runs. Returns\n``{candidates, new_guilds, added_players, errors}``.",
        "operationId": "scan_new_guilds_tasks_scan_guilds_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        },
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ]
      }
    },
    "/tasks/update/events": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Update Events",
        "description": "Refresh live events from Comlink ``/getEvents`` into ``db.events``.\n\nEach event is flattened into one Mongo doc per ``(event, instance)``\npair so time-window queries (``active`` / ``upcoming`` / ``past``) hit\nindexed range filters directly.\n\n``refresh_loc`` (default ``True``) also refreshes the localization\nbundle so ``event.localized.*`` is stamped against the latest\ntranslations. Pass ``false`` to use whatever's currently in\n``db.localization`` and skip the loc fetch.",
        "operationId": "update_events_tasks_update_events_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "refresh_loc",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Refresh Loc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/backfill/guild-events": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Backfill Guild Events",
        "description": "One-shot: recover finished TB / TW results from stored snapshots.\n\nComlink's guild envelope only carries the last **one** Territory Battle\nand the last **eight** wars, but ``Guilds._save_history`` has been\nsnapshotting whole envelopes for as long as guilds have been tracked \u2014\nso older events are still on disk, buried in ~648 KB rows nothing read.\nThis walks them into ``db.guild_tb_results`` / ``db.guild_tw_results``.\n\nNothing is invented: a row appears only if some snapshot actually\nobserved that event. Idempotent, so re-running reports zeros rather\nthan duplicating, and it is safe to run while the daily refresh is\ngoing.",
        "operationId": "backfill_guild_events_tasks_backfill_guild_events_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "guild_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/backfill/gac-direction": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Backfill Gac Direction",
        "description": "One-shot: repair GAC promotion/demotion events stored inverted.\n\nDivision 5 is the top of a league, not Division 1, so every\n``gac_promoted`` / ``gac_demoted`` row written before that was fixed\nsays the opposite of what happened.\n\n**Dry run by default** \u2014 this rewrites history, so ``apply=false``\nreturns the counts without touching anything. Pass ``apply=true`` to\nwrite.\n\nThe direction is recomputed from each row's own ``details`` rather than\nthe type being flipped: a league change was already correct (the league\ndominates), and a blind flip would corrupt those. That also makes it\nidempotent.",
        "operationId": "backfill_gac_direction_tasks_backfill_gac_direction_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "apply",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Apply"
            }
          },
          {
            "name": "player_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/backfill/localization": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Backfill Localization",
        "description": "One-shot: stamp ``data.localized.*`` on existing game-data docs.\n\nRefreshes the localization bundle and walks every game-data collection\n(or just ``type_``), resolving ``data.{nameKey,descKey,descriptionKey}``\ninto ``data.localized.{name,desc,description}`` for each doc that has\nat least one resolvable key. Idempotent \u2014 re-running rewrites the same\nfields from scratch, no duplication.",
        "operationId": "backfill_localization_tasks_backfill_localization_post",
        "security": [
          {
            "APIKeyQuery": []
          },
          {
            "APIKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "type_",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Type "
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/units/{unit_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Unit",
        "operationId": "get_unit_units__unit_id___get",
        "parameters": [
          {
            "name": "unit_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Unit Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/units/{unit_id}/materials/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Unit Materials",
        "description": "Step-by-step gear + relic cost to take this unit to max.\n\nOne entry per remaining upgrade \u2014 finishing the gear ladder, then\neach outstanding relic tier \u2014 plus a combined ``total``. Costs are\nbaselined from what the unit has now, including partially-filled\ngear slots.\n\nTotals are gross: Comlink exposes no player inventory, so this is\nwhat the unit requires, not what's left after what the player\nalready holds.",
        "operationId": "unit_materials_units__unit_id__materials__get",
        "parameters": [
          {
            "name": "unit_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Unit Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Unit Materials Units  Unit Id  Materials  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/characters/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Characters",
        "description": "List characters.\n\nBy default returns one row per playable unit \u2014 ``canonical=true``\ncollapses the raw Comlink rows (which emit one row per rarity tier and\nseveral non-playable variants like ``PVE_*``, ``_GL_EVENT``,\n``_GLE_INHERIT``, ``_TRANSFORMED``) down to the maxRarity row of each\nplayable unit. Pass ``canonical=false`` to see every Comlink row\nunfiltered.\n\n``gl=true`` returns only Galactic Legends (``data.legend == true`` from\nComlink), ``gl=false`` returns only non-GLs, omitting the param applies\nno GL filter. Combines with ``canonical``: ``?gl=true`` alone gives\nevery GL variant, ``?gl=true&canonical=true`` (the default) gives one\nrow per playable GL.\n\n``ships=true`` returns only ships, ``ships=false`` returns only\ncharacters (i.e. non-ships), omitting the param returns both. Comlink\nlumps both unit kinds into the same ``units`` segment, hence both end\nup in this collection; the filter keys off ``data.combatType``\n(string ``\"CHARACTER\"`` or ``\"SHIP\"``).",
        "operationId": "list_characters_characters__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          },
          {
            "name": "gl",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Gl"
            }
          },
          {
            "name": "ships",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Ships"
            }
          },
          {
            "name": "canonical",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": true,
              "title": "Canonical"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Characters Characters  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/characters/names/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Character Names",
        "description": "``{baseId: display name}`` for every playable character.\n\nA slim companion to ``GET /characters/`` for the common case of\n\"turn a base_id into a name\". The full catalog is ~16 MB because\neach record carries its whole gear/skill/stat tree; this is ~20 KB.\nUse it for any name lookup, and reserve the full endpoint for\ncallers that actually read the other fields (the unit catalog and\npicker filter on combatType / obtainable, for example).",
        "operationId": "character_names_characters_names__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "type": "object",
                  "title": "Response Character Names Characters Names  Get"
                }
              }
            }
          }
        }
      }
    },
    "/characters/{character_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Character",
        "operationId": "get_character_characters__character_id___get",
        "parameters": [
          {
            "name": "character_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Character Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Character Characters  Character Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/gear/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Gear",
        "operationId": "list_gear_gear__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Gear Gear  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/gear/{gear_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Gear",
        "operationId": "get_gear_gear__gear_id___get",
        "parameters": [
          {
            "name": "gear_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Gear Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Gear Gear  Gear Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/game-data/types/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Types",
        "description": "List the game-data collections currently present in Mongo.",
        "operationId": "list_types_game_data_types__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array",
                  "title": "Response List Types Game Data Types  Get"
                }
              }
            }
          }
        }
      }
    },
    "/game-data/{type_}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Items",
        "description": "List items of one type. Supports `skip`, `limit`, and `name` regex.",
        "operationId": "list_items_game_data__type____get",
        "parameters": [
          {
            "name": "type_",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Type "
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Items Game Data  Type    Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/game-data/{type_}/{item_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Item",
        "description": "Fetch a single item from ``db[type_]`` by its Comlink id.",
        "operationId": "get_item_game_data__type____item_id___get",
        "parameters": [
          {
            "name": "type_",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Type "
            }
          },
          {
            "name": "item_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Item Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Item Game Data  Type    Item Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/mods/recommendations/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Recommendations",
        "description": "List documents from ``db.mod_recommendation``.",
        "operationId": "list_recommendations_mods_recommendations__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Recommendations Mods Recommendations  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/mods/recommendations/{recommendation_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Recommendation",
        "description": "Fetch a single mod-recommendation doc by its ``_id``.",
        "operationId": "get_recommendation_mods_recommendations__recommendation_id___get",
        "parameters": [
          {
            "name": "recommendation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Recommendation Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Recommendation Mods Recommendations  Recommendation Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/abilities/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Abilities",
        "operationId": "list_abilities_abilities__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Abilities Abilities  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/abilities/{ability_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Ability",
        "operationId": "get_ability_abilities__ability_id___get",
        "parameters": [
          {
            "name": "ability_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Ability Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Ability Abilities  Ability Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/skills/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Skills",
        "operationId": "list_skills_skills__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Skills Skills  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/skills/{skill_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Skill",
        "operationId": "get_skill_skills__skill_id___get",
        "parameters": [
          {
            "name": "skill_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Skill Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Skill Skills  Skill Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lightspeed/tokens/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Tokens",
        "description": "List documents from ``db.lightspeed_token``.",
        "operationId": "list_tokens_lightspeed_tokens__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Tokens Lightspeed Tokens  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/lightspeed/tokens/{token_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Token",
        "description": "Fetch a single Lightspeed Token by its Comlink id.",
        "operationId": "get_token_lightspeed_tokens__token_id___get",
        "parameters": [
          {
            "name": "token_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Token Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Token Lightspeed Tokens  Token Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/conquests/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Conquests",
        "description": "List documents from ``db.conquests``.",
        "operationId": "list_conquests_conquests__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Conquests Conquests  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/conquests/{conquest_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Conquest",
        "description": "Fetch a single conquest definition by its Comlink id.",
        "operationId": "get_conquest_conquests__conquest_id___get",
        "parameters": [
          {
            "name": "conquest_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Conquest Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Conquest Conquests  Conquest Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/raids/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Raids",
        "description": "List documents from ``db.guild_raids``.",
        "operationId": "list_raids_raids__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Raids Raids  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/raids/{raid_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Raid",
        "description": "Fetch a single guild-raid definition by its Comlink id.",
        "operationId": "get_raid_raids__raid_id___get",
        "parameters": [
          {
            "name": "raid_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Raid Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Raid Raids  Raid Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/territory/battles/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Battles",
        "description": "List documents from ``db.territory_battles``.",
        "operationId": "list_battles_territory_battles__get",
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          },
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Name"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Battles Territory Battles  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/territory/battles/{battle_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Battle",
        "description": "Fetch a single territory-battle definition by its Comlink id.",
        "operationId": "get_battle_territory_battles__battle_id___get",
        "parameters": [
          {
            "name": "battle_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Battle Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Battle Territory Battles  Battle Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/events/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Events",
        "description": "List event instances.\n\n``status`` filters by current time-window: ``active`` (running now),\n``upcoming`` (starts later), ``past`` (already ended). Anything else\n(including omitting it) returns the whole collection. ``type`` filters\non Comlink's readable enum string for ``event.type`` \u2014 e.g.\n``DOUBLE_DROP``, ``CONQUEST``, ``SHIP_EVENT`` \u2014 pass the value as-is.\n\nSorted most-recent-first by ``start_time_ms``.",
        "operationId": "list_events_events__get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Type"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 200,
              "title": "Limit"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Events Events  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/events/{event_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Event",
        "description": "Return the most-recent instance for ``event_id``.\n\nMany events recur (e.g. ``shipevent_PRELUDE_ACKBAR`` runs continuously);\nthis endpoint surfaces the latest occurrence as a single doc. To get a\nspecific historical instance use the ``/{event_id}/{instance_id}/`` form\nor the list endpoint with appropriate filters.",
        "operationId": "get_event_events__event_id___get",
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Event Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Event Events  Event Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/events/{event_id}/{instance_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Event Instance",
        "description": "Return one exact ``(event, instance)`` occurrence by composite key.",
        "operationId": "get_event_instance_events__event_id___instance_id___get",
        "parameters": [
          {
            "name": "event_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Event Id"
            }
          },
          {
            "name": "instance_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Instance Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Event Instance Events  Event Id   Instance Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/task-history/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Task History",
        "description": "List task-run summaries, most-recent first.\n\nOptional filters:\n\n- ``task_name`` \u2014 exact match (e.g. ``refresh_guilds``,\n  ``refresh_game_data``, ``scan_new_guilds``, \u2026).\n- ``status`` \u2014 ``success`` or ``failed``.\n- ``trigger`` \u2014 ``scheduled`` or ``manual``.\n\n``limit`` is clamped to 1000 to keep responses bounded.",
        "operationId": "list_task_history_task_history__get",
        "parameters": [
          {
            "name": "task_name",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Task Name"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Status"
            }
          },
          {
            "name": "trigger",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Trigger"
            }
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "title": "Skip"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Task History Task History  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/task-history/{run_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Task Run",
        "description": "Fetch a single task-run summary by its ``_id``.\n\nThe id is the stringified ObjectId returned in the list endpoint.",
        "operationId": "get_task_run_task_history__run_id___get",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Run Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Task Run Task History  Run Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/teams/base-ids/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Team Base Ids",
        "description": "Flat deduplicated list of every base_id used by any team slot.\n\nDrives the PlayerCompare \"key units\" head-to-head \u2014 units that\nshow up in at least one defined team are GAC-relevant by\ndefinition (officers curate by editing teams). Sorted\nalphabetically so the response is stable across calls.\n\nPublic \u2014 same policy as the rest of the team-list reads.",
        "operationId": "list_team_base_ids_teams_base_ids__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "type": "string"
                  },
                  "type": "array",
                  "title": "Response List Team Base Ids Teams Base Ids  Get"
                }
              }
            }
          }
        }
      }
    },
    "/teams/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Teams",
        "description": "List all teams, optionally filtered. Newest first.\n\nPublic \u2014 same policy as the team-readiness rollups that read\nfrom this list. Create / update / delete remain officer-gated.",
        "operationId": "list_teams_teams__get",
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Category"
            }
          },
          {
            "name": "combat_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Combat Type"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Teams Teams  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Create Team",
        "operationId": "create_team_teams__post",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTeamPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Create Team Teams  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/teams/{team_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Team",
        "description": "Single-team detail. Public \u2014 the list endpoint already returns\nthe same ``public_team`` shape for every team, so gating just one\nof them would be inconsistent. Edit / delete remain officer-gated.",
        "operationId": "get_team_teams__team_id___get",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Team Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Team Teams  Team Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "swgoh"
        ],
        "summary": "Update Team",
        "description": "Partial update.\n\nOnly fields explicitly present in the request body are touched.\nRequired-non-null fields (``name`` / ``combat_type`` / ``members``)\nsilently drop an explicit ``null`` rather than corrupting the doc;\nnullable fields (``description`` / ``category``) honor the clear.",
        "operationId": "update_team_teams__team_id___patch",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Team Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTeamPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update Team Teams  Team Id   Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "swgoh"
        ],
        "summary": "Delete Team",
        "operationId": "delete_team_teams__team_id___delete",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Team Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete Team Teams  Team Id   Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/team-readiness/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Guild Team Readiness Summary",
        "description": "Per-team bucket distributions across the whole guild.\n\nOne row per team. The frontend either renders the granular\n``buckets`` directly (twelve-bar histogram) or rolls them up into\nthe four-headline ``summary`` for the overview list.\n\nPublic \u2014 same policy as ``/guilds/{id}/unlock-readiness/``. Team\ncreation/edit/delete remains officer-gated; the *list* is just a\nderived rollup over public roster data.",
        "operationId": "guild_team_readiness_summary_guilds__guild_id__team_readiness__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Guild Team Readiness Summary Guilds  Guild Id  Team Readiness  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/team-readiness/{team_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Guild Team Readiness Detail",
        "description": "Per-member breakdown of a single team across the guild.\n\nReturns one entry per guild member with that player's tier, the\nweakest-link descriptor (when one exists), and a parallel-to-the-\nteam-roster array of slim per-slot details so the detail table\ncan colour each cell by individual unit tier.",
        "operationId": "guild_team_readiness_detail_guilds__guild_id__team_readiness__team_id___get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Team Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Guild Team Readiness Detail Guilds  Guild Id  Team Readiness  Team Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/team-readiness/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Player Team Readiness",
        "description": "Every defined team scored against one player's roster.\n\nSorted server-side by best-tier-first so the player (or anyone\nlooking at them) sees \"what they're ready for\" before \"what\nthey're missing\". Ties broken by team name for stability.\n\nPublic \u2014 same policy as ``/players/{id}/unlock-requirements/``;\nsurfacing one player's readiness against the team list doesn't\nexpose anything an officer-only roster view would have hidden.",
        "operationId": "player_team_readiness_players__player_id__team_readiness__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Player Team Readiness Players  Player Id  Team Readiness  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/unit-ownership/{base_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Guild Unit Ownership",
        "description": "Per-character ownership snapshot across one guild.\n\nWalks each member's unit doc for ``base_id`` and buckets them on\nthe same granular tier ladder team-readiness uses (``missing`` /\n``unlocked`` / ``g13`` / ``r1`` \u2026 ``r9``). Returns the headline\nownership numbers + the bucket histogram + the coarse 4-headline\nsummary the frontend uses to render the \"Your guild\" card on\nCharacterDetail.\n\nPublic \u2014 same policy as the per-character unlock endpoints. The\ndata is derived from public roster info; we don't expose\nanything ``/players/{id}/`` doesn't already.",
        "operationId": "guild_unit_ownership_guilds__guild_id__unit_ownership__base_id___get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Guild Unit Ownership Guilds  Guild Id  Unit Ownership  Base Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/characters/{base_id}/unlock-requirements/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Character Unlock Requirements",
        "description": "Catalog view: what does it take to unlock this unit?\n\n404 when the unit has no guide entry at all (most non-event\ncharacters \u2014 they're farmable, no unlock requirements). Returns\n``has_data=False`` for units that *have* a guide entry but where\nwe couldn't resolve a per-character requirement list (older\nLegendary events that gate by category rather than named units).",
        "operationId": "character_unlock_requirements_characters__base_id__unlock_requirements__get",
        "parameters": [
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Character Unlock Requirements Characters  Base Id  Unlock Requirements  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/unlock-requirements/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Player Unlock Requirements Bulk",
        "description": "Bulk: every gated character scored against the player's roster.\n\nWith ``?gl=true`` the response is restricted to Galactic Legends\n(the highest-interest unlocks); with ``?gl=false`` to non-GLs;\nomitted returns both. Default is \"everything we have a guide for\"\nso the front-end can decide what to filter client-side.\n\nPublic \u2014 same as the per-character variant. Officers don't get\nadditional info here.",
        "operationId": "player_unlock_requirements_bulk_players__player_id__unlock_requirements__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "gl",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Gl"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Player Unlock Requirements Bulk Players  Player Id  Unlock Requirements  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/unlock-requirements/{base_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Player Unlock Requirements",
        "description": "Player-scored view: catalog + this player's progress overlay.\n\nSame 404 semantics as the catalog endpoint. When the player owns\nno units at all (unknown player_id) the response still returns\n``has_data`` from the catalog and per-task ``met=False`` rather\nthan 404 \u2014 there's nothing player-specific that's missing, just\neverything-is-zero.",
        "operationId": "player_unlock_requirements_players__player_id__unlock_requirements__base_id___get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Player Unlock Requirements Players  Player Id  Unlock Requirements  Base Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/players/{player_id}/unlock-requirements/{base_id}/materials/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Player Unlock Materials",
        "description": "Total gear + relic materials still needed for this unlock.\n\nSums, across every required character the player hasn't yet brought\nto its threshold, the gear salvage / relic materials / credits\nneeded to close the gap \u2014 baselined from what each character has\n*now*, including partially-filled gear slots.\n\nKept separate from the scored endpoint above because it walks the\nrecipe tree across three collections; that endpoint is consumed by\nseveral list views and shouldn't pay this cost. Fetch this one\nlazily when the panel is opened.\n\nNote the totals are gross: Comlink exposes no player inventory, so\nthis is what the characters require, not what's left after what the\nplayer already holds. The response says so in ``caveats``.",
        "operationId": "player_unlock_materials_players__player_id__unlock_requirements__base_id__materials__get",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Player Unlock Materials Players  Player Id  Unlock Requirements  Base Id  Materials  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/unlock-readiness/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Guild Unlock Readiness Overview",
        "description": "Public guild overview: every gated character with guild-wide aggregates.\n\nFor each unlockable character (filterable to GLs / non-GLs), counts\nmembers in five buckets: already_unlocked, ready (all prereqs met\nbut not unlocked), near (within 2 prereqs), in_progress (any\nprogress), locked_away (no progress at all). Plus the top-3\nclosest members per character so the row preview tells the leader\n\"push these three\" without a click.\n\nSort: ``members_near_unlock`` desc, then ``members_unlocked`` desc,\nthen alphabetical. Surfaces \"where farm pushes pay off most\" first.",
        "operationId": "guild_unlock_readiness_overview_guilds__guild_id__unlock_readiness__get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "gl",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Gl"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Guild Unlock Readiness Overview Guilds  Guild Id  Unlock Readiness  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/guilds/{guild_id}/unlock-readiness/{base_id}/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Guild Unlock Readiness",
        "description": "Public guild rollup: every guild member ranked against one gated unit.\n\nUseful for \"who in the guild is closest to unlocking GL Luke?\" and\nfor prioritising farm assignments. Each row carries the same per-\nplayer summary the bulk player endpoint produces (overall_met,\noverall_total, already_unlocked, phases). Members not in the\nunits collection at all are still listed with everything zeroed\nso the leader sees \"we don't have roster data for X\" instead of\nsilently dropping them.",
        "operationId": "guild_unlock_readiness_guilds__guild_id__unlock_readiness__base_id___get",
        "parameters": [
          {
            "name": "guild_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Guild Id"
            }
          },
          {
            "name": "base_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Base Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Guild Unlock Readiness Guilds  Guild Id  Unlock Readiness  Base Id   Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/backfills/status": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Backfill Status",
        "description": "Current state of everything the panel can act on.\n\nCheap counts only \u2014 no scan of the ~1.9 GB snapshot collection. The\npoint is to answer \"is there anything to do here\" without running\nanything.",
        "operationId": "backfill_status_admin_backfills_status_get",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Backfill Status Admin Backfills Status Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/backfills/guild-events": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Run Guild Events Backfill",
        "description": "Recover finished TB / TW results from stored guild snapshots.\n\nIdempotent and safe to run while the daily refresh is going, so there\nis no confirmation step \u2014 the worst case is that it reports zeros.",
        "operationId": "run_guild_events_backfill_admin_backfills_guild_events_post",
        "parameters": [
          {
            "name": "guild_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Guild Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Run Guild Events Backfill Admin Backfills Guild Events Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/backfills/gac-direction": {
      "post": {
        "tags": [
          "admin"
        ],
        "summary": "Run Gac Direction Backfill",
        "description": "Repair GAC promotion/demotion events stored with the direction\ninverted.\n\n**Dry run by default.** This one rewrites history, so ``apply`` is\nopt-in here exactly as it is on the API-key surface and the command\nline \u2014 the panel shows the dry-run counts first and only then offers\nto write.",
        "operationId": "run_gac_direction_backfill_admin_backfills_gac_direction_post",
        "parameters": [
          {
            "name": "apply",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false,
              "title": "Apply"
            }
          },
          {
            "name": "player_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Player Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Run Gac Direction Backfill Admin Backfills Gac Direction Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/admin/unlock-visibility/": {
      "get": {
        "tags": [
          "admin"
        ],
        "summary": "Get Unlock Visibility",
        "description": "Editor state: full gated list + each entry's current visibility.",
        "operationId": "get_unlock_visibility_admin_unlock_visibility__get",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Get Unlock Visibility Admin Unlock Visibility  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "admin"
        ],
        "summary": "Put Unlock Visibility",
        "description": "Replace the hidden list with the editor's serialised state.",
        "operationId": "put_unlock_visibility_admin_unlock_visibility__put",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VisibilityPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Put Unlock Visibility Admin Unlock Visibility  Put"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/login": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Login",
        "description": "Verify credentials, set the session cookie, return the user.\n\nGeneric 401 on any failure \u2014 never leak whether the username exists.",
        "operationId": "login_auth_login_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Login Auth Login Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/register": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Register",
        "description": "Self-serve signup. Creates a ``viewer`` and auto-logs in.\n\nTwo failure modes return 409 \u2014 username already taken, or the\ngiven ally code is already linked to another account. The data\nlayer's unique indexes (``username``, ``player_id``) enforce both;\nwe disambiguate by inspecting which key the duplicate fired on.\n\nOfficers and admins are still admin-created via ``POST /auth/users/``.\nSelf-registration intentionally has no role field on the wire.",
        "operationId": "register_auth_register_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterPayload"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Register Auth Register Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Logout",
        "operationId": "logout_auth_logout_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": true,
                  "type": "object",
                  "title": "Response Logout Auth Logout Post"
                }
              }
            }
          }
        }
      }
    },
    "/auth/me": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "Me",
        "operationId": "me_auth_me_get",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Me Auth Me Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "auth"
        ],
        "summary": "Update Me",
        "description": "Patch the current user's preferences.\n\nOnly fields explicitly present in the request body are touched \u2014\npydantic's ``model_fields_set`` gives us the explicit-set list, so\nwe can distinguish \"omit\" from \"set to null\" without a sentinel\non the wire.",
        "operationId": "update_me_auth_me_patch",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreferencesPatch"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update Me Auth Me Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/me/password": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Change Password",
        "operationId": "change_password_auth_me_password_post",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordChangePayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Change Password Auth Me Password Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/": {
      "get": {
        "tags": [
          "auth"
        ],
        "summary": "List Users",
        "operationId": "list_users_auth_users__get",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  },
                  "title": "Response List Users Auth Users  Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Create User",
        "operationId": "create_user_auth_users__post",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateUserPayload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Create User Auth Users  Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/{username}": {
      "patch": {
        "tags": [
          "auth"
        ],
        "summary": "Update User",
        "operationId": "update_user_auth_users__username__patch",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateUserPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Update User Auth Users  Username  Patch"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "auth"
        ],
        "summary": "Delete User",
        "operationId": "delete_user_auth_users__username__delete",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Delete User Auth Users  Username  Delete"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/auth/users/{username}/password": {
      "post": {
        "tags": [
          "auth"
        ],
        "summary": "Admin Reset Password",
        "operationId": "admin_reset_password_auth_users__username__password_post",
        "parameters": [
          {
            "name": "username",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Username"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminPasswordResetPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Response Admin Reset Password Auth Users  Username  Password Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/leaderboards/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Get Leaderboard",
        "description": "Ranked top-N tracked players by one headline metric.\n\n``metric`` must be one of the keys in\n:data:`app.swgoh.leaderboards.RANKED_METRICS`; unrecognised\nmetric strings 400. ``limit`` is clamped to ``[1, 500]``.\n\n``guild_id`` (optional) scopes the ranking to a single guild's\ncurrent roster \u2014 the \"see only one guild\" filter. When the\nguild isn't tracked the response carries ``guild_not_tracked:\ntrue`` with an empty ``rows`` so the UI can show a hint.\n\nEach row carries the ranked metric value + a small set of side\nmetrics (GP / skill_rating / R7+ count / etc.) so the UI can\nrender context columns without re-fetching per player.",
        "operationId": "get_leaderboard_leaderboards__get",
        "parameters": [
          {
            "name": "metric",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "default": "gp_total",
              "title": "Metric"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "guild_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/leaderboards/metrics/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Metrics",
        "description": "List the whitelisted ranked metrics.\n\nDrives the metric picker on the leaderboards view so the frontend\ndoesn't keep a parallel table \u2014 adding a new metric is one entry\nin the backend whitelist and the picker picks it up automatically.",
        "operationId": "list_metrics_leaderboards_metrics__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "type": "array",
                  "title": "Response List Metrics Leaderboards Metrics  Get"
                }
              }
            }
          }
        }
      }
    },
    "/leaderboards/recent-unlocks/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "Recent Unlocks",
        "description": "Cross-player ``unit_acquired`` event feed, newest first.\n\n``guild_id`` (optional) scopes the feed to that guild's current\nmembers \u2014 pairs with the leaderboard's guild filter so both\npanels move together. Capped at 500. Each row carries identity +\nthe unit's base_id + rarity / gear / relic_display at acquisition\ntime. The frontend renders these with localized unit names via\nits existing catalog.",
        "operationId": "recent_unlocks_leaderboards_recent_unlocks__get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 100,
              "title": "Limit"
            }
          },
          {
            "name": "guild_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Guild Id"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/notifications/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Notifications",
        "description": "Per-user notification feed.\n\nAggregates ``db.player_events`` for the logged-in user's own\n``player_id`` plus their followed players, filtered to the\nnotifiable event types. Returns recent events + total unread\ncount (events newer than ``notifications_seen_at``).",
        "operationId": "list_notifications_me_notifications__get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 50,
              "title": "Limit"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/notifications/seen/": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Mark Notifications Seen",
        "description": "Mark all notifications as seen up to now.\n\nStamps ``users.preferences.notifications_seen_at`` to the current\nepoch second. Subsequent ``list_notifications`` calls compute\nunread_count against this watermark.",
        "operationId": "mark_notifications_seen_me_notifications_seen__post",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/follows/": {
      "get": {
        "tags": [
          "swgoh"
        ],
        "summary": "List Follows",
        "description": "Return the followed-player list with names + guild context.",
        "operationId": "list_follows_me_follows__get",
        "parameters": [
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/me/follows/{player_id}/": {
      "post": {
        "tags": [
          "swgoh"
        ],
        "summary": "Follow Player",
        "description": "Add ``player_id`` to the user's followed list. Idempotent.\n\nCapped at 50 follows per user \u2014 the cap is enforced server-side\nin :func:`app.swgoh.notifications.follow` and silently drops\nthe 51st request to keep the panel snappy.",
        "operationId": "follow_player_me_follows__player_id___post",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "swgoh"
        ],
        "summary": "Unfollow Player",
        "description": "Remove ``player_id`` from the user's followed list. Idempotent.",
        "operationId": "unfollow_player_me_follows__player_id___delete",
        "parameters": [
          {
            "name": "player_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Player Id"
            }
          },
          {
            "name": "swgoh_session",
            "in": "cookie",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "title": "Swgoh Session"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "422": {
            "description": "Validation Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        }
      }
    },
    "/": {
      "get": {
        "summary": "Root",
        "operationId": "root__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    },
    "/health/": {
      "get": {
        "tags": [
          "health"
        ],
        "summary": "Health",
        "operationId": "health_health__get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AdminPasswordResetPayload": {
        "properties": {
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password"
          }
        },
        "type": "object",
        "required": [
          "new_password"
        ],
        "title": "AdminPasswordResetPayload"
      },
      "CreateTeamPayload": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Name"
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "categories": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Categories"
          },
          "combat_type": {
            "type": "string",
            "title": "Combat Type",
            "default": "character"
          },
          "lineup_size": {
            "type": "integer",
            "maximum": 10.0,
            "minimum": 1.0,
            "title": "Lineup Size",
            "default": 5
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/TeamMember"
            },
            "type": "array",
            "maxItems": 10,
            "minItems": 1,
            "title": "Members"
          }
        },
        "type": "object",
        "required": [
          "name",
          "members"
        ],
        "title": "CreateTeamPayload"
      },
      "CreateUserPayload": {
        "properties": {
          "username": {
            "type": "string",
            "maxLength": 64,
            "minLength": 1,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "title": "Password"
          },
          "role": {
            "type": "string",
            "title": "Role",
            "default": "viewer"
          },
          "player_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Player Id"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "CreateUserPayload"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "LoginPayload": {
        "properties": {
          "username": {
            "type": "string",
            "minLength": 1,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 1,
            "title": "Password"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "LoginPayload"
      },
      "PasswordChangePayload": {
        "properties": {
          "current_password": {
            "type": "string",
            "minLength": 1,
            "title": "Current Password"
          },
          "new_password": {
            "type": "string",
            "minLength": 8,
            "title": "New Password"
          }
        },
        "type": "object",
        "required": [
          "current_password",
          "new_password"
        ],
        "title": "PasswordChangePayload"
      },
      "PreferencesPatch": {
        "properties": {
          "player_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Player Id"
          },
          "preferences": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preferences"
          }
        },
        "type": "object",
        "title": "PreferencesPatch",
        "description": "Partial-update payload for the current user.\n\nBoth fields are optional and merged independently \u2014 ``None`` for\n``player_id`` is meaningful (clears the mapping), so the patch\nhelper interprets a missing key vs. an explicit ``null`` differently."
      },
      "RegisterPayload": {
        "properties": {
          "username": {
            "type": "string",
            "maxLength": 32,
            "minLength": 3,
            "title": "Username"
          },
          "password": {
            "type": "string",
            "minLength": 8,
            "title": "Password"
          },
          "player_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Player Id"
          }
        },
        "type": "object",
        "required": [
          "username",
          "password"
        ],
        "title": "RegisterPayload",
        "description": "Self-registration payload \u2014 always lands as a ``viewer``.\n\n``player_id`` is the in-game ally code (digits only). Optional;\nusers who don't provide one set it later in Settings. Validated\nhere so the data layer's uniqueness collision is the only\nfailure mode we pass through."
      },
      "TeamMember": {
        "properties": {
          "base_id": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Base Id"
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "default": true
          },
          "min_relic": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 9.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Relic"
          },
          "min_zetas": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 10.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Zetas"
          },
          "min_omicrons": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 10.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Omicrons"
          },
          "required_skills": {
            "items": {
              "$ref": "#/components/schemas/TeamSkillRequirement"
            },
            "type": "array",
            "title": "Required Skills"
          }
        },
        "type": "object",
        "required": [
          "base_id"
        ],
        "title": "TeamMember",
        "description": "One slot in a team \u2014 base_id plus per-slot requirements.\n\n``required`` defaults to True (the today-behavior \u2014 every slot\nmust be present for the team to count as ready). ``min_relic`` is\nthe displayed relic threshold (game UI value 0\u20139), or ``None`` for\n\"no specific minimum, take whatever the unit is at\".\n\n``min_zetas`` / ``min_omicrons`` are coarse per-slot ability-count\nthresholds (officer's choice via a 0\u20133 dropdown in the editor).\n``required_skills`` is the precise list \u2014 each entry forces a\nspecific skill to be at zeta or omicron tier. Both are honoured\nAND-style by the readiness scorer: every threshold must hold.\n\nFor ship teams the relic / zeta / omicron fields are silently\ncoerced to inert defaults at the model level (see\n:func:`_coerce_ship_thresholds`)."
      },
      "TeamSkillRequirement": {
        "properties": {
          "skill_id": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Skill Id"
          },
          "kind": {
            "type": "string",
            "pattern": "^(zeta|omicron)$",
            "title": "Kind"
          }
        },
        "type": "object",
        "required": [
          "skill_id",
          "kind"
        ],
        "title": "TeamSkillRequirement",
        "description": "One per-skill requirement attached to a slot's\n``required_skills`` list. ``kind`` picks zeta vs omicron \u2014 both\nflow through the same scoring path but checked against different\ntier-flags on the skill definition."
      },
      "UpdateTeamPayload": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "categories": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Categories"
          },
          "combat_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Combat Type"
          },
          "lineup_size": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 10.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Lineup Size"
          },
          "members": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/TeamMember"
                },
                "type": "array",
                "maxItems": 10,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Members"
          }
        },
        "type": "object",
        "title": "UpdateTeamPayload",
        "description": "Partial-update payload.\n\nRequired-non-null fields (``name`` / ``combat_type`` / ``members``)\nmust validate when present; the router refuses to apply an explicit\n``null`` to them. ``description`` accepts ``null`` to clear.\n``categories`` accepts an empty list to clear all tags \u2014 there's no\n\"null\" for a list-typed field, so omit the key to leave it alone."
      },
      "UpdateUserPayload": {
        "properties": {
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role"
          },
          "player_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Player Id"
          }
        },
        "type": "object",
        "title": "UpdateUserPayload"
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "VisibilityPayload": {
        "properties": {
          "hidden_base_ids": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Hidden Base Ids"
          }
        },
        "type": "object",
        "title": "VisibilityPayload",
        "description": "Replace-the-list payload for the PUT endpoint.\n\nEach entry is a ``unit_guide_definition._id`` (== character base_id).\nItems that don't currently exist in the guide collection are still\naccepted and stored \u2014 they're harmless filters that may match a\nfuture character. Cleanup is left to the admin's discretion."
      }
    },
    "securitySchemes": {
      "APIKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "api-key"
      },
      "APIKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      }
    }
  }
}
