feat(platform): migrate bot admins from config.yaml to database

- Add BotAdmin ORM model (bot_admins table) scoped per bot_uuid
- Add Alembic migration 0007 to create table and migrate legacy config admins
- Remove top-level admins key from config.yaml template
- Add GET/POST/DELETE /api/v1/platform/bots/<uuid>/admins endpoints
- Update cmdmgr privilege check to query bot_admins table (bot-scoped)
- Add BotAdminsPanel frontend component in bot detail sessions tab
- Add i18n keys (zh-Hans, en-US)
This commit is contained in:
dadachann
2026-06-26 12:43:30 -04:00
parent 48905ea080
commit 2ef3aebe16
11 changed files with 358 additions and 15 deletions
+13 -1
View File
@@ -22,11 +22,12 @@ import {
import BotForm from '@/app/home/bots/components/bot-form/BotForm';
import { BotLogListComponent } from '@/app/home/bots/components/bot-log/view/BotLogListComponent';
import BotSessionMonitor from '@/app/home/bots/components/bot-session/BotSessionMonitor';
import BotAdminsPanel from '@/app/home/bots/components/bot-admins/BotAdminsPanel';
import type { BotSessionMonitorHandle } from '@/app/home/bots/components/bot-session/BotSessionMonitor';
import { httpClient } from '@/app/infra/http/HttpClient';
import { useSidebarData } from '@/app/home/components/home-sidebar/SidebarDataContext';
import { useTranslation } from 'react-i18next';
import { Settings, FileText, Users, RefreshCw, Trash2 } from 'lucide-react';
import { Settings, FileText, Users, RefreshCw, Trash2, ShieldCheck } from 'lucide-react';
import { cn } from '@/lib/utils';
import { toast } from 'sonner';
@@ -229,6 +230,10 @@ export default function BotDetailContent({ id }: { id: string }) {
</button>
)}
</TabsTrigger>
<TabsTrigger value="admins" className="gap-1.5">
<ShieldCheck className="size-3.5" />
{t('bots.admins.title')}
</TabsTrigger>
</TabsList>
{/* Tab: Configuration */}
@@ -291,6 +296,13 @@ export default function BotDetailContent({ id }: { id: string }) {
<TabsContent value="sessions" className="flex-1 min-h-0 mt-4">
<BotSessionMonitor ref={sessionMonitorRef} botId={id} />
</TabsContent>
{/* Tab: Admins */}
<TabsContent value="admins" className="flex-1 min-h-0 overflow-y-auto mt-4">
<div className="mx-auto max-w-3xl pb-8">
<BotAdminsPanel botId={id} />
</div>
</TabsContent>
</Tabs>
</div>