-
-
Notifications
You must be signed in to change notification settings - Fork 25
Expand file tree
/
Copy pathanalytics.js
More file actions
40 lines (35 loc) · 1.68 KB
/
Copy pathanalytics.js
File metadata and controls
40 lines (35 loc) · 1.68 KB
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
// GET /api/irl/analytics: site-wide /irl usage rollup for operators.
// Auth mirrors /api/ops/health exactly: authorizeOps (signed-in platform admin
// OR `x-ops-secret` / Bearer OPS_SECRET). This surface exposes aggregate usage
// volume, not any individual's location or identity, but it's still internal
// operating data, so it wears the same gate as the rest of the ops APIs.
//
// Every number is a real query over irl_events (api/_lib/irl-analytics.js),
// irl_interactions, and irl_drop_claims — no cached/sampled/fake figures.
import { wrap, cors, json, error } from '../_lib/http.js';
import { limits, clientIp } from '../_lib/rate-limit.js';
import { rateLimited } from '../_lib/http.js';
import { authorizeOps } from '../_lib/ops-auth.js';
import { getIrlAnalyticsSummary } from '../_lib/irl-analytics.js';
export default wrap(async (req, res) => {
if (cors(req, res, { methods: 'GET,OPTIONS', origins: 'same' })) return;
if (req.method?.toUpperCase() !== 'GET') return error(res, 405, 'method_not_allowed', 'GET only');
const rl = await limits.authIp(clientIp(req));
if (!rl.success) return rateLimited(res, rl);
const auth = await authorizeOps(req);
if (!auth.ok) return error(res, 401, 'unauthorized', 'admin session or x-ops-secret required');
try {
const summary = await getIrlAnalyticsSummary();
return json(res, 200, summary);
} catch (err) {
// Table absent (pre-deploy) or DB hiccup — report an honest empty summary
// rather than 500ing the dashboard.
return json(res, 200, {
windows: {},
placement_modes_30d: {},
daily_series_30d: [],
generated_at: new Date().toISOString(),
note: `analytics_unavailable: ${err?.message || 'db error'}`,
});
}
});