← back to Norma
app/api/partners/posts/route.ts
82 lines
import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { requireRole } from '@/lib/require-role';
/**
* GET /api/partners/posts?partner_id=&platform=&limit=
* Returns social posts from partners, optionally filtered.
*/
export async function GET(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
const { searchParams } = new URL(request.url);
const partnerId = searchParams.get('partner_id');
const platform = searchParams.get('platform');
let limit = parseInt(searchParams.get('limit') || '50', 10);
if (isNaN(limit) || limit < 1) limit = 50;
if (limit > 200) limit = 200;
const conditions: string[] = [];
const params: unknown[] = [];
let idx = 1;
if (partnerId) {
conditions.push(`pp.partner_id = $${idx++}`);
params.push(partnerId);
}
if (platform) {
conditions.push(`pp.platform = $${idx++}`);
params.push(platform);
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
try {
const { rows } = await query(
`SELECT pp.*, p.name AS partner_name, p.twitter_handle, p.vetting_status, p.partner_type
FROM partner_posts pp
JOIN partners p ON p.id = pp.partner_id
${whereClause}
ORDER BY pp.post_date DESC NULLS LAST
LIMIT $${idx}`,
[...params, limit]
);
return NextResponse.json({ posts: rows });
} catch (err) {
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
}
}
/**
* POST /api/partners/posts
* Manually add a social post for a partner.
*/
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 { partner_id, platform, content, url, post_date, likes_count, retweets_count, replies_count } = body;
if (!partner_id || !content) {
return NextResponse.json({ error: 'partner_id and content required' }, { status: 400 });
}
const { rows } = await query(
`INSERT INTO partner_posts (partner_id, platform, content, url, post_date, likes_count, retweets_count, replies_count)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING *`,
[
partner_id, platform || 'twitter', content, url || null,
post_date ? new Date(post_date) : null,
likes_count || 0, retweets_count || 0, replies_count || 0,
]
);
return NextResponse.json({ post: rows[0] }, { status: 201 });
} catch (err) {
return NextResponse.json({ error: (err as Error).message }, { status: 500 });
}
}