fix upload image trip
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { runCron } from "@/lib/cron-runner";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import {
|
||||
deleteTripImage,
|
||||
listTripImageNames,
|
||||
tripImageMtime,
|
||||
TRIP_IMAGE_URL_PREFIX,
|
||||
} from "@/lib/trip-image-storage";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
/** File yang lebih tua dari ini & tak direferensikan DB dianggap yatim. */
|
||||
const ORPHAN_AGE_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Cron — hapus file gambar trip yatim.
|
||||
*
|
||||
* Form create-trip multi-step mengunggah foto SEBELUM trip tersimpan; kalau
|
||||
* user menutup form di tengah jalan, file menggantung di disk tanpa pernah
|
||||
* jadi `TripImage`. Sweep ini menghapus file >24 jam yang tidak direferensikan
|
||||
* `TripImage` mana pun. Idempotent — aman dijalankan berulang.
|
||||
*
|
||||
* Trigger: lihat docs/CRON_SETUP.md. Header wajib `Authorization: Bearer ${CRON_SECRET}`.
|
||||
*/
|
||||
export async function GET(req: NextRequest) {
|
||||
const secret = process.env.CRON_SECRET;
|
||||
if (!secret) {
|
||||
console.error("[cron/cleanup-trip-images] CRON_SECRET tidak di-set");
|
||||
return NextResponse.json(
|
||||
{ error: "Server misconfigured" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
if (req.headers.get("authorization") !== `Bearer ${secret}`) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const outcome = await runCron("cleanup-trip-images", async () => {
|
||||
const names = await listTripImageNames();
|
||||
if (names.length === 0) return { scanned: 0, deleted: 0 };
|
||||
|
||||
const referenced = await prisma.tripImage.findMany({
|
||||
where: { url: { startsWith: TRIP_IMAGE_URL_PREFIX } },
|
||||
select: { url: true },
|
||||
});
|
||||
const referencedNames = new Set(
|
||||
referenced.map((r) => r.url.slice(TRIP_IMAGE_URL_PREFIX.length))
|
||||
);
|
||||
|
||||
const now = Date.now();
|
||||
let deleted = 0;
|
||||
for (const name of names) {
|
||||
if (referencedNames.has(name)) continue;
|
||||
const mtime = await tripImageMtime(name);
|
||||
// File baru di-upload tapi trip belum tersimpan → beri tenggang 24 jam.
|
||||
if (!mtime || now - mtime.getTime() < ORPHAN_AGE_MS) continue;
|
||||
await deleteTripImage(name);
|
||||
deleted++;
|
||||
}
|
||||
return { scanned: names.length, deleted };
|
||||
});
|
||||
|
||||
if (!outcome.ok) {
|
||||
console.error("[cron/cleanup-trip-images] gagal", outcome.error);
|
||||
return NextResponse.json(
|
||||
{ error: "Gagal menjalankan cleanup" },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
console.log("[cron/cleanup-trip-images] selesai", outcome.payload);
|
||||
return NextResponse.json({ ok: true, ...outcome.payload });
|
||||
}
|
||||
Reference in New Issue
Block a user