mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
feat: refactor User/Bot architecture and implement multi-channel gateway
Major changes: 1. Core Architecture: Decoupled Bots from Users. Bots now have independent lifecycles, member management (bot_members), and dedicated configurations. 2. Channel Gateway: - Implemented a unified Channel Manager supporting Feishu, Telegram, and Local (Web/CLI) adapters. - Added message processing pipeline to normalize interactions across different platforms. - Introduced a Contact system for identity binding and guest access policies. 3. Database & Tooling: - Consolidated all migrations into 0001_init with updated schema for bots, channels, and contacts. - Optimized sqlc.yaml to automatically track the migrations directory. 4. Agent Enhancements: - Introduced ToolContext to provide Agents with platform-aware execution capabilities (e.g., messaging, contact lookups). - Added tool logging and fallback mechanisms for toolChoice execution. 5. UI & Docs: Updated frontend stores, UI components, and Swagger documentation to align with the new Bot-centric model.
This commit is contained in:
@@ -1,13 +1,24 @@
|
||||
DROP TABLE IF EXISTS user_settings;
|
||||
DROP TABLE IF EXISTS history;
|
||||
DROP TABLE IF EXISTS schedule;
|
||||
DROP TABLE IF EXISTS subagents;
|
||||
DROP TABLE IF EXISTS schedule;
|
||||
DROP TABLE IF EXISTS lifecycle_events;
|
||||
DROP TABLE IF EXISTS container_versions;
|
||||
DROP TABLE IF EXISTS snapshots;
|
||||
DROP TABLE IF EXISTS containers;
|
||||
DROP TABLE IF EXISTS channel_sessions;
|
||||
DROP TABLE IF EXISTS contact_bind_tokens;
|
||||
DROP TABLE IF EXISTS contact_channels;
|
||||
DROP TABLE IF EXISTS contacts;
|
||||
DROP TABLE IF EXISTS bot_channel_configs;
|
||||
DROP TABLE IF EXISTS user_channel_bindings;
|
||||
DROP TABLE IF EXISTS history;
|
||||
DROP TABLE IF EXISTS conversations;
|
||||
DROP TABLE IF EXISTS bot_model_configs;
|
||||
DROP TABLE IF EXISTS bot_settings;
|
||||
DROP TABLE IF EXISTS bot_members;
|
||||
DROP TABLE IF EXISTS bots;
|
||||
DROP TABLE IF EXISTS model_variants;
|
||||
DROP TABLE IF EXISTS models;
|
||||
DROP TABLE IF EXISTS llm_providers;
|
||||
DROP TABLE IF EXISTS snapshots;
|
||||
DROP TABLE IF EXISTS containers;
|
||||
DROP TABLE IF EXISTS users;
|
||||
DROP TYPE IF EXISTS user_role;
|
||||
|
||||
+208
-58
@@ -25,39 +25,6 @@ CREATE TABLE IF NOT EXISTS users (
|
||||
CONSTRAINT users_username_unique UNIQUE (username)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS containers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
container_id TEXT NOT NULL,
|
||||
container_name TEXT NOT NULL,
|
||||
image TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'created',
|
||||
namespace TEXT NOT NULL DEFAULT 'default',
|
||||
auto_start BOOLEAN NOT NULL DEFAULT true,
|
||||
host_path TEXT,
|
||||
container_path TEXT NOT NULL DEFAULT '/data',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
last_started_at TIMESTAMPTZ,
|
||||
last_stopped_at TIMESTAMPTZ,
|
||||
CONSTRAINT containers_container_id_unique UNIQUE (container_id),
|
||||
CONSTRAINT containers_container_name_unique UNIQUE (container_name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_containers_user_id ON containers(user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS snapshots (
|
||||
id TEXT PRIMARY KEY,
|
||||
container_id TEXT NOT NULL REFERENCES containers(container_id) ON DELETE CASCADE,
|
||||
parent_snapshot_id TEXT REFERENCES snapshots(id) ON DELETE SET NULL,
|
||||
snapshotter TEXT NOT NULL,
|
||||
digest TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_container_id ON snapshots(container_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_parent_id ON snapshots(parent_snapshot_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS llm_providers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
@@ -99,6 +66,203 @@ CREATE TABLE IF NOT EXISTS model_variants (
|
||||
CREATE INDEX IF NOT EXISTS idx_model_variants_model_uuid ON model_variants(model_uuid);
|
||||
CREATE INDEX IF NOT EXISTS idx_model_variants_variant_id ON model_variants(variant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
owner_user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
type TEXT NOT NULL,
|
||||
display_name TEXT,
|
||||
avatar_url TEXT,
|
||||
is_active BOOLEAN NOT NULL DEFAULT true,
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT bots_type_check CHECK (type IN ('personal', 'public'))
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_bots_owner_user_id ON bots(owner_user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bot_members (
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
role TEXT NOT NULL DEFAULT 'member',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT bot_members_role_check CHECK (role IN ('owner', 'admin', 'member')),
|
||||
CONSTRAINT bot_members_unique UNIQUE (bot_id, user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_bot_members_user_id ON bot_members(user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bot_settings (
|
||||
bot_id UUID PRIMARY KEY REFERENCES bots(id) ON DELETE CASCADE,
|
||||
max_context_load_time INTEGER NOT NULL DEFAULT 1440,
|
||||
language TEXT NOT NULL DEFAULT 'Same as user input',
|
||||
allow_guest BOOLEAN NOT NULL DEFAULT false
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bot_model_configs (
|
||||
bot_id UUID PRIMARY KEY REFERENCES bots(id) ON DELETE CASCADE,
|
||||
chat_model_id UUID REFERENCES models(id) ON DELETE SET NULL,
|
||||
embedding_model_id UUID REFERENCES models(id) ON DELETE SET NULL,
|
||||
memory_model_id UUID REFERENCES models(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS conversations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
session_id TEXT NOT NULL,
|
||||
channel_type TEXT NOT NULL,
|
||||
chat_id TEXT,
|
||||
sender_id TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT conversations_session_unique UNIQUE (bot_id, session_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_conversations_bot_id ON conversations(bot_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS history (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
session_id TEXT NOT NULL,
|
||||
messages JSONB NOT NULL,
|
||||
skills TEXT[] NOT NULL DEFAULT '{}'::text[],
|
||||
timestamp TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_history_bot ON history(bot_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_history_session ON history(session_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_history_timestamp ON history(timestamp);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_channel_bindings (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
channel_type TEXT NOT NULL,
|
||||
config JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT user_channel_bindings_unique UNIQUE (user_id, channel_type)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_user_channel_bindings_user_id ON user_channel_bindings(user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bot_channel_configs (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
channel_type TEXT NOT NULL,
|
||||
credentials JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
external_identity TEXT,
|
||||
self_identity JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
routing JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
capabilities JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
verified_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT bot_channel_status_check CHECK (status IN ('pending', 'verified', 'disabled')),
|
||||
CONSTRAINT bot_channel_unique UNIQUE (bot_id, channel_type)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_bot_channel_external_identity
|
||||
ON bot_channel_configs(channel_type, external_identity);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_bot_channel_bot_id ON bot_channel_configs(bot_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS contacts (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
display_name TEXT,
|
||||
alias TEXT,
|
||||
tags TEXT[] NOT NULL DEFAULT '{}'::text[],
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT contacts_status_check CHECK (status IN ('active', 'blocked', 'pending'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_contacts_bot_user_unique
|
||||
ON contacts(bot_id, user_id)
|
||||
WHERE user_id IS NOT NULL;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contacts_bot_id ON contacts(bot_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS contact_channels (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
platform TEXT NOT NULL,
|
||||
external_id TEXT NOT NULL,
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT contact_channels_unique UNIQUE (bot_id, platform, external_id)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_channels_contact_id ON contact_channels(contact_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_channels_platform_external ON contact_channels(platform, external_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS contact_bind_tokens (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
contact_id UUID NOT NULL REFERENCES contacts(id) ON DELETE CASCADE,
|
||||
token TEXT NOT NULL,
|
||||
target_platform TEXT,
|
||||
target_external_id TEXT,
|
||||
issued_by_user_id UUID REFERENCES users(id) ON DELETE SET NULL,
|
||||
expires_at TIMESTAMPTZ NOT NULL,
|
||||
used_at TIMESTAMPTZ,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
CONSTRAINT contact_bind_tokens_unique UNIQUE (token)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_bind_tokens_contact_id ON contact_bind_tokens(contact_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_contact_bind_tokens_expires ON contact_bind_tokens(expires_at);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS channel_sessions (
|
||||
session_id TEXT PRIMARY KEY,
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
channel_config_id UUID REFERENCES bot_channel_configs(id) ON DELETE SET NULL,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
contact_id UUID REFERENCES contacts(id) ON DELETE SET NULL,
|
||||
platform TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_channel_sessions_bot_id ON channel_sessions(bot_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_channel_sessions_user_id ON channel_sessions(user_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS containers (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
container_id TEXT NOT NULL,
|
||||
container_name TEXT NOT NULL,
|
||||
image TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'created',
|
||||
namespace TEXT NOT NULL DEFAULT 'default',
|
||||
auto_start BOOLEAN NOT NULL DEFAULT true,
|
||||
host_path TEXT,
|
||||
container_path TEXT NOT NULL DEFAULT '/data',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
last_started_at TIMESTAMPTZ,
|
||||
last_stopped_at TIMESTAMPTZ,
|
||||
CONSTRAINT containers_container_id_unique UNIQUE (container_id),
|
||||
CONSTRAINT containers_container_name_unique UNIQUE (container_name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_containers_bot_id ON containers(bot_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS snapshots (
|
||||
id TEXT PRIMARY KEY,
|
||||
container_id TEXT NOT NULL REFERENCES containers(container_id) ON DELETE CASCADE,
|
||||
parent_snapshot_id TEXT REFERENCES snapshots(id) ON DELETE SET NULL,
|
||||
snapshotter TEXT NOT NULL,
|
||||
digest TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_container_id ON snapshots(container_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_snapshots_parent_id ON snapshots(parent_snapshot_id);
|
||||
|
||||
@@ -124,26 +288,6 @@ CREATE TABLE IF NOT EXISTS lifecycle_events (
|
||||
CREATE INDEX IF NOT EXISTS idx_lifecycle_events_container_id ON lifecycle_events(container_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_lifecycle_events_event_type ON lifecycle_events(event_type);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS history (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
messages JSONB NOT NULL,
|
||||
skills TEXT[] NOT NULL DEFAULT '{}'::text[],
|
||||
timestamp TIMESTAMPTZ NOT NULL,
|
||||
"user" UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_history_user ON history("user");
|
||||
CREATE INDEX IF NOT EXISTS idx_history_timestamp ON history(timestamp);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_settings (
|
||||
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
chat_model_id TEXT,
|
||||
memory_model_id TEXT,
|
||||
embedding_model_id TEXT,
|
||||
max_context_load_time INTEGER NOT NULL DEFAULT 1440,
|
||||
language TEXT NOT NULL DEFAULT 'Same as user input'
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS schedule (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name TEXT NOT NULL,
|
||||
@@ -155,10 +299,10 @@ CREATE TABLE IF NOT EXISTS schedule (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
enabled BOOLEAN NOT NULL DEFAULT true,
|
||||
command TEXT NOT NULL,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_user_id ON schedule(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_bot_id ON schedule(bot_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_schedule_enabled ON schedule(enabled);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS subagents (
|
||||
@@ -169,12 +313,18 @@ CREATE TABLE IF NOT EXISTS subagents (
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
deleted BOOLEAN NOT NULL DEFAULT false,
|
||||
deleted_at TIMESTAMPTZ,
|
||||
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
|
||||
messages JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
skills JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
CONSTRAINT subagents_name_unique UNIQUE (name)
|
||||
CONSTRAINT subagents_name_unique UNIQUE (bot_id, name)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_subagents_user_id ON subagents(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_subagents_bot_id ON subagents(bot_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_subagents_deleted ON subagents(deleted);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_settings (
|
||||
user_id UUID PRIMARY KEY REFERENCES users(id) ON DELETE CASCADE,
|
||||
max_context_load_time INTEGER NOT NULL DEFAULT 1440,
|
||||
language TEXT NOT NULL DEFAULT 'Same as user input'
|
||||
);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
-- name: CreateBot :one
|
||||
INSERT INTO bots (owner_user_id, type, display_name, avatar_url, is_active, metadata)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING id, owner_user_id, type, display_name, avatar_url, is_active, metadata, created_at, updated_at;
|
||||
|
||||
-- name: GetBotByID :one
|
||||
SELECT id, owner_user_id, type, display_name, avatar_url, is_active, metadata, created_at, updated_at
|
||||
FROM bots
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: ListBotsByOwner :many
|
||||
SELECT id, owner_user_id, type, display_name, avatar_url, is_active, metadata, created_at, updated_at
|
||||
FROM bots
|
||||
WHERE owner_user_id = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: ListBotsByMember :many
|
||||
SELECT b.id, b.owner_user_id, b.type, b.display_name, b.avatar_url, b.is_active, b.metadata, b.created_at, b.updated_at
|
||||
FROM bots b
|
||||
JOIN bot_members m ON m.bot_id = b.id
|
||||
WHERE m.user_id = $1
|
||||
ORDER BY b.created_at DESC;
|
||||
|
||||
-- name: UpdateBotProfile :one
|
||||
UPDATE bots
|
||||
SET display_name = $2,
|
||||
avatar_url = $3,
|
||||
is_active = $4,
|
||||
metadata = $5,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, owner_user_id, type, display_name, avatar_url, is_active, metadata, created_at, updated_at;
|
||||
|
||||
-- name: UpdateBotOwner :one
|
||||
UPDATE bots
|
||||
SET owner_user_id = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, owner_user_id, type, display_name, avatar_url, is_active, metadata, created_at, updated_at;
|
||||
|
||||
-- name: DeleteBotByID :exec
|
||||
DELETE FROM bots WHERE id = $1;
|
||||
|
||||
-- name: UpsertBotMember :one
|
||||
INSERT INTO bot_members (bot_id, user_id, role)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (bot_id, user_id) DO UPDATE SET
|
||||
role = EXCLUDED.role
|
||||
RETURNING bot_id, user_id, role, created_at;
|
||||
|
||||
-- name: ListBotMembers :many
|
||||
SELECT bot_id, user_id, role, created_at
|
||||
FROM bot_members
|
||||
WHERE bot_id = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: GetBotMember :one
|
||||
SELECT bot_id, user_id, role, created_at
|
||||
FROM bot_members
|
||||
WHERE bot_id = $1 AND user_id = $2
|
||||
LIMIT 1;
|
||||
|
||||
-- name: DeleteBotMember :exec
|
||||
DELETE FROM bot_members WHERE bot_id = $1 AND user_id = $2;
|
||||
@@ -1,10 +1,10 @@
|
||||
-- name: UpsertContainer :exec
|
||||
INSERT INTO containers (
|
||||
user_id, container_id, container_name, image, status, namespace, auto_start,
|
||||
bot_id, container_id, container_name, image, status, namespace, auto_start,
|
||||
host_path, container_path, last_started_at, last_stopped_at
|
||||
)
|
||||
VALUES (
|
||||
sqlc.arg(user_id),
|
||||
sqlc.arg(bot_id),
|
||||
sqlc.arg(container_id),
|
||||
sqlc.arg(container_name),
|
||||
sqlc.arg(image),
|
||||
@@ -17,7 +17,7 @@ VALUES (
|
||||
sqlc.arg(last_stopped_at)
|
||||
)
|
||||
ON CONFLICT (container_id) DO UPDATE SET
|
||||
user_id = EXCLUDED.user_id,
|
||||
bot_id = EXCLUDED.bot_id,
|
||||
container_name = EXCLUDED.container_name,
|
||||
image = EXCLUDED.image,
|
||||
status = EXCLUDED.status,
|
||||
|
||||
+13
-13
@@ -1,31 +1,31 @@
|
||||
-- name: CreateHistory :one
|
||||
INSERT INTO history (messages, skills, timestamp, "user")
|
||||
VALUES ($1, $2, $3, $4)
|
||||
RETURNING id, messages, skills, timestamp, "user";
|
||||
INSERT INTO history (bot_id, session_id, messages, skills, timestamp)
|
||||
VALUES ($1, $2, $3, $4, $5)
|
||||
RETURNING id, bot_id, session_id, messages, skills, timestamp;
|
||||
|
||||
-- name: ListHistoryByUserSince :many
|
||||
SELECT id, messages, skills, timestamp, "user"
|
||||
-- name: ListHistoryByBotSessionSince :many
|
||||
SELECT id, bot_id, session_id, messages, skills, timestamp
|
||||
FROM history
|
||||
WHERE "user" = $1 AND timestamp >= $2
|
||||
WHERE bot_id = $1 AND session_id = $2 AND timestamp >= $3
|
||||
ORDER BY timestamp ASC;
|
||||
|
||||
-- name: GetHistoryByID :one
|
||||
SELECT id, messages, skills, timestamp, "user"
|
||||
SELECT id, bot_id, session_id, messages, skills, timestamp
|
||||
FROM history
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: ListHistoryByUser :many
|
||||
SELECT id, messages, skills, timestamp, "user"
|
||||
-- name: ListHistoryByBotSession :many
|
||||
SELECT id, bot_id, session_id, messages, skills, timestamp
|
||||
FROM history
|
||||
WHERE "user" = $1
|
||||
WHERE bot_id = $1 AND session_id = $2
|
||||
ORDER BY timestamp DESC
|
||||
LIMIT $2;
|
||||
LIMIT $3;
|
||||
|
||||
-- name: DeleteHistoryByID :exec
|
||||
DELETE FROM history
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: DeleteHistoryByUser :exec
|
||||
-- name: DeleteHistoryByBotSession :exec
|
||||
DELETE FROM history
|
||||
WHERE "user" = $1;
|
||||
WHERE bot_id = $1 AND session_id = $2;
|
||||
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
-- name: CreateSchedule :one
|
||||
INSERT INTO schedule (name, description, pattern, max_calls, enabled, command, user_id)
|
||||
INSERT INTO schedule (name, description, pattern, max_calls, enabled, command, bot_id)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id;
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id;
|
||||
|
||||
-- name: GetScheduleByID :one
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id
|
||||
FROM schedule
|
||||
WHERE id = $1;
|
||||
|
||||
-- name: ListSchedulesByUser :many
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id
|
||||
-- name: ListSchedulesByBot :many
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id
|
||||
FROM schedule
|
||||
WHERE user_id = $1
|
||||
WHERE bot_id = $1
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: ListEnabledSchedules :many
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id
|
||||
SELECT id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id
|
||||
FROM schedule
|
||||
WHERE enabled = true
|
||||
ORDER BY created_at DESC;
|
||||
@@ -30,7 +30,7 @@ SET name = $2,
|
||||
command = $7,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id;
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id;
|
||||
|
||||
-- name: DeleteSchedule :exec
|
||||
DELETE FROM schedule
|
||||
@@ -45,5 +45,5 @@ SET current_calls = current_calls + 1,
|
||||
END,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, user_id;
|
||||
RETURNING id, name, description, pattern, max_calls, current_calls, created_at, updated_at, enabled, command, bot_id;
|
||||
|
||||
|
||||
+18
-4
@@ -3,7 +3,7 @@ SELECT user_id, chat_model_id, memory_model_id, embedding_model_id, max_context_
|
||||
FROM user_settings
|
||||
WHERE user_id = $1;
|
||||
|
||||
-- name: UpsertSettings :one
|
||||
-- name: UpsertUserSettings :one
|
||||
INSERT INTO user_settings (user_id, chat_model_id, memory_model_id, embedding_model_id, max_context_load_time, language)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (user_id) DO UPDATE SET
|
||||
@@ -14,7 +14,21 @@ ON CONFLICT (user_id) DO UPDATE SET
|
||||
language = EXCLUDED.language
|
||||
RETURNING user_id, chat_model_id, memory_model_id, embedding_model_id, max_context_load_time, language;
|
||||
|
||||
-- name: DeleteSettingsByUserID :exec
|
||||
DELETE FROM user_settings
|
||||
WHERE user_id = $1;
|
||||
-- name: GetSettingsByBotID :one
|
||||
SELECT bot_id, max_context_load_time, language, allow_guest
|
||||
FROM bot_settings
|
||||
WHERE bot_id = $1;
|
||||
|
||||
-- name: UpsertBotSettings :one
|
||||
INSERT INTO bot_settings (bot_id, max_context_load_time, language, allow_guest)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (bot_id) DO UPDATE SET
|
||||
max_context_load_time = EXCLUDED.max_context_load_time,
|
||||
language = EXCLUDED.language,
|
||||
allow_guest = EXCLUDED.allow_guest
|
||||
RETURNING bot_id, max_context_load_time, language, allow_guest;
|
||||
|
||||
-- name: DeleteSettingsByBotID :exec
|
||||
DELETE FROM bot_settings
|
||||
WHERE bot_id = $1;
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
-- name: CreateSubagent :one
|
||||
INSERT INTO subagents (name, description, user_id, messages, metadata, skills)
|
||||
INSERT INTO subagents (name, description, bot_id, messages, metadata, skills)
|
||||
VALUES ($1, $2, $3, $4, $5, $6)
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills;
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills;
|
||||
|
||||
-- name: GetSubagentByID :one
|
||||
SELECT id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills
|
||||
SELECT id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills
|
||||
FROM subagents
|
||||
WHERE id = $1 AND deleted = false;
|
||||
|
||||
-- name: ListSubagentsByUser :many
|
||||
SELECT id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills
|
||||
-- name: ListSubagentsByBot :many
|
||||
SELECT id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills
|
||||
FROM subagents
|
||||
WHERE user_id = $1 AND deleted = false
|
||||
WHERE bot_id = $1 AND deleted = false
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
-- name: UpdateSubagent :one
|
||||
@@ -21,21 +21,21 @@ SET name = $2,
|
||||
metadata = $4,
|
||||
updated_at = now()
|
||||
WHERE id = $1 AND deleted = false
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills;
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills;
|
||||
|
||||
-- name: UpdateSubagentMessages :one
|
||||
UPDATE subagents
|
||||
SET messages = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1 AND deleted = false
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills;
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills;
|
||||
|
||||
-- name: UpdateSubagentSkills :one
|
||||
UPDATE subagents
|
||||
SET skills = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1 AND deleted = false
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, user_id, messages, metadata, skills;
|
||||
RETURNING id, name, description, created_at, updated_at, deleted, deleted_at, bot_id, messages, metadata, skills;
|
||||
|
||||
-- name: SoftDeleteSubagent :exec
|
||||
UPDATE subagents
|
||||
|
||||
+45
-3
@@ -4,7 +4,7 @@ VALUES (
|
||||
sqlc.arg(username),
|
||||
sqlc.arg(email),
|
||||
sqlc.arg(password_hash),
|
||||
sqlc.arg(role),
|
||||
sqlc.arg(role)::user_role,
|
||||
sqlc.arg(display_name),
|
||||
sqlc.arg(avatar_url),
|
||||
sqlc.arg(is_active),
|
||||
@@ -18,7 +18,7 @@ VALUES (
|
||||
sqlc.arg(username),
|
||||
sqlc.arg(email),
|
||||
sqlc.arg(password_hash),
|
||||
sqlc.arg(role),
|
||||
sqlc.arg(role)::user_role,
|
||||
sqlc.arg(display_name),
|
||||
sqlc.arg(avatar_url),
|
||||
sqlc.arg(is_active),
|
||||
@@ -38,6 +38,9 @@ RETURNING *;
|
||||
-- name: GetUserByUsername :one
|
||||
SELECT * FROM users WHERE username = sqlc.arg(username);
|
||||
|
||||
-- name: GetUserByIdentity :one
|
||||
SELECT * FROM users WHERE username = sqlc.arg(identity) OR email = sqlc.arg(identity);
|
||||
|
||||
-- name: GetUserByID :one
|
||||
SELECT * FROM users WHERE id = sqlc.arg(id);
|
||||
|
||||
@@ -48,7 +51,7 @@ VALUES (
|
||||
sqlc.arg(username),
|
||||
sqlc.arg(email),
|
||||
sqlc.arg(password_hash),
|
||||
sqlc.arg(role),
|
||||
sqlc.arg(role)::user_role,
|
||||
sqlc.arg(display_name),
|
||||
sqlc.arg(avatar_url),
|
||||
sqlc.arg(is_active),
|
||||
@@ -58,3 +61,42 @@ RETURNING *;
|
||||
|
||||
-- name: CountUsers :one
|
||||
SELECT COUNT(*)::bigint AS count FROM users;
|
||||
|
||||
-- name: ListUsers :many
|
||||
SELECT * FROM users
|
||||
ORDER BY created_at DESC;
|
||||
|
||||
|
||||
-- name: UpdateUserProfile :one
|
||||
UPDATE users
|
||||
SET display_name = $2,
|
||||
avatar_url = $3,
|
||||
is_active = $4,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateUserAdmin :one
|
||||
UPDATE users
|
||||
SET role = sqlc.arg(role)::user_role,
|
||||
display_name = sqlc.arg(display_name),
|
||||
avatar_url = sqlc.arg(avatar_url),
|
||||
is_active = sqlc.arg(is_active),
|
||||
updated_at = now()
|
||||
WHERE id = sqlc.arg(id)
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateUserPassword :one
|
||||
UPDATE users
|
||||
SET password_hash = $2,
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
-- name: UpdateUserLastLogin :one
|
||||
UPDATE users
|
||||
SET last_login_at = now(),
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user