From 32d7d969f60e50d175112f30c1eccadef1d71009 Mon Sep 17 00:00:00 2001 From: oliver Date: Sun, 11 Oct 2026 07:55:04 +0800 Subject: [PATCH] feat: refine cutover operations board and monitoring performance Protect previous wave coverage, normalize batch identities, cache shared metric evidence, and batch diff inserts. Add live continuity KPIs, server paging and filters, scoped business selection, and preserve legacy monitor rule metadata. Validation: 198 backend tests passed with 1 opt-in benchmark skipped; 14 frontend unit tests and 24 browser checks passed; TypeScript and production build passed. --- docs/reviews/assets/cutover-monitor-board.png | Bin 0 -> 110161 bytes .../reviews/assets/cutover-monitor-mobile.png | Bin 0 -> 46226 bytes netx_api/biz_migration/evaluate.py | 47 ++- netx_api/biz_migration/service.py | 50 ++- tests/test_biz_migration_integrity.py | 78 ++++ web/src/i18n/en.ts | 53 ++- web/src/i18n/zh.ts | 53 ++- web/src/index.css | 48 +++ web/src/pages/network/BizMigrationPage.tsx | 343 +++++++++++++----- .../pages/network/BizMonitorTemplatesPage.tsx | 47 +-- web/src/services/api.ts | 4 + web/tests/bizMigration.browser.mjs | 159 ++++++++ 12 files changed, 731 insertions(+), 151 deletions(-) create mode 100644 docs/reviews/assets/cutover-monitor-board.png create mode 100644 docs/reviews/assets/cutover-monitor-mobile.png create mode 100644 web/tests/bizMigration.browser.mjs diff --git a/docs/reviews/assets/cutover-monitor-board.png b/docs/reviews/assets/cutover-monitor-board.png new file mode 100644 index 0000000000000000000000000000000000000000..e6041006ccdb358b01301d5fb89d36f39fe10263 GIT binary patch literal 110161 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
    -+rAK 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 z

    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 dict[str, set[str]]: if it.get("key") is not None: k = it.get("key") if isinstance(k, (list, tuple)): - joined = KEY_SEP.join(str(p).strip() for p in k if str(p).strip()) - if joined: + joined = KEY_SEP.join(scalar_text(p).strip() for p in k) + if joined.strip(KEY_SEP): bucket.add(joined) else: - s = normalize_expect_key(str(k or "")) + s = normalize_expect_key(scalar_text(k)) if s: bucket.add(s) keys = it.get("keys") @@ -120,14 +120,14 @@ def parse_expect_set(raw: dict[str, Any] | None) -> dict[str, set[str]]: # Flat list of segments → one composite key; else each entry is a key # (string or nested list/tuple of segments). if keys and all(not isinstance(x, (list, tuple, dict)) for x in keys): - joined = KEY_SEP.join(str(x).strip() for x in keys if str(x).strip()) - if joined: + joined = KEY_SEP.join(scalar_text(x).strip() for x in keys) + if joined.strip(KEY_SEP): bucket.add(joined) else: for x in keys: if isinstance(x, (list, tuple)): - joined = KEY_SEP.join(str(p).strip() for p in x if str(p).strip()) - if joined: + joined = KEY_SEP.join(scalar_text(p).strip() for p in x) + if joined.strip(KEY_SEP): bucket.add(joined) else: s = normalize_expect_key(str(x or "")) @@ -272,6 +272,10 @@ def _eval_field_op( raw = "" if not row else scalar_text(row.get(f)).strip() val = raw.lower() o = str(op or "eq").strip().lower() + if row and f not in row: + # A missing parser field is not evidence for a negative condition such as + # state != down. Only an explicit empty check may match that absence. + return o == "empty" if o in ("changed", "diff"): base = "" if not base_row else scalar_text(base_row.get(f)).strip().lower() if not row: @@ -1119,6 +1123,7 @@ def evaluate_metric_dual( from ..biz_state.iface_normalize import ( apply_iface_normalize_rows, normalize_iface_rules, + normalize_iface_name, ) sid = str(sheet_id or "").strip() or str(metric_id or "").strip() @@ -1155,6 +1160,15 @@ def evaluate_metric_dual( ) norm_rules = normalize_iface_rules(iface_normalize_rules) + def normalized_key(key: str) -> str: + parts = key.split(KEY_SEP) if KEY_SEP in key else ([key] if len(key_fields) == 1 else key.split("|")) + if len(parts) != len(key_fields): + return key + return KEY_SEP.join(normalize_iface_name(p, norm_rules) if f in iface_fields else p + for p, f in zip(parts, key_fields)) + + expect_keys = {normalized_key(key) for key in expect_keys} + previous_keys = {normalized_key(key) for key in previous_keys} old_baseline_rows = apply_iface_normalize_rows( [strip_netx(r) for r in raw_old_base], iface_fields=iface_fields, rules=norm_rules ) @@ -1238,7 +1252,7 @@ def evaluate_metric_dual( # Mapping describes identity; an explicit batch selection defines scope. # Port selection also covers business rows attached to those interfaces. for scope, keys in ((expect, expect_keys), (previous_expect or {}, previous_keys)): - ports = scope.get("_ports") or set() + ports = {normalize_iface_name(p, norm_rules) for p in scope.get("_ports") or set()} if ports and not keys and iface_fields: for ks, diff in old_idx.items(): row = diff.get("before") or diff.get("after") or {} @@ -1293,6 +1307,7 @@ def evaluate_metric_dual( progress_total = 0 anomaly = 0 anomaly_in_expect = 0 + steady_outside = 0 rules_by_field = field_rule_map(field_rules) integrity_fields = effective_compare_fields(compare_fields, field_rules) # Status transitions are interpreted by the monitor's correction rules. @@ -1390,9 +1405,10 @@ def evaluate_metric_dual( verdict, rule_hit = "migrated_previous", "previous_batch_received" elif color != "red": verdict, color, rule_hit = "unfinished_previous", "red", "previous_batch_not_received" - # Retain all drift outside scope, but avoid filling the board with stable - # unmapped inventory when a port map defines the legacy migration scope. - if map_scoped and not in_exp and verdict == "not_involved": + # Stable inventory is covered by the comparison and counted, but does + # not need a full persisted evidence card on every high-frequency run. + if not in_exp and verdict == "not_involved": + steady_outside += 1 continue if in_exp and verdict == "migrated" and color == "green": progress_ok += 1 @@ -1404,9 +1420,9 @@ def evaluate_metric_dual( # Prefer live raw rows; fall back to baseline raw. Never use port-mapped # synthetic "before" as the new-side display row. raw_old = old_raw_cur_idx.get(old_ks) or old_raw_base_idx.get(old_ks) - raw_new = new_raw_cur_idx.get(new_ks) or new_raw_cur_idx.get(old_ks) + raw_new = new_raw_cur_idx.get(new_ks) if not raw_new: - raw_new = new_raw_base_idx.get(new_ks) or new_raw_base_idx.get(old_ks) + raw_new = new_raw_base_idx.get(new_ks) display_old = display_key_from_raw(raw_old, key_fields) or old_ks display_new = display_key_from_raw(raw_new, key_fields) or ( @@ -1420,8 +1436,8 @@ def evaluate_metric_dual( new_disp = strip_netx(raw_new) if raw_new else {} old_base_raw = strip_netx(old_raw_base_idx.get(old_ks)) if old_raw_base_idx.get(old_ks) else {} new_base_raw = ( - strip_netx(new_raw_base_idx.get(new_ks) or new_raw_base_idx.get(old_ks)) - if (new_raw_base_idx.get(new_ks) or new_raw_base_idx.get(old_ks)) + strip_netx(new_raw_base_idx.get(new_ks)) + if new_raw_base_idx.get(new_ks) else {} ) @@ -1512,6 +1528,7 @@ def evaluate_metric_dual( "progress_total": progress_total, "anomaly": anomaly, "anomaly_in_expect": anomaly_in_expect, + "steady_outside": steady_outside, "rows": rows_out, "new_baseline_mode": new_baseline_mode, "new_baseline_missing": new_baseline_missing, diff --git a/netx_api/biz_migration/service.py b/netx_api/biz_migration/service.py index c39183b..8138df8 100644 --- a/netx_api/biz_migration/service.py +++ b/netx_api/biz_migration/service.py @@ -7,9 +7,10 @@ from typing import Any from uuid import uuid4 from fastapi import HTTPException +from sqlalchemy import insert from sqlalchemy.orm import Session -from ..biz_state.compare_rules import apply_row_filters +from ..biz_state.compare_rules import apply_row_filters, scalar_text from ..biz_state.compare_service import ( _load_metric_rows, _port_map_dict, @@ -949,6 +950,13 @@ def run_evaluate( from ..biz_state.compare_validation import validate_template_body validate_template_body({"metrics": sheets, "iface_normalize_rules": iface_norm}) + from ..biz_state.iface_normalize import normalize_iface_name + + normalized_map = {normalize_iface_name(k, iface_norm): normalize_iface_name(v, iface_norm) + for k, v in port_map.items()} + if len(normalized_map) != len(port_map) or len(set(normalized_map.values())) != len(normalized_map): + raise HTTPException(status_code=400, detail="mapping_target_ambiguous") + port_map = normalized_map known_sheets = {sheet_key(s) for s in sheets} known_metrics = {str(s.get("metric_id") or "") for s in sheets} for override in sheet_overrides: @@ -967,7 +975,8 @@ def run_evaluate( rows_cache: dict[tuple[str, str], list[dict[str, Any]]] = {} command_cache: dict[str, dict[str, Any]] = {} scope_ids = {str(s.get("metric_id") or "") for s in sheets} | {sheet_key(s) for s in sheets} | {"_ports"} - uncovered_scope = sorted(k for k, values in expect.items() if values and k not in scope_ids) + uncovered_scope = sorted({k for scope in (expect, previous_expect) for k, values in scope.items() + if values and k not in scope_ids}) def metric_rows(bid: str, mid: str) -> list[dict[str, Any]]: key = (bid, mid) @@ -1116,6 +1125,7 @@ def run_evaluate( "progress_total": one["progress_total"], "anomaly": one["anomaly"], "anomaly_in_expect": int(one.get("anomaly_in_expect") or 0), + "steady_outside": int(one.get("steady_outside") or 0), "old_summary": one["old_summary"], "new_summary": one["new_summary"], "new_baseline_mode": one.get("new_baseline_mode") or "provided", @@ -1189,12 +1199,14 @@ def run_evaluate( ], "verdict_counts": verdict_counts, "anomaly_outside_expect": sum(int(c.get("anomaly") or 0) - int(c.get("anomaly_in_expect") or 0) for c in active_cards), + "steady_outside": sum(int(c.get("steady_outside") or 0) for c in active_cards), "duplicate_keys": sum(int(c.get("duplicate_keys_before") or 0) + int(c.get("duplicate_keys_after") or 0) for c in active_cards), "uncovered_scope": uncovered_scope, "coverage_complete": bool(sheet_cards) and not uncovered_scope and not any(c.get("collect_skipped") or c.get("current_missing") or c.get("awaiting_peer") or c.get("duplicate_keys_before") or c.get("duplicate_keys_after") for c in sheet_cards), "config_snapshot": {"sheets": sheets, "sheet_overrides": sheet_overrides, "defaults": defaults, "iface_normalize": iface_norm, - "port_map": port_map, "expect_set": mb.expect_set_json}, + "port_map": port_map, "expect_set": mb.expect_set_json, + "previous_expect": {k: sorted(v) for k, v in previous_expect.items()}}, "window_active": window_active, "expect_ports": sorted(expect.get("_ports") or ()), "old_current_task_id": current_task_id(proj, "old"), @@ -1204,6 +1216,7 @@ def run_evaluate( ) db.add(run) db.flush() + pending_diffs: list[dict[str, Any]] = [] for r in all_rows: key_list = r.get("key") or [] ev = r.get("evidence") if isinstance(r.get("evidence"), dict) else {} @@ -1222,8 +1235,8 @@ def run_evaluate( str(r.get("metric_id") or ""), ] ) - db.add( - BizMigrationDiff( + pending_diffs.append( + dict( id=uuid4().hex, run_id=run.id, metric_id=str(r.get("metric_id") or ""), @@ -1254,6 +1267,11 @@ def run_evaluate( search_text=search[:2000], ) ) + if len(pending_diffs) >= 500: + db.execute(insert(BizMigrationDiff), pending_diffs) + pending_diffs.clear() + if pending_diffs: + db.execute(insert(BizMigrationDiff), pending_diffs) db.flush() if _commit: db.commit() @@ -1436,6 +1454,11 @@ def list_baseline_expect_objects(db: Session, project_id: str) -> dict[str, Any] collect_ids = set(resolve_collect_metric_ids(db, p)) port_map = _port_map_dict(db, p.mapping_id) out_sheets: list[dict[str, Any]] = [] + from ..biz_state.iface_normalize import apply_iface_normalize, resolve_mapped_iface, normalize_iface_name + from .evaluate import KEY_SEP + + rows_cache: dict[str, list[dict[str, Any]]] = {} + port_map = {normalize_iface_name(k, _norm): normalize_iface_name(v, _norm) for k, v in port_map.items()} for sheet in sheets: mid = str(sheet.get("metric_id") or "").strip() sid = sheet_key(sheet) @@ -1449,25 +1472,32 @@ def list_baseline_expect_objects(db: Session, project_id: str) -> dict[str, Any] if sheet_ov.get("skip_dual"): continue iface_fields = [str(k) for k in (sheet.get("iface_fields") or []) if str(k).strip()] + if mid not in rows_cache: + rows_cache[mid] = _load_metric_rows(db, batch_id=p.old_baseline_batch_id, metric_id=mid) rows_raw = apply_row_filters( - _load_metric_rows(db, batch_id=p.old_baseline_batch_id, metric_id=mid), + rows_cache[mid], list(sheet.get("row_filters") or []), ) items: list[dict[str, Any]] = [] + seen_keys: set[str] = set() for r in rows_raw: - keys = [str(r.get(f) or "").strip() for f in key_fields] + normalized = apply_iface_normalize(dict(r), iface_fields=iface_fields, rules=_norm) + keys = [scalar_text(normalized.get(f)).strip() for f in key_fields] if not any(keys): continue - key_str = "|".join(keys) + key_str = KEY_SEP.join(keys) + if key_str in seen_keys: + continue + seen_keys.add(key_str) mapped = "" if iface_fields and key_fields and key_fields[0] in iface_fields: - mapped = port_map.get(keys[0]) or "" + mapped = resolve_mapped_iface(keys[0], port_map) if port_map else "" items.append( { "key": key_str, "keys": keys, "mapped_to": mapped, - "label": key_str, + "label": "|".join(scalar_text(r.get(f)).strip() for f in key_fields), "row": {f: r.get(f) for f in list(dict.fromkeys([*key_fields, *iface_fields, "description", "admin", "phy", "prot"])) if f in r}, } ) diff --git a/tests/test_biz_migration_integrity.py b/tests/test_biz_migration_integrity.py index 7a36f71..a1e9140 100644 --- a/tests/test_biz_migration_integrity.py +++ b/tests/test_biz_migration_integrity.py @@ -197,6 +197,84 @@ def test_port_mapping_does_not_remap_business_key_with_same_text(): assert out["progress_ok"] == 1 +def test_unmapped_same_name_target_is_not_used_as_mapped_target_evidence(): + out = evaluate(metric_id="interface_brief", key_fields=["port"], compare_fields=[], + old_baseline_rows=[{"port": "old"}], new_current_rows=[{"port": "old"}], + expect=parse_expect_set({"ports": ["old"]})) + row = next(r for r in out["rows"] if r["in_expect"]) + assert row["verdict"] == "lost" + assert row["new"] == {} + assert row["new_key"] == "" + assert row["match_new_key"] == "new" + + +def test_legacy_raw_interface_expect_uses_same_alias_normalization(): + out = evaluate(metric_id="interface_brief", key_fields=["port"], + old_baseline_rows=[{"port": "GE-1"}], new_current_rows=[{"port": "GE-2"}], + compare_fields=[], port_map={"gei-1": "gei-2"}, + expect=parse_expect_set({"ports": ["GE-1"]}), + iface_normalize_rules=[{"from": "GE", "to": "gei"}]) + assert out["progress_ok"] == 1 + + +def test_baseline_picker_matches_normalized_keys_but_displays_originals(db): + ct = db.get(BizCompareTemplate, "ct") + ct.metrics_json = [{"metric_id": "arp", "sheet_id": "s", "key_fields": ["ip", "port"], "iface_fields": ["port"]}] + ct.iface_normalize_json = [{"from": "GE", "to": "gei"}] + db.get(BizStateMetricRow, "row-ob").data_json = {"ip": 0, "port": "GE-1"} + db.commit() + item = svc.list_baseline_expect_objects(db, "p")["sheets"][0]["items"][0] + assert item["keys"] == ["0", "gei-1"] + assert item["label"] == "0|GE-1" + assert parse_expect_set({"items": [{"metric_id": "arp", "key": item["keys"]}]})["arp"] == {"0\x1fgei-1"} + + +def test_empty_composite_segments_are_preserved_and_false_is_not_blank(): + assert parse_expect_set({"items": [{"metric_id": "x", "key": [0, "", False]}]})["x"] == {"0\x1f\x1ffalse"} + + +def test_missing_status_field_cannot_match_negative_success_condition(): + assert not _eval_field_op({"ip": "a"}, "state", "ne", "down") + assert not _eval_field_op({"ip": "a"}, "state", "not_in", ["down"]) + assert _eval_field_op({"ip": "a"}, "state", "empty", None) + + +def test_stable_outside_inventory_is_counted_without_repeated_evidence_cards(): + row = {"ip": "a", "mac": "good", "port": "old"} + out = evaluate(expect={}, old_current_rows=[row], new_current_rows=[]) + assert out["rows"] == [] + assert out["steady_outside"] == 1 + assert out["anomaly"] == 0 + + +def test_removed_previous_wave_sheet_blocks_full_coverage_acceptance(db): + db.add(BizMigrationBatch(id="prior", project_id="p", status="done", + created_at=utcnow_naive() - timedelta(days=1), + expect_set_json={"items": [{"sheet_id": "removed-sheet", "metric_id": "arp", "key": "old-customer"}]})) + db.commit() + finished = svc.finish_batch(db, "wave") + assert not finished["accept_summary"]["passed"] + assert finished["run"]["summary"]["uncovered_scope"] == ["removed-sheet"] + + +def test_split_sheets_share_loaded_rows_and_command_metadata(db): + from unittest.mock import patch + + ct = db.get(BizCompareTemplate, "ct") + sheet = ct.metrics_json[0] + ct.metrics_json = [sheet, {**sheet, "sheet_id": "s2"}] + for i in range(500): + for bid in ("ob", "nc"): + db.add(BizStateMetricRow(id=f"bulk-{bid}-{i}", batch_id=bid, + batch_command_id="cmd-" + bid, metric_id="arp", data_json={"ip": f"bulk-{i}", "mac": "good"})) + db.commit() + with patch.object(svc, "_load_metric_rows", wraps=svc._load_metric_rows) as load, patch.object(svc, "_command_brief", wraps=svc._command_brief) as command: + run = svc.run_evaluate(db, batch_id="wave") + assert load.call_count == 4 # once for each (batch, metric), not once per sheet + assert command.call_count == 2 # baseline + current metadata, independent of row count + assert svc.list_run_diffs(db, run["id"], limit=1)["total"] == 1002 + + def test_wave_acceptance_rolls_back_whole_transaction_on_ticket_failure(db): from unittest.mock import patch diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 71324ab..82a2d75 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -696,6 +696,55 @@ const en = { colChange: "Changes", }, bizMigration: { + latestSnapshot: "Latest snapshot", + steadyOutside: "{{n}} stable items outside scope", + "followLive": "Follow live", + "historySnapshot": "Historical snapshot", + "evaluatedAt": "Evaluated", + "refreshBoard": "Refresh board", + "oldestSample": "Oldest sample", + "liveOverview": "Business migration overview", + "remaining": "Remaining items", + "anomalyInBatch": "Current wave anomalies", + "anomalyOutsideBatch": "Outside wave anomalies", + "coverageUnknown": "Uncertain coverage; acceptance cannot pass", + "coverageUnknownHint": "Resolve missing, stale or misaligned samples and duplicate keys. Healthy samples cover their own monitor items.", + "awaitingPeer": "Awaiting target sample", + "migratedPrevious": "Previous wave received", + "unfinishedPrevious": "Previous wave unfinished", + "sample_time_missing": "Sample time missing", + "sample_skew": "Samples too far apart", + "sample_stale": "Stale samples", + "duplicateKeys": "Duplicate business keys", + "uncoveredScope": "Missing scope sheets", + "refreshFailed": "Refresh failed; showing retained snapshot:", + "lastAcceptance": "Last acceptance", + "diffSearch": "Search business key / verdict / status", + "verdictFilter": "Verdict filter", + "allVerdicts": "All verdicts", + "warningVerdict": "In progress / warning", + "healthyVerdict": "Received / healthy", + "unknownVerdict": "Uncertain", + "loadingBoard": "Updating…", + "rowsMatched": "{{n}} matching items", + "showOutsideAnomalies": "Show outside anomalies", + "scopeCurrent": "Current wave", + "scopePrevious": "Previous wave", + "scopeOutside": "Outside scope", + "fieldChanges": "{{n}} changed fields", + "outsideProtection": "Protect businesses outside this wave", + "outsideProtectionHint": "Report drift outside this wave. Continue checking migrated businesses from previous waves without counting them in current progress.", + "reason_service_not_received": "Source departed; target not healthy", + "reason_target_unhealthy": "Target unhealthy", + "reason_old_service_not_in_baseline": "Business missing from source baseline", + "reason_service_content_changed": "Received business content differs", + "reason_old_service_still_present": "Business still on source", + "reason_target_sample_predates_source": "Target sample predates source departure", + "reason_previous_batch_received": "Previous wave remains healthy", + "reason_previous_batch_not_received": "Previous wave not received", + "reason_unmapped_same_iface": "Drift on unmapped interface", + "reason_out_of_expect:anomaly": "Business drift outside scope", + "reason_out_of_expect:lost": "Business lost outside scope", title: "Cutover monitor", hint: "Separate from business compare: baseline drift, expect set, dual-device verdict. Reuses collect tasks and port mappings.", hintPort: @@ -862,8 +911,8 @@ const en = { acceptFailedShort: "Fail", colMapped: "Mapped new", colDesc: "Description", - colOldPort: "Old port", - colNewPort: "New port", + colOldPort: "Old business key", + colNewPort: "New business key", colOldStatus: "Old admin/phy/prot", colNewStatus: "New admin/phy/prot", colOld: "Old", diff --git a/web/src/i18n/zh.ts b/web/src/i18n/zh.ts index 1406fb1..4697994 100644 --- a/web/src/i18n/zh.ts +++ b/web/src/i18n/zh.ts @@ -695,6 +695,55 @@ const zh = { colChange: "变更", }, bizMigration: { + latestSnapshot: "最新快照", + steadyOutside: "范围外稳定 {{n}} 条", + "followLive": "实时跟随", + "historySnapshot": "历史快照", + "evaluatedAt": "最近判定", + "refreshBoard": "刷新看板", + "oldestSample": "最早采集", + "liveOverview": "业务迁移概览", + "remaining": "待迁移条目", + "anomalyInBatch": "本批异常", + "anomalyOutsideBatch": "范围外异常", + "coverageUnknown": "数据待确认,不能视为验收通过", + "coverageUnknownHint": "采集缺失、过期、不同步或键冲突需要处理;正常样本仅代表对应监控条目。", + "awaitingPeer": "等待新侧采集确认", + "migratedPrevious": "前批已接续", + "unfinishedPrevious": "前批未接续", + "sample_time_missing": "采集时间缺失", + "sample_skew": "两侧采集间隔过大", + "sample_stale": "采集已过期", + "duplicateKeys": "重复业务键", + "uncoveredScope": "范围对应表已失效", + "refreshFailed": "获取失败,当前显示保留快照:", + "lastAcceptance": "上次终验", + "diffSearch": "搜索业务键 / 判定 / 状态", + "verdictFilter": "判定筛选", + "allVerdicts": "全部判定", + "warningVerdict": "迁移中 / 提示", + "healthyVerdict": "已接续 / 正常", + "unknownVerdict": "待确认", + "loadingBoard": "正在更新…", + "rowsMatched": "匹配 {{n}} 条", + "showOutsideAnomalies": "查看范围外异常", + "scopeCurrent": "本批范围", + "scopePrevious": "前批范围", + "scopeOutside": "范围之外", + "fieldChanges": "字段变化 {{n}} 项", + "outsideProtection": "范围外业务持续保护", + "outsideProtectionHint": "本批之外的业务漂移仍报异常;前批已迁移业务持续检查新侧健康,不计入本批进度。", + "reason_service_not_received": "老侧退出,新侧未健康接续", + "reason_target_unhealthy": "新侧业务状态异常", + "reason_old_service_not_in_baseline": "老基线中未找到业务", + "reason_service_content_changed": "接续业务内容不一致", + "reason_old_service_still_present": "老侧业务尚未退出", + "reason_target_sample_predates_source": "新侧样本早于老侧退出", + "reason_previous_batch_received": "前批业务持续健康", + "reason_previous_batch_not_received": "前批业务未正常接续", + "reason_unmapped_same_iface": "未映射端口发生迁移变化", + "reason_out_of_expect:anomaly": "范围外业务漂移", + "reason_out_of_expect:lost": "范围外业务丢失", title: "割接监控", hint: "与业务对比独立:相对基线漂移 + 本批预期 + 老/新双端判定。复用采集任务与端口映射。", hintPort: "当前监控项:端口状态(interface_brief / admin·phy·prot)。选基线 → 勾选本批端口 → 判定看板。", @@ -857,8 +906,8 @@ const zh = { acceptFailedShort: "未过", colMapped: "映射新口", colDesc: "描述", - colOldPort: "老端口", - colNewPort: "新端口", + colOldPort: "老侧业务标识", + colNewPort: "新侧业务标识", colOldStatus: "老状态 admin/phy/prot", colNewStatus: "新状态 admin/phy/prot", colOld: "老侧", diff --git a/web/src/index.css b/web/src/index.css index 614894b..6b3e694 100644 --- a/web/src/index.css +++ b/web/src/index.css @@ -11175,6 +11175,54 @@ html.login-page--paused .login-page__flare { overflow: auto; } +/* Cutover operations console: readable device samples, continuity and scope. */ +.bm-live-header, .bm-live-header > div, .bm-live-filters { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 10px; +} +.bm-live-header { justify-content: space-between; border-bottom: 1px solid rgba(148,163,184,.25); padding-bottom: 10px; } +.bm-live-state { font-size: 11px; padding: 3px 8px; border: 1px solid rgba(148,163,184,.35); border-radius: 3px; } +.bm-live-state.is-live { color: #34d399; border-color: rgba(52,211,153,.45); } +.bm-live-state.is-live::before { content: ""; display: inline-block; width: 6px; height: 6px; background: currentColor; margin-right: 6px; border-radius: 50%; } +.bm-live-sources { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); gap: 10px; } +.bm-live-sources > div { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 12px; padding: 10px 12px; border: 1px solid rgba(148,163,184,.24); border-left: 3px solid #64748b; border-radius: 4px; min-width: 0; } +.bm-live-sources > div:last-child { border-left-color: #38bdf8; } +.bm-live-sources small { flex-basis: 100%; font-variant-numeric: tabular-nums; } +.bm-live-sources strong { overflow-wrap: anywhere; } +.bm-live-kpis { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 10px; } +.bm-live-kpis > div { display: flex; flex-direction: column; gap: 5px; padding: 12px 14px; border: 1px solid rgba(148,163,184,.25); border-radius: 4px; } +.bm-live-kpis span { font-size: 12px; opacity: .8; } +.bm-live-kpis strong { font: 600 26px/1.2 ui-monospace,monospace; font-variant-numeric: tabular-nums; } +.bm-live-kpis strong small { font-size: 13px; opacity: .7; } +.bm-live-kpis .is-ok strong { color: #34d399; } +.bm-live-kpis .is-bad strong { color: #f87171; } +.bm-live-warning { display: flex; flex-wrap: wrap; gap: 6px 14px; padding: 10px 12px; border: 1px solid rgba(251,191,36,.3); border-left: 3px solid #fbbf24; border-radius: 3px; background: rgba(251,191,36,.06); font-size: 12px; overflow-wrap: anywhere; } +.bm-live-warning strong { flex-basis: 100%; } +.bm-live-filters > input { flex: 1 1 240px; min-width: 0; } +.bm-live-filters > .ui-field-select { max-width: 230px; } +.bm-diff-row.is-red > td:first-child { box-shadow: inset 3px 0 #f87171; } +.bm-diff-row.is-yellow > td:first-child { box-shadow: inset 3px 0 #fbbf24; } +.bm-scope-label { display: block; font-size: 10px; opacity: .65; padding-top: 3px; } +.bm-field-changes { font-size: 11px; margin-top: 5px; } +.bm-field-changes summary { cursor: pointer; color: #fbbf24; } +.bm-field-changes div { padding-top: 5px; overflow-wrap: anywhere; } +.bm-field-changes ins { color: #f87171; text-decoration: none; } +.bm-board .bs-cmp-main { min-width: 0; } +@media (max-width: 720px) { + .bm-live-sources { grid-template-columns: 1fr; } + .bm-live-kpis { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 6px; } + .bm-live-header > .muted { flex: 1 1 100%; font-size: 11px; } + .bm-board .bs-cmp-board__toolbar { display: grid; grid-template-columns: minmax(0,1fr); } + .bm-board .bs-id-row { min-width: 0; } + .bm-board .bs-cmp-board__body { display: flex; flex-direction: column; min-width: 0; } + .bm-board .bs-cmp-nav { width: 100%; max-width: none; } + .bm-board .bs-cmp-nav__list { max-height: 180px; } + .bm-live-filters > .ui-field-select { max-width: none; width: 100%; } + .bm-board__table { max-width: 100%; } +} + /* Cutover create wizard */ .bm-create { min-height: min(52vh, 520px); diff --git a/web/src/pages/network/BizMigrationPage.tsx b/web/src/pages/network/BizMigrationPage.tsx index 2ab2cd9..bf06b24 100644 --- a/web/src/pages/network/BizMigrationPage.tsx +++ b/web/src/pages/network/BizMigrationPage.tsx @@ -1,5 +1,5 @@ import { Button, Input, Modal } from "@heroui/react"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { Link } from "react-router-dom"; import { ListPager } from "../../components/ListPager"; import { AppModalShell } from "../../components/ui/AppModalShell"; @@ -237,6 +237,8 @@ type DiffRow = { old_status?: string; new_status?: string; rule_hit?: string; + integrity_changes?: Array<{ field: string; before: unknown; after: unknown }>; + previous_batch?: boolean; evidence?: { old?: { device?: { ne_name?: string; ne_ip?: string }; @@ -285,6 +287,13 @@ type SheetCard = { new_baseline_mode?: string; collect_skipped?: boolean; current_missing?: boolean; + awaiting_peer?: number; + sample_issues?: string[]; + old_collected_at?: string; + new_collected_at?: string; + duplicate_keys_before?: number; + duplicate_keys_after?: number; + age_limit_sec?: number; }; type EvalRun = { id: string; @@ -335,6 +344,9 @@ const VERDICT_I18N: Record = { not_involved: "bizMigration.verdictNotInvolved", unexpected_new: "bizMigration.verdictUnexpected", unfinished: "bizMigration.verdictUnfinished", + awaiting_peer: "bizMigration.awaitingPeer", + migrated_previous: "bizMigration.migratedPrevious", + unfinished_previous: "bizMigration.unfinishedPrevious", ok: "bizMigration.verdictOk", }; @@ -343,13 +355,6 @@ function fmtTime(v?: string | null) { return formatSystemTime(v) || v; } -function taskLabel(x: TaskOpt) { - const base = `${x.ne_name || x.id} (${x.ne_ip || "-"})`; - const note = x.note ? ` · ${x.note}` : ""; - const iv = x.interval_sec ? ` · ${x.interval_sec}s` : ""; - return `${base}${note}${iv}`; -} - export function BizMigrationPage() { const { t } = useI18n(); const { showOk, showError } = useToast(); @@ -416,11 +421,19 @@ export function BizMigrationPage() { const [board, setBoard] = useState<{ run?: { id: string; + created_at?: string; + purpose?: string; summary?: { sheet_cards?: SheetCard[]; progress?: { ok: number; total: number }; anomaly?: number; expect_ports?: string[]; + coverage_complete?: boolean; + anomaly_outside_expect?: number; + steady_outside?: number; + verdict_counts?: Record; + duplicate_keys?: number; + uncovered_scope?: string[]; }; } | null; } | null>(null); @@ -432,6 +445,7 @@ export function BizMigrationPage() { const [expectMetricId, setExpectMetricId] = useState(""); const [selectedExpectKeys, setSelectedExpectKeys] = useState>(new Set()); const [portFilter, setPortFilter] = useState(""); + const [expectPage, setExpectPage] = useState(1); const [redTickets, setRedTickets] = useState([]); const [openRedCount, setOpenRedCount] = useState(0); const [acceptInfo, setAcceptInfo] = useState(null); @@ -439,6 +453,22 @@ export function BizMigrationPage() { const [pinNewBatchId, setPinNewBatchId] = useState(""); const [evalRuns, setEvalRuns] = useState([]); const [selectedRunId, setSelectedRunId] = useState(""); + const [followLatest, setFollowLatest] = useState(true); + const [diffPage, setDiffPage] = useState(1); + const [diffTotal, setDiffTotal] = useState(0); + const [boardColor, setBoardColor] = useState(""); + const [boardKeyword, setBoardKeyword] = useState(""); + const boardSearch = useDebouncedValue(boardKeyword, 300); + const [boardLoading, setBoardLoading] = useState(false); + const [boardError, setBoardError] = useState(""); + const [boardClock, setBoardClock] = useState(Date.now()); + const boardRequest = useRef(0); + const runsRequest = useRef(0); + const activeBatchRef = useRef(batchId); + activeBatchRef.current = batchId; + const activeProjectRef = useRef(projectId); + activeProjectRef.current = projectId; + const historyRunId = followLatest ? "" : selectedRunId; const project = useMemo( () => projects.find((p) => p.id === projectId) || null, @@ -446,29 +476,14 @@ export function BizMigrationPage() { ); const batch = useMemo(() => batches.find((b) => b.id === batchId) || null, [batches, batchId]); const sheetCards = board?.run?.summary?.sheet_cards || []; - const visibleDiffs = useMemo(() => { - let rows = diffs; - if (boardMetricId) { - rows = rows.filter( - (d) => sheetIdentity(d) === boardMetricId || d.metric_id === boardMetricId, - ); - } - if (onlyExpect) rows = rows.filter((d) => d.in_expect); - return rows; - }, [diffs, onlyExpect, boardMetricId]); - - const boardMetricOptions = useMemo(() => { - const ids = new Set(); - for (const c of sheetCards) { - const id = sheetIdentity(c); - if (id) ids.add(id); - } - for (const d of diffs) { - const id = sheetIdentity(d); - if (id) ids.add(id); - } - return [...ids]; - }, [sheetCards, diffs]); + const visibleDiffs = diffs; + const liveSummary = board?.run?.summary; + const liveProgress = liveSummary?.progress; + const monitorIsLive = followLatest && batch?.status === "active" && project?.status !== "done"; + const samplesStale = monitorIsLive && sheetCards.some((c) => + [c.old_collected_at, c.new_collected_at].some((at) => at && + boardClock - Date.parse(at) > (c.age_limit_sec || 180) * 1000)); + const coverageUnknown = Boolean(board?.run && (liveSummary?.coverage_complete !== true || samplesStale)); const filteredProjects = useMemo(() => { const kw = debouncedListKw.trim().toLowerCase(); @@ -519,6 +534,9 @@ export function BizMigrationPage() { return blob.includes(kw); }); }, [expectSheets, expectMetricId, portFilter]); + const expectPages = Math.max(1, Math.ceil(filteredExpectItems.length / 100)); + const safeExpectPage = Math.min(expectPage, expectPages); + const visibleExpectItems = filteredExpectItems.slice((safeExpectPage - 1) * 100, safeExpectPage * 100); const reloadProjects = useCallback(async () => { const res = await cutoverCachedGet("bizMigration:projects", () => bizMigrationListProjects(), { @@ -603,16 +621,20 @@ export function BizMigrationPage() { } try { const res = await bizMigrationListBaselineExpect(pid); + if (pid !== activeProjectRef.current) return; const sheets = (res.sheets || []) as ExpectSheet[]; setExpectSheets(sheets); setExpectMetricId((prev) => { if (prev && sheets.some((s) => sheetIdentity(s) === prev)) return prev; return sheets[0] ? sheetIdentity(sheets[0]) : ""; }); - } catch { - setExpectSheets([]); + } catch (e) { + if (pid === activeProjectRef.current) { + setExpectSheets([]); + showError(formatErr(e)); + } } - }, []); + }, [showError]); const loadRedTickets = useCallback(async (pid: string) => { if (!pid) { @@ -622,13 +644,13 @@ export function BizMigrationPage() { } try { const res = await bizMigrationListRedTickets(pid); + if (pid !== activeProjectRef.current) return; setRedTickets((res.items || []) as RedTicket[]); setOpenRedCount(Number(res.open_count || 0)); - } catch { - setRedTickets([]); - setOpenRedCount(0); + } catch (e) { + if (pid === activeProjectRef.current) showError(formatErr(e)); } - }, []); + }, [showError]); useEffect(() => { void (async () => { @@ -690,6 +712,12 @@ export function BizMigrationPage() { }, [showError]); useEffect(() => { + let cancelled = false; + setBatchId(""); + setBatches([]); + setAcceptInfo(null); + setRedTickets([]); + setOpenRedCount(0); if (!projectId) { setBatches([]); setBatchId(""); @@ -706,18 +734,29 @@ export function BizMigrationPage() { void (async () => { try { const res = await bizMigrationListBatches(projectId); + if (cancelled || projectId !== activeProjectRef.current) return; const items = (res.items || []) as MigBatch[]; setBatches(items); - setBatchId((prev) => (items.find((b) => b.id === prev) ? prev : items[0]?.id || "")); + setBatchId(items.find((b) => b.status === "active")?.id || items[0]?.id || ""); await loadBaselineExpect(projectId); await loadRedTickets(projectId); } catch (e) { - showError(formatErr(e)); + if (!cancelled) showError(formatErr(e)); } })(); + return () => { cancelled = true; }; }, [projectId, showError, loadBaselineExpect, loadRedTickets]); useEffect(() => { + setBoard(null); + setDiffs([]); + setDiffTotal(0); + setDiffPage(1); + setBoardMetricId(""); + setFollowLatest(true); + setBoardError(""); + boardRequest.current += 1; + runsRequest.current += 1; if (!batchId) { setBoard(null); setDiffs([]); @@ -726,10 +765,33 @@ export function BizMigrationPage() { return; } void loadRuns(batchId); - void loadBoard(batchId); // eslint-disable-next-line react-hooks/exhaustive-deps }, [batchId]); + useEffect(() => { + if (!batchId || detailTab !== "board") return; + let cancelled = false; + let timer: ReturnType | undefined; + const refresh = async () => { + if (document.visibilityState === "visible") { + await loadBoard(batchId, historyRunId); + if (!cancelled && followLatest) await loadRuns(batchId); + } + if (!cancelled && monitorIsLive) { + timer = setTimeout(() => void refresh(), 10000); + } + }; + void refresh(); + return () => { + cancelled = true; + if (timer) clearTimeout(timer); + boardRequest.current += 1; + runsRequest.current += 1; + }; + // Requests are serial within each refresh cycle; filters start a new cycle. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [batchId, detailTab, monitorIsLive, historyRunId, followLatest, boardMetricId, onlyExpect, boardColor, boardSearch, diffPage]); + useEffect(() => { if (!createOpen) return; let cancelled = false; @@ -757,84 +819,101 @@ export function BizMigrationPage() { }, [createOpen, createNeSource, debouncedCreateNeKw, createNePage, createNePageSize, showError]); useEffect(() => { + let cancelled = false; if (!createOldNe) { setCreateOldBatches([]); setCreateOldHasPortrait(false); setCreateOldBaselineId(""); return; } + setCreateOldBaselineId(""); + setCreateOldBatches([]); void bizMigrationNePortrait({ source: neSourceOf(createOldNe), ne_id: createOldNe.id, limit: 30, }).then((r) => { + if (cancelled) return; setCreateOldHasPortrait(Boolean(r.task?.id)); setCreateOldBatches( - (r.batches || []).map((x) => ({ + (r.batches || []).filter((x) => ["success", "partial"].includes(String(x.status || ""))).map((x) => ({ id: String(x.id || ""), started_at: x.started_at || null, alias: String(x.alias || ""), })), ); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [createOldNe]); useEffect(() => { + let cancelled = false; if (!createNewNe) { setCreateNewBatches([]); setCreateNewHasPortrait(false); setCreateNewBaselineId(""); return; } + setCreateNewBaselineId(""); + setCreateNewBatches([]); void bizMigrationNePortrait({ source: neSourceOf(createNewNe), ne_id: createNewNe.id, limit: 30, }).then((r) => { + if (cancelled) return; setCreateNewHasPortrait(Boolean(r.task?.id)); setCreateNewBatches( - (r.batches || []).map((x) => ({ + (r.batches || []).filter((x) => ["success", "partial"].includes(String(x.status || ""))).map((x) => ({ id: String(x.id || ""), started_at: x.started_at || null, alias: String(x.alias || ""), })), ); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [createNewNe]); useEffect(() => { + let cancelled = false; if (!project?.old_task_id) { setOldBatches([]); return; } void bizStateListBatches(project.old_task_id, 30).then((r) => { + if (cancelled) return; setOldBatches( - ((r.items || []) as Record[]).map((x) => ({ + ((r.items || []) as Record[]).filter((x) => ["success", "partial"].includes(String(x.status || ""))).map((x) => ({ id: String(x.id || ""), started_at: (x.started_at as string) || null, alias: String(x.alias || ""), })), ); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [project?.old_task_id]); useEffect(() => { + let cancelled = false; if (!project?.new_task_id) { setNewBatches([]); return; } void bizStateListBatches(project.new_task_id, 30).then((r) => { + if (cancelled) return; setNewBatches( - ((r.items || []) as Record[]).map((x) => ({ + ((r.items || []) as Record[]).filter((x) => ["success", "partial"].includes(String(x.status || ""))).map((x) => ({ id: String(x.id || ""), started_at: (x.started_at as string) || null, alias: String(x.alias || ""), })), ); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [project?.new_task_id]); useEffect(() => { + let cancelled = false; const ids = [ ...(project?.old_hf_bindings || []).map((b) => b.task_id), project?.old_hf_task_id || "", @@ -845,6 +924,7 @@ export function BizMigrationPage() { return; } void Promise.all(uniq.map((tid) => bizStateListBatches(tid, 30))).then((results) => { + if (cancelled) return; const seen = new Set(); const items: { id: string; started_at?: string | null; alias?: string }[] = []; for (const r of results) { @@ -860,10 +940,12 @@ export function BizMigrationPage() { } } setHfOldBatches(items); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [project?.old_hf_task_id, project?.old_hf_bindings]); useEffect(() => { + let cancelled = false; const ids = [ ...(project?.new_hf_bindings || []).map((b) => b.task_id), project?.new_hf_task_id || "", @@ -874,6 +956,7 @@ export function BizMigrationPage() { return; } void Promise.all(uniq.map((tid) => bizStateListBatches(tid, 30))).then((results) => { + if (cancelled) return; const seen = new Set(); const items: { id: string; started_at?: string | null; alias?: string }[] = []; for (const r of results) { @@ -889,7 +972,8 @@ export function BizMigrationPage() { } } setHfNewBatches(items); - }); + }).catch((e) => { if (!cancelled) showError(formatErr(e)); }); + return () => { cancelled = true; }; }, [project?.new_hf_task_id, project?.new_hf_bindings]); useEffect(() => { @@ -926,8 +1010,10 @@ export function BizMigrationPage() { ]); async function loadRuns(bid: string) { + const request = ++runsRequest.current; try { const res = await bizMigrationListRuns(bid, 20); + if (request !== runsRequest.current || bid !== activeBatchRef.current) return; const items = (res.items || []) as EvalRun[]; setEvalRuns(items); setSelectedRunId((prev) => { @@ -935,24 +1021,39 @@ export function BizMigrationPage() { return items[0]?.id || ""; }); } catch { - setEvalRuns([]); + if (request === runsRequest.current && bid === activeBatchRef.current) setEvalRuns([]); } } async function loadBoard(bid: string, runId = "") { + const request = ++boardRequest.current; + setBoardLoading(true); try { const b = await bizMigrationGetBoard(bid, runId); - setBoard(b as typeof board); + if (request !== boardRequest.current || bid !== activeBatchRef.current) return; const rid = String((b as { run?: { id?: string } })?.run?.id || runId || ""); - if (rid) setSelectedRunId(rid); + let rows: DiffRow[] = []; + let total = 0; if (rid) { - const d = await bizMigrationListDiffs({ runId: rid, limit: 500 }); - setDiffs((d.items || []) as DiffRow[]); - } else { - setDiffs([]); + const d = await bizMigrationListDiffs({ runId: rid, sheetId: boardMetricId, + onlyExpect, color: boardColor, kw: boardSearch, offset: (diffPage - 1) * 100, limit: 100 }); + rows = (d.items || []) as DiffRow[]; + total = Number(d.total || 0); } + if (request !== boardRequest.current || bid !== activeBatchRef.current) return; + setBoard(b as typeof board); + setBoardClock(Date.now()); + if (rid) setSelectedRunId(rid); + setDiffs(rows); + setDiffTotal(total); + setBoardError(""); + if (diffPage > Math.max(1, Math.ceil(total / 100))) setDiffPage(Math.max(1, Math.ceil(total / 100))); } catch (e) { - showError(formatErr(e)); + if (request === boardRequest.current && bid === activeBatchRef.current) { + setBoardError(formatErr(e)); + } + } finally { + if (request === boardRequest.current) setBoardLoading(false); } } @@ -1189,17 +1290,19 @@ export function BizMigrationPage() { async function onCreateBatch() { if (!projectId) return; // One item per selected key. A flat `keys: [a, b]` is parsed as one composite key. - const items: Array<{ metric_id: string; sheet_id?: string; key: string }> = []; + const items: Array<{ metric_id: string; sheet_id?: string; key: string[] }> = []; const ports: string[] = []; for (const sheet of expectSheets) { - const keys = sheet.items.map((it) => it.key).filter((k) => selectedExpectKeys.has(k)); const sid = sheetIdentity(sheet); - for (const key of keys) { - items.push({ metric_id: sheet.metric_id, sheet_id: sid, key }); + for (const item of sheet.items) { + if (selectedExpectKeys.has(JSON.stringify([sid, item.key]))) { + items.push({ metric_id: sheet.metric_id, sheet_id: sid, key: item.keys }); + if (sheet.metric_id === "interface_brief" && sheet.key_fields.length === 1 && + sheet.iface_fields.includes(sheet.key_fields[0])) ports.push(item.keys[0]); + } } - if (sheet.metric_id === "interface_brief") ports.push(...keys); } - if (!items.length && !ports.length) { + if (!items.length) { showError(t("bizMigration.needExpectPorts")); return; } @@ -1405,7 +1508,8 @@ export function BizMigrationPage() { } } - function toggleExpectKey(key: string) { + function toggleExpectKey(rawKey: string) { + const key = JSON.stringify([expectMetricId || sheetIdentity(expectSheets[0]), rawKey]); setSelectedExpectKeys((prev) => { const next = new Set(prev); if (next.has(key)) next.delete(key); @@ -2421,7 +2525,6 @@ export function BizMigrationPage() { setBatchLabel(e.target.value)} - size="sm" placeholder={t("bizMigration.defaultBatchLabel")} aria-label={t("bizMigration.batchLabel")} style={{ minWidth: 100 }} @@ -2492,7 +2595,7 @@ export function BizMigrationPage() { role="tab" aria-selected={active} className={`ct-editor__nav-item${active ? " is-active" : ""}`} - onClick={() => setExpectMetricId(sid)} + onClick={() => { setExpectMetricId(sid); setExpectPage(1); }} > {sheetLabel(s)} {s.items.length} @@ -2504,9 +2607,8 @@ export function BizMigrationPage() {
    setPortFilter(e.target.value)} + onChange={(e) => { setPortFilter(e.target.value); setExpectPage(1); }} placeholder={t("bizMigration.portFilterPh")} />
    @@ -2521,7 +2623,7 @@ export function BizMigrationPage() { - {filteredExpectItems.map((it) => { + {visibleExpectItems.map((it) => { const row = it.row || {}; const statusBits = ["admin", "phy", "prot"] .map((k) => (row[k] != null ? String(row[k]) : "")) @@ -2539,12 +2641,14 @@ export function BizMigrationPage() { sheetIdentity(s) === expectMetricId) || expectSheets[0])} ${it.label || it.key}`} + checked={selectedExpectKeys.has(JSON.stringify([expectMetricId || sheetIdentity(expectSheets[0]), it.key]))} + onClick={(e) => e.stopPropagation()} onChange={() => toggleExpectKey(it.key)} /> - {it.key} + {it.label || it.key} {it.mapped_to || "—"} {desc || "—"} @@ -2561,6 +2665,8 @@ export function BizMigrationPage() {
    + @@ -2568,8 +2674,48 @@ export function BizMigrationPage() { {detailTab === "board" ? (
    +
    +
    + + {followLatest ? t(monitorIsLive ? "bizMigration.followLive" : "bizMigration.latestSnapshot") : t("bizMigration.historySnapshot")} + + {batch?.batch_label || "—"} +
    + {t("bizMigration.evaluatedAt")} {fmtTime(board?.run?.created_at)} + +
    +
    + {(["old", "new"] as const).map((side) => { + const device = side === "old" ? project?.old_task : project?.new_task; + const times = sheetCards.map((c) => side === "old" ? c.old_collected_at : c.new_collected_at) + .filter((v): v is string => Boolean(v)).sort(); + return
    + {t(side === "old" ? "bizMigration.pickOldNe" : "bizMigration.pickNewNe")} + {device?.ne_name || "—"}{device?.ne_ip || "—"} + {t("bizMigration.oldestSample")} {fmtTime(times[0])} +
    ; + })} +
    +
    +
    {t("bizMigration.progress")}{liveProgress?.ok ?? 0} / {liveProgress?.total ?? 0}
    +
    {t("bizMigration.remaining")}{Math.max(0, (liveProgress?.total ?? 0) - (liveProgress?.ok ?? 0))}
    +
    {t("bizMigration.anomalyInBatch")}{Math.max(0, (liveSummary?.anomaly ?? 0) - (liveSummary?.anomaly_outside_expect ?? 0))}
    +
    {t("bizMigration.anomalyOutsideBatch")}{liveSummary?.anomaly_outside_expect ?? 0}
    +
    + {coverageUnknown ?
    + {t("bizMigration.coverageUnknown")}{t("bizMigration.coverageUnknownHint")} + {samplesStale ? {t("bizMigration.sample_stale")} : null} + {sheetCards.filter((c) => c.sample_issues?.length || c.awaiting_peer).map((c) => + {sheetLabel(c)}: {c.awaiting_peer ? t("bizMigration.awaitingPeer") : + c.sample_issues?.map((issue) => t(`bizMigration.${issue}`)).join(" · ")})} + {liveSummary?.duplicate_keys ? {t("bizMigration.duplicateKeys")} {liveSummary.duplicate_keys} : null} + {liveSummary?.uncovered_scope?.length ? {t("bizMigration.uncoveredScope")}: {liveSummary.uncovered_scope.join(", ")} : null} +
    : null} + {boardError ?
    {t("bizMigration.refreshFailed")} {boardError}
    : null} {acceptInfo ? (
    + {t("bizMigration.lastAcceptance")} @@ -2624,17 +2770,16 @@ export function BizMigrationPage() { {batchOptions(hfNewBatches)} { const rid = e.target.value; + setFollowLatest(!rid); + setDiffPage(1); setSelectedRunId(rid); - if (batchId && rid) void loadBoard(batchId, rid); }} aria-label={t("bizMigration.runHistory")} > - {!evalRuns.length ? ( - - ) : null} + {evalRuns.map((r) => (
    - +
    + { setBoardKeyword(e.target.value); setDiffPage(1); }} + placeholder={t("bizMigration.diffSearch")} aria-label={t("bizMigration.diffSearch")} /> + { setBoardColor(e.target.value); setDiffPage(1); }}> + + + + + + + {boardLoading ? t("bizMigration.loadingBoard") : t("bizMigration.rowsMatched", { n: String(diffTotal) })} + {liveSummary?.steady_outside ? {t("bizMigration.steadyOutside", { n: String(liveSummary.steady_outside) })} : null} + {onlyExpect && (liveSummary?.anomaly_outside_expect ?? 0) > 0 ? + : null} +
    {sheetCards.some((c) => c.new_baseline_missing) ? (
    {t("bizMigration.newBaselineMissingBanner", { @@ -2705,7 +2867,7 @@ export function BizMigrationPage() { onClick={() => setBoardSubTab("diffs")} > {t("bizMigration.board")} - {visibleDiffs.length} + {diffTotal}
    )} + {boardSubTab === "diffs" && board?.run ? : null} ) : null} diff --git a/web/src/pages/network/BizMonitorTemplatesPage.tsx b/web/src/pages/network/BizMonitorTemplatesPage.tsx index 3308205..ca40de9 100644 --- a/web/src/pages/network/BizMonitorTemplatesPage.tsx +++ b/web/src/pages/network/BizMonitorTemplatesPage.tsx @@ -233,7 +233,7 @@ function normalizeGroups( .map((g) => (g || []) .filter(Boolean) - .map((c) => migrateLegacyCond(c as unknown as Record)), + .map((c) => typeof c === "string" ? tokenToCond(c) : migrateLegacyCond(c as unknown as Record)), ) .filter((g) => g.length > 0); } @@ -251,9 +251,10 @@ function normalizePat(pat: DualPat, opts?: { allowEmptySide?: boolean }): DualPa const old_groups = normalizeGroups(pat.old_groups, pat.old_conds, pat.old_mode, pat.old); const new_groups = normalizeGroups(pat.new_groups, pat.new_conds, pat.new_mode, pat.new); if (allowEmpty) { - return { old_groups, new_groups }; + return { ...pat, old_groups, new_groups }; } return { + ...pat, old_groups: old_groups.length ? old_groups : [emptyGroup("presence")], new_groups: new_groups.length ? new_groups : [emptyGroup("presence")], }; @@ -819,7 +820,7 @@ export function BizMonitorTemplatesPage() { const [name, setName] = useState(""); const [compareId, setCompareId] = useState(""); const [note, setNote] = useState(""); - const [outOfExpect, setOutOfExpect] = useState("strict"); + const [defaultsDraft, setDefaultsDraft] = useState>({}); const [collectIds, setCollectIds] = useState([]); const [overrides, setOverrides] = useState([]); const [activeSheetIdx, setActiveSheetIdx] = useState(0); @@ -908,8 +909,6 @@ export function BizMonitorTemplatesPage() { return schema?.fields || []; }, [metricSchemas, activeMetricId]); - const sheetKey = useMemo(() => sheets.map((s) => sheetIdentity(s)).join("|"), [sheets]); - useEffect(() => { if (!sheets.length) { setActiveSheetIdx(0); @@ -918,18 +917,6 @@ export function BizMonitorTemplatesPage() { if (activeSheetIdx >= sheets.length) setActiveSheetIdx(0); }, [sheets, activeSheetIdx]); - useEffect(() => { - if (!sheetKey) return; - setOverrides((prev) => { - const byId = new Map(prev.map((o) => [o.sheet_id || o.metric_id, o])); - return sheets.map( - (s) => - byId.get(sheetIdentity(s)) || - emptyOverride(s.metric_id, sheetIdentity(s)), - ); - }); - }, [compareId, sheetKey]); - const syncOverride = (metricId: string, patch: Partial, sheetId = "") => { const sid = sheetId || sheetIdentity({ metric_id: metricId, sheet_id: sheetId }); setOverrides((prev) => { @@ -944,7 +931,7 @@ export function BizMonitorTemplatesPage() { setName(""); setCompareId(compareTpls[0]?.id || ""); setNote(""); - setOutOfExpect("strict"); + setDefaultsDraft({}); setCollectIds([]); setOverrides([]); setActiveSheetIdx(0); @@ -960,7 +947,7 @@ export function BizMonitorTemplatesPage() { setName(row.name || ""); setCompareId(row.compare_template_id || ""); setNote(row.note || ""); - setOutOfExpect(String((row.defaults || {}).out_of_expect || "strict")); + setDefaultsDraft({ ...(row.defaults || {}) }); setCollectIds(Array.isArray(row.collect_metric_ids) ? [...row.collect_metric_ids] : []); setOverrides(Array.isArray(row.sheet_overrides) ? (row.sheet_overrides as SheetOverride[]) : []); setActiveSheetIdx(0); @@ -993,7 +980,7 @@ export function BizMonitorTemplatesPage() { showError(t("bizMonitorTpl.needName")); return; } - let sheet_overrides = overrides + let sheet_overrides: SheetOverride[] = overrides .filter((o) => o.metric_id) .map((o) => ({ ...o, @@ -1004,11 +991,8 @@ export function BizMonitorTemplatesPage() { try { const parsed = JSON.parse(overridesText || "[]") as unknown[]; if (!Array.isArray(parsed)) throw new Error("overrides"); - sheet_overrides = (parsed as SheetOverride[]).map((o) => ({ - ...o, - success: (o.success || []).map((p) => normalizePat(p)), - anomaly: (o.anomaly || []).map((p) => normalizePat(p, { allowEmptySide: true })), - })); + // Advanced JSON is authoritative; the API validates its complete shape. + sheet_overrides = parsed as SheetOverride[]; } catch { showError(t("bizMonitorTpl.overridesInvalid")); return; @@ -1018,7 +1002,7 @@ export function BizMonitorTemplatesPage() { name: name.trim(), compare_template_id: compareId, collect_metric_ids: collectIds, - defaults: { dual_mode: "migrate_pair", out_of_expect: outOfExpect || "strict" }, + defaults: { ...defaultsDraft, dual_mode: "migrate_pair", out_of_expect: "strict" }, sheet_overrides, note: note.trim(), }; @@ -1251,16 +1235,7 @@ export function BizMonitorTemplatesPage() { ))} - setOutOfExpect(e.target.value)} - fullWidth - > - - - - +
    {t("bizMigration.outsideProtection")}{t("bizMigration.outsideProtectionHint")}
    {!sheets.length ? ( diff --git a/web/src/services/api.ts b/web/src/services/api.ts index a8f8561..9b3d08e 100644 --- a/web/src/services/api.ts +++ b/web/src/services/api.ts @@ -2380,6 +2380,8 @@ export const bizMigrationGetBoard = (batchId: string, runId = "") => { export const bizMigrationListDiffs = (params: { runId: string; metricId?: string; + sheetId?: string; + onlyExpect?: boolean; verdict?: string; color?: string; kw?: string; @@ -2388,6 +2390,8 @@ export const bizMigrationListDiffs = (params: { }) => { const p = new URLSearchParams(); if (params.metricId) p.set("metric_id", params.metricId); + if (params.sheetId) p.set("sheet_id", params.sheetId); + if (params.onlyExpect) p.set("only_expect", "true"); if (params.verdict) p.set("verdict", params.verdict); if (params.color) p.set("color", params.color); if (params.kw) p.set("kw", params.kw); diff --git a/web/tests/bizMigration.browser.mjs b/web/tests/bizMigration.browser.mjs new file mode 100644 index 0000000..08054af --- /dev/null +++ b/web/tests/bizMigration.browser.mjs @@ -0,0 +1,159 @@ +// Local Vite + fixture APIs only. No device connection or production database. +import assert from "node:assert/strict"; +import { createRequire } from "node:module"; +import { mkdir } from "node:fs/promises"; +import path from "node:path"; +const require = createRequire(import.meta.url); +const { chromium } = require(process.env.NETX_PLAYWRIGHT_MODULE || "playwright"); +const base = process.env.NETX_TEST_URL || "http://127.0.0.1:5179"; +const output = path.resolve(process.env.NETX_TEST_OUTPUT || "../docs/reviews/assets"); +await mkdir(output, { recursive: true }); +const browser = await chromium.launch({ headless: true, channel: process.env.NETX_TEST_BROWSER || "chrome" }); +const page = await browser.newPage({ viewport: { width: 1440, height: 1080 } }); +const errors = [], passed = [], requests = [], writes = []; +page.on("pageerror", (e) => errors.push(e.message)); +let liveRunId = "live-1", uncertain = false, failBoard = false, delayedSheet = ""; +const now = new Date().toISOString(); +const project = { id: "p", name: "核心 PE 替换", old_task_id: "op", new_task_id: "np", old_hf_task_id: "oh", new_hf_task_id: "nh", old_baseline_batch_id: "ob", new_baseline_batch_id: "nb", monitor_template_id: "mt", hf_interval_sec: 60, status: "active", created_at: now, + old_task: { id: "op", ne_name: "PE-OLD", ne_ip: "10.0.0.1" }, new_task: { id: "np", ne_name: "PE-NEW", ne_ip: "10.0.0.2" } }; +const second = { ...project, id: "p2", name: "第二割接项目" }; +const wave = { id: "wave", batch_label: "第一批 · 客户专线", status: "active", accept_status: "none" }; +const sheets = ["s1", "s2"].map((sid, i) => ({ sheet_id: sid, metric_id: "arp", title: `ARP · ${i ? "专线" : "公网"}`, key_fields: ["ip"], compare_fields: ["mac"], iface_fields: [] })); +const monitor = { id: "mt", name: "业务连续性", compare_template_id: "ct", compare_template_name: "业务模板", collect_metric_ids: ["arp"], collect_metric_ids_effective: ["arp"], defaults: { custom_setting: false, threshold: 7, out_of_expect: "ignore" }, sheet_overrides: [{ metric_id: "arp", success: [{ old_groups: [["removed"]], new_groups: [["added"]], name: "客户迁移规则" }], anomaly: [] }] }; +const dataset = Array.from({ length: 601 }, (_, i) => ({ id: `row-${i}`, metric_id: "arp", sheet_id: i % 2 ? "s2" : "s1", verdict: i === 600 ? "anomaly" : "migrated", color: i === 600 ? "red" : "green", in_expect: i !== 600, old_key: `10.1.${Math.floor(i / 255)}.${i % 255}`, new_key: `10.1.${Math.floor(i / 255)}.${i % 255}`, old_status: "gone", new_status: "up", rule_hit: i === 600 ? "service_content_changed" : "success#1", integrity_changes: i === 600 ? [{ field: "mac", before: "aa:bb", after: "cc:dd" }] : [] })); +function run(rid, pid = "p") { + return { id: rid, purpose: rid === "hist" ? "manual" : "auto", created_at: now, + summary: { progress: { ok: pid === "p2" ? 3 : 99, total: pid === "p2" ? 3 : 101 }, anomaly: 1, anomaly_outside_expect: 1, coverage_complete: !uncertain, duplicate_keys: uncertain ? 2 : 0, + sheet_cards: sheets.map((s) => ({ ...s, progress_ok: 49, progress_total: 50, anomaly: 0, old_collected_at: now, new_collected_at: now, age_limit_sec: 180, sample_issues: uncertain ? ["sample_skew"] : [] })) } }; +} +await page.route("**/v1/**", async (route) => { + const req = route.request(), url = new URL(req.url()), p = url.pathname; + requests.push({ p, query: Object.fromEntries(url.searchParams), method: req.method() }); + let data = { items: [] }; + if (p === "/v1/auth/me") data = { user: { id: "fixture", username: "fixture", role: "admin", is_active: true } }; + else if (req.method() === "PATCH" && p.endsWith("/monitor-templates/mt")) { data = { ...monitor, ...req.postDataJSON() }; writes.push(req.postDataJSON()); } + else if (req.method() === "POST" && p.endsWith("/p/batches")) { writes.push(req.postDataJSON()); data = { ...wave, id: "created-wave", ...req.postDataJSON() }; } + else if (p.endsWith("/biz-migration/projects")) data = { items: [project, second] }; + else if (p.endsWith("/monitor-templates")) data = { items: [monitor] }; + else if (p.endsWith("/compare/templates")) data = { items: [{ id: "ct", name: "业务模板", metrics: sheets }] }; + else if (p.endsWith("/compare/metrics")) data = { items: [{ metric_id: "arp", fields: [{ name: "ip" }, { name: "mac" }] }] }; + else if (p.endsWith("/baseline-expect")) data = { sheets: sheets.map((sheet) => ({ ...sheet, items: Array.from({ length: 201 }, (_, i) => ({ key: `biz-${i}`, keys: [`biz-${i}`], label: `业务 ${i}`, row: { ip: `biz-${i}` } })) })) }; + else if (p.endsWith("/red-tickets")) data = { items: [], open_count: 0 }; + else if (p.includes("/biz-migration/projects/") && p.endsWith("/batches")) data = { items: [{ ...wave, id: p.includes("/p2/") ? "wave2" : "wave" }] }; + else if (p.endsWith("/board")) { + if (failBoard) { await route.fulfill({ status: 500, contentType: "application/json", body: JSON.stringify({ detail: "fixture_refresh_error" }) }); return; } + data = { project, batch: wave, run: run(url.searchParams.get("run_id") || liveRunId, p.includes("wave2") ? "p2" : "p") }; + } else if (p.endsWith("/runs")) data = { items: [run(liveRunId), run("hist")] }; + else if (p.endsWith("/diffs")) { + let rows = dataset; + if (url.searchParams.get("sheet_id")) rows = rows.filter((r) => r.sheet_id === url.searchParams.get("sheet_id")); + if (url.searchParams.get("only_expect")) rows = rows.filter((r) => r.in_expect); + if (url.searchParams.get("color")) rows = rows.filter((r) => r.color === url.searchParams.get("color")); + if (url.searchParams.get("kw")) rows = rows.filter((r) => r.old_key.includes(url.searchParams.get("kw"))); + const offset = Number(url.searchParams.get("offset") || 0), limit = Number(url.searchParams.get("limit") || 100); + data = { items: rows.slice(offset, offset + limit), total: rows.length }; + if (delayedSheet && url.searchParams.get("sheet_id") === delayedSheet) await new Promise((resolve) => setTimeout(resolve, 900)); + } else if (p.endsWith("/batches")) data = { items: [{ id: "ok", status: "success", started_at: now }, { id: "bad", status: "failed" }, { id: "running", status: "running" }] }; + await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify(data) }); +}); +const dialog = () => page.getByRole("dialog"); +const table = () => dialog().locator(".bm-board__table table"); +const waitRows = (n) => page.waitForFunction((count) => document.querySelectorAll(".bm-board__table tbody tr").length === count, n); +try { + await page.goto(`${base}/network/cutover/biz-migration`); + const projectRow = page.locator(".pt-list table tbody tr").filter({ has: page.getByText(project.name, { exact: true }) }); + await projectRow.getByRole("button", { name: "进度看板", exact: true }).click(); + await waitRows(100); + await dialog().getByText("范围外异常", { exact: true }).waitFor(); + assert.equal(await dialog().locator(".bm-live-kpis .is-bad").last().locator("strong").textContent(), "1"); + assert.equal(requests.filter((r) => r.p.endsWith("/diffs")).at(-1).query.limit, "100"); + passed.push("live continuity KPIs", "outside anomaly visible before acceptance", "100 row page bound"); + await dialog().getByRole("button", { name: "下一页", exact: true }).click(); + await page.waitForFunction(() => document.querySelector('.bm-board__table tbody tr code')?.textContent === '10.1.0.100'); + passed.push("server pagination beyond first page"); + await dialog().getByRole("checkbox", { name: "仅预期", exact: true }).check(); + await dialog().getByRole("button", { name: "查看范围外异常", exact: true }).click(); + await waitRows(1); + await dialog().getByText("接续业务内容不一致", { exact: true }).waitFor(); + assert.ok(requests.filter((r) => r.p.endsWith("/diffs")).at(-1).query.color === "red"); + await dialog().getByText("字段变化 1 项", { exact: true }).click(); + await dialog().getByText("aa:bb", { exact: true }).waitFor(); + passed.push("late outside anomaly found with server filter", "scope switch resets pagination", "field integrity evidence readable"); + await page.screenshot({ path: path.join(output, "cutover-monitor-board.png"), fullPage: true }); + await dialog().getByRole("combobox", { name: "判定筛选", exact: true }).selectOption(""); + await waitRows(100); + // Slow response for one sheet must not overwrite the next sheet selection. + delayedSheet = "s1"; + const delayedRequest = page.waitForRequest((r) => r.url().includes("sheet_id=s1")); + await dialog().locator(".bs-cmp-nav").getByRole("tab", { name: /ARP · 公网/ }).click(); + await delayedRequest; + await dialog().locator(".bs-cmp-nav").getByRole("tab", { name: /ARP · 专线/ }).click(); + await page.waitForTimeout(1300); + assert.ok((await table().locator("tbody tr td:first-child").allTextContents()).every((v) => v.includes("专线"))); + passed.push("slow sheet response cannot overwrite current sheet"); + delayedSheet = ""; + await dialog().locator(".bs-cmp-nav").getByRole("tab", { name: "全部监控项", exact: true }).click(); + uncertain = true; + await dialog().getByRole("button", { name: "刷新看板", exact: true }).click(); + await dialog().getByText("数据待确认,不能视为验收通过", { exact: true }).waitFor(); + await dialog().getByText(/两侧采集间隔过大/).first().waitFor(); + passed.push("uncertain sampling visibly blocks healthy appearance", "duplicate key warning"); + uncertain = false; + await dialog().getByRole("combobox", { name: "判定历史", exact: true }).selectOption("hist"); + await dialog().getByText("历史快照", { exact: true }).waitFor(); + const historyBoardRequests = requests.filter((r) => r.p.endsWith("/board")).length; + await page.waitForTimeout(10500); + assert.equal(requests.filter((r) => r.p.endsWith("/board")).length, historyBoardRequests); + passed.push("historical view remains frozen"); + liveRunId = "live-2"; + await dialog().getByRole("combobox", { name: "判定历史", exact: true }).selectOption(""); + await waitRows(100); + const liveCount = requests.filter((r) => r.p.endsWith("/board")).length; + await page.waitForTimeout(10500); + assert.ok(requests.filter((r) => r.p.endsWith("/board")).length > liveCount); + passed.push("active live board automatically refreshes", "refresh cycles do not overlap"); + failBoard = true; + await dialog().getByRole("button", { name: "刷新看板", exact: true }).click(); + await dialog().getByRole("alert").filter({ hasText: "获取失败" }).waitFor(); + assert.equal(await table().locator("tbody tr").count(), 100); + passed.push("refresh failure keeps snapshot with explicit error"); + failBoard = false; + await page.setViewportSize({ width: 390, height: 1000 }); + assert.ok(await dialog().locator(".bm-live-kpis").evaluate((el) => el.scrollWidth <= el.clientWidth + 1)); + assert.ok(await dialog().locator(".bm-board").evaluate((el) => el.scrollWidth <= el.clientWidth + 1)); + await page.screenshot({ path: path.join(output, "cutover-monitor-mobile.png"), fullPage: true }); + passed.push("390px responsive board", "table overflow stays within scroll container"); + await dialog().getByRole("button", { name: "割接批次", exact: true }).click(); + await page.waitForFunction(() => document.querySelectorAll('.bm-expect-table tbody tr').length === 100); + await dialog().getByRole("checkbox", { name: "ARP · 公网 业务 0", exact: true }).check(); + assert.ok(await dialog().getByRole("checkbox", { name: "ARP · 公网 业务 0", exact: true }).isChecked()); + await dialog().getByRole("button", { name: "下一页", exact: true }).click(); + await dialog().getByRole("checkbox", { name: "ARP · 公网 业务 100", exact: true }).check(); + await dialog().locator(".ct-editor__nav").getByRole("tab", { name: /ARP · 专线/ }).click(); + assert.equal(await dialog().getByRole("checkbox", { name: "ARP · 专线 业务 0", exact: true }).isChecked(), false); + await dialog().getByRole("button", { name: "新建", exact: true }).click(); + const create = writes.at(-1); + assert.deepEqual(create.expect_set.items, [{ metric_id: "arp", sheet_id: "s1", key: ["biz-0"] }, { metric_id: "arp", sheet_id: "s1", key: ["biz-100"] }]); + passed.push("scope picker renders at most 100 rows", "checkbox click toggles exactly once", "selection survives pagination", "same business key in another sheet stays unselected", "wave stores structured keys and precise sheet scope"); + await dialog().getByRole("button", { name: "关闭", exact: true }).click(); + await page.setViewportSize({ width: 1440, height: 1080 }); + await page.goto(`${base}/network/cutover/monitor-templates`); + await page.locator("table tbody tr").filter({ hasText: monitor.name }).getByRole("button", { name: "编辑", exact: true }).click(); + await dialog().getByText("范围外业务持续保护", { exact: true }).waitFor(); + await dialog().getByRole("button", { name: /保存/, exact: true }).click(); + await dialog().waitFor({ state: "hidden" }); + assert.equal(writes.at(-1).defaults.custom_setting, false); + assert.equal(writes.at(-1).defaults.threshold, 7); + assert.equal(writes.at(-1).defaults.out_of_expect, "strict"); + assert.equal(writes.at(-1).sheet_overrides[0].success[0].new_groups[0][0].value, "added"); + assert.equal(writes.at(-1).sheet_overrides[0].success[0].name, "客户迁移规则"); + passed.push("monitor edit preserves extended defaults", "outside protection policy explained", "legacy group tokens and rule metadata preserved"); + assert.deepEqual(errors, []); + console.log(JSON.stringify({ passed, errors }, null, 2)); +} catch (error) { + await page.screenshot({ path: path.join(output, "cutover-monitor-failure.png"), fullPage: true }); + console.log(JSON.stringify({ passed, errors, recentRequests: requests.slice(-12) }, null, 2)); + throw error; +} finally { + await browser.close(); +}