mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-06-11 14:11:29 +00:00
73389d2715
- Fix 6 data contract mismatches between Go backend JSON tags and React frontend TypeScript interfaces (field renames, response envelope changes) - Add timezone selector to topbar with 12 common timezone options - Replace date-fns formatting with native Intl.DateTimeFormat for timezone-aware chart labels (reduces bundle ~20KB) - Add missing SnapshotTimeSeries fields (memory_docs, memory_chunks, kg_entities, kg_relations) that caused empty usage page - Add error banner to usage page for API error visibility - Sanitize backend error messages in usage HTTP handlers - Add batch chunking (max 3000 rows) for snapshot upserts - Remove userId display from topbar - Add usage analytics i18n strings for en/vi/zh
80 lines
3.3 KiB
SQL
80 lines
3.3 KiB
SQL
-- ============================================================
|
|
-- Part 1: New indexes on EXISTING tables (optimize aggregation)
|
|
-- ============================================================
|
|
|
|
-- Traces: snapshot worker scans by start_time for root traces only
|
|
-- Replaces Seq Scan (2.5ms→0.1ms at current scale, critical at 100K+ rows)
|
|
CREATE INDEX IF NOT EXISTS idx_traces_start_root ON traces (start_time DESC)
|
|
WHERE parent_trace_id IS NULL;
|
|
|
|
-- Spans: snapshot worker joins on trace_id filtering by span_type
|
|
-- Current idx_spans_trace is (trace_id, start_time) — start_time useless here
|
|
-- This index lets PG filter span_type IN the index, avoiding wide-row fetches
|
|
CREATE INDEX IF NOT EXISTS idx_spans_trace_type ON spans (trace_id, span_type);
|
|
|
|
-- ============================================================
|
|
-- Part 2: usage_snapshots table
|
|
-- ============================================================
|
|
|
|
CREATE TABLE IF NOT EXISTS usage_snapshots (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v7(),
|
|
bucket_hour TIMESTAMPTZ NOT NULL,
|
|
agent_id UUID,
|
|
provider VARCHAR(50) NOT NULL DEFAULT '',
|
|
model VARCHAR(200) NOT NULL DEFAULT '',
|
|
channel VARCHAR(50) NOT NULL DEFAULT '',
|
|
|
|
-- Token metrics
|
|
input_tokens BIGINT NOT NULL DEFAULT 0,
|
|
output_tokens BIGINT NOT NULL DEFAULT 0,
|
|
cache_read_tokens BIGINT NOT NULL DEFAULT 0,
|
|
cache_create_tokens BIGINT NOT NULL DEFAULT 0,
|
|
thinking_tokens BIGINT NOT NULL DEFAULT 0,
|
|
|
|
-- Cost
|
|
total_cost NUMERIC(12,6) NOT NULL DEFAULT 0,
|
|
|
|
-- Counts
|
|
request_count INTEGER NOT NULL DEFAULT 0,
|
|
llm_call_count INTEGER NOT NULL DEFAULT 0,
|
|
tool_call_count INTEGER NOT NULL DEFAULT 0,
|
|
error_count INTEGER NOT NULL DEFAULT 0,
|
|
unique_users INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Duration
|
|
avg_duration_ms INTEGER NOT NULL DEFAULT 0,
|
|
|
|
-- Memory & Knowledge Graph (point-in-time counts)
|
|
memory_docs INTEGER NOT NULL DEFAULT 0,
|
|
memory_chunks INTEGER NOT NULL DEFAULT 0,
|
|
kg_entities INTEGER NOT NULL DEFAULT 0,
|
|
kg_relations INTEGER NOT NULL DEFAULT 0,
|
|
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
-- ============================================================
|
|
-- Part 3: usage_snapshots indexes
|
|
-- ============================================================
|
|
|
|
-- Time-series queries: GROUP BY bucket_hour ORDER BY bucket_hour
|
|
CREATE INDEX IF NOT EXISTS idx_usage_snapshots_bucket ON usage_snapshots (bucket_hour DESC);
|
|
|
|
-- Agent-scoped time-series: WHERE agent_id = $1 ORDER BY bucket_hour
|
|
CREATE INDEX IF NOT EXISTS idx_usage_snapshots_agent_bucket ON usage_snapshots (agent_id, bucket_hour DESC);
|
|
|
|
-- Cross-filter: WHERE provider = $1 AND bucket_hour BETWEEN ...
|
|
CREATE INDEX IF NOT EXISTS idx_usage_snapshots_provider_bucket ON usage_snapshots (provider, bucket_hour DESC)
|
|
WHERE provider != '';
|
|
|
|
-- Cross-filter: WHERE channel = $1 AND bucket_hour BETWEEN ...
|
|
CREATE INDEX IF NOT EXISTS idx_usage_snapshots_channel_bucket ON usage_snapshots (channel, bucket_hour DESC)
|
|
WHERE channel != '';
|
|
|
|
-- Upsert dedup: ON CONFLICT — prevents duplicate snapshot rows
|
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_usage_snapshots_unique ON usage_snapshots (
|
|
bucket_hour,
|
|
COALESCE(agent_id, '00000000-0000-0000-0000-000000000000'),
|
|
provider, model, channel
|
|
);
|