Files
wanderer/lib/wanderer_app_web/api_router/routes.ex
2025-07-16 23:17:47 +00:00

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