1.9 KiB
1.9 KiB
Database Contract
This app reads an existing New API PostgreSQL schema. It does not own migrations.
Required Environment
PG_CONNECTION_STRING=postgres://user:password@host:5432/database
Tables Read By The App
logs
Primary analytics source. Only rows with type = 2 are included.
Expected columns:
id: monotonically increasing log id, used for latest-first log pagination.created_at: Unix timestamp in seconds.type: log type; analytics filters to2.user_id: user id.username: username captured on the log row.model_name: requested model name.channel_id: upstream channel id.prompt_tokens: input token count.completion_tokens: output token count.quota: New API quota units.use_time: request latency in milliseconds.is_stream: stream flag.token_name: API token display name.other: JSON text with optionalupstream_model_name,cache_creation_tokens, andcache_tokens.
users
Used for display-name enrichment.
Expected columns:
idusernamedisplay_name
channels
Used for channel-name enrichment.
Expected columns:
idname
Recommended Indexes
For large logs tables, add or verify indexes that match dashboard filters:
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_logs_type_created_at
ON logs (type, created_at);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_logs_type_username_created_at
ON logs (type, username, created_at);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_logs_type_channel_created_at
ON logs (type, channel_id, created_at);
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_logs_type_id_desc
ON logs (type, id DESC);
Model filtering uses the real-model expression derived from other::jsonb->>'upstream_model_name' with fallback to model_name. Add an expression index only after validating the exact production column type and query plan.