← back to Norma

app/api/pulse/activity/route.ts

74 lines

import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { requireRole } from '@/lib/require-role';
import type { AuthSession } from '@/lib/auth';

/**
 * GET /api/pulse/activity
 * Returns the authenticated user's signature history with petition details.
 * Requires any authenticated role (admin, staff, pulse).
 *
 * Query params:
 *   ?page=1       — page number (default 1)
 *   ?limit=20     — results per page (default 20, max 100)
 */
export async function GET(request: NextRequest) {
  const result = requireRole(request, 'admin', 'staff', 'pulse');
  if (result instanceof NextResponse) return result;
  const session = result as AuthSession;

  try {
    const { searchParams } = new URL(request.url);
    let page = parseInt(searchParams.get('page') || '1', 10);
    if (isNaN(page) || page < 1) page = 1;
    let limit = parseInt(searchParams.get('limit') || '20', 10);
    if (isNaN(limit) || limit < 1) limit = 20;
    if (limit > 100) limit = 100;
    const offset = (page - 1) * limit;

    // Count total signatures by this user
    const countRes = await query(
      `SELECT COUNT(*)::int AS total
       FROM petition_signatures
       WHERE signed_by_username = $1`,
      [session.username],
    );
    const total = countRes.rows[0]?.total ?? 0;

    // Fetch signatures with petition details
    const dataRes = await query(
      `SELECT
         ps.id AS signature_id,
         ps.signed_at,
         ps.comment,
         p.id AS petition_id,
         p.title AS petition_title,
         p.category,
         p.status,
         p.signature_count,
         p.signature_goal,
         p.is_featured
       FROM petition_signatures ps
       JOIN petitions p ON p.id = ps.petition_id
       WHERE ps.signed_by_username = $1
       ORDER BY ps.signed_at DESC
       LIMIT $2 OFFSET $3`,
      [session.username, limit, offset],
    );

    return NextResponse.json({
      activity: dataRes.rows,
      total,
      page,
      limit,
      totalPages: Math.ceil(total / limit),
    });
  } catch (err) {
    console.error('[api/pulse/activity] GET error:', (err as Error).message);
    return NextResponse.json(
      { error: 'Failed to fetch activity' },
      { status: 500 },
    );
  }
}