mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-13 19:25:53 +00:00
582 lines
17 KiB
Elixir
582 lines
17 KiB
Elixir
defmodule WandererAppWeb.ApiRoutes do
|
|
@moduledoc """
|
|
Centralized API route definitions using structured RouteSpec.
|
|
|
|
This module consolidates all API routes into a single version (v1)
|
|
with full feature support including filtering, sorting, pagination,
|
|
includes, and all CRUD operations.
|
|
"""
|
|
|
|
alias WandererAppWeb.ApiRouter.RouteSpec
|
|
|
|
@route_definitions %{
|
|
"1" => [
|
|
# Maps API - Full CRUD with all features
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :index_v1,
|
|
features: ~w(filtering sorting pagination includes),
|
|
metadata: %{
|
|
auth_required: false,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List all maps with full feature set"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :id),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :show_v1,
|
|
features: ~w(sparse_fieldsets includes),
|
|
metadata: %{
|
|
auth_required: false,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 201,
|
|
error_status: 422,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Create a new map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 maps :id),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update an existing map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 maps :id),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Delete a map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps :id duplicate),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :duplicate_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Duplicate an existing map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps bulk),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :bulk_create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Bulk create maps"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 maps bulk),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :bulk_update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Bulk update maps"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 maps bulk),
|
|
controller: WandererAppWeb.MapAPIController,
|
|
action: :bulk_delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Bulk delete maps"
|
|
}
|
|
},
|
|
|
|
# Characters API - Full CRUD with filtering and includes
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 characters),
|
|
controller: WandererAppWeb.CharactersAPIController,
|
|
action: :index_v1,
|
|
features: ~w(filtering sorting pagination includes),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List user characters"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 characters :id),
|
|
controller: WandererAppWeb.CharactersAPIController,
|
|
action: :show_v1,
|
|
features: ~w(sparse_fieldsets includes),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific character"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 characters),
|
|
controller: WandererAppWeb.CharactersAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :strict,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Create a new character"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 characters :id),
|
|
controller: WandererAppWeb.CharactersAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update a character"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 characters :id),
|
|
controller: WandererAppWeb.CharactersAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Delete a character"
|
|
}
|
|
},
|
|
|
|
# Map Systems API - Full CRUD with filtering and includes
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id systems),
|
|
controller: WandererAppWeb.MapSystemAPIController,
|
|
action: :index_v1,
|
|
features: ~w(filtering sorting pagination includes),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List systems for a map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id systems :id),
|
|
controller: WandererAppWeb.MapSystemAPIController,
|
|
action: :show_v1,
|
|
features: ~w(sparse_fieldsets includes),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific system"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps :map_id systems),
|
|
controller: WandererAppWeb.MapSystemAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Create a new system"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 maps :map_id systems :id),
|
|
controller: WandererAppWeb.MapSystemAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update a system"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 maps :map_id systems :id),
|
|
controller: WandererAppWeb.MapSystemAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Delete a system"
|
|
}
|
|
},
|
|
|
|
# Map Connections API
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id connections),
|
|
controller: WandererAppWeb.MapConnectionAPIController,
|
|
action: :index_v1,
|
|
features: ~w(filtering sorting pagination),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List connections for a map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id connections :id),
|
|
controller: WandererAppWeb.MapConnectionAPIController,
|
|
action: :show_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific connection"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps :map_id connections),
|
|
controller: WandererAppWeb.MapConnectionAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Create a new connection"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 maps :map_id connections :id),
|
|
controller: WandererAppWeb.MapConnectionAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update a connection"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 maps :map_id connections :id),
|
|
controller: WandererAppWeb.MapConnectionAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Delete a connection"
|
|
}
|
|
},
|
|
|
|
# Webhooks API
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id webhooks),
|
|
controller: WandererAppWeb.MapWebhooksAPIController,
|
|
action: :index_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List webhooks for a map"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id webhooks :id),
|
|
controller: WandererAppWeb.MapWebhooksAPIController,
|
|
action: :show_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific webhook"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 maps :map_id webhooks),
|
|
controller: WandererAppWeb.MapWebhooksAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Create a new webhook"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 maps :map_id webhooks :id),
|
|
controller: WandererAppWeb.MapWebhooksAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update a webhook"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 maps :map_id webhooks :id),
|
|
controller: WandererAppWeb.MapWebhooksAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Delete a webhook"
|
|
}
|
|
},
|
|
|
|
# Real-time Events API
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 maps :map_id events stream),
|
|
controller: WandererAppWeb.Api.EventsController,
|
|
action: :stream_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :relaxed,
|
|
success_status: 200,
|
|
content_type: "text/event-stream",
|
|
description: "Stream real-time events for a map"
|
|
}
|
|
},
|
|
|
|
# Access Lists API
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 acls),
|
|
controller: WandererAppWeb.AccessListAPIController,
|
|
action: :index_v1,
|
|
features: ~w(filtering sorting pagination),
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "List access control lists"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :get,
|
|
path: ~w(api v1 acls :id),
|
|
controller: WandererAppWeb.AccessListAPIController,
|
|
action: :show_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Show a specific access list"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 acls :id),
|
|
controller: WandererAppWeb.AccessListAPIController,
|
|
action: :update_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update an access list"
|
|
}
|
|
},
|
|
|
|
# ACL Members API
|
|
%RouteSpec{
|
|
verb: :post,
|
|
path: ~w(api v1 acls :acl_id members),
|
|
controller: WandererAppWeb.AccessListMemberAPIController,
|
|
action: :create_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 201,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Add a member to an access list"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :put,
|
|
path: ~w(api v1 acls :acl_id members :member_id),
|
|
controller: WandererAppWeb.AccessListMemberAPIController,
|
|
action: :update_role_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 200,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Update a member's role"
|
|
}
|
|
},
|
|
%RouteSpec{
|
|
verb: :delete,
|
|
path: ~w(api v1 acls :acl_id members :member_id),
|
|
controller: WandererAppWeb.AccessListMemberAPIController,
|
|
action: :delete_v1,
|
|
features: [],
|
|
metadata: %{
|
|
auth_required: true,
|
|
rate_limit: :standard,
|
|
success_status: 204,
|
|
content_type: "application/vnd.api+json",
|
|
description: "Remove a member from an access list"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
@deprecated_versions []
|
|
@sunset_dates %{}
|
|
|
|
def table, do: @route_definitions
|
|
def deprecated_versions, do: @deprecated_versions
|
|
def sunset_date(version), do: Map.get(@sunset_dates, version)
|
|
|
|
@doc """
|
|
Get all routes for a specific version.
|
|
"""
|
|
def routes_for_version(version) do
|
|
Map.get(@route_definitions, version, [])
|
|
end
|
|
|
|
@doc """
|
|
Get all available versions.
|
|
"""
|
|
def available_versions do
|
|
Map.keys(@route_definitions)
|
|
end
|
|
|
|
@doc """
|
|
Check if a version is deprecated.
|
|
"""
|
|
def deprecated?(version) do
|
|
version in @deprecated_versions
|
|
end
|
|
|
|
@doc """
|
|
Validate all route definitions on module load.
|
|
"""
|
|
def validate_all_routes do
|
|
Enum.reduce(@route_definitions, [], fn {version, routes}, errors ->
|
|
version_errors =
|
|
Enum.reduce(routes, [], fn route_spec, acc ->
|
|
case RouteSpec.validate(route_spec) do
|
|
{:ok, _} -> acc
|
|
{:error, error} -> [{version, route_spec, error} | acc]
|
|
end
|
|
end)
|
|
|
|
errors ++ version_errors
|
|
end)
|
|
end
|
|
end
|