Skip to content

feat(ops): home account-spend tiles (anthropic-cost-integration Phase 2)#441

Merged
silversurfer562 merged 1 commit into
mainfrom
feat/anthropic-cost-phase2-home-tiles
May 19, 2026
Merged

feat(ops): home account-spend tiles (anthropic-cost-integration Phase 2)#441
silversurfer562 merged 1 commit into
mainfrom
feat/anthropic-cost-phase2-home-tiles

Conversation

@silversurfer562
Copy link
Copy Markdown
Member

Summary

Wires Phase 1's anthropic_cost.fetch_summary into the home page route. Adds three account-spend KPI tiles ("Today (account)", "7d (account)", "MTD (account)") gated on cost_summary availability, with a "Connect billing" CTA when no admin key is configured and a friendly "Key rejected" notice on auth-failed.

Implements spec docs/specs/anthropic-cost-integration/tasks.md Phase 2.

What's in the diff

  • src/attune/ops/routes/dashboard.py: home() now calls fetch_summary inside a defensive try/except, passes cost_summary and cost_error to the template; ?refresh=1 forces a cache bypass
  • src/attune/ops/templates/home.html: new <section class="kpi-grid kpi-cluster-account"> block after the existing telemetry cluster, with three render paths (valid summary → tiles, no_key → CTA, auth_failed → notice, other errors → silent fall-through)
  • src/attune/ops/static/css/main.css: .kpi-cluster-account styles, including the thin left-edge accent border and color-coded variants for .kpi-cta and .kpi-notice
  • tests/unit/ops/test_anthropic_cost_home_integration.py: six new tests covering all four spec-2.4 scenarios plus the default-refresh-false and exception-swallow paths

Trade-offs / non-obvious choices

  • CTA copy: shipped option 1 from the open-question list ("Set up cost reporting" linking to docs/reference/) rather than option 2 ("Coming in Phase 4 …"). Cleaner, doesn't reference a future state. Easily revisited when Phase 4 lands.
  • Visual distinction: left-edge accent border (3px solid var(--accent)) rather than the spec's "right-edge" suggestion. Reads more naturally with the existing tile flex direction; functionally equivalent for the "tell at a glance which data source" goal.
  • Defensive try/except: catches everything (except Exception with # noqa: BLE001) because a billing-fetch surprise must not block the dashboard render. Surfaces in DEBUG logs only — verified by the silent-degradation test which mocks fetch_summary to raise RuntimeError.
  • Patch target in tests: attune.ops.anthropic_cost.fetch_summary (source module) rather than attune.ops.routes.dashboard.anthropic_cost.fetch_summary (consumer site). The latter triggers mock.patch's _importer to attempt module-walk on a function attribute. Source-module patching works because dashboard.anthropic_cost IS the same module object as the source; replacing the attribute on the source flows through.

Caught in flight

The formatter stripped the from attune.ops import anthropic_cost import after my initial import-only edit (before the usage line was added), per the existing CLAUDE.md lesson about formatters stripping unused-at-the-moment imports. Re-added with the usage line in place; runtime confirmed dashboard.anthropic_cost resolves to the module. Worth a session lesson: even brief edit-formatter cycles trigger this, not just multi-minute pauses.

Test plan

  • 6 new tests in test_anthropic_cost_home_integration.py pass
  • 50 tests in test_home.py + test_anthropic_cost.py + new file pass (no regressions)
  • Ruff clean on Python files
  • Pre-commit hooks pass (black, ruff, bandit, detect-secrets, markdown checks, help-template freshness)
  • CI green on all platforms
  • Manual verification: dashboard launches with no admin key → CTA tile renders; with valid CostSummary mock → three tiles populated

Related

  • #432 — Phase 1 backend client this PR consumes
  • #431 — original spec
  • Next: Phase 3 (/telemetry per-day panel), Phase 4 (attune ops setup-billing CLI), Phase 5 (polish + docs)

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment May 19, 2026 5:29pm

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

🔒 Security Scan Results

Status: PASSED - No blocking issues

Summary

Severity Count Action
🔴 CRITICAL 0 BLOCKS PR
🟡 MEDIUM 0 ⚠️ Review recommended
🔵 LOW 0 ℹ️ Informational

Total Findings: 0



🛠️ Need Help?

If findings are false positives:

  1. Add clarifying comments in code (e.g., # Security Note: Test data only)
  2. Request security review: Add security-review label
  3. Security team will evaluate and add security-approved label if safe

For emergency hotfixes:

  1. Add hotfix label to bypass blocking
  2. Create follow-up ticket to address findings
  3. Security team will review post-deployment

Scanner Accuracy: ~82% (Industry-leading!)

Powered by Attune AI Security Scanner | Documentation

@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

…gration Phase 2)

Wires Phase 1's anthropic_cost.fetch_summary into the home page route.
Adds three KPI tiles ("Today (account)", "7d (account)", "MTD (account)")
gated on cost_summary availability, with a "Connect billing" CTA when
no admin key is configured and a friendly "Key rejected" notice on
auth-failed.

Visual distinction via the .kpi-cluster-account class — thin accent
border on the left edge of each tile in the new cluster so account
spend reads as a separate data source from workflow telemetry above.

Defensive try/except in the home route swallows any unexpected
exception from fetch_summary; the page still renders, the cost
cluster simply doesn't appear, and the failure surfaces in DEBUG
logs only. Six regression tests cover all four spec-2.4 scenarios
(no key, valid summary, auth failed, ?refresh=1) plus default
?refresh=False and the exception-swallow path.

Spec: docs/specs/anthropic-cost-integration/tasks.md (Phase 2)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@silversurfer562 silversurfer562 force-pushed the feat/anthropic-cost-phase2-home-tiles branch from 83730b5 to e364dcb Compare May 19, 2026 17:28
@silversurfer562
Copy link
Copy Markdown
Member Author

Rebased onto current main (which now includes #439 telemetry fix and #440 docs). The earlier diff against origin/main showed -300 lines because the branch was behind main — what looked like a bundled removal of _track_sdk_run_telemetry and friends was actually just absence of #439's additions on this branch.

After rebase, the diff is exactly 4 files (+255 / -1):

  • src/attune/ops/routes/dashboard.py — home route wires anthropic_cost.fetch_summary
  • src/attune/ops/templates/home.html — 3 KPI tiles + no_key CTA + auth_failed notice
  • src/attune/ops/static/css/main.css.kpi-cluster-account styling
  • tests/unit/ops/test_anthropic_cost_home_integration.py — 6 integration tests

40/40 tests pass post-rebase. PR is now cleanly aligned with what the title advertises.

@silversurfer562 silversurfer562 merged commit 615add3 into main May 19, 2026
35 of 36 checks passed
@silversurfer562 silversurfer562 deleted the feat/anthropic-cost-phase2-home-tiles branch May 19, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant