import { notFound } from "next/navigation"; import { BackendDownNotice } from "@/components/BackendDownNotice"; import { ForeshadowBoard } from "@/components/foreshadow/ForeshadowBoard"; import { fetchForeshadow, fetchProject } from "@/lib/api/server"; import type { ForeshadowView, ProjectResponse } from "@/lib/api/types"; interface PageProps { params: Promise<{ id: string }>; } // 伏笔看板页(UX §6.8)。Server Component 取项目 + 全量伏笔(GET .../foreshadow); // ForeshadowBoard(Client)按 status 分四泳道并承载登记/状态变更交互。 export default async function ForeshadowPage({ params }: PageProps) { const { id } = await params; // 仅当项目确实不存在(404)才判 notFound;后端不可用等其它失败降级为「后端不可达」提示, // 不把整页变成「找不到页面」。 let project: ProjectResponse; try { project = await fetchProject(id); } catch (err) { if (isNotFoundError(err)) notFound(); return ; } // 伏笔看板(GET .../foreshadow)。瞬时错误降级为空看板,不阻塞进页。 let initialItems: ForeshadowView[] = []; try { const board = await fetchForeshadow(id); initialItems = board.foreshadow ?? []; } catch { initialItems = []; } return ; } // fetchProject 抛错信息形如「请求失败 404: ...」;据此区分「项目不存在」与「后端不可用」。 function isNotFoundError(err: unknown): boolean { return err instanceof Error && err.message.includes("请求失败 404"); }