File size: 5,388 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
-- Upgrade dashboard_summary: add hourly_stats column + update refresh function
-- Run this in Supabase SQL Editor (safe to run on existing table)

-- 1. Add hourly_stats column if missing
ALTER TABLE dashboard_summary
  ADD COLUMN IF NOT EXISTS hourly_stats jsonb DEFAULT '[]'::jsonb;

-- 2. Replace the refresh function with hourly support
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;

-- 3. Refresh now to populate hourly data
SELECT refresh_dashboard_summary();