Skip to content

Optimize dashboard stats queries and creator group lookups#122

Merged
Abd-Standard merged 4 commits into
Core-Foundry:mainfrom
success-OG:feat/queries
Jul 20, 2026
Merged

Optimize dashboard stats queries and creator group lookups#122
Abd-Standard merged 4 commits into
Core-Foundry:mainfrom
success-OG:feat/queries

Conversation

@success-OG

Copy link
Copy Markdown
Contributor

Summary

This PR reduces the cost of loading dashboard statistics by collapsing multi-pass aggregations into a single query path on the frontend, and by indexing on-chain group lookups by creator so dashboard-style reads no longer scan every group.

Previously, the overview widget computed totals with multiple client-side passes over the same dataset, and get_groups_by_creator loaded all groups before filtering. Both patterns scale poorly as group/task volume grows. This change preserves the same dashboard numbers and group listing behavior while cutting query work and round-trips.

What changed

Frontend — single aggregated stats query

  • Added frontend/src/lib/dashboard-stats.ts
    • Optimized path: one data read + one aggregation pass
    • Naive path kept for comparison: models the old multi-query approach (6 reads)
    • Returns identical aggregates from both strategies so regressions are easy to catch
  • Added GET /api/dashboard/stats
    • One response with groups, totals, member counts, max funds, and transaction totals
    • Uses Cache-Control: no-store consistent with other API routes
  • Extracted shared group fixtures to frontend/src/constants/dashboard-groups.ts
  • Updated ActiveGroupsWidget to fetch from /api/dashboard/stats instead of recomputing locally
    • Same UI: Total Funds, Active Groups, Members, ranked group list
    • Adds loading/error states without changing the visual layout

Contract — creator index for group lookups

  • Added DataKey::CreatorGroups(Address) storage index
  • create_autoshare now maintains the per-creator group ID list
  • get_groups_by_creator now:
    • Reads only that creator’s indexed IDs
    • Loads those groups directly
    • Avoids full AllGroups scan + filter (O(all groups)O(creator’s groups))
  • Extended tests to assert multi-creator isolation still works

Acceptance criteria

  • Reduce query count — optimized dashboard stats path uses 1 query vs naive 6
  • Improve response time — single aggregation pass + single API round-trip for overview stats
  • Preserve existing functionality — same totals and group data:
    • Total funds: 70050 ($70.1K)
    • Active groups: 5
    • Members: 35
    • Max funds: 24500
    • Total transactions: 118

Design notes

Why this approach

The repo does not use a traditional SQL ORM for the dashboard. Stats currently come from an in-memory/fixture dataset on the frontend, and group ownership lives on Soroban. Optimizations are therefore applied where the real query cost is:

  1. Frontend/API: collapse multiple metric “queries” into one aggregated read
  2. Contract: index creator → group IDs so dashboard ownership lookups stay cheap as total group count grows

Query reduction (frontend)

Strategy Query count Behavior
Naive (legacy) 6 Separate passes for list, funds, count, members, max, transactions
Optimized (new) 1 Single read + single aggregation loop

Contract lookup cost

Method Before After
get_groups_by_creator Load all groups, then filter Load creator index, then fetch only those groups

Test plan

  • cd frontend && pnpm lint — 0 errors
  • cd frontend && pnpm test — 31 passed (includes new dashboard stats tests)
  • cd frontend && pnpm build — succeeds; route /api/dashboard/stats present
  • cd contract && cargo fmt --check
  • cd contract && cargo test --locked — 91 passed
  • cd contract && cargo clippy --all-targets --all-features -- -D warnings
  • Confirm GitHub Frontend CI + Contract CI pass on this PR
  • Manually open /user/overview and verify:
    • Stats cards render the same totals
    • Group list order/content matches previous behavior
    • Network tab shows a single GET /api/dashboard/stats call

Follow-ups (out of scope)

  • Persist dashboard fixtures to a real DB/indexer and keep the same single-stats API shape
  • Add TanStack Query caching/revalidation for the overview widget
  • Add a contract-side summary method that returns aggregates without loading full group details

closes #78

@Abd-Standard
Abd-Standard merged commit 2d9ed69 into Core-Foundry:main Jul 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Optimize Database Queries for Dashboard Statistics

2 participants