A workshop dashboard for selectable Claude Code and Codex usage. Claude Code supports Amazon Bedrock and Claude Enterprise channels; Codex uses Bedrock Mantle or Runtime. Claude metrics and Codex structured OpenTelemetry logs flow through a collector into ClickHouse; an Express API serves both the data and a React SPA.
- Usage, token/cache types, spend, models, users and tools by enabled coding client. Claude spend is client-reported; Codex costs are labelled AWS list-price estimates.
- Claude detail pages retain channel comparisons, adoption, commits, code changes, activity measures and opt-in computed-cost diagnostics.
- Request/tool reliability and observed timing; Claude also has optional trace measures.
- A SQL chat assistant for Claude telemetry, backed by Bedrock with authentication and read-only query controls.
- Optional organization OIDC login with explicit viewer/analyst/admin groups, encrypted short-lived sessions and role-gated SQL chat. See SSO operations.
These are observations and estimates, not invoices, causal adoption effects, or validated employee productivity scores. Combined user counts union distinct emitted IDs across clients; they are neither a verified employee directory nor a sum of client headcounts. Claude channels are inferred per session; model names do not establish client identity.
The commercial target is a dedicated installation in each customer's AWS account. Product release acceptance tracks the installation, operations, security, support and verification requirements. Features and passing development checks alone do not establish commercial-release readiness.
Docker Compose runs the local database and built dashboard:
git clone https://github.com/Atom-oh/claude-code-usage-dashboard.git
cd claude-code-usage-dashboard
docker compose -f dashboard/docker-compose.yml up -d --buildOpen the dashboard at http://localhost:8080. Compose binds the app to loopback,
uses synthetic seed data, and explicitly disables app authentication for local use.
The database publishes ports 8123 and 9000 on all interfaces; run this development stack on a trusted
machine, not an exposed server. Seeds initialize only a new volume. down -v deletes it.
The SQL chat returns 503 on this default stack: it also needs authenticated access and a confirmed read-only ClickHouse session.
For source development, use Node.js 22.12 or newer; the container builds with Node 24. Install the packages separately:
(cd dashboard/server && npm ci)
(cd dashboard/web && npm ci)
docker compose -f dashboard/docker-compose.yml up -d clickhouseRun the API and Vite in separate terminals:
# Terminal 1, from the repository root
cd dashboard/server
CH_URL=http://127.0.0.1:8123 CH_USER=default AUTH_ALLOW_INSECURE=1 npm run dev# Terminal 2, from the repository root
cd dashboard/web
npm run devUse the Vite URL printed in the terminal. To serve the SPA directly through Express,
build dashboard/web first. .env.example is a configuration template: the application
does not load .env automatically. Export variables explicitly, or use Node's
--env-file option with the appropriate file path. The template's port 18123 is a
port-forward example; Compose publishes ClickHouse on 8123.
scripts/setup.sh is a legacy convenience wrapper using npm install and optional local
hooks; it does not enforce the Node version or load environment variables into the app.
The commands above are the reproducible setup path.
See .env.example and the API reference. Key contracts:
| Setting | Behavior |
|---|---|
BASIC_AUTH_USER, BASIC_AUTH_PASSWORD |
Required together; missing credentials fail startup unless the explicit local bypass is set. |
AUTH_ALLOW_INSECURE |
Local-development bypass only. Health probes never require it. |
CH_URL |
Takes priority over CH_HOST/CH_PORT; fallback is http://localhost:8123. |
CH_DB, CH_USER, CH_PASSWORD |
Defaults: claude_code, default, and empty password. Supply deployment credentials securely. |
CLAUDE_ENABLED, CODEX_ENABLED |
Defaults: true, false. Enable either client or both; both false is invalid. Keep dashboard, bootstrap and collector settings consistent. |
CODEX_BEDROCK_ENDPOINT |
mantle (default) or runtime; selects Codex launcher defaults independently of Claude channels. |
CODEX_PRICING_JSON |
Validated inline JSON overrides for Codex AWS list-price estimates; see the Codex runbook. |
CODEX_COST_READ_FROM |
Empty by default. Verified UTC coverage boundary for typed Codex cost/full overview reads after migration 007 and backfill; see the cutover runbook. |
CODEX_DIAGNOSTIC_READ_FROM |
Empty by default. Verified UTC coverage boundary for tools/performance diagnostic states after migration 008 and backfill; see the diagnostic cutover runbook. |
GROUP_MODE |
ab or single; affects Claude presentation, not channel inference or client selection. |
DEFAULT_RANGE_DAYS, RANGE_CAP_DAYS |
Default window 2 days, maximum 90 days; invalid configuration fails startup. |
PII_MASK_ENABLED |
Presentation/CSV/chat masking; not an authorization boundary for raw API access. |
PRICING_JSON |
Inline JSON overrides for diagnostic token prices, not a filename. |
PRICING_CACHE_WRITE_TTL |
Diagnostic cache-write assumption: 1h or 5m, default 1h. |
AWS_PRICE_LIST |
on (default) or off. On, the server refreshes AWS Price List rates (pricing:GetProducts, us-east-1) in the background after startup; off keeps the image's snapshot and code tables. Invalid values fail startup. See ADR-017. |
AWS_PRICE_REFRESH_HOURS |
Refresh interval in hours, 1-168, default 12. A failed refresh keeps the last good rates. |
CHAT_MODEL_ID, BEDROCK_REGION, AWS_REGION |
Configure the chat's Bedrock model and region; check deployment overrides. |
CHAT_ALLOW_INSECURE |
Independent chat-auth bypass for local development only; never enable on an internet-facing deployment. |
DATA_STALE_MINUTES |
Freshness threshold for enabled sources, default 360 minutes: Claude metric TimeUnix or Codex log Timestamp. |
ALERT_WEBHOOK_URL, ALERT_REPEAT_MINUTES |
Optional stale-data alerts; the webhook is a secret. |
JSON API responses use no-store; successful chat SSE currently uses no-cache.
The server has its own bounded cache/warmer. Unavailable telemetry is distinct from
measured zero.
Deployments with both clients enabled open the all-client overview; a single-client deployment
selects that client. All selections share the same nine menus and default layout.
Claude-specific analysis remains available through view=detail; switching clients
keeps the current route and compatible filters. Common views
use /api/clients/overview, with minute buckets through four hours and hourly buckets
for longer ranges. Mixed ranges share Claude's aligned effective_range; historical
rollup approximations remain. See the data contract.
The collector must remain running for data to arrive. Use supervised startup and its
disk-backed queue; follow the operator procedures
and the actual user-data.sh/collector configuration. Claude uses the loopback OTLP/gRPC
receiver; ccdash-codex sends structured logs to http://127.0.0.1:4318/v1/logs.
The collector promotes Codex's observed time into otel_logs.Timestamp when source
time is zero. Usage-bearing completions are deduplicated before pricing; no new schema
is required. A recent export from either client does not prove complete capture.
Production uses an EKS-hosted image. Source definitions do not establish deployed state: verify the image, readiness, CDN asset hashes, schema probes, and migration ledger.
- Deploy production
- Select clients and qualify Codex telemetry
- Deploy for another organization
- Schema migrations
- Backup and restore
- Ingest-user cutover
- Alerting
- Workshop deployment notes
Follow the data reference for attribute-string replacement, managed-setting ownership, retained attribution keys and project-label privacy.
(cd dashboard/server && npm test)
(cd dashboard/web && npm test && npm run build)
bash tests/run-all.sh
terraform fmt -check -recursive infra/
(cd infra && terraform init -backend=false && terraform validate)GitHub CI runs server/web tests, the shell harness, and Terraform validation. AI review uses a separate self-hosted runner for independent Codex and Claude specialists, plus Kiro where applicable. Failed or missing required review coverage is not a passing result. See the review runbook.
| Area | Entry point |
|---|---|
| Engineering instructions | AGENTS.md and scoped guides; CLAUDE.md files import them |
| Architecture | docs/architecture.md |
| API and metrics | API reference, metric definitions |
| Implementation details | Reference index |
| Decisions | ADRs |
| Documentation language/ownership | Documentation policy |
| Static site | site/; separate GitHub Pages workflow |
| Video | video/AGENTS.md; separate pinned toolchain |
Project documentation is English-only. The application remains Korean-first.
The repository is proprietary; see LICENSE. Package version 1.0.0 does
not imply a tagged release; see CHANGELOG.md for dated history.