# Dashboard Ops Controls & Reports v1

Use this reference for FinanceManager sprints that add local operations controls and runtime-only reports to the Vue/FastAPI dashboard.

## Scope boundary

- Build Ops controls first, then Reports. Do not start new import sources, grocery expansion, fixed-cost expansion, OCR/camera, provider integrations, schedulers, cloud deployment, tax reports, backtests, analyst ratings, or watchlists unless explicitly re-authorized.
- Keep the system local-first and Tailscale-compatible.
- Never put API keys in the frontend. Never commit runtime DBs, generated reports, raw CSVs, PDFs, spreadsheets, or real financial values.
- In chat summaries, report only yes/no status, test counts, hashes, links, and aggregate/sanitized status. Do not quote real report amounts.

## Safe Ops controls pattern

1. Add fixed scripts under `scripts/`, e.g.:
   - `restart_backend.sh`
   - `restart_frontend.sh`
   - `restart_dashboard.sh`
2. Scripts must:
   - start backend on `0.0.0.0:8000`;
   - start frontend on `0.0.0.0:5173`;
   - set `VITE_API_BASE_URL` to the browser-visible Tailscale backend origin, e.g. `http://<tailscale-ip>:8000`;
   - stop existing processes cleanly using PID files/known port ownership;
   - write PID/logs only under the external runtime directory, e.g. `~/jarvis_runtime/finance-system/logs/`;
   - avoid logging secrets.
3. Backend Ops service must use an allowlist of action names to fixed repo script paths. It must never accept free-form commands, user-provided paths, shell fragments, or token/log passthrough from the UI.
4. API endpoints should be small and sanitized:
   - `GET /api/system/status`
   - `POST /api/system/restart-backend`
   - `POST /api/system/restart-frontend`
   - `POST /api/system/restart-dashboard`
5. Endpoint responses should contain only fields such as `status`, `action`, `started_at`, `finished_at`, `message`, `error`, `return_code`; never return full logs or environment data.
6. Write an audit-like Ops event to runtime, e.g. `logs/ops_actions.jsonl`.
7. Frontend header control should be compact: a `System` button/dropdown with Backend/Frontend status, API URL, runtime DB availability, last restart if known, and restart actions.
8. Every restart action needs a confirmation dialog and reloads system status afterward. Toast/message feedback should be success/error only, not long logs.

## Reports v1 runtime-only pattern

Report engine should live backend-side and write only under `~/jarvis_runtime/finance-system/reports/`.

Supported MVP report types:

- `budget_monthly`: month, confirmed income/expense, net cashflow, budget consumption, fixed costs, top categories, top merchants, budget overrun/missing-budget hints, open review candidates, duplicate/covered hints, data quality.
- `cashflow_household`: income vs expenses by month, net cashflow, savings rate, fixed-cost ratio, variable/one-off expenses where classified, transfers and investment transfers separately.
- `budget_review_status`: open candidates, auto-categorized, needs-review, duplicates, covered-by-source, transfers, possible income, candidates by source such as VISA/Migros/AKB/Raiffeisen/manual, merchant/rule status, next actions.
- `crypto_status`: use existing local data only; total value if available, coin count, wallet count, biggest positions, missing/stale prices, wallet verification, last price update, existing report link if present.
- `portfolio_status`: local MVP summary: total portfolio if available, equities/ETF, cash, crypto, unvalued positions, missing prices/FX, data-quality warnings.

Rules:

- Actuals are confirmed-only. Candidates never count as real income/expense.
- Transfers, credit-card settlements, `covered_by_source`/`covered_by_migros`, ignored/superseded/reference candidates stay separate.
- Use strict period validation (`YYYY-MM` for month reports, `YYYY` where yearly cashflow is needed) and exclusive upper-bound month ranges.
- Generate metadata and an event such as `report_generated` in runtime, e.g. `reports/report_events.jsonl`.
- Support HTML and Markdown. If PDF is requested but no renderer exists, generate HTML fallback and record a warning/status rather than failing the whole flow.
- Report list/download APIs must only serve files resolved under the runtime reports directory. Protect against path traversal.

## Reports UI pattern

On `/reports` expose:

- report type selector;
- period/month/year selector;
- format selector: HTML, Markdown, PDF-if-available;
- Preview button;
- Generate button;
- list of existing runtime reports;
- open/download link.

Keep the page as a local runtime surface. Avoid dark/low-contrast legacy classes if the dashboard has a light PrimeVue/Aura style gate.

## Tests and verification

Backend tests:

- system status endpoint returns backend/frontend/API/runtime fields;
- restart endpoints call only allowlisted script paths;
- invalid action is rejected;
- script failure returns sanitized error with no secret/log leak;
- report writes under runtime reports only;
- report metadata and `report_generated` event are written;
- HTML fallback works for PDF request;
- budget monthly counts confirmed income/expense and excludes candidates/transfers;
- cashflow computes income/expense/net/savings/fixed-cost ratios and keeps transfers separate;
- review status groups candidates by source/status including duplicates and covered rows;
- crypto/portfolio reports degrade to warnings when local data is missing rather than calling providers.

Frontend tests:

- header System controls visible;
- restart buttons require confirm;
- success/error message or toast shown;
- status reload happens after action;
- reports page renders;
- report type/period/format selectable;
- preview and generate actions work;
- runtime reports list is visible.

Full gate before final report:

- `python -m compileall -q src tests`
- full `pytest`
- full frontend test suite
- `npm run build`
- source secret scan with realistic token regexes; avoid false positives from harmless CSS/package substrings
- frontend build secret scan
- Git-safety for runtime/report/DB artifacts
- browser/Tailscale sanity for Command Center, Reports, System Header, Budget Übersicht, Data Explorer
- `git diff --check`
- commit, push, remote hash equality

## Pitfalls

- Do not run `npm install` as part of normal restart if `node_modules` already exists; start Vite directly unless dependencies changed.
- Do not make the backend restart endpoint depend on user-provided shell text. Self-restart can be implemented via fixed script/supervisor semantics; if technically fragile, schedule the restart after the HTTP response or document the supervisor recommendation.
- Do not expose absolute report paths as the only user-facing affordance; use open/download links, while still keeping files runtime-only.
- Full frontend style gates may reject dark preview panels (`bg-slate-950`, `text-slate-100`) on PrimeVue/Aura pages. Use light code/preview surfaces.
- Browser-check Command Center after API tests; it can retain legacy KPI/status queries even if backend unit tests pass.
