← back to Norma
app/api/drafts/route.ts
97 lines
import { NextRequest, NextResponse } from 'next/server';
import { query } from '@/lib/db';
import { requireRole } from '@/lib/require-role';
import { getOrgId } from '@/lib/orgId';
/**
* GET /api/drafts
* List drafts with optional filters:
* ?session_id= — filter by session
* ?lane= — filter by lane (A, B, C)
* ?status= — filter by status
* ?search= — full-text search on subject
* ?limit= — rows per page (default 50, max 200)
* ?offset= — pagination offset (default 0)
* Ordered by created_at DESC.
*/
export async function GET(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
try {
const { searchParams } = new URL(request.url);
const sessionId = searchParams.get('session_id');
const lane = searchParams.get('lane');
const status = searchParams.get('status');
const search = searchParams.get('search');
let limit = parseInt(searchParams.get('limit') || '50', 10);
if (isNaN(limit) || limit < 1) limit = 50;
if (limit > 200) limit = 200;
let offset = parseInt(searchParams.get('offset') || '0', 10);
if (isNaN(offset) || offset < 0) offset = 0;
const orgId = auth.role === 'admin' ? getOrgId(request) : auth.orgId;
const conditions: string[] = [];
const values: unknown[] = [];
let paramIndex = 1;
if (orgId) {
conditions.push(`d.org_id = $${paramIndex}`);
values.push(orgId);
paramIndex++;
}
if (sessionId) {
conditions.push(`d.session_id = $${paramIndex}`);
values.push(sessionId);
paramIndex++;
}
if (lane) {
conditions.push(`d.lane = $${paramIndex}`);
values.push(lane.toUpperCase());
paramIndex++;
}
if (status) {
conditions.push(`d.status = $${paramIndex}`);
values.push(status);
paramIndex++;
}
if (search) {
conditions.push(`d.subject ILIKE $${paramIndex}`);
values.push(`%${search}%`);
paramIndex++;
}
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
const countResult = await query(
`SELECT COUNT(*)::int AS total FROM drafts d ${whereClause}`,
values
);
const total = countResult.rows[0]?.total ?? 0;
const result = await query(
`SELECT d.*,
s.title AS session_title,
s.session_date
FROM drafts d
LEFT JOIN sessions s ON s.id = d.session_id
${whereClause}
ORDER BY d.created_at DESC
LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`,
[...values, limit, offset]
);
return NextResponse.json({ drafts: result.rows, total, limit, offset });
} catch (err) {
console.error('[api/drafts] GET error:', (err as Error).message);
return NextResponse.json({ error: 'Failed to fetch drafts' }, { status: 500 });
}
}