合入遗留收口分支 nr8/l 的复核修复(变化记录先占住那一行再读改写、召回里行序不定的指标、事件触发列表按任务各取上限、选对象按名字查用 ilike、子工作流写入认旧键、几处测试的竞态)

# Conflicts:
#	backend/app/ledger/recall.py
This commit is contained in:
ThearchyHelios
2026-10-19 12:05:19 +08:00
20 changed files with 438 additions and 65 deletions
+2
View File
@@ -79,6 +79,8 @@ export function RecallPreviewRow({ workflowId, version }: { workflowId: string;
const STATE_COLOR: Record<string, string | undefined> = {
changed: 'var(--st-waiting)', failed: 'var(--err)', not_recomputable: 'var(--text-faint)', unchanged: 'var(--ok)',
// 核对不了(行序不定):要人去核对,和「数变了」同一种提醒色
row_order: 'var(--st-waiting)',
}
/** 列表先列几组,其余收起 */
const SHOWN = 6
+2
View File
@@ -133,6 +133,8 @@ export const LEDGER_UI = {
recall: {
/** 口径升版后在同一份数据上重算过、数没变 */
checked: (caliber: string) => `已按口径${caliber} 核对,不影响`,
/** 部分指标行序不定:那几项没能核对,照实列出 */
checkedRowOrder: (names: string[]) => `其中${names.map((x) => `「${x}」`).join('、')}行序不定,没能核对`,
/** 依据有变:目录里影响数字的项被驳回或修改、出现新码值、处理变化时改了目录(目录类),表或列被删、类型变了(表结构) */
basis: (what: 'catalog' | 'structure' | 'other', items: number) =>
`${what === 'structure' ? '依据的表结构有变' : what === 'catalog' ? '依据的数据目录有变' : '答案的依据有变'}`
+3 -1
View File
@@ -58,6 +58,7 @@ export const RECALL_TEXT = {
const parts = [
c.changed ? `数变了 ${n(c.changed)} 组` : '',
c.unchanged ? `没变 ${n(c.unchanged)} 组` : '',
c.row_order ? `核对不了(行序不定)${n(c.row_order)} 组` : '',
c.running ? `正在重算 ${n(c.running)} 组` : '',
c.failed ? `重算失败 ${n(c.failed)} 组` : '',
c.not_recomputable ? `无法重算 ${n(c.not_recomputable)} 组` : '',
@@ -65,7 +66,8 @@ export const RECALL_TEXT = {
return parts.join(',')
},
state: {
changed: '数变了', unchanged: '没变', failed: '重算失败', running: '正在重算', pending: '未重算',
changed: '数变了', unchanged: '没变', row_order: '核对不了(行序不定)', failed: '重算失败', running: '正在重算',
pending: '未重算',
not_recomputable: '无法重算',
} as Record<string, string>,
reason: (state: string, reason: string) => (state === 'not_recomputable' ? `无法重算:${reason}` : reason),
+6 -1
View File
@@ -127,7 +127,12 @@ export function RecallMarks({ recall }: { recall?: LedgerRecallMarks }) {
{[...checked.values()].map((c) => (
<li key={`c-${c.workflow_id ?? ''}`} className="flex items-start gap-1.5 text-dim" data-ledger-recall-checked={c.to_version ?? ''}>
<CircleCheck size={11} className="mt-[2px] shrink-0 text-faint" aria-hidden />
<span>{R.checked(caliberName(c.workflow_name, c.to_version))}</span>
<span>
{R.checked(caliberName(c.workflow_name, c.to_version))}
{!!c.row_order_metrics?.length && (
<span className="ml-1" data-ledger-recall-row-order="">{R.checkedRowOrder(c.row_order_metrics)}</span>
)}
</span>
</li>
))}
{[...basis.entries()].map(([group, b]) => (
+2
View File
@@ -220,6 +220,8 @@ export interface LedgerRecallMarks {
recall_run?: string | null
changed?: boolean
at?: string | null
/** 行序不定、没能核对的那几项(服务端 ledger/recall.settle):不算进「不影响」 */
row_order_metrics?: string[]
}[]
/** 依据有变:kind 是 catalog(目录里影响数字的项被驳回或修改)/ structure(表结构)/ values(新码值)/ catalog_edit */
basis?: { kind?: string | null; items?: number; new_errors?: number; at?: string | null }[]
+2 -1
View File
@@ -42,7 +42,8 @@ export interface RecallPreview {
reasons: { reason: string; groups: number }[]
}
export type RecallGroupState = 'changed' | 'unchanged' | 'failed' | 'running' | 'pending' | 'not_recomputable'
/** row_order:全部指标行序不定、核对不了(服务端 ledger/recall.settle),已开待办请人核对 */
export type RecallGroupState = 'changed' | 'unchanged' | 'row_order' | 'failed' | 'running' | 'pending' | 'not_recomputable'
/** 召回批次里的一组 */
export interface RecallGroup {