mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-07-17 09:56:06 +00:00
feat(platform): migrate bot admins from config.yaml to database (#2289)
* 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) * fix(ci): ruff/prettier format, fix test_importutil assertion * fix(ci): prettier format BackendClient.ts and i18n locales * fix(ci): eslint-prettier fix BackendClient.ts single-param formatting * refactor: move admin management into session monitor, fix session_id enum format - Remove standalone admins tab, replace with BotAdminsDialog in session monitor - Add admin toggle button inline in chat header next to Active status - Add BotAdminsDialog component with useBotAdmins hook - Fix session_id written as LauncherTypes.PERSON_xxx instead of person_xxx (monitoring_helper.py x4, pipelinemgr.py x1 missing .value on launcher_type) - Fix duplicate platform/person label in session list and chat header - Migrate existing malformed session_id records in DB --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""add bot_admins table and migrate config admins
|
||||
|
||||
Revision ID: 0007_add_bot_admins
|
||||
Revises: 0006_normalize_mcp_remote_mode
|
||||
Create Date: 2026-06-26
|
||||
"""
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision = '0007_add_bot_admins'
|
||||
down_revision = '0006_normalize_mcp_remote_mode'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
conn = op.get_bind()
|
||||
if 'bot_admins' in sa.inspect(conn).get_table_names():
|
||||
return
|
||||
op.create_table(
|
||||
'bot_admins',
|
||||
sa.Column('id', sa.Integer, primary_key=True, autoincrement=True),
|
||||
sa.Column('bot_uuid', sa.String(255), nullable=False),
|
||||
sa.Column('launcher_type', sa.String(64), nullable=False),
|
||||
sa.Column('launcher_id', sa.String(255), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime, nullable=False, server_default=sa.func.now()),
|
||||
sa.UniqueConstraint('bot_uuid', 'launcher_type', 'launcher_id', name='uq_bot_admin'),
|
||||
)
|
||||
|
||||
# Migrate old config-based admins into the first bot (best-effort)
|
||||
inspector = sa.inspect(conn)
|
||||
tables = inspector.get_table_names()
|
||||
|
||||
if 'bots' not in tables:
|
||||
return
|
||||
|
||||
# Read the first bot uuid
|
||||
row = conn.execute(sa.text('SELECT uuid FROM bots ORDER BY created_at LIMIT 1')).first()
|
||||
if row is None:
|
||||
return
|
||||
first_bot_uuid = row[0]
|
||||
|
||||
# Read instance_config metadata key that holds the admins list
|
||||
if 'metadata' not in tables:
|
||||
return
|
||||
meta_row = conn.execute(sa.text("SELECT value FROM metadata WHERE key = 'instance_config'")).first()
|
||||
if meta_row is None:
|
||||
return
|
||||
|
||||
import json
|
||||
|
||||
try:
|
||||
cfg = json.loads(meta_row[0])
|
||||
except Exception:
|
||||
return
|
||||
|
||||
admins = cfg.get('admins', [])
|
||||
for entry in admins:
|
||||
parts = entry.split('_', 1)
|
||||
if len(parts) != 2:
|
||||
continue
|
||||
launcher_type, launcher_id = parts
|
||||
try:
|
||||
conn.execute(
|
||||
sa.text(
|
||||
'INSERT OR IGNORE INTO bot_admins (bot_uuid, launcher_type, launcher_id) VALUES (:bu, :lt, :li)'
|
||||
),
|
||||
{'bu': first_bot_uuid, 'lt': launcher_type, 'li': launcher_id},
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Remove admins key from stored config
|
||||
if 'admins' in cfg:
|
||||
del cfg['admins']
|
||||
conn.execute(
|
||||
sa.text("UPDATE metadata SET value = :v WHERE key = 'instance_config'"),
|
||||
{'v': json.dumps(cfg)},
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_table('bot_admins')
|
||||
Reference in New Issue
Block a user