File size: 6,281 Bytes
ee68d8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
-- Dashboard summary table + pg_cron hourly refresh
-- Run this in the Supabase SQL Editor

-- 1. Create the summary table (single row, updated hourly)
CREATE TABLE IF NOT EXISTS dashboard_summary (
  id text PRIMARY KEY DEFAULT 'current',
  updated_at timestamptz DEFAULT now(),
  total_tokens_saved bigint DEFAULT 0,
  total_cost_saved numeric DEFAULT 0,
  total_requests int DEFAULT 0,
  unique_instances int DEFAULT 0,
  active_days int DEFAULT 0,
  daily_stats jsonb DEFAULT '[]'::jsonb,
  hourly_stats jsonb DEFAULT '[]'::jsonb,
  top_instances jsonb DEFAULT '[]'::jsonb,
  os_breakdown jsonb DEFAULT '{}'::jsonb,
  version_breakdown jsonb DEFAULT '{}'::jsonb
);

-- 2. RLS: anon can SELECT (public dashboard), only postgres can write
ALTER TABLE dashboard_summary ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Public read access" ON dashboard_summary
  FOR SELECT USING (true);

-- 3. The aggregation function (called by pg_cron)
CREATE OR REPLACE FUNCTION refresh_dashboard_summary()
RETURNS void AS $$
DECLARE
  _daily jsonb;
  _hourly jsonb;
  _top jsonb;
  _os jsonb;
  _versions jsonb;
  _total_tokens bigint;
  _total_cost numeric;
  _total_requests int;
  _unique_instances int;
  _active_days int;
BEGIN
  -- Daily totals: MAX per instance per day (beacon is cumulative), then SUM across instances
  WITH instance_daily AS (
    SELECT
      instance_id,
      created_at::date AS day,
      MAX(COALESCE(tokens_saved, 0)) AS tokens_saved,
      MAX(COALESCE(cost_saved_usd, 0)) AS cost_saved,
      MAX(COALESCE(requests, 0)) AS requests
    FROM proxy_telemetry_v2
    GROUP BY instance_id, created_at::date
  ),
  daily_agg AS (
    SELECT
      day,
      SUM(tokens_saved) AS tokens_saved,
      SUM(cost_saved)::numeric(12,2) AS cost_saved,
      SUM(requests) AS requests,
      COUNT(DISTINCT instance_id) AS instances
    FROM instance_daily
    GROUP BY day
    ORDER BY day
  )
  SELECT
    COALESCE(jsonb_agg(jsonb_build_object(
      'date', day,
      'tokens_saved', tokens_saved,
      'cost_saved', cost_saved,
      'requests', requests,
      'instances', instances
    ) ORDER BY day), '[]'::jsonb),
    COALESCE(SUM(tokens_saved), 0),
    COALESCE(SUM(cost_saved), 0),
    COALESCE(SUM(requests), 0),
    COUNT(DISTINCT day)
  INTO _daily, _total_tokens, _total_cost, _total_requests, _active_days
  FROM daily_agg;

  -- Hourly totals: last 48 hours, MAX per instance per hour, then SUM across instances
  WITH instance_hourly AS (
    SELECT
      instance_id,
      date_trunc('hour', created_at) AS hour,
      MAX(COALESCE(tokens_saved, 0)) AS tokens_saved,
      MAX(COALESCE(cost_saved_usd, 0)) AS cost_saved,
      MAX(COALESCE(requests, 0)) AS requests
    FROM proxy_telemetry_v2
    WHERE created_at >= now() - interval '48 hours'
    GROUP BY instance_id, date_trunc('hour', created_at)
  ),
  hourly_agg AS (
    SELECT
      hour,
      SUM(tokens_saved) AS tokens_saved,
      SUM(cost_saved)::numeric(12,2) AS cost_saved,
      SUM(requests) AS requests,
      COUNT(DISTINCT instance_id) AS instances
    FROM instance_hourly
    GROUP BY hour
    ORDER BY hour
  )
  SELECT COALESCE(jsonb_agg(jsonb_build_object(
    'hour', to_char(hour, 'YYYY-MM-DD HH24:MI'),
    'tokens_saved', tokens_saved,
    'cost_saved', cost_saved,
    'requests', requests,
    'instances', instances
  ) ORDER BY hour), '[]'::jsonb)
  INTO _hourly
  FROM hourly_agg;

  -- Unique instances
  SELECT COUNT(DISTINCT instance_id) INTO _unique_instances FROM proxy_telemetry_v2;

  -- Top 20 instances by total tokens saved
  WITH instance_totals AS (
    SELECT
      instance_id,
      SUM(max_tokens) AS tokens_saved,
      SUM(max_cost)::numeric(12,2) AS cost_saved,
      MAX(os) AS os,
      MAX(version) AS version
    FROM (
      SELECT
        instance_id,
        created_at::date,
        MAX(COALESCE(tokens_saved, 0)) AS max_tokens,
        MAX(COALESCE(cost_saved_usd, 0)) AS max_cost,
        MAX(os) AS os,
        MAX(headroom_version) AS version
      FROM proxy_telemetry_v2
      GROUP BY instance_id, created_at::date
    ) sub
    GROUP BY instance_id
    ORDER BY tokens_saved DESC
    LIMIT 20
  )
  SELECT COALESCE(jsonb_agg(jsonb_build_object(
    'instance_id', LEFT(instance_id, 8),
    'tokens_saved', tokens_saved,
    'cost_saved', cost_saved,
    'os', SPLIT_PART(COALESCE(os, '?'), ' ', 1),
    'version', version
  ) ORDER BY tokens_saved DESC), '[]'::jsonb)
  INTO _top
  FROM instance_totals;

  -- OS breakdown
  SELECT COALESCE(jsonb_object_agg(os_name, cnt), '{}'::jsonb)
  INTO _os
  FROM (
    SELECT SPLIT_PART(COALESCE(os, '?'), ' ', 1) AS os_name, COUNT(*) AS cnt
    FROM proxy_telemetry_v2
    GROUP BY os_name
  ) sub;

  -- Version breakdown
  SELECT COALESCE(jsonb_object_agg(COALESCE(headroom_version, '?'), cnt), '{}'::jsonb)
  INTO _versions
  FROM (
    SELECT headroom_version, COUNT(*) AS cnt
    FROM proxy_telemetry_v2
    GROUP BY headroom_version
  ) sub;

  -- Upsert the single summary row
  INSERT INTO dashboard_summary (id, updated_at, total_tokens_saved, total_cost_saved,
    total_requests, unique_instances, active_days, daily_stats, hourly_stats,
    top_instances, os_breakdown, version_breakdown)
  VALUES ('current', now(), _total_tokens, _total_cost, _total_requests,
    _unique_instances, _active_days, _daily, _hourly, _top, _os, _versions)
  ON CONFLICT (id) DO UPDATE SET
    updated_at = EXCLUDED.updated_at,
    total_tokens_saved = EXCLUDED.total_tokens_saved,
    total_cost_saved = EXCLUDED.total_cost_saved,
    total_requests = EXCLUDED.total_requests,
    unique_instances = EXCLUDED.unique_instances,
    active_days = EXCLUDED.active_days,
    daily_stats = EXCLUDED.daily_stats,
    hourly_stats = EXCLUDED.hourly_stats,
    top_instances = EXCLUDED.top_instances,
    os_breakdown = EXCLUDED.os_breakdown,
    version_breakdown = EXCLUDED.version_breakdown;
END;
$$ LANGUAGE plpgsql;

-- 4. Run it once to populate
SELECT refresh_dashboard_summary();

-- 5. Enable pg_cron extension (if not already)
CREATE EXTENSION IF NOT EXISTS pg_cron;

-- 6. Schedule hourly refresh (runs at minute 7 to avoid :00 congestion)
SELECT cron.schedule(
  'refresh-dashboard',
  '7 * * * *',
  'SELECT refresh_dashboard_summary()'
);

-- Verify the schedule
SELECT * FROM cron.job;