← back to Norma
app/api/social/posts/approve/route.ts
109 lines
import { NextRequest, NextResponse } from 'next/server';
import { query, getClient } from '@/lib/db';
export const dynamic = 'force-dynamic';
/**
* POST /api/social/posts/approve
* Body: { post_id, action: 'approve'|'reject', approver, reason?, scheduled_at? }
*/
export async function POST(request: NextRequest) {
let body: {
post_id?: string;
action?: 'approve' | 'reject';
approver?: string;
reason?: string;
scheduled_at?: string;
};
try {
body = await request.json();
} catch {
return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
}
const { post_id, action, approver, reason, scheduled_at } = body;
if (!post_id || !action || !approver) {
return NextResponse.json(
{ error: 'post_id, action, and approver are required' },
{ status: 400 },
);
}
if (action !== 'approve' && action !== 'reject') {
return NextResponse.json(
{ error: "action must be 'approve' or 'reject'" },
{ status: 400 },
);
}
const client = await getClient();
try {
await client.query('BEGIN');
if (action === 'approve') {
const newStatus = scheduled_at ? 'scheduled' : 'draft';
const updateResult = await client.query(
`UPDATE social_posts
SET status = $1,
approved_by = $2,
approved_at = NOW(),
rejection_reason = NULL,
updated_at = NOW()
WHERE id = $3
RETURNING *`,
[newStatus, approver, post_id],
);
if (updateResult.rowCount === 0) {
await client.query('ROLLBACK');
return NextResponse.json({ error: 'Post not found' }, { status: 404 });
}
if (scheduled_at) {
await client.query(
`INSERT INTO social_schedule (post_id, scheduled_at, status, next_run_at)
VALUES ($1, $2, 'pending', $2)`,
[post_id, scheduled_at],
);
}
await client.query('COMMIT');
return NextResponse.json({ post: updateResult.rows[0] });
}
// reject
const updateResult = await client.query(
`UPDATE social_posts
SET status = 'draft',
rejection_reason = $1,
approved_by = $2,
approved_at = NOW(),
updated_at = NOW()
WHERE id = $3
RETURNING *`,
[reason ?? null, approver, post_id],
);
if (updateResult.rowCount === 0) {
await client.query('ROLLBACK');
return NextResponse.json({ error: 'Post not found' }, { status: 404 });
}
await client.query('COMMIT');
return NextResponse.json({ post: updateResult.rows[0] });
} catch (err) {
try {
await client.query('ROLLBACK');
} catch {
/* ignore rollback error */
}
console.error('[posts/approve] error:', (err as Error).message);
return NextResponse.json(
{ error: 'Failed to process approval' },
{ status: 500 },
);
} finally {
client.release();
}
}