Add JSON REST API for MCP integration
Build, Lint, and Test / Build, Lint, and Test (push) Failing after 13m0s

- Add /api/v1 namespace with Bearer token auth (PINCHFLAT_API_TOKEN env var)
- API controllers for sources, media items, media profiles, settings, tasks
- Support for all source actions: create, update, delete, force_download_pending,
  force_redownload, force_index, force_metadata_refresh, sync_files_on_disk
- Media item endpoints: list, show, search, force_download, update, delete
- Media profile CRUD endpoints
- Settings show/update and app_info endpoints
- Task listing endpoints
- Add Jason.Encoder for Task schema
- Comprehensive test suite for all API endpoints
- Gitea Actions CI workflow (runs existing checks + API-specific tests)
- API documentation in docs/API.md
This commit is contained in:
2026-07-03 23:22:24 +00:00
parent 67d8bd5598
commit 172c1ff264
19 changed files with 1122 additions and 1 deletions
+46
View File
@@ -20,6 +20,10 @@ defmodule PinchflatWeb.Router do
plug :accepts, ["json"]
end
pipeline :api_auth do
plug PinchflatWeb.ApiAuthPlug
end
scope "/", PinchflatWeb do
pipe_through [:maybe_basic_auth, :token_protected_route]
@@ -71,6 +75,48 @@ defmodule PinchflatWeb.Router do
get "/healthcheck", HealthController, :check, log: false
end
# JSON API for MCP integration and other programmatic clients.
# Protected by Bearer token auth (PINCHFLAT_API_TOKEN env var).
scope "/api/v1", PinchflatWeb.Api.V1 do
pipe_through [:api, :api_auth]
get "/sources", ApiSourceController, :index
get "/sources/:id", ApiSourceController, :show
post "/sources", ApiSourceController, :create
put "/sources/:id", ApiSourceController, :update
patch "/sources/:id", ApiSourceController, :update
delete "/sources/:id", ApiSourceController, :delete
post "/sources/:source_id/force_download_pending", ApiSourceController, :force_download_pending
post "/sources/:source_id/force_redownload", ApiSourceController, :force_redownload
post "/sources/:source_id/force_index", ApiSourceController, :force_index
post "/sources/:source_id/force_metadata_refresh", ApiSourceController, :force_metadata_refresh
post "/sources/:source_id/sync_files_on_disk", ApiSourceController, :sync_files_on_disk
get "/media", ApiMediaItemController, :index
get "/media/search", ApiMediaItemController, :search
get "/media/:id", ApiMediaItemController, :show
put "/media/:id", ApiMediaItemController, :update
patch "/media/:id", ApiMediaItemController, :update
delete "/media/:id", ApiMediaItemController, :delete
post "/media/:media_item_id/force_download", ApiMediaItemController, :force_download
get "/media_profiles", ApiMediaProfileController, :index
get "/media_profiles/:id", ApiMediaProfileController, :show
post "/media_profiles", ApiMediaProfileController, :create
put "/media_profiles/:id", ApiMediaProfileController, :update
patch "/media_profiles/:id", ApiMediaProfileController, :update
delete "/media_profiles/:id", ApiMediaProfileController, :delete
get "/settings", ApiSettingController, :show
put "/settings", ApiSettingController, :update
patch "/settings", ApiSettingController, :update
get "/app_info", ApiSettingController, :app_info
get "/tasks", ApiTaskController, :index
get "/tasks/:id", ApiTaskController, :show
end
scope "/dev" do
pipe_through :browser