From 889b70b8f99cc39a34d0b74e70d43e80e5c36d73 Mon Sep 17 00:00:00 2001 From: uncle6me-web Date: Sun, 9 Aug 2026 13:28:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(portal):=20=E5=9F=B7=E8=A1=8C=E7=B4=80?= =?UTF-8?q?=E9=8C=84=E4=BF=9D=E7=95=99=E6=9C=9F=20UI=EF=BC=88P7=20?= =?UTF-8?q?=E8=A3=9C=E5=89=8D=E7=AB=AF=EF=BC=8Carcrun-rag#21=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 後端(4ca23c2)已提供 GET/PUT /portal/admin/execution-log-retention, 但管理頁完全沒有對應介面——leo 只能自己 curl。本次補管理頁「執行紀錄保留期」 卡片:顯示目前保留天數、可改天數、可勾「不刪除」(企業稽核)。純薄殼, 零業務邏輯,呼叫既有端點(rule 07 薄殼原則)。 驗證(本機真瀏覽器 E2E,非 curl/非讀原始碼): 本機起兩個真 wrangler dev(kbdb:18787/cypher-executor:18788,local D1+KV, 真的套用 migrations 0001-0006)+本機靜態伺服 console-ui/public(18790, config.js 指向本機 apiBase)+UI_ORIGINS 加白名單解 CORS。瀏覽器走真實 「首次設定」流程建帳號、登入、進管理頁: - 預設值:保留天數顯示 90(無資料時退回預設,非空白) - 改 45 天 → 儲存 → 畫面即時更新「目前設定:保留 45 天」→ reload 頁面仍是 45 - 勾「不刪除」→ 儲存 → 天數輸入框停用、清空 → 顯示「不刪除(企業稽核)」 → reload 仍是不刪除 - 改回 90 天 → 儲存 → reload 仍是 90(雙向都驗過) - 全程 Network 面板每筆 GET/PUT 皆 200;console 除了測試前置階段的舊 bootstrap-conflict 雜訊外,無新增紅字 發現但沒動的問題:console-ui 本身沒有本機可跑的 dev/test 腳本 (package.json 只有 deploy/verify),E2E 用的是手工起 wrangler dev + python http.server 兜出來的,建議之後補一支 `npm run preview:local` 方便下次驗證不用重找路。 Co-Authored-By: Claude Opus 5 --- console-ui/public/portal/index.html | 63 +++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/console-ui/public/portal/index.html b/console-ui/public/portal/index.html index 56393b2..70ddf20 100644 --- a/console-ui/public/portal/index.html +++ b/console-ui/public/portal/index.html @@ -443,6 +443,21 @@ if (!window.ARCRUN_API_BASE) {
管理帳號與知識庫授權
+
執行紀錄保留期
+
+
保留天數
+
執行紀錄是稽核資料,超過保留天數會被每日自動清除;預設 90 天(3 個月),也可設為「不刪除」(企業稽核用途)。
+
+ + + +
+
+
+
+
帳號管理
新增同仁帳號
@@ -1573,9 +1588,57 @@ function taipeiMonthDay(ms) { var d = new Date(ms + TAIPEI_OFFSET_MS); return { }); } + // 執行紀錄保留期(P7):GET/PUT /portal/admin/execution-log-retention,role=admin 閘(server 端)。 + // retention_days: number=自訂天數;null=「不刪除」(企業稽核,leo 08-07:「我願意花很多錢 + // 保存,不要刪除」);未設定過的租戶也會回一個值(KBDB 端退回預設 90 天)。 + function loadRetention() { + $('ad-ret-current').textContent = '載入中…'; + adminApi('GET', '/portal/admin/execution-log-retention') + .then(function (x) { + if (guard401(x.status)) return; + if (!x.ok) { $('ad-ret-current').textContent = ''; $('ad-ret-status').textContent = x.d.error || ('讀取失敗(HTTP ' + x.status + ')'); return; } + var days = x.d.retention_days; + var def = x.d.default_days || 90; + $('ad-ret-never').checked = (days === null); + $('ad-ret-days').value = (days === null) ? '' : (days != null ? days : def); + $('ad-ret-days').disabled = (days === null); + $('ad-ret-current').textContent = (days === null) + ? '目前設定:不刪除(企業稽核)' + : '目前設定:保留 ' + (days != null ? days : def) + ' 天' + (days == null ? '(沿用預設值,尚未自訂)' : ''); + }) + .catch(function (e) { $('ad-ret-current').textContent = ''; $('ad-ret-status').textContent = friendlyErr(e); }); + } + $('ad-ret-never').addEventListener('change', function () { + $('ad-ret-days').disabled = this.checked; + }); + $('ad-ret-save').addEventListener('click', function () { + var st = $('ad-ret-status'); + st.textContent = ''; + var never = $('ad-ret-never').checked; + var body; + if (never) { + body = { retention_days: null }; + } else { + var n = parseInt($('ad-ret-days').value, 10); + if (!n || n <= 0) { st.textContent = '請輸入大於 0 的天數,或勾「不刪除」'; return; } + body = { retention_days: n }; + } + $('ad-ret-save').disabled = true; + adminApi('PUT', '/portal/admin/execution-log-retention', body) + .then(function (x) { + $('ad-ret-save').disabled = false; + if (guard401(x.status)) return; + if (!x.ok) { st.textContent = x.d.error || ('儲存失敗(HTTP ' + x.status + ')'); return; } + toast('保留期已更新'); + loadRetention(); + }) + .catch(function (e) { $('ad-ret-save').disabled = false; st.textContent = friendlyErr(e); }); + }); + function loadAdmin() { $('ad-users').innerHTML = '
載入中…
'; $('ad-libs').innerHTML = '
載入中…
'; + loadRetention(); adminApi('GET', '/portal/admin/libraries') .then(function (x) { if (guard401(x.status)) return;