- DirectorAppointmentTab: table + 'Acceptance Letter' modal with company/director dropdowns - GET/POST /api/appointments: create record, generate HTML letter, convert to PDF via LibreOffice, email to director via himalaya SMTP - PATCH /api/appointments/[id]: save signature PNG, embed in signed letter PDF, mail to all company directors - GET /api/appointments/sign/[token]: public token lookup - /sign/[token]/page.tsx: public signature canvas (mouse + touch) - ysterbaard_director_appointments PB collection (requires manual schema setup) - Section 3 'Director Appointment' now active in ResolutionExplorer - NEXT_PUBLIC_APP_URL added to .env.local
33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
// app/api/tasks/[id]/retry/route.ts
|
|
// POST /api/tasks/[id]/retry
|
|
// Manual re-queue: failed | done → ready. Resets claim fields.
|
|
|
|
import { NextRequest, NextResponse } from "next/server";
|
|
import { fetchRecord, updateRecord, PBRecord } from "@/lib/pb";
|
|
|
|
export const dynamic = "force-dynamic";
|
|
|
|
const COLLECTION = "tasks";
|
|
|
|
export async function POST(_req: NextRequest, { params }: { params: { id: string } }) {
|
|
try {
|
|
const current = await fetchRecord<PBRecord>(COLLECTION, params.id);
|
|
if (current.status !== "failed" && current.status !== "done") {
|
|
return NextResponse.json(
|
|
{ ok: false, error: `cannot retry from status '${current.status}'` },
|
|
{ status: 409 },
|
|
);
|
|
}
|
|
const updated = await updateRecord<PBRecord>(COLLECTION, params.id, {
|
|
status: "ready",
|
|
error: null,
|
|
completed_at: null,
|
|
claimed_by: null,
|
|
claimed_at: null,
|
|
started_at: null,
|
|
});
|
|
return NextResponse.json({ ok: true, task: updated });
|
|
} catch (err: any) {
|
|
return NextResponse.json({ ok: false, error: err.message }, { status: 500 });
|
|
}
|
|
}
|