fix: block unconfirmed birth-time candidate adoption

This commit is contained in:
732642856
2026-07-21 16:06:30 +08:00
parent fcf5794513
commit d82218e70a
7 changed files with 36 additions and 337 deletions
@@ -1,9 +1,5 @@
import { NextResponse } from "next/server";
import { z } from "zod";
import { candidateWorkingTime } from "@/lib/birth-time-candidate-completion";
import { createAdminSupabaseClient } from "@/lib/supabase/admin";
import { isSupabaseConfigurationError } from "@/lib/supabase/config";
import { createServerSupabaseClient } from "@/lib/supabase/server";
export const runtime = "nodejs";
@@ -13,57 +9,12 @@ const requestSchema = z.object({
time: z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/),
}).strict();
/** Compatibility endpoint for stale clients; unconfirmed candidates never write profiles. */
export async function POST(request: Request) {
try {
const supabase = await createServerSupabaseClient();
const { data: { user }, error: authError } = await supabase.auth.getUser();
if (authError || !user) {
return NextResponse.json({ error: "请先登录" }, { status: 401 });
}
const parsed = requestSchema.safeParse(await request.json().catch(() => null));
if (!parsed.success) {
return NextResponse.json({ error: "候选时间格式不正确" }, { status: 400 });
}
const admin = createAdminSupabaseClient();
const { data: stored, error: caseError } = await admin
.from("birth_time_rectification_cases")
.select("id,user_id,status,candidate_result_id,candidate_result,turn_state")
.eq("id", parsed.data.caseId)
.eq("user_id", user.id)
.maybeSingle();
const time = candidateWorkingTime(stored, { ...parsed.data, userId: user.id });
if (caseError || !time) {
return NextResponse.json(
{ error: "候选结果已变化", message: "请使用当前评估结果继续。" },
{ status: 409 },
);
}
const { data: profile, error: profileError } = await admin
.from("profiles")
.update({
active_birth_time: time,
birth_time_status: "candidate",
updated_at: new Date().toISOString(),
})
.eq("id", user.id)
.eq("rectification_case_id", parsed.data.caseId)
.select("id")
.maybeSingle();
if (profileError || !profile) {
return NextResponse.json(
{ error: "候选时间暂时无法保存", message: "当前评估结果仍已保留,请稍后重试。" },
{ status: 503 },
);
}
return NextResponse.json({ ok: true, activeTime: time, birthTimeStatus: "candidate" });
} catch (error) {
if (isSupabaseConfigurationError(error)) {
return NextResponse.json({ error: "Supabase 尚未配置" }, { status: 503 });
}
return NextResponse.json({ error: "候选时间暂时无法保存" }, { status: 500 });
}
const parsed = requestSchema.safeParse(await request.json().catch(() => null));
if (!parsed.success) return NextResponse.json({ error: "候选时间格式不正确" }, { status: 400 });
return NextResponse.json(
{ error: "候选时间不能直接采用", message: "候选范围已保留;请补充资料,或在高置信结果出现后通过正式确认继续。" },
{ status: 409 },
);
}