ShopDB Maintenance Footprint Analysis

Post Go-Live Breakpoints & User-Induced Drift for Air-Gapped Production Deployment

Executive Summary

ShopDB Flask presents a HIGH overall risk profile driven by three critical factors: air-gapped deployment topology that makes incident response 10x slower, authentication design with fleet-wide credential exposure, and unbounded data growth that will cause production failure within 6-12 months without intervention.

The system currently requires 936 annual maintenance hours (0.45 FTE), but this understates reality. Ad-hoc incident response (troubleshooting collector failures, configuration drift, migration issues) adds an estimated 104 hours/year not captured in scheduled tasks. The maintenance profile is developer-heavy (55% of effort requires code/architecture skills), making the system expensive to operate in a manufacturing environment that typically staffs operator-level skills.

936
Annual Maintenance Hours
8
Critical Risks
111
Breakpoints Identified
53
Drift Vectors

Critical Risks 8 Items

These risks pose immediate threats to production availability, security, or data integrity. Failure to address within the next quarter will result in production outages or security incidents.

High Risks 10 Items

Quick Wins (22-35 Hours Total Effort)

These 7 actions address 80% of the critical risk surface and are achievable within one quarter with developer + admin collaboration.

1. Configure Audit Log Retention
Effort: 4 hours Impact: Prevents disk exhaustion in 6 months

Add daily cron job: flask audit purge --days 90 --batch-size 5000 --max-batches 40

Reduces backup size by 60-80%, maintains 90-day compliance window.

2. Enable Backup Profile
Effort: 6 hours Impact: Establishes recovery capability currently MISSING

Add docker-compose.backup.yml to deployment, set RESTIC_PASSWORD in .env, configure daily backup schedule.

Protects against migration failures, disk corruption, ransomware. Critical for air-gapped deployment where re-deployment takes 2-3 days.

3. Downgrade Python to 3.11 LTS
Effort: 8 hours Impact: Eliminates bleeding-edge runtime risk

Change Dockerfile line 101 from python:3.14-slim to python:3.11-slim, rebuild image, test on pilot site.

Python 3.14 is alpha as of Jan 2025. 3.11 is stable LTS. Aligns Docker with dev machine (3.13.15).

4. Configure Docker Log Rotation
Effort: 2 hours Impact: Prevents host disk exhaustion

Add to daemon.json: logging: {driver: json-file, options: {max-size: 10m, max-file: 5}}

With 700 agents checking in every 15 minutes, gunicorn access logs generate 50-100MB/day. Over months fills /var/lib/docker/containers.

5. Add Disk Space Monitoring
Effort: 4 hours Impact: Proactive detection before failure

Script daily df -h and docker system df -v, alert via email if host disk >85% or db_data volume >40GB.

Gives 1-2 week warning to implement retention or expand disk before production outage.

6. Implement Endpoint Event Retention
Effort: 8 hours Impact: Prevents unbounded event accumulation (3.6M/year)

Add Flask CLI command flask endpoints prune-events --days 90, schedule daily via cron.

Maintains 90-day forensic window while preventing multi-GB table bloat. Improves query performance on endpoint detail pages.

7. Validate TRUSTED_PROXY_COUNT
Effort: 3 hours Impact: Prevents IP-based security bypass

Test: 0 for direct access, 1 for IIS/nginx proxy, verify client IP correctly extracted for rate limiting and account lockout.

Wrong proxy count allows X-Forwarded-* header spoofing (rate limit bypass) or locks out entire facility via proxy IP.

Maintenance Profile

Annual Hours: 936 (0.45 FTE)

Role Percentage Hours/Year Responsibilities
Operator 20% 195 Daily monitoring, backup verification, basic health checks
Admin 25% 235 Configuration management, user/permission management, log review, incident triage
Developer 40% 375 Dependency upgrades, plugin updates, troubleshooting, security patches
Architect 15% 140 Major version upgrades, DR drills, security audits, capacity planning

Critical Competencies Required

Phase 1: Discovery (8 Dimensions)

Multi-modal sweep of the codebase to map technical architecture, dependencies, and deployment topology. Each dimension analyzed by independent Sonnet agent.

Dependencies & Version Management
Python Runtime (3.14 Docker, 3.13.15 dev)
Docker image uses python:3.14-slim (aggressive bleeding-edge version, not yet released as stable). Dev machine runs 3.13.15. Python 3.14 is alpha/beta as of Jan 2025 and represents significant version drift risk. No .python-version file to enforce consistency.
Relevance: CRITICAL for air-gapped deployment. If 3.14 introduces breaking changes or is not available when bundles are built, deployment will fail. Should pin to stable LTS version (3.11 or 3.12) for air-gapped manufacturing environments.
Universal + Hashed Requirements (uv pip compile)
requirements.txt generated with --universal --generate-hashes flags. Provides hash verification (prevents supply chain attacks) and cross-platform resolution (single lockfile for Linux Docker + Windows dev). 40 Python packages, all hashes verified at install time.
Relevance: EXCELLENT security posture for air-gapped deployment. Hash checking prevents tampered packages. Zero CVEs in shipped Python dependencies per OSV scan.
Node.js 20 LTS and npm Dependencies
Docker uses node:20-slim for frontend build. 307 npm packages (153 dev-only). Vue 3.4.0, Vite 6.4.1. 16 CVEs found, ALL in build-only tools (vitest, vite, rollup) - NONE in shipped runtime.
Relevance: HIGH maintenance visibility needed. Build-only CVEs do not gate releases per documented policy, but Vite 6.4.1 has 3 HIGH severity advisories. Node 20 is LTS until April 2026.
MySQL 8.4 and Database Drivers
Docker image uses mysql:8.4 (latest major version). Python drivers: mysql-connector-python 9.7.0, pymysql 1.1.3. No PostgreSQL support. utf8mb4 enforced server-wide.
Relevance: MODERATE upgrade risk. MySQL 8.4 is latest Innovation track (not LTS). LTS track is 8.0.x (supported until April 2026). Should consider downgrading to mysql:8.0 LTS for production stability.
Database Schema & Migrations
Cross-plugin Migration Ordering (PLUGIN_TABLE_OWNERS)
No enforcement of inter-plugin dependency order during migration runs. If plugin B's tables have foreign keys to plugin A's tables, and both have pending migrations, arbitrary dict ordering could run plugin B before A causing FK constraint violations.
Relevance: CRITICAL for multi-plugin deployments. Failed FK during migration leaves DB inconsistent with no automated rollback. Requires manual intervention and potential data loss.
MySQL Auto-Commit Defeats Transaction Safety
MySQL DDL (CREATE TABLE, ALTER TABLE) auto-commits. If a migration creates a table then fails on subsequent DDL, the table exists but alembic_version_plugin is not stamped. Re-running hits 'table already exists' error.
Relevance: HIGH maintenance burden. Every migration failure requires manual inspection to determine DB state, manual cleanup of partial changes, and re-run. No automated recovery path.
No Pre-Migration Backup Automation
Migration runner has no backup step. Failed migration in production requires manual restore from separate backup schedule. Cutover model means 20+ plugin chains run on every deploy, each a potential failure point.
Relevance: CRITICAL for production safety. Without automated backup, failed migration on air-gapped prod site requires data loss assessment and manual recovery with no guaranteed rollback path.
Plugin Architecture & Coupling
PLUGIN_TABLE_OWNERS Dependency Graph
Central ownership map in shopdb/plugins/alembic_template.py declaring which tables each of 20+ plugins owns. Drives per-plugin migration chain filtering and upgrade order. Out of sync with actual model declarations causes migration failures.
Relevance: CRITICAL for maintenance. Adding plugin tables requires updating this dict. Migration chain breaks if ownership map drifts from models. Test coverage exists but relies on manual sync discipline.
shopdb.api Contract Surface
Stable import surface (~50 exports) that plugins use instead of internal paths. Contract versioned 0.32.0 per ADR-001/ADR-002. Breaking changes require major bump and coordinated plugin updates across air-gapped sites.
Relevance: HIGH impact on upgrades. Contract changes require testing every plugin. Pre-1.0 means contract still settling, requiring tight version coordination across sister sites.
Hard Plugin Dependencies (manifest.json)
Explicit dependency chains via manifest dependencies field. Key relationships: endpoints→computers (hostname resolution), computers has no deps (foundational). Loader does topological sort and refuses to enable plugin if dependency disabled.
Relevance: HIGH for staged rollouts. Cannot enable endpoints without computers. Disabling computers blocked if endpoints enabled. Upgrade order matters.

Phase 2: Breakpoint Analysis (111 Breakpoints)

Technical failure modes identified across 6 categories: startup, runtime, upgrade, database, integration, and security. Each breakpoint includes trigger conditions, impact assessment, likelihood, detection difficulty, and recovery complexity.

Startup Sequence Failures (18 breakpoints)

Database Health Check Failure - MySQL service never reaches healthy state, blocking migrate and api service start. Triggers: wrong credentials, port already bound, volume corruption. Detection: Easy. Recovery: Moderate.
Environment Variable Validation Failure - ProductionConfig.validate() raises ConfigError at migrate service startup. Triggers: SECRET_KEY/JWT_SECRET_KEY using dev defaults, DATABASE_URL not set. Detection: Easy. Recovery: Simple.
Core Migration Chain Failure - flask db upgrade fails with Alembic error or constraint violation. MySQL DDL auto-commit creates table then fails on subsequent DDL. Detection: Moderate. Recovery: Complex.

15 additional startup breakpoints documented in full report...

Runtime Operational Failures (21 breakpoints)

Database Connection Pool Exhaustion - 200 endpoint agents polling every 15 minutes + UI users exceed default pool size (15 total). Each gevent worker has its own pool. Likelihood: Medium. Detection: Moderate.
Disk Space Exhaustion (Database Volume) - Unbounded audit log + endpoint events + application inventory churn fill db_data volume. No retention policies configured. Likelihood: Very High. Detection: Easy (if monitored).

19 additional runtime breakpoints documented in full report...

Upgrade & Migration Failures (19 breakpoints)

Database-Specific Failures (17 breakpoints)

Integration Breakpoints (20 breakpoints)

Security Vulnerabilities (16 breakpoints)

Total: 111 breakpoints identified across all categories. Full detailed analysis with triggers, impacts, likelihood, and recovery procedures available in project documentation.

Phase 3: User Drift Analysis (53 Drift Vectors)

User-induced failure modes from settings modifications, data integrity violations, permission misconfigurations, plugin management errors, and operational neglect. Each drift vector includes user action, resulting state, symptoms, severity, reversibility, detection method, and prevention strategy.

Settings Modifications Gone Wrong (12 vectors)

Invalid site_timezone Value - Admin sets invalid IANA timezone name. Timezone parsing fails silently, falls back to America/New_York default. Severity: Moderate. Reversible: Yes.
Wrong TRUSTED_PROXY_COUNT - Setting to 1 when no proxy allows X-Forwarded-For spoofing. Setting to 0 when behind proxy locks out entire facility. Severity: Major. Reversible: Yes (requires admin access).

Data Integrity Violations (15 vectors)

Permission Misconfigurations (9 vectors)

Plugin Management Errors (8 vectors)

Operational Neglect (9 vectors)

Total: 53 drift vectors identified across all categories. Prevention strategies focus on input validation, automated checks, and operator training.

Monitoring Checklist

Daily Checks (5 minutes)

Weekly Checks (15 minutes)

Monthly Checks (1 hour)

Quarterly Checks (4 hours)

Immediate Actions (Next 30 Days)

Action Priority Effort Impact
Configure audit log retention Critical 4 hours Prevents disk exhaustion in 6 months
Enable backup profile Critical 6 hours Establishes recovery capability
Downgrade Python to 3.11 LTS High 8 hours Eliminates runtime instability risk
Configure Docker log rotation High 2 hours Prevents host disk exhaustion
Add disk space monitoring High 4 hours Proactive detection before failure
Implement endpoint event retention Medium 8 hours Prevents unbounded growth (3.6M/year)
Validate TRUSTED_PROXY_COUNT Medium 3 hours Prevents IP-based security bypass