mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
bc374fe8cd
* refactor(attachment): multimodal attachment refactor with snapshot schema and storage layer - Add snapshot schema migration (0008) and update init/versions/snapshots - Add internal/attachment and internal/channel normalize for unified attachment handling - Move containerfs provider from internal/media to internal/storage - Update agent types, channel adapters (Telegram/Feishu), inbound and handlers - Add containerd snapshot lineage and local_channel tests - Regenerate sqlc, swagger and SDK * refactor(media): content-addressed asset system with unified naming - Replace asset_id foreign key with content_hash as sole identifier for bot_history_message_assets (pure soft-link model) - Remove mime, size_bytes, storage_key from DB; derive at read time via media.Resolve from actual storage - Merge migrations 0008/0009 into single 0008; keep 0001 as canonical schema - Add Docker initdb script for deterministic migration execution order - Fix cross-channel real-time image display (Telegram → WebUI SSE) - Fix message disappearing on refresh (null assets fallback) - Fix file icon instead of image preview (mime derivation from storage) - Unify AssetID → ContentHash naming across Go, Agent, and Frontend - Change storage key prefix from 4-char to 2-char for directory sharding - Add server-entrypoint.sh for Docker deployment migration handling * refactor(infra): embedded migrations, Docker simplification, and config consolidation - Embed SQL migrations into Go binary, removing shell-based migration scripts - Consolidate config files into conf/ directory (app.example.toml, app.docker.toml, app.dev.toml) - Simplify Docker setup: remove initdb.d scripts, streamline nginx config and entrypoint - Remove legacy CLI, feishu-echo commands, and obsolete incremental migration files - Update install script and docs to require sudo for one-click install - Add mise tasks for dev environment orchestration * chore: recover migrations --------- Co-authored-by: Acbox <acbox0328@gmail.com>
458 lines
13 KiB
Go
458 lines
13 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.30.0
|
|
// source: messages.sql
|
|
|
|
package sqlc
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
const createMessage = `-- name: CreateMessage :one
|
|
INSERT INTO bot_history_messages (
|
|
bot_id,
|
|
route_id,
|
|
sender_channel_identity_id,
|
|
sender_account_user_id,
|
|
channel_type,
|
|
source_message_id,
|
|
source_reply_to_message_id,
|
|
role,
|
|
content,
|
|
metadata,
|
|
usage
|
|
)
|
|
VALUES (
|
|
$1,
|
|
$2::uuid,
|
|
$3::uuid,
|
|
$4::uuid,
|
|
$5::text,
|
|
$6::text,
|
|
$7::text,
|
|
$8,
|
|
$9,
|
|
$10,
|
|
$11
|
|
)
|
|
RETURNING
|
|
id,
|
|
bot_id,
|
|
route_id,
|
|
sender_channel_identity_id,
|
|
sender_account_user_id AS sender_user_id,
|
|
channel_type AS platform,
|
|
source_message_id AS external_message_id,
|
|
source_reply_to_message_id,
|
|
role,
|
|
content,
|
|
metadata,
|
|
usage,
|
|
created_at
|
|
`
|
|
|
|
type CreateMessageParams struct {
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
}
|
|
|
|
type CreateMessageRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (CreateMessageRow, error) {
|
|
row := q.db.QueryRow(ctx, createMessage,
|
|
arg.BotID,
|
|
arg.RouteID,
|
|
arg.SenderChannelIdentityID,
|
|
arg.SenderUserID,
|
|
arg.Platform,
|
|
arg.ExternalMessageID,
|
|
arg.SourceReplyToMessageID,
|
|
arg.Role,
|
|
arg.Content,
|
|
arg.Metadata,
|
|
arg.Usage,
|
|
)
|
|
var i CreateMessageRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.BotID,
|
|
&i.RouteID,
|
|
&i.SenderChannelIdentityID,
|
|
&i.SenderUserID,
|
|
&i.Platform,
|
|
&i.ExternalMessageID,
|
|
&i.SourceReplyToMessageID,
|
|
&i.Role,
|
|
&i.Content,
|
|
&i.Metadata,
|
|
&i.Usage,
|
|
&i.CreatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const deleteMessagesByBot = `-- name: DeleteMessagesByBot :exec
|
|
DELETE FROM bot_history_messages
|
|
WHERE bot_id = $1
|
|
`
|
|
|
|
func (q *Queries) DeleteMessagesByBot(ctx context.Context, botID pgtype.UUID) error {
|
|
_, err := q.db.Exec(ctx, deleteMessagesByBot, botID)
|
|
return err
|
|
}
|
|
|
|
const listMessages = `-- name: ListMessages :many
|
|
SELECT
|
|
m.id,
|
|
m.bot_id,
|
|
m.route_id,
|
|
m.sender_channel_identity_id,
|
|
COALESCE(ci.user_id, m.sender_account_user_id) AS sender_user_id,
|
|
m.channel_type AS platform,
|
|
m.source_message_id AS external_message_id,
|
|
m.source_reply_to_message_id,
|
|
m.role,
|
|
m.content,
|
|
m.metadata,
|
|
m.usage,
|
|
m.created_at,
|
|
ci.display_name AS sender_display_name,
|
|
ci.avatar_url AS sender_avatar_url
|
|
FROM bot_history_messages m
|
|
LEFT JOIN channel_identities ci ON ci.id = m.sender_channel_identity_id
|
|
WHERE m.bot_id = $1
|
|
ORDER BY m.created_at ASC
|
|
LIMIT 10000
|
|
`
|
|
|
|
type ListMessagesRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
SenderDisplayName pgtype.Text `json:"sender_display_name"`
|
|
SenderAvatarUrl pgtype.Text `json:"sender_avatar_url"`
|
|
}
|
|
|
|
func (q *Queries) ListMessages(ctx context.Context, botID pgtype.UUID) ([]ListMessagesRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessages, botID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListMessagesRow
|
|
for rows.Next() {
|
|
var i ListMessagesRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.BotID,
|
|
&i.RouteID,
|
|
&i.SenderChannelIdentityID,
|
|
&i.SenderUserID,
|
|
&i.Platform,
|
|
&i.ExternalMessageID,
|
|
&i.SourceReplyToMessageID,
|
|
&i.Role,
|
|
&i.Content,
|
|
&i.Metadata,
|
|
&i.Usage,
|
|
&i.CreatedAt,
|
|
&i.SenderDisplayName,
|
|
&i.SenderAvatarUrl,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessagesBefore = `-- name: ListMessagesBefore :many
|
|
SELECT
|
|
m.id,
|
|
m.bot_id,
|
|
m.route_id,
|
|
m.sender_channel_identity_id,
|
|
COALESCE(ci.user_id, m.sender_account_user_id) AS sender_user_id,
|
|
m.channel_type AS platform,
|
|
m.source_message_id AS external_message_id,
|
|
m.source_reply_to_message_id,
|
|
m.role,
|
|
m.content,
|
|
m.metadata,
|
|
m.usage,
|
|
m.created_at,
|
|
ci.display_name AS sender_display_name,
|
|
ci.avatar_url AS sender_avatar_url
|
|
FROM bot_history_messages m
|
|
LEFT JOIN channel_identities ci ON ci.id = m.sender_channel_identity_id
|
|
WHERE m.bot_id = $1
|
|
AND m.created_at < $2
|
|
ORDER BY m.created_at DESC
|
|
LIMIT $3
|
|
`
|
|
|
|
type ListMessagesBeforeParams struct {
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
MaxCount int32 `json:"max_count"`
|
|
}
|
|
|
|
type ListMessagesBeforeRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
SenderDisplayName pgtype.Text `json:"sender_display_name"`
|
|
SenderAvatarUrl pgtype.Text `json:"sender_avatar_url"`
|
|
}
|
|
|
|
func (q *Queries) ListMessagesBefore(ctx context.Context, arg ListMessagesBeforeParams) ([]ListMessagesBeforeRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessagesBefore, arg.BotID, arg.CreatedAt, arg.MaxCount)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListMessagesBeforeRow
|
|
for rows.Next() {
|
|
var i ListMessagesBeforeRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.BotID,
|
|
&i.RouteID,
|
|
&i.SenderChannelIdentityID,
|
|
&i.SenderUserID,
|
|
&i.Platform,
|
|
&i.ExternalMessageID,
|
|
&i.SourceReplyToMessageID,
|
|
&i.Role,
|
|
&i.Content,
|
|
&i.Metadata,
|
|
&i.Usage,
|
|
&i.CreatedAt,
|
|
&i.SenderDisplayName,
|
|
&i.SenderAvatarUrl,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessagesLatest = `-- name: ListMessagesLatest :many
|
|
SELECT
|
|
m.id,
|
|
m.bot_id,
|
|
m.route_id,
|
|
m.sender_channel_identity_id,
|
|
COALESCE(ci.user_id, m.sender_account_user_id) AS sender_user_id,
|
|
m.channel_type AS platform,
|
|
m.source_message_id AS external_message_id,
|
|
m.source_reply_to_message_id,
|
|
m.role,
|
|
m.content,
|
|
m.metadata,
|
|
m.usage,
|
|
m.created_at,
|
|
ci.display_name AS sender_display_name,
|
|
ci.avatar_url AS sender_avatar_url
|
|
FROM bot_history_messages m
|
|
LEFT JOIN channel_identities ci ON ci.id = m.sender_channel_identity_id
|
|
WHERE m.bot_id = $1
|
|
ORDER BY m.created_at DESC
|
|
LIMIT $2
|
|
`
|
|
|
|
type ListMessagesLatestParams struct {
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
MaxCount int32 `json:"max_count"`
|
|
}
|
|
|
|
type ListMessagesLatestRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
SenderDisplayName pgtype.Text `json:"sender_display_name"`
|
|
SenderAvatarUrl pgtype.Text `json:"sender_avatar_url"`
|
|
}
|
|
|
|
func (q *Queries) ListMessagesLatest(ctx context.Context, arg ListMessagesLatestParams) ([]ListMessagesLatestRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessagesLatest, arg.BotID, arg.MaxCount)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListMessagesLatestRow
|
|
for rows.Next() {
|
|
var i ListMessagesLatestRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.BotID,
|
|
&i.RouteID,
|
|
&i.SenderChannelIdentityID,
|
|
&i.SenderUserID,
|
|
&i.Platform,
|
|
&i.ExternalMessageID,
|
|
&i.SourceReplyToMessageID,
|
|
&i.Role,
|
|
&i.Content,
|
|
&i.Metadata,
|
|
&i.Usage,
|
|
&i.CreatedAt,
|
|
&i.SenderDisplayName,
|
|
&i.SenderAvatarUrl,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listMessagesSince = `-- name: ListMessagesSince :many
|
|
SELECT
|
|
m.id,
|
|
m.bot_id,
|
|
m.route_id,
|
|
m.sender_channel_identity_id,
|
|
COALESCE(ci.user_id, m.sender_account_user_id) AS sender_user_id,
|
|
m.channel_type AS platform,
|
|
m.source_message_id AS external_message_id,
|
|
m.source_reply_to_message_id,
|
|
m.role,
|
|
m.content,
|
|
m.metadata,
|
|
m.usage,
|
|
m.created_at,
|
|
ci.display_name AS sender_display_name,
|
|
ci.avatar_url AS sender_avatar_url
|
|
FROM bot_history_messages m
|
|
LEFT JOIN channel_identities ci ON ci.id = m.sender_channel_identity_id
|
|
WHERE m.bot_id = $1
|
|
AND m.created_at >= $2
|
|
ORDER BY m.created_at ASC
|
|
`
|
|
|
|
type ListMessagesSinceParams struct {
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
}
|
|
|
|
type ListMessagesSinceRow struct {
|
|
ID pgtype.UUID `json:"id"`
|
|
BotID pgtype.UUID `json:"bot_id"`
|
|
RouteID pgtype.UUID `json:"route_id"`
|
|
SenderChannelIdentityID pgtype.UUID `json:"sender_channel_identity_id"`
|
|
SenderUserID pgtype.UUID `json:"sender_user_id"`
|
|
Platform pgtype.Text `json:"platform"`
|
|
ExternalMessageID pgtype.Text `json:"external_message_id"`
|
|
SourceReplyToMessageID pgtype.Text `json:"source_reply_to_message_id"`
|
|
Role string `json:"role"`
|
|
Content []byte `json:"content"`
|
|
Metadata []byte `json:"metadata"`
|
|
Usage []byte `json:"usage"`
|
|
CreatedAt pgtype.Timestamptz `json:"created_at"`
|
|
SenderDisplayName pgtype.Text `json:"sender_display_name"`
|
|
SenderAvatarUrl pgtype.Text `json:"sender_avatar_url"`
|
|
}
|
|
|
|
func (q *Queries) ListMessagesSince(ctx context.Context, arg ListMessagesSinceParams) ([]ListMessagesSinceRow, error) {
|
|
rows, err := q.db.Query(ctx, listMessagesSince, arg.BotID, arg.CreatedAt)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
var items []ListMessagesSinceRow
|
|
for rows.Next() {
|
|
var i ListMessagesSinceRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.BotID,
|
|
&i.RouteID,
|
|
&i.SenderChannelIdentityID,
|
|
&i.SenderUserID,
|
|
&i.Platform,
|
|
&i.ExternalMessageID,
|
|
&i.SourceReplyToMessageID,
|
|
&i.Role,
|
|
&i.Content,
|
|
&i.Metadata,
|
|
&i.Usage,
|
|
&i.CreatedAt,
|
|
&i.SenderDisplayName,
|
|
&i.SenderAvatarUrl,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|