fix(api): add sync safety guards against degenerate SDS responses

Add SYNC_GUARDS thresholds so a partial/degenerate upstream response never
triggers a destructive operation:
- skip stale category deletion when the fetched tree is suspiciously small
  vs the existing SDS category count
- skip delist detection unless both leaf-category and seen-product counts
  are healthy

Verified: 77 tests pass; live SDS returns 226 categories (guard off),
incident-case ratios (2/226, 2/2) are correctly blocked.
This commit is contained in:
yeuimu
2026-08-20 16:37:44 +08:00
parent 79fabd85f7
commit aed9afef92
6 changed files with 342 additions and 45 deletions
+13
View File
@@ -9,6 +9,13 @@ const POD_HEADERS = {
Referer: 'https://inkpod.vip/',
} as const;
/**
* Minimum number of category nodes a healthy `category/tree/3` response contains.
* Below this the response is treated as degenerate and rejected so the caller
* never runs a destructive sync against a partial tree.
*/
export const MIN_SDS_CATEGORY_NODES = 10;
export interface SdsCategoryTreeNode {
id: number | string | null;
name?: string;
@@ -109,6 +116,12 @@ export class SdsClientService {
if (!Array.isArray(data)) {
throw new Error(`SDS category tree returned ${typeof data}, expected array`);
}
if (data.length < MIN_SDS_CATEGORY_NODES) {
throw new Error(
`SDS category tree is degenerate (${data.length} nodes < ${MIN_SDS_CATEGORY_NODES}) — ` +
`aborting to avoid destructive sync`,
);
}
return data as SdsCategoryTreeNode[];
}