feat(22-02): add firstReportTicketId to campaigns list route

- Alias campaigns table as c, add correlated subquery for the earliest
  linked report's ticket_id so the list page can navigate a row click
  straight to /phishing/tickets/{firstReportTicketId}
- Additive only: count query, limit/offset, requirePermission gate, and
  the { items, total, limit, offset } envelope all unchanged
This commit is contained in:
lorentz 2026-07-16 14:43:43 -04:00
parent 9e83ec09ee
commit c70b30a000

View file

@ -20,6 +20,7 @@ interface CampaignRow {
report_count: number;
status: string;
created_at: string;
first_report_ticket_id: string | null;
}
export async function GET(request: NextRequest) {
@ -37,15 +38,16 @@ export async function GET(request: NextRequest) {
let statusFilter = '';
if (status) {
params.push(status);
statusFilter = `WHERE status = $${params.length}`;
statusFilter = `WHERE c.status = $${params.length}`;
}
const campaigns = await postgresClient.query<CampaignRow>(
`SELECT id::text, campaign_key, group_method, first_seen_at::text, last_seen_at::text,
report_count, status, created_at::text
FROM campaigns
`SELECT c.id::text, c.campaign_key, c.group_method, c.first_seen_at::text, c.last_seen_at::text,
c.report_count, c.status, c.created_at::text,
(SELECT r.ticket_id::text FROM reports r WHERE r.campaign_id = c.id ORDER BY r.created_at ASC LIMIT 1) AS first_report_ticket_id
FROM campaigns c
${statusFilter}
ORDER BY last_seen_at DESC NULLS LAST
ORDER BY c.last_seen_at DESC NULLS LAST
LIMIT $1 OFFSET $2`,
params
);
@ -72,6 +74,7 @@ export async function GET(request: NextRequest) {
reportCount: c.report_count,
status: c.status,
createdAt: c.created_at,
firstReportTicketId: c.first_report_ticket_id,
}));
return NextResponse.json({ items, total, limit, offset });