feat(home): import doris dashboard from workspace repo

Migrates workspace-only dashboard work from commits 6f0c5cd, c851073, and d04eff3 into the canonical truenas-stacks repo.
This commit is contained in:
Fizzlepoof
2026-05-14 18:14:34 +00:00
parent 84b87baf2c
commit d7670fde4b
11 changed files with 977 additions and 1 deletions

View File

@@ -0,0 +1,238 @@
# Doris Dashboard
Local static homepage for Johns morning briefing and peek-anytime news dashboard.
Canonical path:
```bash
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
```
Generated page:
```bash
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public/index.html
```
## What it shows
- Morning briefing with fleshed-out cards
- Today panel for calendar placeholders
- To-do panel for Donetick/to-do placeholders
- Notes panel
- Sky / Space
- Homelab / Smart Home / Ham Radio
- Local news
- Other signal
- Source/candidate stats
## Generate manually
```bash
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
bin/generate_dashboard.py
```
## Preview locally
```bash
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public
python3 -m http.server 8787
```
Then open:
```text
http://localhost:8787/
```
If viewing from another machine on the LAN, use NOMADs LAN IP instead of localhost and make sure the firewall allows the port.
## Cron refresh
Installed in `fizzlepoof`s crontab:
```cron
# BEGIN DORIS DASHBOARD
DORIS_DASHBOARD_DIR=/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
# Refresh local dashboard after digest collection windows.
5,35 6-23 * * * cd $DORIS_DASHBOARD_DIR && bin/generate_dashboard.py >> logs/generate.log 2>&1
# END DORIS DASHBOARD
```
Inspect with:
```bash
crontab -l | sed -n '/# BEGIN DORIS DASHBOARD/,/# END DORIS DASHBOARD/p'
```
## Data inputs
Main news source:
```bash
/home/fizzlepoof/.openclaw/workspace/doris-digest/data/candidates.json
/home/fizzlepoof/.openclaw/workspace/doris-digest/data/preferences.json
```
Local dashboard placeholders:
```bash
data/todos.json
data/calendar.json
data/notes.json
```
These are intentionally simple JSON arrays so calendar/Donetick integrations can be added later without rewriting the page.
## Next integrations to add
1. Donetick tasks
2. Calendar events
3. Weather / severe weather
4. Moon phase / ISS passes / meteor shower calendar
5. Homelab health pulse
6. Article feedback buttons or quick links back to Doris
## Privacy/deployment note
This dashboard is local-only on NOMAD unless John explicitly asks to expose it. Do not publish it externally without asking.
## LAN service
The dashboard is exposed on NOMAD's LAN IP via systemd:
```text
http://10.5.1.16:8787/
```
Service file:
```bash
/etc/systemd/system/doris-dashboard.service
```
Manage it:
```bash
sudo systemctl status doris-dashboard.service
sudo systemctl restart doris-dashboard.service
sudo systemctl stop doris-dashboard.service
```
The service runs as `fizzlepoof`, serves `public/`, binds `0.0.0.0:8787`, and regenerates the page before starting.
At setup time UFW was inactive, so no firewall rule was required.
## Buildout added 2026-05-12
The dashboard generator now builds a richer local homepage directly on NOMAD.
Added sections/data:
- Weather metrics for Clarksville via Open-Meteo (`data/weather.json`)
- Moon phase / sky note calculated locally (`data/sky.json`)
- Homelab pulse checks (`data/homelab.json`): dashboard service, cron, digest freshness, workspace disk
- Article export from Doris Digest candidates (`data/articles.json`)
- Dashboard metadata (`data/dashboard.json`)
The generated page still lives at:
```bash
/home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard/public/index.html
```
And the LAN service remains:
```text
http://10.5.1.16:8787/
```
Verification commands:
```bash
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
python3 -m py_compile bin/generate_dashboard.py
bin/generate_dashboard.py
curl -fsS http://127.0.0.1:8787/ | grep 'Doris Dashboard'
systemctl is-active doris-dashboard.service
crontab -l | sed -n '/# BEGIN DORIS DASHBOARD/,/# END DORIS DASHBOARD/p'
```
Notes:
- Weather.gov and NASA API are not used; Open-Meteo worked reliably without an API key.
- Donetick live task import is still not enabled in the dashboard; `data/todos.json` remains the safe placeholder until the exact read-only endpoint is confirmed.
- Raw secrets are not written to dashboard output.
## Compact news layout
2026-05-13: News/article sections were changed from large cards to compact rows so the dashboard can keep plenty of articles without making John scroll forever.
Implementation:
- `generate_dashboard.py` renders article sections with `compact-card` rows by default.
- `public/style.css` contains the compact layout rules.
- Metrics/weather/homelab pulse remain large cards.
## Donetick integration
2026-05-13: The dashboard now imports open Donetick chores read-only during generation.
Implementation notes:
- Secrets remain encrypted in `/home/fizzlepoof/.openclaw/workspace/.secrets/donetick_secrets.json.enc`.
- `bin/generate_dashboard.py` decrypts secrets at runtime using the local encryption key and logs in with the Doris service account.
- It reads `/api/v1/chores` and `/api/v1/users` only.
- It writes sanitized task data to `data/todos.json` for the dashboard.
- It does not expose tokens, passwords, or raw secrets in generated HTML/JSON.
Verify:
```bash
cd /home/fizzlepoof/.openclaw/workspace/sgt_angel/truenas-stacks/home/doris-dashboard
bin/generate_dashboard.py
python3 - <<'PY'
import json
from pathlib import Path
for item in json.loads(Path('data/todos.json').read_text()):
print(item.get('time'), item.get('title'), item.get('assignee'))
PY
```
## Donetick compact board + topic feedback
2026-05-14: The dashboard's Donetick section was reworked to match the tighter PD Dakboard pattern more closely.
Current behavior:
- Donetick renders compact task cards with due cue, task title, label chips, and a short subtitle.
- Tasks are sorted by urgency first (overdue/today/upcoming/no due date), then due time.
- The dashboard injects a pinned Paperless follow-up card into the Donetick area so that cleanup work stays visible.
- News cards now show `👍 / 👎` topic buttons.
- Topic feedback is persisted through the local dashboard server into `../doris-digest/data/feedback.json` with `origin: "dashboard"`.
- `Reset hidden topics` clears both browser state and dashboard-origin feedback entries.
- Paperless review cards now have `Acknowledge` / `Dismiss` actions persisted to `data/paperless_review_state.json`.
- Major dashboard sections are collapsible and remember collapsed state in the browser.
Important note:
- The interactive actions require the dashboard to be served by `bin/dashboard_server.py`, not plain `python -m http.server`.
## Cron fix — 2026-05-13
The dashboard cron now uses `bin/cron_generate_dashboard.sh`, which checks America/Chicago daytime internally. This avoids relying on `CRON_TZ`, which NOMAD's cron did not honor consistently.
## Paperless review queue contract
The dashboard displays sanitized Paperless intake triage items written by n8n at `data/paperless_review.json`. Example contract: `data/paperless_review.example.json`.
Expected shape is a JSON array. Each item may include:
- `id`, `title`, `original_filename`, `added`, `archive_url`
- `current.correspondent`, `current.document_type`, `current.tags`
- `triage.summary`, `triage.suggested_title`, `triage.document_type`, `triage.suggested_tags`, `triage.due_date`, `triage.needs_review`, `triage.urgency`, `triage.reason`, `triage.confidence`
- `safety.forced_review`, `safety.eligible_for_safe_apply`, `safety.apply_safe_enabled`
- `queued_at`
Do not write tokens, raw OCR text, API responses, or credentials into this file. It is display-only derived data for local review.