feat(admin): add ConfigSync page + close ADMIN-01/02 (AUDIT_TRACKER)
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

- ADMIN-01 FIXED: ConfigSync.tsx page with ProTable + pagination
  - config-sync service calling GET /config/sync-logs
  - route + nav item + breadcrumb
  - backend @reserved → @connected
- ADMIN-02 FALSE_POSITIVE: Logs.tsx + logs service already exist
This commit is contained in:
iven
2026-04-05 01:40:38 +08:00
parent 745c2fd754
commit d6b1f44119
7 changed files with 140 additions and 3 deletions

View File

@@ -20,6 +20,7 @@ import {
CrownOutlined,
SafetyOutlined,
FieldTimeOutlined,
SyncOutlined,
} from '@ant-design/icons'
import { Avatar, Dropdown, Tooltip, Drawer } from 'antd'
import { useAuthStore } from '@/stores/authStore'
@@ -51,6 +52,7 @@ const navItems: NavItem[] = [
{ path: '/knowledge', name: '知识库', icon: <BookOutlined />, permission: 'knowledge:read', group: '资源管理' },
{ path: '/billing', name: '计费管理', icon: <CrownOutlined />, permission: 'billing:read', group: '核心' },
{ path: '/logs', name: '操作日志', icon: <FileTextOutlined />, permission: 'admin:full', group: '运维' },
{ path: '/config-sync', name: '同步日志', icon: <SyncOutlined />, permission: 'config:read', group: '运维' },
{ path: '/config', name: '系统配置', icon: <SettingOutlined />, permission: 'config:read', group: '系统' },
{ path: '/prompts', name: '提示词管理', icon: <MessageOutlined />, permission: 'prompt:read', group: '系统' },
]
@@ -219,6 +221,7 @@ const breadcrumbMap: Record<string, string> = {
'/config': '系统配置',
'/prompts': '提示词管理',
'/logs': '操作日志',
'/config-sync': '同步日志',
}
// ============================================================

View File

@@ -0,0 +1,111 @@
// ============================================================
// 配置同步日志
// ============================================================
import { useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { Tag, Typography } from 'antd'
import type { ProColumns } from '@ant-design/pro-components'
import { ProTable } from '@ant-design/pro-components'
import { configSyncService } from '@/services/config-sync'
import type { ConfigSyncLog } from '@/types'
const { Title } = Typography
const actionLabels: Record<string, string> = {
push: '推送',
merge: '合并',
pull: '拉取',
diff: '差异',
}
const actionColors: Record<string, string> = {
push: 'blue',
merge: 'green',
pull: 'cyan',
diff: 'orange',
}
export default function ConfigSync() {
const [page, setPage] = useState(1)
const { data, isLoading } = useQuery({
queryKey: ['config-sync', page],
queryFn: ({ signal }) => configSyncService.list({ page, page_size: 20 }, signal),
})
const columns: ProColumns<ConfigSyncLog>[] = [
{
title: '操作',
dataIndex: 'action',
width: 100,
render: (_, r) => (
<Tag color={actionColors[r.action] || 'default'}>
{actionLabels[r.action] || r.action}
</Tag>
),
},
{
title: '客户端指纹',
dataIndex: 'client_fingerprint',
width: 160,
render: (_, r) => <code>{r.client_fingerprint.substring(0, 16)}...</code>,
},
{
title: '配置键',
dataIndex: 'config_keys',
width: 200,
ellipsis: true,
},
{
title: '客户端值',
dataIndex: 'client_values',
width: 150,
ellipsis: true,
render: (_, r) => r.client_values || '-',
},
{
title: '服务端值',
dataIndex: 'saas_values',
width: 150,
ellipsis: true,
render: (_, r) => r.saas_values || '-',
},
{
title: '解决方式',
dataIndex: 'resolution',
width: 120,
render: (_, r) => r.resolution || '-',
},
{
title: '时间',
dataIndex: 'created_at',
width: 180,
render: (_, r) => new Date(r.created_at).toLocaleString('zh-CN'),
},
]
return (
<div>
<div style={{ marginBottom: 24 }}>
<Title level={4} style={{ margin: 0 }}></Title>
</div>
<ProTable<ConfigSyncLog>
columns={columns}
dataSource={data?.items ?? []}
loading={isLoading}
rowKey="id"
search={false}
toolBarRender={false}
pagination={{
total: data?.total ?? 0,
pageSize: 20,
current: page,
onChange: setPage,
showSizeChanger: false,
}}
/>
</div>
)
}

View File

@@ -35,6 +35,7 @@ export const router = createBrowserRouter([
{ path: 'config', lazy: () => import('@/pages/Config').then((m) => ({ Component: m.default })) },
{ path: 'prompts', lazy: () => import('@/pages/Prompts').then((m) => ({ Component: m.default })) },
{ path: 'logs', lazy: () => import('@/pages/Logs').then((m) => ({ Component: m.default })) },
{ path: 'config-sync', lazy: () => import('@/pages/ConfigSync').then((m) => ({ Component: m.default })) },
],
},
])

View File

@@ -0,0 +1,7 @@
import request, { withSignal } from './request'
import type { ConfigSyncLog, PaginatedResponse } from '@/types'
export const configSyncService = {
list: (params?: Record<string, unknown>, signal?: AbortSignal) =>
request.get<PaginatedResponse<ConfigSyncLog>>('/config/sync-logs', withSignal({ params }, signal)).then((r) => r.data),
}

View File

@@ -324,3 +324,16 @@ export interface CreateTemplateRequest {
description?: string
permissions?: string[]
}
/** 配置同步日志 */
export interface ConfigSyncLog {
id: number
account_id: string
client_fingerprint: string
action: string
config_keys: string
client_values: string | null
saas_values: string | null
resolution: string | null
created_at: string
}

View File

@@ -137,7 +137,7 @@ pub async fn config_diff(
}
/// GET /api/v1/config/sync-logs?page=1&page_size=20
// @reserved - no frontend caller
/// @connected - admin-v2 ConfigSync page
pub async fn list_sync_logs(
State(state): State<AppState>,
Extension(ctx): Extension<AuthContext>,

View File

@@ -43,8 +43,8 @@
| SEC-V9-02 | relay 输入验证可加强 | **FALSE_POSITIVE** | relay/handlers.rs 已有完整验证body size/model/role/content/temperature/max_tokens/queue/permission |
| AUDIT-01 | 前端 audit-logger 无消费者 | **FALSE_POSITIVE** | 文件已于先前清理中删除 |
| DEAD-04 | director.rs 907 行孤立代码 | **FALSE_POSITIVE** | 与 V11-P3-05 相同multi-agent feature gate 已正确隔离 |
| ADMIN-01 | config_sync_logs 无 Admin 页面 | OPEN | - | - | 添加页面 |
| ADMIN-02 | operation_logs 无 Admin 页面 | OPEN | - | - | 添加页面 |
| ADMIN-01 | config_sync_logs 无 Admin 页面 | **FIXED** | admin-v2 ConfigSync.tsx + config-sync service + route + nav |
| ADMIN-02 | operation_logs 无 Admin 页面 | **FALSE_POSITIVE** | admin-v2 已有 Logs.tsx + logs service 完整实现 |
## P4: 低优先级
@@ -274,6 +274,8 @@
| 2026-04-05 | V11-P2-05 | 部分关闭 → FIXED | 完整审计: 160 @connected + 16 @reserved + 1 未注册 = 177 总命令 |
| 2026-04-05 | TYPE-01 | OPEN → FIXED | ConnectionState 统一(含 handshaking); saas-types PromptTemplate/PromptVariable union literal; CreateRoleRequest optional; PropertyPanel as any→类型安全; chatStore window cast |
| 2026-04-05 | AUD3-DB-01 | OPEN → FIXED | 16 个 down migration SQL + db::run_down_migrations() + migrate_down task (timestamp=20260402) |
| 2026-04-05 | ADMIN-01 | OPEN → FIXED | admin-v2 ConfigSync.tsx 页面 + config-sync service + route + nav + 后端 @reserved@connected |
| 2026-04-05 | ADMIN-02 | OPEN → FALSE_POSITIVE | admin-v2 已有 Logs.tsx + logs service + route 完整实现 |
## V12 模块化端到端审计修复 (2026-04-04)