← back to Norma

app/api/accounts/route.ts

67 lines

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

/**
 * GET /api/accounts — List all active nonprofit platform accounts
 * for the org switcher dropdown.
 */
export async function GET(request: NextRequest) {
  const auth = requireRole(request, 'admin', 'staff');
  if (auth instanceof NextResponse) return auth;

  try {
    // Staff users only see their own org; admin sees all for org switcher
    const orgFilter = auth.role === 'staff' ? ' AND id = $1' : '';
    const params = auth.role === 'staff' ? [auth.orgId] : [];
    const result = await query(
      `SELECT
        id, org_name, short_name, ein, website, mission,
        focus_areas, org_email, org_phone, brand_color, donate_url, logo_url,
        address_street, address_city, address_state, address_zip,
        twitter_handle, linkedin_url, instagram_handle, facebook_url,
        staff, lanes, voice_modes, search_keywords,
        org_size, annual_budget, year_founded
      FROM nonprofit_accounts
      WHERE is_active = true${orgFilter}
      ORDER BY org_name`,
      params,
    );

    const orgs = result.rows.map((r) => ({
      id: r.id,
      org_name: r.org_name,
      short_name: r.short_name || r.org_name.slice(0, 4),
      ein: r.ein || '',
      website: r.website || '',
      mission: r.mission || '',
      focus_areas: r.focus_areas || [],
      org_email: r.org_email || '',
      org_phone: r.org_phone || '',
      brand_color: r.brand_color || '#10b981',
      donate_url: r.donate_url || '',
      logo_url: r.logo_url || null,
      address_street: r.address_street || '',
      address_city: r.address_city || '',
      address_state: r.address_state || '',
      address_zip: r.address_zip || '',
      twitter_handle: r.twitter_handle || '',
      linkedin_url: r.linkedin_url || '',
      instagram_handle: r.instagram_handle || '',
      facebook_url: r.facebook_url || '',
      staff: r.staff || [],
      lanes: r.lanes || {},
      voice_modes: r.voice_modes || ['advocacy'],
      search_keywords: r.search_keywords || [],
      org_size: r.org_size || '',
      annual_budget: r.annual_budget || '',
      year_founded: r.year_founded || null,
    }));

    return NextResponse.json({ orgs });
  } catch (err) {
    console.error('[api/accounts] GET error:', (err as Error).message);
    return NextResponse.json({ error: 'Failed to fetch accounts' }, { status: 500 });
  }
}