Make repeated channel-monitor setup safer

Admins often recreate monitors with the same endpoint, model, and request settings. A server-side duplicate keeps the stored API key out of the browser, creates a disabled copy for review, and uses stable operation identity to recover ambiguous retries without creating extra rows.

Constraint: Stored monitor API keys must never be returned to the browser
Constraint: Applying a request template must preserve internal duplicate recovery metadata
Rejected: Rebuild the monitor from list data | list responses only contain a masked API key
Rejected: Copy runtime state and history | a duplicate should start as an unverified configuration
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep duplicated monitors disabled until an administrator reviews and enables them
Tested: Go unit tests for repository, service, and admin handler; integration-tag compile; go vet; golangci-lint v2.9; frontend Vitest, ESLint, typecheck, production build; Playwright duplicate flow
Not-tested: PostgreSQL container integration locally because Docker is unavailable; CI will execute the database-backed suite
This commit is contained in:
yan9651688
2026-07-16 16:30:19 +08:00
parent 393a8fe56a
commit e2e375d694
19 changed files with 1512 additions and 29 deletions
@@ -479,6 +479,11 @@ export default {
runNow: 'Run Now',
runSuccess: 'Check completed',
runFailed: 'Check failed',
duplicate: 'Duplicate',
duplicating: 'Duplicating',
duplicateSuccess: 'Monitor duplicated as "{name}" and disabled. Review its configuration before enabling it.',
duplicateFailed: 'Failed to duplicate monitor',
duplicateKeyUnavailable: 'The API key cannot be decrypted. Re-enter it before duplicating this monitor.',
apiKeyDecryptFailed: 'API Key decryption failed. Please re-edit this monitor with a fresh key.',
createSuccess: 'Monitor created',
updateSuccess: 'Monitor updated',
@@ -479,6 +479,11 @@ export default {
runNow: '立即检测',
runSuccess: '检测完成',
runFailed: '检测失败',
duplicate: '复制',
duplicating: '复制中',
duplicateSuccess: '监控已复制为「{name}」,已默认停用,请确认配置后再启用',
duplicateFailed: '复制监控失败',
duplicateKeyUnavailable: 'API Key 无法解密,请先编辑并重新填写 Key 后再复制',
apiKeyDecryptFailed: 'API Key 解密失败,请重新编辑该监控并填入新的 Key',
createSuccess: '监控创建成功',
updateSuccess: '监控更新成功',