Getting Started
- Fork the repository: https://github.com/JointSave-org/Joint_Save
- Clone your fork:
git clone https://github.com/<your-username>/Joint_Save.git
cd Joint_Save
- Create a new branch:
git checkout -b feat/protocol-analytics-dashboard
Overview
JointSave has no public-facing analytics page that shows overall protocol health. Users and potential integrators have no way to see how much total value is locked across all pools, how many active pools exist, member growth trends, or transaction volume over time. The factory contract tracks deployed pools via get_all_pools() but this data is never surfaced at the protocol level.
Checked frontend/app/explore/page.tsx — shows individual pool cards but no aggregate stats. The Supabase pools table has created_at and total_saved columns that could power aggregate queries, but no API route aggregates them.
This issue adds a public analytics dashboard accessible from the landing page and navbar, displaying key protocol metrics with historical charts powered by Chart.js or Recharts.
Requirements
API Changes
- New route:
GET /api/analytics/protocol
- Returns cached (5-minute TTL) aggregate metrics:
total_value_locked: sum of total_saved across all pools
active_pools: count of pools where status is not 'completed'
total_pools_created: count of all pools
total_members: distinct count of wallet addresses across all pool_members records
total_transactions: count of rows in pool_activity
pools_by_type: { rotational: N, target: N, flexible: N }
tvl_by_type: { rotational: X, target: X, flexible: X }
- Historical data:
daily_stats array for the last 30 days with date, tvl, new_pools, new_members, transaction_count
- Computed from Supabase queries against
pools, pool_members, and pool_activity tables
- Rate limited with the existing
readLimiter
Frontend Changes
- New page:
frontend/app/analytics/page.tsx
- Public page (no wallet connection required)
- Hero section with 4 large metric cards: TVL, Active Pools, Total Members, Total Transactions
- TVL trend line chart (30-day history) using Recharts
- Pool type distribution donut chart (Rotational / Target / Flexible)
- Daily new pools bar chart (30-day)
- Member growth area chart (30-day)
- All charts use a responsive grid layout (2 columns on desktop, 1 on mobile)
- Skeleton loading states while data fetches
- New component:
frontend/components/analytics/protocol-charts.tsx
- Encapsulates all Recharts components
- Shared color palette: Rotational=#3b82f6 (blue), Target=#8b5cf6 (purple), Flexible=#10b981 (emerald)
- Tooltips on hover showing exact values
- Responsive: charts resize and stack vertically below 768px
- New component:
frontend/components/analytics/metric-card.tsx
- Displays a single metric with icon, label, value, and optional trend indicator (+12% this week)
- Animated counter on page load (counts up from 0 to final value)
- Navigation:
- Add "Analytics" link to the landing page navbar and the dashboard sidebar
- Add
/analytics to the public routes in the layout
Dependencies
Data Pipeline
- For historical data, create a Supabase Edge Function or Vercel Cron (
/api/cron/snapshot-daily) that runs daily at midnight UTC and inserts a row into a new protocol_daily_snapshots table:
date (date, PK)
tvl (numeric)
active_pools (integer)
total_members (integer)
transaction_count (integer)
new_pools (integer)
new_members (integer)
- The analytics API reads from this snapshots table for historical charts, and computes live values for the current-day metrics
Acceptance Criteria
Getting Started
Overview
JointSave has no public-facing analytics page that shows overall protocol health. Users and potential integrators have no way to see how much total value is locked across all pools, how many active pools exist, member growth trends, or transaction volume over time. The factory contract tracks deployed pools via
get_all_pools()but this data is never surfaced at the protocol level.Checked
frontend/app/explore/page.tsx— shows individual pool cards but no aggregate stats. The Supabasepoolstable hascreated_atandtotal_savedcolumns that could power aggregate queries, but no API route aggregates them.This issue adds a public analytics dashboard accessible from the landing page and navbar, displaying key protocol metrics with historical charts powered by Chart.js or Recharts.
Requirements
API Changes
GET /api/analytics/protocoltotal_value_locked: sum oftotal_savedacross all poolsactive_pools: count of pools where status is not 'completed'total_pools_created: count of all poolstotal_members: distinct count of wallet addresses across allpool_membersrecordstotal_transactions: count of rows inpool_activitypools_by_type:{ rotational: N, target: N, flexible: N }tvl_by_type:{ rotational: X, target: X, flexible: X }daily_statsarray for the last 30 days withdate,tvl,new_pools,new_members,transaction_countpools,pool_members, andpool_activitytablesreadLimiterFrontend Changes
frontend/app/analytics/page.tsxfrontend/components/analytics/protocol-charts.tsxfrontend/components/analytics/metric-card.tsx/analyticsto the public routes in the layoutDependencies
Data Pipeline
/api/cron/snapshot-daily) that runs daily at midnight UTC and inserts a row into a newprotocol_daily_snapshotstable:date(date, PK)tvl(numeric)active_pools(integer)total_members(integer)transaction_count(integer)new_pools(integer)new_members(integer)Acceptance Criteria
/api/analytics/protocolreturns all specified metrics with correct values