feat(server/m7-cover-sources): admin cover-sources HTTP handlers

Three endpoints for the admin Settings UI:
- GET /api/admin/cover-sources — lists registered providers with
  current settings + capability badges + sources_version
- PATCH /api/admin/cover-sources/{provider_id} — updates enabled
  and/or api_key; returns version_bumped: true only when the
  enabled set changed
- POST /api/admin/cover-sources/{provider_id}/test — invokes
  TestableProvider.TestConnection; returns ok:bool + duration_ms +
  error string. Returns 200 in both success and failure cases (the
  operation completed; the test result is data, not an error).

api_key is never echoed in GET — replaced with api_key_set: bool
to follow the standard credential-display convention. PATCH
api_key: "" clears; omitting the field leaves it unchanged. PATCH
on an unknown provider_id returns 404.

All under existing RequireAdmin middleware. Routes registered
alongside the library/coverage endpoint in the /api/admin/ tree.

handlers struct gains a coverSettings *coverart.SettingsService
field; server.New + cmd/minstrel/main.go plumb the existing
coverSettings instance through.

coverart.ResetRegistryForTests() exported wrapper added so api
package tests can reset the registry without importing internals.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 13:08:45 -04:00
parent 00cd28e79b
commit b6632136b7
6 changed files with 439 additions and 5 deletions
+7
View File
@@ -153,3 +153,10 @@ func resetRegistryForTests() {
defer registry.mu.Unlock()
registry.providers = nil
}
// ResetRegistryForTests is an exported wrapper around resetRegistryForTests
// for use by tests in other packages (e.g. internal/api). Never call from
// production code.
func ResetRegistryForTests() {
resetRegistryForTests()
}