← back to Freddy

app/api/causes/route.ts

77 lines

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

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

  try {
    const sort = request.nextUrl.searchParams.get('sort') || 'urgency';
    const category = request.nextUrl.searchParams.get('category');

    let sql = `
      SELECT id, title, description, category, urgency_score, petition_velocity,
             news_mentions, total_votes, total_supporters, trending_rank,
             source, tags, featured, status, created_at, updated_at
      FROM causes
      WHERE status = 'active'
    `;
    const params: unknown[] = [];

    if (category) {
      params.push(category);
      sql += ` AND category = $${params.length}`;
    }

    if (sort === 'votes') {
      sql += ' ORDER BY total_votes DESC';
    } else if (sort === 'trending') {
      sql += ' ORDER BY trending_rank ASC NULLS LAST';
    } else {
      sql += ' ORDER BY urgency_score DESC';
    }

    sql += ' LIMIT 100';

    const result = await query(sql, params);
    return NextResponse.json({ causes: result.rows });
  } catch (err) {
    console.error('[causes] GET error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to fetch causes' }, { status: 500 });
  }
}

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

  try {
    const body = await request.json();
    const { title, description, category, urgency_score, tags } = body;

    if (!title) {
      return NextResponse.json({ error: 'Title is required' }, { status: 400 });
    }

    const result = await query(
      `INSERT INTO causes (title, description, category, urgency_score, tags, source)
       VALUES ($1, $2, $3, $4, $5, 'user')
       RETURNING *`,
      [title, description || null, category || null, urgency_score || 0.5, tags || []],
    );

    await auditLog('cause.created', 'cause', result.rows[0].id, { title, user });

    return NextResponse.json({ cause: result.rows[0] }, { status: 201 });
  } catch (err) {
    console.error('[causes] POST error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to create cause' }, { status: 500 });
  }
}