refactor: inbox (#137)

* refactor: inbox

* fix: migrations

* fix: migrations
This commit is contained in:
Acbox Liu
2026-02-26 20:16:02 +08:00
committed by GitHub
parent d2878d841b
commit fe10abf3fc
21 changed files with 404 additions and 62 deletions
+4 -2
View File
@@ -399,12 +399,14 @@ CREATE TABLE IF NOT EXISTS bot_history_message_assets (
CREATE INDEX IF NOT EXISTS idx_message_assets_message_id ON bot_history_message_assets(message_id);
-- bot_inbox: per-bot message inbox for non-mentioned group messages, emails, etc.
-- bot_inbox: per-bot message inbox for channel messages, notifications, etc.
CREATE TABLE IF NOT EXISTS bot_inbox (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
bot_id UUID NOT NULL REFERENCES bots(id) ON DELETE CASCADE,
source TEXT NOT NULL DEFAULT '',
content JSONB NOT NULL DEFAULT '{}'::jsonb,
header JSONB NOT NULL DEFAULT '{}'::jsonb,
content TEXT NOT NULL DEFAULT '',
action TEXT NOT NULL DEFAULT 'notify',
is_read BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
read_at TIMESTAMPTZ
@@ -0,0 +1,11 @@
-- 0018_inbox_refactor (down)
-- Revert bot_inbox to original schema: merge header+content back into content JSONB.
-- 1. Convert content back to JSONB, merging header and text.
ALTER TABLE bot_inbox ALTER COLUMN content DROP DEFAULT;
ALTER TABLE bot_inbox ALTER COLUMN content TYPE JSONB USING (COALESCE(header, '{}'::jsonb) || jsonb_build_object('text', content));
ALTER TABLE bot_inbox ALTER COLUMN content SET DEFAULT '{}'::jsonb;
-- 2. Drop added columns.
ALTER TABLE bot_inbox DROP COLUMN IF EXISTS action;
ALTER TABLE bot_inbox DROP COLUMN IF EXISTS header;
+27
View File
@@ -0,0 +1,27 @@
-- 0018_inbox_refactor
-- Refactor bot_inbox: split content JSONB into content TEXT + header JSONB, add action column.
-- 1. Add new columns (idempotent).
ALTER TABLE bot_inbox ADD COLUMN IF NOT EXISTS header JSONB NOT NULL DEFAULT '{}'::jsonb;
ALTER TABLE bot_inbox ADD COLUMN IF NOT EXISTS action TEXT NOT NULL DEFAULT 'notify';
-- 2. Migrate data and convert column type.
-- Only needed when content is still JSONB (upgrade path).
-- On a fresh DB (0001_init already defines content as TEXT), this is a no-op.
DO $$
BEGIN
IF EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_name = 'bot_inbox' AND column_name = 'content' AND data_type = 'jsonb'
) THEN
UPDATE bot_inbox
SET header = content - 'text',
action = 'notify'
WHERE content IS NOT NULL AND content::text <> '{}';
ALTER TABLE bot_inbox ALTER COLUMN content DROP DEFAULT;
ALTER TABLE bot_inbox ALTER COLUMN content TYPE TEXT USING COALESCE(content ->> 'text', '');
ALTER TABLE bot_inbox ALTER COLUMN content SET DEFAULT '';
END IF;
END
$$;
+3 -3
View File
@@ -1,6 +1,6 @@
-- name: CreateInboxItem :one
INSERT INTO bot_inbox (bot_id, source, content)
VALUES (sqlc.arg(bot_id), sqlc.arg(source), sqlc.arg(content))
INSERT INTO bot_inbox (bot_id, source, header, content, action)
VALUES (sqlc.arg(bot_id), sqlc.arg(source), sqlc.arg(header), sqlc.arg(content), sqlc.arg(action))
RETURNING *;
-- name: GetInboxItemByID :one
@@ -35,7 +35,7 @@ WHERE bot_id = sqlc.arg(bot_id)
-- name: SearchInboxItems :many
SELECT * FROM bot_inbox
WHERE bot_id = sqlc.arg(bot_id)
AND content::text ILIKE '%' || sqlc.arg(query) || '%'
AND content ILIKE '%' || sqlc.arg(query) || '%'
AND (sqlc.narg(start_time)::timestamptz IS NULL OR created_at >= sqlc.narg(start_time)::timestamptz)
AND (sqlc.narg(end_time)::timestamptz IS NULL OR created_at <= sqlc.narg(end_time)::timestamptz)
AND (sqlc.narg(include_read)::boolean IS NULL OR sqlc.narg(include_read)::boolean = TRUE OR is_read = FALSE)