Add cutover migration monitor and day-based batch retention.

Protect baselines and compare/migration-referenced batches from purge or delete, and let operators mark baselines and clean high-freq data manually.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-18 16:43:26 +08:00
parent c7539e379d
commit 8631f58113
23 changed files with 3837 additions and 91 deletions

View file

@ -158,6 +158,7 @@ const en = {
portTrafficWall: "Traffic wall",
bizState: "Business state",
bizCompare: "Business compare",
bizMigration: "Cutover monitor",
},
collapseNav: "Collapse sidebar",
expandNav: "Expand sidebar",
@ -199,7 +200,25 @@ const en = {
intervalUnitDays: "days",
intervalUnitHours: "hours",
intervalUnitSeconds: "seconds",
retention: "Keep batches",
retention: "Retention days",
retentionHint: "Batches older than this are purged; baselines and compare/cutover refs are kept.",
dailyKeepEnabled: "Daily keep policy",
dailyKeepCount: "Keep per day",
dailyKeepHint: "When on: keep only the newest N batches per past day; extras purge next day (off by default).",
markBaseline: "Mark baseline",
unmarkBaseline: "Unmark baseline",
baseline: "Baseline",
protected: "Protected",
deleteBatch: "Delete",
bulkDelete: "Bulk delete",
confirmDeleteBatch: "Delete this batch? Protected batches cannot be deleted.",
confirmBulkDelete: "Delete {{count}} selected batches? Protected ones are skipped.",
batchDeleted: "Batch deleted",
bulkDeleted: "Deleted {{deleted}}, skipped {{skipped}}",
purgeNow: "Purge now",
purgeOk: "Purge done: dropped {{dropped}}",
selectAll: "Select deletable",
colProtect: "Protect",
saveSchedule: "Save schedule",
scheduleSaved: "Schedule saved",
colInterval: "Interval",
@ -428,6 +447,89 @@ const en = {
colKey: "Identity",
colChange: "Changes",
},
bizMigration: {
title: "Cutover monitor",
hint: "Separate from business compare: baseline drift, expect set, dual-device verdict. Reuses collect tasks and port mappings.",
hintPort:
"Metric focus: port status (interface_brief / admin·phy·prot). Baseline → pick ports → evaluate board.",
createProject: "New cutover project",
projectName: "Project name",
oldTask: "Old-device collect task",
newTask: "New-device collect task",
portMapping: "Port mapping",
oldBaseline: "Old baseline batch",
newBaseline: "New baseline batch (optional)",
needProjectFields: "Enter a name and pick old/new collect tasks",
needExpectPorts: "Select at least one expected port for this batch",
needBaselineFirst: "Save an old baseline batch first to list ports",
projectCreated: "Project created",
projects: "Projects",
emptyProjects: "No cutover projects yet",
saveBaseline: "Save baseline / mapping",
baselineSaved: "Baseline saved",
pickExpectPorts: "Expected ports (from old baseline)",
portFilterPh: "Filter interface / description",
emptyBaselinePorts: "No interface_brief rows in baseline (enable that profile on the task)",
batchLabel: "Batch label",
defaultBatchLabel: "Night N",
expectPorts: "Expected ports (old side)",
expectPortsPh: "Comma or newline separated",
createBatch: "New batch",
batchCreated: "Batch created",
batches: "Batches",
startBatch: "Start batch",
finishBatch: "Finish batch",
evaluate: "Evaluate now",
evaluated: "Evaluation done",
statusUpdated: "Status updated",
board: "Progress board",
metricPort: "Port status",
progress: "Progress",
anomaly: "Anomaly",
onlyExpect: "Expected ports only",
colMetric: "Metric",
colKey: "Object",
colPort: "Old port",
colMapped: "Mapped new",
colDesc: "Description",
colOldPort: "Old port",
colNewPort: "New port",
colOldStatus: "Old admin/phy/prot",
colNewStatus: "New admin/phy/prot",
colOld: "Old",
colNew: "New",
colVerdict: "Verdict",
emptyDiffs: "No rows yet — run Evaluate",
verdictMigrated: "Migrated",
verdictMigrating: "Migrating",
verdictLost: "Lost",
verdictAnomaly: "Anomaly",
verdictNotInvolved: "Not involved",
verdictUnexpected: "Unexpected new",
verdictOk: "OK",
enableHighfreq: "Enable high-freq port collect",
highfreqHint:
"Creates/reuses biz-state tasks with interface_brief only on old/new NEs. Add BGP etc. later on the same tasks in Business state.",
highfreqReady: "High-freq port collect tasks ready and bound to this project",
collectNow: "Collect old+new now",
collectTriggered: "Collect triggered",
openBizState: "Open business state",
boundTasks: "Bound collect tasks",
acceptTitle: "Batch acceptance summary",
acceptPassed: "Batch acceptance passed",
acceptFailed: "Batch acceptance failed ({{n}} red tickets; you may continue)",
acceptPassedShort: "Passed",
acceptFailedShort: "Failed",
acceptCarryHint: "Failure does not block the next batch; red tickets stay until resolved.",
openRedHint: "{{n}} open red ticket(s) on this project (carry allowed)",
redTitle: "Red tickets",
redOpen: "open",
resolveRed: "Resolve",
redResolved: "Red ticket resolved",
batchCreatedWithRed: "Batch created ({{n}} open red tickets; carry allowed)",
colStatus: "Status",
verdictUnfinished: "Unfinished",
},
portTraffic: {
title: "Port traffic",
create: "Monitor device",