Files
shopdb-flask/docs/wiki-drafts/README.md
cproudlock 1a6ac67cab
Some checks failed
CI / backend (push) Has been cancelled
CI / naming (push) Has been cancelled
CI / gates (push) Has been cancelled
CI / frontend (push) Has been cancelled
CI / lean-build (push) Has been cancelled
Say what a plugin settings tab can actually do, and catch a declaration that cannot work
Finding F12 of the architectural review, checked against the code and found
worse than reported: the dynamic component import cannot be rewritten by the
bundler, so the built file ships the unresolved path and a plugin tab answers
404 in every production build, staged or not. It works only under the dev
server. Nothing shipping is affected, because the one plugin that declares a
tab also registers the same page as an ordinary route, and that is the one
sites reach.

- The ADR draft now carries a "Constraints as implemented" section: only the
  model catalog hub registers plugin tabs, registration happens when that hub
  mounts so a tab is not deep-linkable and does not survive a refresh, and the
  build finding above with the bundler's own warning. The two ways out are
  stated as the open decision rather than taken.
- The hook's docstring reads as instructions to a plugin author, and its
  example no longer names a path that does not exist at build time.
- A route declared for a hub that cannot render it is dropped with an error
  naming the plugin, the hub and the hubs that do work, and the same is logged
  at startup. Enabling the plugin still succeeds: a tab nobody can reach is no
  reason to take a working backend offline.
- Tests hold the two halves together: no bundled plugin may declare a hub the
  frontend does not implement, and the list in the server must equal the hubs
  that really register routes, so the two cannot drift apart again.
2026-09-16 09:57:51 -04:00

457 lines
15 KiB
Markdown

# 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/<name>/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/<name>/views/X.vue`, made by `scripts/stage-frontend.mjs`
from `plugins/<name>/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.