fix: Bug 1+2+3 — SQL Cross-Join, PATCH 404 vs 400, API-Test-Skip
- getCampaignRecipients: EXISTS-Subquery statt Cross-Join verhindert Mehrfachversand - updateCampaign: SELECT vor UPDATE unterscheidet 'nicht gefunden' (404) von 'nicht im Draft' (400) - campaigns-api.test.ts: describe.skip entfernt, Mocks für DB-Abhängigkeiten ergänzt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getCampaign, updateCampaignStatus } from '../../../../../server/db/campaigns'
|
||||
import { getCampaign, updateCampaignStatus, getCampaignRecipients } from '../../../../../server/db/campaigns'
|
||||
import { emailSendQueue } from '../../../../../queues/email-send.queue'
|
||||
import { withTenant } from '../../../../../server/db/tenant'
|
||||
import { hashEmail } from '../../../../../lib/crypto'
|
||||
import { checkSuppression } from '../../../../../server/suppression/check'
|
||||
import { getTenantId } from '../../../../../lib/tenant-header'
|
||||
@@ -25,22 +24,13 @@ export async function POST(req: NextRequest, { params }: { params: { id: string
|
||||
return NextResponse.json({ error: statusResult.error.message }, { status: 500 })
|
||||
}
|
||||
|
||||
let recipients: { email: string }[]
|
||||
try {
|
||||
recipients = await withTenant(tenantId, (client) =>
|
||||
client.query<{ email: string }>(
|
||||
`SELECT s.email FROM subscribers s
|
||||
JOIN campaign_recipients cr ON cr.campaign_id = $1
|
||||
WHERE (cr.list_id IS NULL OR s.list_id = cr.list_id)
|
||||
AND s.status = 'active'`,
|
||||
[params.id]
|
||||
)
|
||||
)
|
||||
} catch (e) {
|
||||
const recipientsResult = await getCampaignRecipients(tenantId, params.id)
|
||||
if (!recipientsResult.ok) {
|
||||
// Rollback auf draft — verhindert verwaisten 'sending'-Status
|
||||
await updateCampaignStatus(tenantId, params.id, 'draft')
|
||||
return NextResponse.json({ error: 'Empfänger konnten nicht geladen werden' }, { status: 500 })
|
||||
}
|
||||
const recipients = recipientsResult.data
|
||||
|
||||
// Suppression-Check PFLICHT — kein Opt-out-Empfänger darf in die Queue
|
||||
const unsuppressedRecipients = await Promise.all(
|
||||
|
||||
Reference in New Issue
Block a user