From 6715cdc51f86a980c8041a43e6370665643ab20e Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Sat, 2 May 2026 20:27:21 +0000 Subject: [PATCH] monitoring(wealth): re-add milestone annotations (now that PG creds rotated) Re-applies the milestone annotation commit reverted in 0ef36aec. The earlier "nothing loads / syntax error" was a red herring: Vault had rotated the wealthfolio_sync DB password 7 days prior, the K8s Secret picked it up automatically (pg-sync sidecar still working), but the Grafana datasource ConfigMap is baked at TF-apply time so Grafana was sending the old password. Every panel + the new annotation alike failed with: pq password authentication failed for user wealthfolio_sync. Fix today: refresh the datasource ConfigMap and roll Grafana. scripts/tg apply -target=kubernetes_config_map.grafana_wealth_datasource kubectl -n monitoring rollout restart deploy/grafana Annotation source verified live via /api/ds/query: SQL returns 5 milestone rows correctly. Dashboard charts now show vertical dashed lines at GBP100k 2021-11-01, GBP250k 2023-07-18, GBP500k 2024-09-19, GBP750k 2025-08-26, GBP1M 2026-04-18. KNOWN FOLLOW-UP: Vault rotates pg-wealthfolio-sync every 7 days (static role). Todays failure will recur unless the Grafana datasource auto-refreshes. Options: 1. Annotate Grafana deploy with stakater/reloader so it restarts when wealthfolio-sync-db-creds Secret changes. 2. Switch datasource provisioning to read password from an env var sourced from the Secret instead of baking into the ConfigMap. Combined with reloader, picks up rotation cleanly. --- .../modules/monitoring/dashboards/wealth.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/stacks/monitoring/modules/monitoring/dashboards/wealth.json b/stacks/monitoring/modules/monitoring/dashboards/wealth.json index f9a22e19..67536e29 100644 --- a/stacks/monitoring/modules/monitoring/dashboards/wealth.json +++ b/stacks/monitoring/modules/monitoring/dashboards/wealth.json @@ -9,6 +9,20 @@ "iconColor": "rgba(0, 211, 255, 1)", "name": "Annotations & Alerts", "type": "dashboard" + }, + { + "datasource": {"type": "grafana-postgresql-datasource", "uid": "wealth-pg"}, + "enable": true, + "hide": false, + "iconColor": "purple", + "name": "Milestones", + "target": { + "rawQuery": true, + "editorMode": "code", + "format": "table", + "refId": "Anno", + "rawSql": "WITH daily AS (SELECT d.valuation_date, SUM(d.total_value) AS nw FROM daily_account_valuation d JOIN accounts a ON a.id = d.account_id GROUP BY d.valuation_date), crossings AS (SELECT t, (SELECT MIN(valuation_date) FROM daily WHERE nw >= t::numeric) AS d FROM unnest(ARRAY[100000, 250000, 500000, 750000, 1000000]) AS t) SELECT d::timestamptz AS time, '£' || CASE WHEN t >= 1000000 THEN (t/1000000)::int::text || 'M' ELSE (t/1000)::int::text || 'k' END AS text FROM crossings WHERE d IS NOT NULL ORDER BY d" + } } ] },