← back to Norma
app/api/agents/org/register/route.ts
98 lines
import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { requireRole } from '@/lib/require-role';
/**
* POST /api/agents/org/register
* Register a new organization from the Agent Apps onboarding form.
* This is a simplified endpoint that doesn't require auth — it's for
* public-facing nonprofit registration.
*/
export async function POST(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
try {
const body = await request.json();
const {
name,
ein,
type,
mission: _mission,
description: _description,
key_issues,
focus_populations,
city,
state,
zip,
website,
email: _email,
contact_email: _contactEmail,
phone,
executive_director,
social_media,
} = body;
// Accept both field name variants
const mission = _mission || _description || null;
const email = _email || _contactEmail || null;
if (!name || !name.trim()) {
return NextResponse.json({ error: 'Organization name is required' }, { status: 400 });
}
if (!email || !email.trim()) {
return NextResponse.json({ error: 'Contact email is required' }, { status: 400 });
}
// Check for duplicate by name + state
const existing = await query(
`SELECT id FROM organizations WHERE LOWER(name) = LOWER($1) AND LOWER(COALESCE(state,'')) = LOWER(COALESCE($2,''))`,
[name.trim(), state || ''],
);
if (existing.rowCount && existing.rowCount > 0) {
return NextResponse.json({
id: existing.rows[0].id,
message: 'Organization already exists',
existing: true,
});
}
const result = await query(
`INSERT INTO organizations (
name, ein, type, mission, key_issues, focus_populations,
city, state, zip, website, email, phone, executive_director,
social_media, source, updated_at
) VALUES (
$1, $2, $3, $4, $5, $6,
$7, $8, $9, $10, $11, $12, $13,
$14, 'agent_onboarding', NOW()
) RETURNING id`,
[
name.trim(),
ein?.trim() || null,
type || 'nonprofit',
mission?.trim() || null,
key_issues || [],
focus_populations || [],
city?.trim() || null,
state || null,
zip?.trim() || null,
website?.trim() || null,
email.trim(),
phone?.trim() || null,
executive_director?.trim() || null,
JSON.stringify(social_media || {}),
],
);
return NextResponse.json({
id: result.rows[0].id,
message: 'Organization registered successfully',
existing: false,
});
} catch (err) {
console.error('[agents/org/register] Error:', (err as Error).message);
return NextResponse.json({ error: 'Failed to register organization' }, { status: 500 });
}
}