00466a9801
Introduces a manifest contract so feature containers self-describe their settings (JSON Schema + access rules). Backend and frontend gain generic plugin proxy and dynamic Extensions UI with zero feature-specific code. Doc-service is the first plugin consumer: exposes /plugin/manifest and /plugin/settings, adds a watchdog-based file watcher that auto-ingests PDFs from a mounted directory, maps subfolders to categories, supports AI-suggested folder/filename (user-confirmed), and enforces a no-remove policy. Access is gated by is_superuser or doc-service-admin group. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.3 KiB
3.3 KiB
2026-04-18 — Generic Plugin Architecture + Watch Directory Feature
Timestamp: 2026-04-18T00:00:00Z
Summary
Implemented a generic plugin/extension infrastructure that allows feature containers to self-describe their settings via a manifest contract, with no feature-specific code required in the backend or frontend. Built the watch-directory feature entirely inside the doc-service container as the first plugin consumer.
Files Added
| File | Description |
|---|---|
backend/app/routers/plugins.py |
Generic plugin proxy: GET/PATCH /api/plugins, /api/plugins/{id}/manifest, /api/plugins/{id}/settings |
frontend/src/components/PluginSchemaForm.tsx |
JSON Schema → React form renderer (boolean/string/number/readOnly) |
frontend/src/pages/PluginSettingsPage.tsx |
Generic plugin settings page driven by manifest |
features/doc-service/app/routers/plugin.py |
Doc-service plugin endpoints: /plugin/manifest, /plugin/settings |
features/doc-service/app/services/file_watcher.py |
watchdog-based PDF watcher with startup scan, folder-to-category mapping, no-remove policy |
features/doc-service/alembic/versions/0003_add_watch_columns.py |
Migration: source, watch_path, suggested_folder, suggested_filename |
dev-watch/.gitkeep |
Dev bind-mount directory for local file watcher testing |
Files Modified
| File | Description |
|---|---|
backend/app/services/service_health.py |
Also fetches and caches /plugin/manifest from healthy services |
backend/app/deps.py |
Added check_plugin_access(plugin_id, user, db) helper |
backend/app/main.py |
Mounted /api/plugins router |
frontend/src/api/client.ts |
Added plugin API functions and suggestion confirm/reject functions; extended DocumentOut with new fields |
frontend/src/components/Sidebar.tsx |
Added dynamic "Extensions" section populated from /api/plugins |
frontend/src/App.tsx |
Added /settings/plugins/:id route |
features/doc-service/app/models/document.py |
Added 4 new columns: source, watch_path, suggested_folder, suggested_filename |
features/doc-service/app/schemas/document.py |
Exposed 4 new fields in DocumentOut |
features/doc-service/app/services/config_reader.py |
Added storage config defaults, get_storage_config(), save_storage_config() |
features/doc-service/app/routers/documents.py |
Watch-user visibility (OR user_id = "watch"); 4 suggestion endpoints |
features/doc-service/app/routers/categories.py |
Watch-owned categories included in list |
features/doc-service/app/main.py |
Lifespan watcher start/stop; plugin router mounted |
features/doc-service/pyproject.toml |
Added watchdog>=4.0 |
features/doc-service/Dockerfile |
Pre-create /data/watch |
docker-compose.yml |
Added watch_data named volume; mounted to doc-service |
docker-compose.dev.yml |
Dev bind-mount ./dev-watch:/data/watch |
CLAUDE.md |
Updated all affected sections (models, migrations, endpoints, routes, tree, query keys, volumes) |
backend/STATUS.md |
Plugin system section added |
features/doc-service/STATUS.md |
Watch feature, plugin endpoints, migration 0003, updated architecture diagram |
frontend/STATUS.md |
Extensions sidebar, PluginSchemaForm, PluginSettingsPage, new API functions |