fix: wire report idempotency and bootstrap scheduler check
This commit is contained in:
@@ -12,8 +12,14 @@ export const POST: APIRoute = async ({ request, redirect, cookies }) => {
|
|||||||
const payload = { fish_slug: String(form.get("fish_slug") || ""), waterbody_slug: String(form.get("waterbody_slug") || ""), x: Number(form.get("x")), y: Number(form.get("y")), weight_g: Number(form.get("weight_g")), bait_name: text("bait_name"), fishing_method: text("fishing_method"), retrieve_method: text("retrieve_method"), retrieve_speed: number("retrieve_speed"), player_name: text("player_name"), comment: text("comment"), website: String(form.get("website") || "") };
|
const payload = { fish_slug: String(form.get("fish_slug") || ""), waterbody_slug: String(form.get("waterbody_slug") || ""), x: Number(form.get("x")), y: Number(form.get("y")), weight_g: Number(form.get("weight_g")), bait_name: text("bait_name"), fishing_method: text("fishing_method"), retrieve_method: text("retrieve_method"), retrieve_speed: number("retrieve_speed"), player_name: text("player_name"), comment: text("comment"), website: String(form.get("website") || "") };
|
||||||
let createdId: string | null = null;
|
let createdId: string | null = null;
|
||||||
let uploadToken: string | null = null;
|
let uploadToken: string | null = null;
|
||||||
|
// Keep one key across retries so a timeout cannot create a duplicate report.
|
||||||
|
let idempotencyKey = cookies.get("rf4-idempotency-key")?.value;
|
||||||
|
if (!idempotencyKey) {
|
||||||
|
idempotencyKey = crypto.randomUUID();
|
||||||
|
cookies.set("rf4-idempotency-key", idempotencyKey, { httpOnly: true, sameSite: "strict", secure: import.meta.env.PROD, path: "/", maxAge: 900 });
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`${base}/api/v1/catch-reports`, { method: "POST", headers: { "content-type": "application/json", "X-Forwarded-For": request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown" }, body: JSON.stringify(payload), signal: AbortSignal.timeout(30_000) });
|
const response = await fetch(`${base}/api/v1/catch-reports`, { method: "POST", headers: { "content-type": "application/json", "Idempotency-Key": idempotencyKey, "X-Forwarded-For": request.headers.get("x-forwarded-for") || request.headers.get("x-real-ip") || "unknown" }, body: JSON.stringify(payload), signal: AbortSignal.timeout(30_000) });
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (response.status === 429) return redirect("/report?state=rate_limited", 303);
|
if (response.status === 429) return redirect("/report?state=rate_limited", 303);
|
||||||
if (response.status >= 500) return redirect("/report?state=server_error", 303);
|
if (response.status >= 500) return redirect("/report?state=server_error", 303);
|
||||||
@@ -32,6 +38,7 @@ export const POST: APIRoute = async ({ request, redirect, cookies }) => {
|
|||||||
return redirect(`/report?state=screenshot_error&report_id=${encodeURIComponent(created.id)}`, 303);
|
return redirect(`/report?state=screenshot_error&report_id=${encodeURIComponent(created.id)}`, 303);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cookies.delete("rf4-idempotency-key", { path: "/" });
|
||||||
return redirect("/report?state=sent", 303);
|
return redirect("/report?state=sent", 303);
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ echo "Caddy configuration valid ✓"
|
|||||||
echo "Validating community scheduler..."
|
echo "Validating community scheduler..."
|
||||||
$compose up --build -d --wait community-scheduler
|
$compose up --build -d --wait community-scheduler
|
||||||
# Scheduler runs in a loop, check it's healthy by verifying the process is running
|
# Scheduler runs in a loop, check it's healthy by verifying the process is running
|
||||||
$compose exec -T community-scheduler python -c "from app.community_scheduler import schedule_interval; print('scheduler module loads OK')" >/dev/null 2>&1 || {
|
$compose exec -T community-scheduler python -c "import app.community_scheduler; print('scheduler module loads OK')" >/dev/null 2>&1 || {
|
||||||
echo "ERROR: Community scheduler failed to start" >&2
|
echo "ERROR: Community scheduler failed to start" >&2
|
||||||
$compose logs --no-color community-scheduler >&2
|
$compose logs --no-color community-scheduler >&2
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
Reference in New Issue
Block a user