mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-27 07:16:19 +09:00
refactor(core): restructure conversation, channel and message domains
- Rename chat module to conversation with flow-based architecture - Move channelidentities into channel/identities subpackage - Add channel/route for routing logic - Add message service with event hub - Add MCP providers: container, directory, schedule - Refactor Feishu/Telegram adapters with directory and stream support - Add platform management page and channel badges in web UI - Update database schema for conversations, messages and channel routes - Add @memoh/shared package for cross-package type definitions
This commit is contained in:
@@ -9,12 +9,12 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/robfig/cron/v3"
|
||||
|
||||
"github.com/memohai/memoh/internal/auth"
|
||||
"github.com/memohai/memoh/internal/db"
|
||||
"github.com/memohai/memoh/internal/db/sqlc"
|
||||
)
|
||||
|
||||
@@ -71,7 +71,7 @@ func (s *Service) Create(ctx context.Context, botID string, req CreateRequest) (
|
||||
if _, err := s.parser.Parse(req.Pattern); err != nil {
|
||||
return Schedule{}, fmt.Errorf("invalid cron pattern: %w", err)
|
||||
}
|
||||
pgBotID, err := parseUUID(botID)
|
||||
pgBotID, err := db.ParseUUID(botID)
|
||||
if err != nil {
|
||||
return Schedule{}, err
|
||||
}
|
||||
@@ -104,7 +104,7 @@ func (s *Service) Create(ctx context.Context, botID string, req CreateRequest) (
|
||||
}
|
||||
|
||||
func (s *Service) Get(ctx context.Context, id string) (Schedule, error) {
|
||||
pgID, err := parseUUID(id)
|
||||
pgID, err := db.ParseUUID(id)
|
||||
if err != nil {
|
||||
return Schedule{}, err
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func (s *Service) Get(ctx context.Context, id string) (Schedule, error) {
|
||||
}
|
||||
|
||||
func (s *Service) List(ctx context.Context, botID string) ([]Schedule, error) {
|
||||
pgBotID, err := parseUUID(botID)
|
||||
pgBotID, err := db.ParseUUID(botID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -135,7 +135,7 @@ func (s *Service) List(ctx context.Context, botID string) ([]Schedule, error) {
|
||||
}
|
||||
|
||||
func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (Schedule, error) {
|
||||
pgID, err := parseUUID(id)
|
||||
pgID, err := db.ParseUUID(id)
|
||||
if err != nil {
|
||||
return Schedule{}, err
|
||||
}
|
||||
@@ -191,7 +191,7 @@ func (s *Service) Update(ctx context.Context, id string, req UpdateRequest) (Sch
|
||||
}
|
||||
|
||||
func (s *Service) Delete(ctx context.Context, id string) error {
|
||||
pgID, err := parseUUID(id)
|
||||
pgID, err := db.ParseUUID(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -253,7 +253,7 @@ func (s *Service) runSchedule(ctx context.Context, schedule Schedule) error {
|
||||
|
||||
// resolveBotOwner returns the owner user ID for the given bot.
|
||||
func (s *Service) resolveBotOwner(ctx context.Context, botID string) (string, error) {
|
||||
pgBotID, err := parseUUID(botID)
|
||||
pgBotID, err := db.ParseUUID(botID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -261,7 +261,7 @@ func (s *Service) resolveBotOwner(ctx context.Context, botID string) (string, er
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get bot: %w", err)
|
||||
}
|
||||
ownerID := toUUIDString(bot.OwnerUserID)
|
||||
ownerID := bot.OwnerUserID.String()
|
||||
if ownerID == "" {
|
||||
return "", fmt.Errorf("bot owner not found")
|
||||
}
|
||||
@@ -281,7 +281,7 @@ func (s *Service) generateTriggerToken(userID string) (string, error) {
|
||||
}
|
||||
|
||||
func (s *Service) scheduleJob(schedule sqlc.Schedule) error {
|
||||
id := toUUIDString(schedule.ID)
|
||||
id := schedule.ID.String()
|
||||
if id == "" {
|
||||
return fmt.Errorf("schedule id missing")
|
||||
}
|
||||
@@ -299,7 +299,7 @@ func (s *Service) scheduleJob(schedule sqlc.Schedule) error {
|
||||
}
|
||||
|
||||
func (s *Service) rescheduleJob(schedule sqlc.Schedule) {
|
||||
id := toUUIDString(schedule.ID)
|
||||
id := schedule.ID.String()
|
||||
if id == "" {
|
||||
return
|
||||
}
|
||||
@@ -321,14 +321,14 @@ func (s *Service) removeJob(id string) {
|
||||
|
||||
func toSchedule(row sqlc.Schedule) Schedule {
|
||||
item := Schedule{
|
||||
ID: toUUIDString(row.ID),
|
||||
ID: row.ID.String(),
|
||||
Name: row.Name,
|
||||
Description: row.Description,
|
||||
Pattern: row.Pattern,
|
||||
CurrentCalls: int(row.CurrentCalls),
|
||||
Enabled: row.Enabled,
|
||||
Command: row.Command,
|
||||
BotID: toUUIDString(row.BotID),
|
||||
BotID: row.BotID.String(),
|
||||
}
|
||||
if row.MaxCalls.Valid {
|
||||
max := int(row.MaxCalls.Int32)
|
||||
@@ -343,32 +343,10 @@ func toSchedule(row sqlc.Schedule) Schedule {
|
||||
return item
|
||||
}
|
||||
|
||||
func parseUUID(id string) (pgtype.UUID, error) {
|
||||
parsed, err := uuid.Parse(strings.TrimSpace(id))
|
||||
if err != nil {
|
||||
return pgtype.UUID{}, fmt.Errorf("invalid UUID: %w", err)
|
||||
}
|
||||
var pgID pgtype.UUID
|
||||
pgID.Valid = true
|
||||
copy(pgID.Bytes[:], parsed[:])
|
||||
return pgID, nil
|
||||
}
|
||||
|
||||
func toUUID(id string) pgtype.UUID {
|
||||
pgID, err := parseUUID(id)
|
||||
pgID, err := db.ParseUUID(id)
|
||||
if err != nil {
|
||||
return pgtype.UUID{}
|
||||
}
|
||||
return pgID
|
||||
}
|
||||
|
||||
func toUUIDString(value pgtype.UUID) string {
|
||||
if !value.Valid {
|
||||
return ""
|
||||
}
|
||||
id, err := uuid.FromBytes(value.Bytes[:])
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return id.String()
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ type TriggerPayload struct {
|
||||
ChatID string
|
||||
}
|
||||
|
||||
// Triggerer 负责触发与聊天相关的调度执行。
|
||||
// Triggerer triggers schedule execution for chat-related jobs.
|
||||
type Triggerer interface {
|
||||
TriggerSchedule(ctx context.Context, botID string, payload TriggerPayload, token string) error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user