feat: held mail release button + per-tenant fetch

- Add releaseHeldMessage() to MimecastClient (POST /api/gateway/hold-release)
- Add POST /api/mimecast/held/release route
- HeldMailTab: tenant selector before load (defaults to Wulf), only fetches selected tenant
- Release button per row with spinner + optimistic removal on success
- Error shown inline under Release button if release fails
This commit is contained in:
lorentz 2026-04-01 07:09:42 -04:00
parent a18d5b66bf
commit a15946daf8
3 changed files with 139 additions and 47 deletions

View file

@ -0,0 +1,34 @@
import { NextRequest, NextResponse } from 'next/server';
import { postgresClient } from '@/lib/services/postgres-client';
import { getMimecastClientForTenant } from '@/lib/services/mimecast-client';
export const dynamic = 'force-dynamic';
export async function POST(req: NextRequest) {
try {
const { id, tenantId } = await req.json();
if (!id || !tenantId) {
return NextResponse.json({ error: 'id and tenantId are required' }, { status: 400 });
}
const r = await postgresClient.query(
`SELECT * FROM mimecast_tenants WHERE id = $1 AND enabled = true`,
[tenantId]
);
if (!r.rows.length) {
return NextResponse.json({ error: 'Tenant not found' }, { status: 404 });
}
const client = getMimecastClientForTenant(r.rows[0]);
const result = await client.releaseHeldMessage(id);
if (!result.released) {
return NextResponse.json({ error: result.error ?? 'Release failed — message may already be released or expired' }, { status: 422 });
}
return NextResponse.json({ released: true });
} catch (error: any) {
console.error('[HeldMail] release error:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
}