Files
LWLT-AIBOT/control-plane/migrations/018_agentbus_account_workers.sql
2026-09-02 15:09:07 +08:00

101 lines
3.2 KiB
SQL

-- Bind each employee-facing AgentBus channel and ERP browser worker to one
-- platform account. Historical AgentBus work remains deliberately unassigned:
-- ownership cannot be inferred safely from an old channel key.
ALTER TABLE users
ADD COLUMN IF NOT EXISTS erp_account text;
ALTER TABLE users
DROP CONSTRAINT IF EXISTS users_erp_account_length_check;
ALTER TABLE users
ADD CONSTRAINT users_erp_account_length_check
CHECK (erp_account IS NULL OR char_length(erp_account) BETWEEN 1 AND 200);
ALTER TABLE users
DROP CONSTRAINT IF EXISTS users_admin_erp_account_check;
ALTER TABLE users
ADD CONSTRAINT users_admin_erp_account_check
CHECK (role <> 'admin' OR erp_account IS NULL);
CREATE UNIQUE INDEX IF NOT EXISTS users_org_erp_account_unique_idx
ON users (organization_id, lower(erp_account))
WHERE erp_account IS NOT NULL;
ALTER TABLE user_channels
ADD COLUMN IF NOT EXISTS owner_user_id uuid;
ALTER TABLE user_channels
DROP CONSTRAINT IF EXISTS user_channels_owner_scope_fkey;
ALTER TABLE user_channels
ADD CONSTRAINT user_channels_owner_scope_fkey
FOREIGN KEY (organization_id, owner_user_id)
REFERENCES users (organization_id, id);
CREATE UNIQUE INDEX IF NOT EXISTS user_channels_owner_unique_idx
ON user_channels (organization_id, owner_user_id)
WHERE owner_user_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS user_channels_owner_status_idx
ON user_channels (organization_id, owner_user_id, enabled, status);
UPDATE user_channels
SET enabled = false,
status = 'error',
last_error = '渠道尚未绑定员工平台账号,监听器不会启动。',
updated_at = now()
WHERE owner_user_id IS NULL
AND enabled = true;
ALTER TABLE tasks
ADD COLUMN IF NOT EXISTS assigned_user_id uuid;
ALTER TABLE tasks
DROP CONSTRAINT IF EXISTS tasks_assignee_scope_fkey;
ALTER TABLE tasks
ADD CONSTRAINT tasks_assignee_scope_fkey
FOREIGN KEY (organization_id, assigned_user_id)
REFERENCES users (organization_id, id);
UPDATE tasks
SET assigned_user_id = created_by
WHERE assigned_user_id IS NULL
AND source = 'manual'
AND created_by IS NOT NULL;
CREATE INDEX IF NOT EXISTS tasks_assignee_visible_created_idx
ON tasks (organization_id, assigned_user_id, created_at DESC, id DESC);
CREATE INDEX IF NOT EXISTS tasks_assignee_queue_idx
ON tasks (organization_id, assigned_user_id, status, created_at, id)
WHERE archived_at IS NULL;
ALTER TABLE browser_connections
ADD COLUMN IF NOT EXISTS erp_account_verified boolean NOT NULL DEFAULT false,
ADD COLUMN IF NOT EXISTS erp_account_fingerprint text;
WITH ranked_connections AS (
SELECT id,
row_number() OVER (
PARTITION BY organization_id, user_id
ORDER BY last_seen_at DESC, id DESC
) AS worker_rank
FROM browser_connections
WHERE status = 'connected'
)
UPDATE browser_connections connection
SET status = 'superseded'
FROM ranked_connections ranked
WHERE connection.id = ranked.id
AND ranked.worker_rank > 1;
CREATE UNIQUE INDEX IF NOT EXISTS browser_connections_active_user_unique_idx
ON browser_connections (organization_id, user_id)
WHERE status = 'connected';
CREATE INDEX IF NOT EXISTS browser_connections_worker_freshness_idx
ON browser_connections (organization_id, user_id, status, last_seen_at DESC);