# Ops Dashboard - Project Context ## Key Paths | What | Path | |------|------| | **Code repo (local)** | `~/dev/ai/OPS/` | | **Code repo (server)** | `/opt/data/ops-dashboard/` | | **Code repo (remote)** | `git.mnsoft.org/git/APPS/ops-dashboard.git` | | **Infrastructure repo (server)** | `/opt/infrastructure/` | | **Infrastructure repo (remote)** | `git.mnsoft.org/git/APPS/infrastructure.git` | | **Notes** | `~/dev/ai/OPS/Notes/` | | **TODO** | `~/dev/ai/OPS/Notes/TODO.md` | ## Server Access ```bash ssh mdf-system.ch # root, port 99 (via ~/.ssh/config) ``` ## Application | What | Detail | |------|--------| | **URL** | https://ops.tekmidian.com | | **Auth token** | `ops-mdf-2026-secure` | | **Container** | `ops-dashboard` | | **Stack** | FastAPI backend, vanilla JS frontend, SSE for real-time ops | ## Architecture - Container mounts: `/opt/data`, `/opt/infrastructure`, `/var/run/docker.sock` + app source - Container has pyyaml 6.0.3 — can import toolkit directly - nsenter bridge for host operations (backup, restore, sync, promote, gen-timers) - `OPS_CLI` = `/usr/local/bin/ops` on host (bash shim -> `python3 -m toolkit.cli`) - Toolkit: `/opt/infrastructure/toolkit/` — 12 Python modules - Registry: `project.yaml` descriptors at `/opt/data/{project}/project.yaml` (source of truth) ## Dashboard Pages | Page | Purpose | |------|---------| | **Dashboard** | Status tiles, project drill-down | | **Services** | Container cards, restart / logs / terminal | | **Backups** | Date-grouped, local + offsite, restore modal, multi-select delete | | **Operations** | Promote, sync, rebuild — SSE streaming modals | | **Schedules** | Backup timer management, edit modal | | **System** | CPU / mem / disk, health checks, timers | ## Deploy ```bash rsync -avz --delete ~/dev/ai/OPS/app/ mdf-system.ch:/opt/data/ops-dashboard/app/ rsync -avz --delete ~/dev/ai/OPS/static/ mdf-system.ch:/opt/data/ops-dashboard/static/ ssh mdf-system.ch 'docker restart ops-dashboard' ``` ## Mandatory Rules - **Never edit files directly on the server** — always rsync from local, then restart - **project.yaml is source of truth** — never hardcode project/env lists in the dashboard - **toolkit is importable** — use `from toolkit.X import Y` directly inside the container; no subprocess ops calls for data reads - **nsenter for mutations** — backup, restore, sync, promote must go through the nsenter bridge to the host Python venv, not direct toolkit calls - **SSE for long ops** — any operation that may take >2s must stream progress via SSE, never block the HTTP response