Add service admin groups, combined settings pages, single Settings button
- Auto-create {service-id}-admin groups at startup (group_bootstrap.py)
- get_service_admin() dep: grants access to superusers OR service group members
- /api/settings/ai and /api/settings/documents/limits now allow service admins
- AI service exposes /plugin/manifest (ai-service-admin access group)
- DocServiceSettingsPage: combined upload limits + watch directory on one page
- ServiceAdminRoute in frontend guards new /apps/documents/settings and /apps/ai/settings
- Single Settings button per app card (visible to admins and service group members)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,7 @@ docker compose up --build -d
|
||||
│ ├── app/
|
||||
│ │ ├── main.py ← App factory, router registration, lifespan (health loop)
|
||||
│ │ ├── database.py ← AsyncEngine, AsyncSessionLocal, Base
|
||||
│ │ ├── deps.py ← get_current_user, get_current_admin, check_plugin_access
|
||||
│ │ ├── deps.py ← get_current_user, get_current_admin, get_service_admin(id), check_plugin_access
|
||||
│ │ ├── core/
|
||||
│ │ │ ├── config.py ← All settings via pydantic-settings (reads .env)
|
||||
│ │ │ ├── security.py ← JWT sign/verify (RS256), bcrypt hash/verify
|
||||
@@ -111,7 +111,8 @@ docker compose up --build -d
|
||||
│ │ │ ├── categories_proxy.py ← Transparent proxy → doc-service /categories/*
|
||||
│ │ │ └── documents_proxy.py ← Transparent proxy → doc-service /documents/*
|
||||
│ │ └── services/
|
||||
│ │ └── service_health.py ← Background 30s health-check loop; caches /plugin/manifest per service
|
||||
│ │ ├── service_health.py ← Background 30s health-check loop; caches /plugin/manifest per service
|
||||
│ │ └── group_bootstrap.py ← Ensures {service-id}-admin group exists for every registered service at startup
|
||||
│ ├── alembic/
|
||||
│ │ ├── env.py ← Async migration runner
|
||||
│ │ └── versions/ ← Migration chain (see Migrations section)
|
||||
@@ -126,6 +127,7 @@ docker compose up --build -d
|
||||
│ │ │ ├── routers/chat.py ← POST /chat (sync, NORMAL priority queue)
|
||||
│ │ │ ├── routers/health.py ← GET /health
|
||||
│ │ │ ├── routers/queue.py ← GET /queue/status, /pause, /resume, /cancel/{id}
|
||||
│ │ │ └── routers/plugin.py ← GET /plugin/manifest (access rules for ai-service-admin group)
|
||||
│ │ │ ├── providers/base.py ← AIProvider abstract class
|
||||
│ │ │ ├── providers/anthropic_provider.py
|
||||
│ │ │ ├── providers/openai_compat.py ← Ollama / LM Studio
|
||||
@@ -174,6 +176,7 @@ docker compose up --build -d
|
||||
│ │ ├── PluginSchemaForm.tsx ← JSON Schema → React form (boolean/string/number/readOnly)
|
||||
│ │ └── ui/ ← shadcn/ui components (Button, Input, …)
|
||||
│ ├── pages/ ← One file per route (see Routes section)
|
||||
│ │ ├── DocServiceSettingsPage.tsx ← Combined doc-service settings: upload limits + watch directory
|
||||
│ │ └── PluginSettingsPage.tsx ← Generic plugin settings page driven by manifest
|
||||
│ ├── lib/utils.ts ← cn() = clsx + tailwind-merge
|
||||
│ └── styles/theme.css ← CSS custom properties, Tailwind setup
|
||||
@@ -465,8 +468,8 @@ Auth: is_superuser OR member of group listed in manifest `required_groups`. Retu
|
||||
| `/` | `DashboardPage` | PrivateRoute |
|
||||
| `/apps` | `AppsPage` | PrivateRoute |
|
||||
| `/apps/documents` | `DocumentsPage` | PrivateRoute |
|
||||
| `/apps/documents/settings/admin` | `DocumentAdminSettingsPage` | AdminRoute |
|
||||
| `/apps/ai/settings/admin` | `AIAdminSettingsPage` | AdminRoute |
|
||||
| `/apps/documents/settings` | `DocServiceSettingsPage` | ServiceAdminRoute (is_admin OR doc-service-admin member) |
|
||||
| `/apps/ai/settings` | `AIAdminSettingsPage` | ServiceAdminRoute (is_admin OR ai-service-admin member) |
|
||||
| `/profile` | `ProfilePage` | PrivateRoute |
|
||||
| `/settings` | `SettingsPage` | PrivateRoute |
|
||||
| `/settings/plugins/:id` | `PluginSettingsPage` | PrivateRoute (auth enforced per-plugin by backend) |
|
||||
|
||||
Reference in New Issue
Block a user