# 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 |