feat(mounts): P4 — admin CRUD endpoints + frontend admin tab

Mounts are now configurable at runtime without DB surgery.

Backend (admin-gated, /api/admin/external-mounts):
- GET    list all configured mounts
- POST   create: validate the provider config up front, create a mount-root
         folder under the admin's drive, insert the row, hot-reload the registry
- DELETE remove the mount row + its root folder (host content is left intact),
         then hot-reload
- ExternalMountRepositoryPort gains create/delete (PG impl); registry.reload()
  runs in-process so changes are live immediately
- audit lines event="external_mount.config" action=create|delete

Frontend:
- admin.ts endpoints: listExternalMounts / createExternalMount / deleteExternalMount
- new "External Mounts" tab in the admin page: add form (name + host path +
  read-only) and a list with delete

Integration test for the repo create/delete round-trip (testcontainers).
This commit is contained in:
Bradley Nelson
2026-06-25 01:07:03 -06:00
parent d8229650ef
commit 07320a3925
7 changed files with 510 additions and 4 deletions
@@ -33,7 +33,17 @@ use uuid::Uuid;
/// Admin API routes — all require admin role.
pub fn admin_routes() -> Router<Arc<AppState>> {
use super::admin_external_mounts as ext_mounts;
Router::new()
// External file mounts
.route(
"/external-mounts",
get(ext_mounts::list_external_mounts).post(ext_mounts::create_external_mount),
)
.route(
"/external-mounts/{id}",
delete(ext_mounts::delete_external_mount),
)
// OIDC settings
.route("/settings/oidc", get(get_oidc_settings))
.route("/settings/oidc", put(save_oidc_settings))