feat: improve datasource query audit workflows

This commit is contained in:
Logan committed 2026-07-06 23:01:04 +08:00
1 parent 74748e4914
commit 644981eef4
32 files changed
+780 -3061

No files matched your search

+22 -2
View File
@@ -57,13 +57,15 @@ type SortState = { column: string | null; direction: SortDirection };
/* Constants */
/* ------------------------------------------------------------------ */
const dbTypeLabel: Record<string, string> = {
mysql: 'MySQL', postgresql: 'PostgreSQL', redis: 'Redis', mongodb: 'MongoDB',
mysql: 'MySQL', postgres: 'PostgreSQL', postgresql: 'PostgreSQL', redis: 'Redis', mongo: 'MongoDB', mongodb: 'MongoDB',
};
const dbTypeIcon: Record<string, string> = {
mysql: '/db-logos/mysql.svg',
postgres: '/db-logos/postgres.svg',
postgresql: '/db-logos/postgres.svg',
redis: '/db-logos/redis.svg',
mongo: '/db-logos/mongo.svg',
mongodb: '/db-logos/mongo.svg',
};
@@ -77,6 +79,20 @@ const placeholderMap: Record<DBType, string> = {
mongodb: "// MongoDB Shell\n// 支持 find, aggregate, count, distinct\n\ndb.users.find({ status: 'active' }).limit(100)",
};
function normalizeDbType(dbType?: string): DBType {
if (dbType === 'postgres' || dbType === 'pg') return 'postgresql';
if (dbType === 'mongo') return 'mongodb';
if (dbType === 'redis') return 'redis';
return 'mysql';
}
const queryPolicyText: Record<DBType, string> = {
mysql: '查询入口仅允许 SELECT / SHOW / DESCRIBE / EXPLAIN;禁止 UPDATE/DELETE/DDL、多语句、SELECT FOR UPDATE。未写 LIMIT 时按平台配置自动限制。',
postgresql: '查询入口仅允许 SELECT / EXPLAIN;禁止 EXPLAIN ANALYZE、写入 CTE、多语句和锁定读。未写 LIMIT 时按平台配置自动限制。',
redis: 'Redis 查询入口仅允许只读命令;写命令请提交变更工单。集群实例会按 slot 路由并扫描所有 master。',
mongodb: 'MongoDB 查询入口用于 find / aggregate / count / distinct 等只读操作;写操作请提交变更工单。',
};
/* ------------------------------------------------------------------ */
/* Helpers */
/* ------------------------------------------------------------------ */
@@ -184,7 +200,7 @@ export default function QueriesPage() {
}, [instanceId, instances]);
const selectedInstance = useMemo(() => instances.find(inst => String(inst.id) === instanceId), [instances, instanceId]);
const dbType = (selectedInstance?.db_type || 'mysql') as DBType;
const dbType = normalizeDbType(selectedInstance?.db_type);
const editorLang = dbType === 'redis' ? 'redis' as const : dbType === 'mongodb' ? 'mongodb' as const : 'sql' as const;
useEffect(() => {
@@ -505,6 +521,10 @@ export default function QueriesPage() {
<span className="px-1.5 py-0.5 rounded bg-[var(--dg-bg-primary)] border border-[var(--dg-border)]">Ctrl+Shift+F 格式化</span>
</div>
</div>
<div className="px-3 py-2 border-t border-[var(--dg-border)] bg-[var(--dg-bg-primary)] text-[11px] text-[var(--dg-text-muted)] flex items-start gap-2">
<AlertTriangle className="w-3.5 h-3.5 text-amber-400 mt-0.5 shrink-0" />
<span>{queryPolicyText[dbType]}</span>
</div>
</div>
</div>