refactor(web): ApiErrorEnvelope 改由生成 schema 派生,防契约漂移
手写 ApiErrorEnvelope 改由 components["schemas"]["ErrorEnvelope"] 派生;accept 端点专属 details.missing_conflict_indices 就地收窄。运行时行为不变(既有 useAccept 测试全绿)。
This commit is contained in:
@@ -4,6 +4,7 @@ import { useCallback, useState } from "react";
|
|||||||
|
|
||||||
import { api } from "@/lib/api/client";
|
import { api } from "@/lib/api/client";
|
||||||
import { useToast } from "@/components/Toast";
|
import { useToast } from "@/components/Toast";
|
||||||
|
import type { components } from "@/lib/api/schema";
|
||||||
import type { AcceptResponse } from "@/lib/api/types";
|
import type { AcceptResponse } from "@/lib/api/types";
|
||||||
import { buildAcceptRequest, type DecisionDraft } from "./decisions";
|
import { buildAcceptRequest, type DecisionDraft } from "./decisions";
|
||||||
|
|
||||||
@@ -29,12 +30,13 @@ export interface UseAccept {
|
|||||||
) => Promise<AcceptOutcome>;
|
) => Promise<AcceptOutcome>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ApiErrorEnvelope {
|
// 错误信封形状从后端 OpenAPI 生成的 schema 派生,避免与契约漂移(不再手抄字段)。
|
||||||
error?: {
|
type ApiErrorEnvelope = components["schemas"]["ErrorEnvelope"];
|
||||||
code?: string;
|
|
||||||
message?: string;
|
// accept 端点 409 CONFLICT_UNRESOLVED 在 details 里携带缺判下标;
|
||||||
details?: { missing_conflict_indices?: number[] } | null;
|
// 生成 schema 的 details 为松散 `{[k]: unknown}`,此处就地收窄该端点专属字段。
|
||||||
};
|
interface ConflictErrorDetails {
|
||||||
|
missing_conflict_indices?: number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 验收:乐观置 accepting → 成功置 accepted(呈现「本次将更新」清单);
|
// 验收:乐观置 accepting → 成功置 accepted(呈现「本次将更新」清单);
|
||||||
@@ -59,7 +61,8 @@ export function useAccept(): UseAccept {
|
|||||||
setStatus("error");
|
setStatus("error");
|
||||||
const env = error as ApiErrorEnvelope | undefined;
|
const env = error as ApiErrorEnvelope | undefined;
|
||||||
const code = env?.error?.code;
|
const code = env?.error?.code;
|
||||||
const missing = env?.error?.details?.missing_conflict_indices ?? [];
|
const details = env?.error?.details as ConflictErrorDetails | undefined;
|
||||||
|
const missing = details?.missing_conflict_indices ?? [];
|
||||||
if (code === "CONFLICT_UNRESOLVED") {
|
if (code === "CONFLICT_UNRESOLVED") {
|
||||||
return { result: null, missingIndices: missing, conflictUnresolved: true };
|
return { result: null, missingIndices: missing, conflictUnresolved: true };
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user