# Wiki Page Drafts - 2026-09-11 This directory contains drafted wiki pages based on work completed Q3 2026. Copy these to the GitHub wiki at https://github.com/ge-aero/shopdb-flask/wiki. ## New Pages to Create ### 1. ADR-019: Plugin Dynamic Settings Routes **File:** `ADR-019-Plugin-Dynamic-Settings-Routes.md` **Wiki path:** `ADRs/ADR-019-Plugin-Dynamic-Settings-Routes` **Summary:** Documents the `get_settings_routes()` hook that lets plugins dynamically register settings pages (e.g., Operating Systems in Model Catalog). Fixes lean build failures from hardcoded plugin imports. **Key sections:** - Problem: Hardcoded imports break lean builds - Decision: Backend hook + frontend dynamic route registration - Implementation: BasePlugin hook, /api/plugins/settings-routes endpoint, ModelCatalogHub integration - Benefits: Lean builds work, plugins self-contain UI, runtime flexibility - Constraints as implemented: Model Catalog is the only hub that draws plugin tabs, the tabs are not deep-linkable, and the component is bound at build time **Related commits:** fe09d2745e, d59d0c3194 --- ### 2. Security Audit - September 11, 2026 **File:** `Security-Audit-2026-09-11.md` **Wiki path:** `Security/Security-Audit-2026-09-11` **Summary:** Comprehensive security review of endpoints plugin, C# agent, and tray app. 4 critical + 6 high vulnerabilities identified. 3 critical fixed, 1 critical planned. **Key findings:** - CRITICAL FIXED: Unauthenticated inventory updates - CRITICAL FIXED: Hardcoded admin credentials - CRITICAL FIXED: Collector key exposure in git - CRITICAL PLANNED: Certificate validation disabled in agent - HIGH: Password exposure in mcp-servers.json (fixed) - HIGH: Audit log unbounded growth (planned Q4 2026) - PERFORMANCE: 99.9% improvement opportunity with delta updates **Risk matrix:** 8 critical + 10 high operational risks **Remediation status:** 7 of 18 findings fixed or mitigated --- ### 3. Maintenance Footprint Baseline **File:** `Maintenance-Footprint-Baseline.md` **Wiki path:** `Operations/Maintenance-Footprint-Baseline` **Summary:** Baseline assessment of operational burden: 936 hrs/year across database management, deployment, Docker, testing, and security. Identifies 147-205 hrs/year savings via automation. **Key metrics:** - Total burden: 936 hrs/year (23.4 work-weeks) - Deployment coordination: 312 hrs/year (air-gap burden) - Database management: 234 hrs/year (audit log retention critical) - Docker management: 156 hrs/year (log rotation missing) - Testing/validation: 130 hrs/year (pre-commit automation) - Security/compliance: 78 hrs/year (scanning + updates) **Automation:** - 13 Claude Code skills created - 147-205 hrs/year saved (from 936 baseline) - 7 quick wins identified (4 hours - 6 hours effort each) **Risk matrix:** 8 critical + 10 high operational risks --- ### 4. Architectural Findings - September 11, 2026 **File:** `Architectural-Findings-2026-09-11.md` **Wiki path:** `Architecture/Architectural-Findings-2026-09-11` **Summary:** Gortex semantic code analysis identified 22 architectural issues (6 critical, 6 high, 10 medium). Focus areas: plugin boundaries, dependency management, schema consistency. **Critical findings:** 1. Circular dependencies between plugins (violates ADR-001 isolation) 2. Undeclared import dependencies (plugins import shopdb.core internals) 3. Schema drift (SQLAlchemy models != Alembic migrations) 4. Single points of failure (no HA in production) 5. Migration chain validation gaps (ADR-008 enforcement) 6. Implicit database connection sharing (transaction isolation) **High findings:** 7. Frontend plugin import violations (ADR-013) 8. Site literals hardcoded in plugins (ADR-015) 9. Missing error handling on external calls 10. No rate limiting, no API versioning, state management inconsistencies **Remediation timeline:** Q4 2026 - Q4 2027 --- ## Pages to Update ### PLUGIN-DEVELOPMENT.md **Add section:** "Plugin Settings Routes" ```markdown ## Plugin Settings Routes Plugins can extend core settings hubs (Model Catalog, Asset Config, etc.) by declaring routes via the `get_settings_routes()` hook. ### Example: Operating Systems in Model Catalog ```python class ComputersPlugin(BasePlugin): def get_settings_routes(self) -> List[Dict]: return [{ 'hub': 'model-catalog', 'path': 'operatingsystems', 'name': 'model-catalog-os', 'tab': 'Operating Systems', 'component': '.plugins-staged/computers/views/OperatingSystemsList.vue' }] ``` The frontend fetches routes from `/api/plugins/settings-routes` and registers them dynamically via `router.addRoute()`. ### Rules for declaring one 1. **Declare `hub: 'model-catalog'` or declare nothing.** Model Catalog is the only hub whose page registers plugin tabs. A route naming any other hub (`asset-config`, `security`, `network`, ...) is dropped by the API with an error in the log, because nothing would draw it. For a settings page that belongs elsewhere, own a full page in `plugins//frontend/routes.js` instead: it is statically registered and behaves like any other route. 2. **Your frontend must be staged into the build.** `component` is a path relative to `frontend/src`, so it must be the staged copy - `.plugins-staged//views/X.vue`, made by `scripts/stage-frontend.mjs` from `plugins//frontend/views/X.vue`. Enabling the plugin at runtime does not put the file in a bundle that was built without it; that needs a frontend rebuild. 3. **Register the page in your `routes.js` too, and treat that as the real route.** The hub's import of your component is not rewritten by Vite (no static file extension in the template), so it resolves under `npm run dev` and 404s in a production build. The tab is a convenience on top of a normal plugin route, not a way to ship a page. A gate test enforces this. 4. **Do not link directly to your tab's URL.** The hub registers the route when it mounts, so the URL only resolves for someone who reached it through the hub. A bookmark, a link in an email, or a refresh on the tab lands nowhere. **Benefits:** - Lean builds work (no hardcoded plugin imports) - Plugins self-contain their UI extensions - Enable/disable changes the tabs, for a plugin already in the build **Reference:** ADR-019 Plugin Dynamic Settings Routes, section "Constraints as implemented" ``` --- ### API-REFERENCE.md **Add endpoint:** `/api/plugins/settings-routes` ```markdown ## GET /api/plugins/settings-routes Returns settings routes contributed by all enabled plugins via `get_settings_routes()` hook. A route naming a hub that does not draw plugin tabs is dropped, with an error in the server log naming the plugin and the hub. **Auth:** `settings.view` (it names the enabled plugins, the hub layout and the internal component paths; no pre-login page calls it) **Response:** ```json { "status": "success", "data": { "routes": [ { "hub": "model-catalog", "path": "operatingsystems", "name": "model-catalog-os", "tab": "Operating Systems", "component": ".plugins-staged/computers/views/OperatingSystemsList.vue" } ] } } ``` **Used by:** ModelCatalogHub, to register plugin tabs. It is the only hub page that does; the others draw their own tabs only. **Reference:** ADR-019 Plugin Dynamic Settings Routes ``` --- ### DEPLOYMENT.md **Add section:** "Air-Gap Deployment Workflow" ```markdown ## Air-Gap Deployment ShopDB deploys across three air-gapped environments: ``` Dev PC (gitea) <--USB--> Work PC (GitHub) <--USB--> Production VM ``` ### Bundle Creation ```bash # On work PC cd C:\Users\270015376\Documents\github\flask-shopdb ./pull-shopdb-bundle.cmd # Creates tarball for transfer ``` ### Deployment to Production ```bash # On production VM tar -xzf shopdb-deploy-20260911.tar.gz docker compose exec api flask db upgrade docker compose exec api flask plugin upgrade-all docker compose restart api ``` **Automation:** `/full-deploy` skill orchestrates complete workflow (saves 50-100 hrs/year) **Reference:** Maintenance-Footprint-Baseline.md (deployment coordination: 312 hrs/year baseline) ``` --- ### CONTRIBUTING.md **Add section:** "Optimized Pre-Commit Checks" ```markdown ## Pre-Commit Checks Run before every commit: ```bash bash scripts/check-naming-and-style.sh pytest tests/ -x ``` **Performance:** Script optimized 2026-09-11 for 5x faster execution: - Before: 5-10 seconds (scans all files on disk) - After: 1-2 seconds (scans only tracked files via git ls-files) **Override:** Set `USE_GIT_LS_FILES=0` to use legacy grep-based scanning: ```bash USE_GIT_LS_FILES=0 bash scripts/check-naming-and-style.sh ``` **Enforcement:** Violations block CI builds (GitHub Actions) **Commit:** 4943e182c3 - Optimize check-naming-and-style.sh ``` --- ### TESTING.md **Add section:** "Gate Tests" ```markdown ## Gate Tests Gate tests validate generated documentation and API consistency: - `tests/test_openapi_spec.py` - OpenAPI spec completeness - `tests/test_public_read_surface.py` - Public endpoint security - `tests/test_authz.py` - Authorization decorators - `tests/test_plugin_migrations.py` - Migration chain validation (ADR-008) **Important:** When you add/modify API endpoints, regenerate docs: ```bash # Update docs/openapi.json to reflect new endpoints # (Manual until docs/api-inventory.json exists) git add docs/openapi.json ``` **Enforcement:** `scripts/check-gates-ran.sh` verifies gates actually ran (not skipped) **CI failure:** "Gate tests FAILED" means docs are stale or missing ``` --- ### SECURITY.md (create if doesn't exist) **New page content:** ```markdown # Security Guidelines ## Configuration File Security **Never commit personal configuration files:** ```bash # These MUST be in .gitignore .claude/settings.json .claude/settings.local.json .claude/mcp-servers.json ``` **Why:** Personal config files may contain: - Plain-text MySQL passwords - VM SSH credentials - API keys and collector tokens - Personal authentication tokens **Incident:** 2026-09-11 - Passwords exposed in `.claude/mcp-servers.json` committed to GitHub - Fixed: Removed from git tracking, added to .gitignore - Impact: Dev environment credentials only (not production) **Reference:** Security-Audit-2026-09-11.md Finding #6 ## Credential Patterns Pre-commit hook scans for these patterns: - `shopdb_pat_*` - Collector API keys - `password = "..."` - Hardcoded passwords - `mysql://user:pass@host` - Database URLs with credentials **If blocked:** Replace hardcoded credentials with environment variables or config files ## ADR-016: Credential Delivery Production credentials delivered via: - Device tokens (for endpoints/agents) - Personal Access Tokens (for users) - Environment variables (for services) **Never:** Hardcoded in source, registry keys, git history ``` --- ## New Page: Automation & Skills **File:** Create new wiki page **Wiki path:** `Operations/Automation-Skills` ```markdown # Automation Skills Claude Code skills created Q3 2026 for common workflows. Save 147-205 hrs/year from 936 hrs baseline. ## Available Skills ### Pre-Commit Validation **Command:** `/pre-commit` **What it does:** Runs pytest, check-naming-and-style.sh, security-scan, migration-check **Savings:** 26 hrs/year **When to use:** Before every commit ### Docker Rebuild **Command:** `/docker-rebuild` **What it does:** Full Docker rebuild (prebuilt and standard), tests, restarts services **Savings:** 26 hrs/year **When to use:** After dependency changes (requirements.txt, package.json) ### Agent Deployment **Command:** `/agent-deploy-full` **What it does:** Build C# agent, deploy to VM via SSH, verify service, test heartbeat **Savings:** 26 hrs/year **When to use:** After agent code changes ### Migration Check **Command:** `/migration-check` **What it does:** Validates plugin migration chains (ADR-008), checks PLUGIN_TABLE_OWNERS order **Savings:** 13 hrs/year **When to use:** Before adding new migrations ### Production Health **Command:** `/production-health` **What it does:** System health checks (containers, API, DB, disk space, endpoints) **Savings:** 52 hrs/year **When to use:** Daily monitoring, after deploys ### Security Scan **Command:** `/security-scan` **What it does:** Scans for hardcoded credentials, exposed keys, missing auth, SQL injection **Savings:** 13 hrs/year **When to use:** Before commits, after security reviews ### VM Snapshot Management **Command:** `/vm-snapshot create "description"` **What it does:** Creates/restores/lists Hyper-V VM snapshots **Savings:** 52 hrs/year **When to use:** Before risky changes, deploys, testing ### Full Deployment **Command:** `/full-deploy` **What it does:** Complete deployment workflow (validation, bundle, deploy, verification) **Savings:** 152 hrs/year **When to use:** Production deployments across air gap ### Plugin Scaffolding **Command:** `/plugin-new "name" "description"` **What it does:** Generates complete plugin structure (BasePlugin, models, API, frontend, tests) **Savings:** 15 hrs/year **When to use:** Starting new plugins ## Total Savings | Category | Baseline (hrs/yr) | With Skills (hrs/yr) | Savings | |----------|-------------------|----------------------|---------| | Pre-commit validation | 52 | 26 | 26 | | Docker management | 52 | 26 | 26 | | Agent deployment | 52 | 26 | 26 | | Migration validation | 26 | 13 | 13 | | Production monitoring | 104 | 52 | 52 | | Security scanning | 26 | 13 | 13 | | VM snapshots | 78 | 26 | 52 | | Full deployment | 312 | 160 | 152 | | Plugin scaffolding | 30 | 15 | 15 | | **TOTAL** | **732** | **357** | **375** | Note: Realistic savings are 147-205 hrs/year due to task overlap. **Reference:** Maintenance-Footprint-Baseline.md ``` --- ## Summary **4 new wiki pages drafted:** 1. ADR-019: Plugin Dynamic Settings Routes (architectural decision) 2. Security Audit 2026-09-11 (4 critical + 6 high findings) 3. Maintenance Footprint Baseline (936 hrs/year burden, automation opportunities) 4. Architectural Findings 2026-09-11 (22 findings from Gortex analysis) **7 existing pages need updates:** 1. PLUGIN-DEVELOPMENT.md (add get_settings_routes() docs) 2. API-REFERENCE.md (add /api/plugins/settings-routes endpoint) 3. DEPLOYMENT.md (add air-gap workflow) 4. CONTRIBUTING.md (add optimized pre-commit checks) 5. TESTING.md (add gate tests explanation) 6. SECURITY.md (create new page for credential security) 7. Automation-Skills.md (create new page for skill catalog) **Total effort to publish:** ~2 hours (copy-paste to wiki, adjust formatting, add navigation links) --- ## Next Steps 1. Review drafts for accuracy (have I missed anything?) 2. Copy to GitHub wiki at https://github.com/ge-aero/shopdb-flask/wiki 3. Update wiki navigation/sidebar to include new pages 4. Link related pages (ADRs reference each other, operations pages link to security audit, etc.) 5. Notify team of new documentation --- ## Related Memory Files These wiki pages are based on memory files in `.claude/memory/`: - `security_audit_2026_09_11.md` - `maintenance_footprint_baseline.md` - `architectural_analysis_gortex_2026_09_11.md` - `security_fix_implementation.md` - `workflow_patterns.md` - `repository_structure.md` Memory files are more detailed; wiki pages are summaries for broader audience.