Files
ai_site/platform/internal/dbsync/ensure_default_channel.go
whm cb76824e94 fix: start system default sync channels by default
Create and restart paths enable IsSystemDefault channels; SyncPage auto-starts after save.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 17:50:27 +08:00

129 lines
3.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package dbsync
import (
"fmt"
"path/filepath"
"strings"
)
// DefaultChannelOpts 创建公司默认同步通道Z12c
type DefaultChannelOpts struct {
TenantID int64
AgentID int64
Name string
RemoteDriver Driver
RemoteDSN string
OnlineDBID string // 空则用 channel id
DatabaseName string
}
// FindSystemDefaultChannel 返回该公司 IsSystemDefault 通道(若有多条取最新启用的)。
func (s *FileStore) FindSystemDefaultChannel(tenantID int64) (*Channel, error) {
s.mu.Lock()
defer s.mu.Unlock()
list, err := s.readChannels()
if err != nil {
return nil, err
}
var best *Channel
for i := range list {
ch := list[i]
if ch.TenantID != tenantID || !ch.IsSystemDefault {
continue
}
cp := ch
if best == nil || cp.UpdatedAt.After(best.UpdatedAt) {
best = &cp
}
}
return best, nil
}
// EnsureSystemDefaultChannel 若无默认同步通道则创建;返回通道(已存在则复用)。
func (s *FileStore) EnsureSystemDefaultChannel(opts DefaultChannelOpts) (Channel, error) {
if opts.TenantID <= 0 {
return Channel{}, fmt.Errorf("tenant_id required")
}
if existing, err := s.FindSystemDefaultChannel(opts.TenantID); err == nil && existing != nil {
ch := *existing
if opts.AgentID > 0 && ch.AgentID == 0 {
ch.AgentID = opts.AgentID
saved, err := s.SaveChannel(ch)
if err != nil {
return Channel{}, err
}
return saved, nil
}
return ch, nil
}
driver := opts.RemoteDriver
if driver == "" {
driver = DriverPostgres
}
dsn := strings.TrimSpace(opts.RemoteDSN)
if dsn == "" {
driver = DriverSQLite
dsn = filepath.ToSlash(filepath.Join(".", "data", "dbsync", fmt.Sprintf("tenant_%d_online.db", opts.TenantID)))
dsn = "file:" + dsn + "?_pragma=busy_timeout(5000)"
}
name := strings.TrimSpace(opts.Name)
if name == "" {
name = fmt.Sprintf("公司默认同步 #%d", opts.TenantID)
}
ch := Channel{
TenantID: opts.TenantID,
Name: name,
Enabled: true, // 默认运行中:可收 agent push并预热 remote
Direction: DirLocalToRemote,
ConflictPolicy: PolicyLWWSource,
IsSystemDefault: true,
AgentID: opts.AgentID,
Local: Endpoint{
Driver: DriverSQLite,
DSN: "file:./data/dbsync/local_placeholder.db?_pragma=busy_timeout(5000)",
Tables: nil,
},
Remote: Endpoint{
Driver: driver,
DSN: dsn,
Tables: nil,
},
PKColumns: map[string]string{},
}
if err := ValidateChannelConfig(&ch); err != nil {
return Channel{}, err
}
saved, err := s.SaveChannel(ch)
if err != nil {
return Channel{}, err
}
return saved, nil
}
// ResolveOnlineDBID 默认 online_db_id优先显式值否则通道 id。
func ResolveOnlineDBID(explicit, channelID string) string {
if s := strings.TrimSpace(explicit); s != "" {
return s
}
return strings.TrimSpace(channelID)
}
// EnsureAndStartSystemDefaultChannel 创建/复用公司默认同步通道并确保处于运行中Enabled + runner
func (m *Manager) EnsureAndStartSystemDefaultChannel(opts DefaultChannelOpts) (Channel, error) {
if m == nil || m.store == nil {
return Channel{}, fmt.Errorf("dbsync not enabled")
}
ch, err := m.store.EnsureSystemDefaultChannel(opts)
if err != nil {
return Channel{}, err
}
if err := m.StartChannel(ch.ID); err != nil {
return ch, fmt.Errorf("start default channel: %w", err)
}
if updated, err := m.store.GetChannel(ch.ID); err == nil {
return *updated, nil
}
ch.Enabled = true
return ch, nil
}