← back to Freddy

app/api/pulse/route.ts

70 lines

import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { verifyAuth } from '@/lib/auth';

export async function GET(request: NextRequest) {
  const user = verifyAuth(request);
  if (!user) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }

  try {
    const [
      causesCount,
      totalVotes,
      orgsCount,
      grantersCount,
      matchesCount,
      fundedAmount,
      revenueStats,
      pendingFees,
      topCauses,
      topOrgs,
      recentMatches,
      fundingRounds,
    ] = await Promise.all([
      query(`SELECT COUNT(*)::int as count FROM causes WHERE status = 'active'`),
      query(`SELECT COALESCE(SUM(total_votes), 0)::int as total FROM causes WHERE status = 'active'`),
      query(`SELECT COUNT(*)::int as count FROM organizations WHERE status IN ('verified', 'featured', 'pending')`),
      query(`SELECT COUNT(*)::int as count FROM granters WHERE status = 'active'`),
      query(`SELECT COUNT(*)::int as count FROM matches`),
      query(`SELECT COALESCE(SUM(funding_amount), 0)::numeric as total FROM matches WHERE status = 'funded'`),
      query(`SELECT COALESCE(SUM(COALESCE(commission_amount, 0) + COALESCE(flat_fee, 0)), 0)::numeric as total FROM revenue WHERE status = 'paid'`),
      query(`SELECT COALESCE(SUM(COALESCE(commission_amount, 0) + COALESCE(flat_fee, 0)), 0)::numeric as total FROM revenue WHERE status IN ('pending', 'invoiced')`),
      query(`SELECT id, title, urgency_score, total_votes, total_supporters, category, tags, trending_rank
             FROM causes WHERE status = 'active' ORDER BY urgency_score DESC, total_votes DESC LIMIT 10`),
      query(`SELECT id, name, category, impact_score, trust_score, total_votes, total_funding_received, status
             FROM organizations WHERE status IN ('verified', 'featured') ORDER BY total_votes DESC, impact_score DESC LIMIT 5`),
      query(`SELECT m.id, m.match_score, m.status, m.created_at,
                    c.title as cause_title, o.name as org_name, g.name as granter_name
             FROM matches m
             JOIN causes c ON c.id = m.cause_id
             JOIN organizations o ON o.id = m.org_id
             LEFT JOIN granters g ON g.id = m.granter_id
             ORDER BY m.created_at DESC LIMIT 5`),
      query(`SELECT id, title, total_pool, allocated, remaining, status, opens_at, closes_at
             FROM funding_rounds ORDER BY created_at DESC LIMIT 5`),
    ]);

    return NextResponse.json({
      stats: {
        total_causes: causesCount.rows[0].count,
        total_votes: totalVotes.rows[0].total,
        registered_orgs: orgsCount.rows[0].count,
        active_granters: grantersCount.rows[0].count,
        total_matches: matchesCount.rows[0].count,
        funds_matched: parseFloat(fundedAmount.rows[0].total) || 0,
        revenue_earned: parseFloat(revenueStats.rows[0].total) || 0,
        pending_fees: parseFloat(pendingFees.rows[0].total) || 0,
      },
      top_causes: topCauses.rows,
      top_orgs: topOrgs.rows,
      recent_matches: recentMatches.rows,
      funding_rounds: fundingRounds.rows,
    });
  } catch (err) {
    console.error('[pulse] GET error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to fetch pulse data' }, { status: 500 });
  }
}