feat(monitoring): decouple AI platforms from media_platforms and expand catalog to 6

Add ai_platforms table + shared catalog (yuanbao/kimi/wenxin/deepseek/doubao/qwen),
drop FKs from platform_accounts and desktop_tasks to media_platforms, and wire
target_account_id + platform into DesktopTaskEvent so the desktop runtime no
longer has to infer them from local state. Desktop client gains generic AI page
detection for binding, drops stale-business-date monitor tasks at the edge, and
refactors AccountsView/AiPlatformsView around the shared catalog. Admin tracking
view surfaces per-platform sampling status cards.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-20 15:40:18 +08:00
parent 25dad49ed3
commit 09295d11a1
21 changed files with 2073 additions and 843 deletions
@@ -0,0 +1,17 @@
DELETE FROM desktop_tasks
WHERE platform_id IN ('yuanbao', 'kimi', 'wenxin', 'deepseek', 'doubao', 'qwen');
DELETE FROM platform_accounts
WHERE platform_id IN ('yuanbao', 'kimi', 'wenxin', 'deepseek', 'doubao', 'qwen');
ALTER TABLE platform_accounts
ADD CONSTRAINT platform_accounts_platform_id_fkey
FOREIGN KEY (platform_id) REFERENCES media_platforms(platform_id);
ALTER TABLE desktop_tasks
ADD CONSTRAINT desktop_tasks_platform_id_fkey
FOREIGN KEY (platform_id) REFERENCES media_platforms(platform_id);
DROP INDEX IF EXISTS idx_ai_platforms_status_sort;
DROP INDEX IF EXISTS uk_ai_platforms_platform_id;
DROP TABLE IF EXISTS ai_platforms;
@@ -0,0 +1,50 @@
CREATE TABLE IF NOT EXISTS ai_platforms (
id BIGSERIAL PRIMARY KEY,
ai_platform_id VARCHAR(64) NOT NULL,
name VARCHAR(100) NOT NULL,
short_name VARCHAR(16) NOT NULL,
accent_color VARCHAR(16) NOT NULL DEFAULT '#1677ff',
login_url TEXT,
status VARCHAR(20) NOT NULL DEFAULT 'active',
sort_order INT NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS uk_ai_platforms_platform_id
ON ai_platforms(ai_platform_id);
CREATE INDEX IF NOT EXISTS idx_ai_platforms_status_sort
ON ai_platforms(status, sort_order, id);
INSERT INTO ai_platforms (
ai_platform_id,
name,
short_name,
accent_color,
login_url,
status,
sort_order
)
VALUES
('yuanbao', '混元 / 元宝', '', '#19bf6b', 'https://yuanbao.tencent.com/', 'active', 10),
('kimi', 'Kimi', 'K', '#111827', 'https://kimi.moonshot.cn/', 'active', 20),
('wenxin', '文心一言', '', '#20c6d7', 'https://yiyan.baidu.com/', 'active', 30),
('deepseek', 'DeepSeek', 'D', '#4468ff', 'https://chat.deepseek.com/', 'active', 40),
('doubao', '豆包', '', '#ff9348', 'https://www.doubao.com/', 'active', 50),
('qwen', '通义千问', '', '#276ef1', 'https://www.qianwen.com/', 'active', 60)
ON CONFLICT (ai_platform_id)
DO UPDATE SET
name = EXCLUDED.name,
short_name = EXCLUDED.short_name,
accent_color = EXCLUDED.accent_color,
login_url = EXCLUDED.login_url,
status = EXCLUDED.status,
sort_order = EXCLUDED.sort_order,
updated_at = NOW();
ALTER TABLE platform_accounts
DROP CONSTRAINT IF EXISTS platform_accounts_platform_id_fkey;
ALTER TABLE desktop_tasks
DROP CONSTRAINT IF EXISTS desktop_tasks_platform_id_fkey;