Files
new-api-analytics/docs/database.md

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 to 2.
  • 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 optional upstream_model_name, cache_creation_tokens, and cache_tokens.

users

Used for display-name enrichment.

Expected columns:

  • id
  • username
  • display_name

channels

Used for channel-name enrichment.

Expected columns:

  • id
  • name

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.