Merge origin/main into mnemonic-ralphised

Resolved conflicts in:
- internal/config/config.go: Combined new bool fields with maintenance settings
- internal/db/gorm/models.go: Merged field reordering with archival fields
- internal/mcp/server.go: Merged field reordering with maintenanceService
- internal/search/manager.go: Updated Metadata field to use 'any' type
- internal/worker/handlers.go: Kept HEAD version
- internal/worker/sdk/processor.go: Combined circuit breaker/dedup with claude path
- internal/worker/service.go: Kept HEAD version
- ui/src/components/Sidebar.vue: Combined new components with useGraphMetrics
- ui/src/utils/api.ts: Combined new APIs with graph/vector metrics
This commit is contained in:
2026-01-11 01:02:25 +00:00
88 changed files with 5333 additions and 629 deletions
+9 -15
View File
@@ -43,21 +43,15 @@ type PatternSyncFunc func(pattern *models.Pattern)
// Detector detects and tracks recurring patterns across observations.
type Detector struct {
config DetectorConfig
ctx context.Context
patternStore *gorm.PatternStore
observationStore *gorm.ObservationStore
// Vector sync callback
syncFunc PatternSyncFunc
// Candidate tracking (patterns not yet confirmed)
candidates map[string]*candidatePattern
candidatesMu sync.RWMutex
// Background analysis
ctx context.Context
cancel context.CancelFunc
wg sync.WaitGroup
syncFunc PatternSyncFunc
candidates map[string]*candidatePattern
cancel context.CancelFunc
config DetectorConfig
wg sync.WaitGroup
candidatesMu sync.RWMutex
}
// SetSyncFunc sets the callback for syncing patterns to vector store.
@@ -67,11 +61,11 @@ func (d *Detector) SetSyncFunc(fn PatternSyncFunc) {
// candidatePattern tracks a potential pattern before it reaches frequency threshold.
type candidatePattern struct {
patternType models.PatternType
title string
signature []string
observationIDs []int64
projects []string
patternType models.PatternType
title string
lastSeenEpoch int64
}
+7 -7
View File
@@ -331,16 +331,16 @@ func TestDefaultConfig(t *testing.T) {
func TestGeneratePatternName(t *testing.T) {
tests := []struct {
patternType models.PatternType
signature []string
title string
wantPrefix string
signature []string
}{
{models.PatternTypeBug, []string{"nil", "error"}, "", "Bug Pattern:"},
{models.PatternTypeRefactor, []string{"extract"}, "", "Refactor Pattern:"},
{models.PatternTypeArchitecture, []string{"service"}, "", "Architecture Pattern:"},
{models.PatternTypeAntiPattern, []string{"god-class"}, "", "Anti-Pattern:"},
{models.PatternTypeBestPractice, []string{"testing"}, "", "Best Practice:"},
{models.PatternTypeBug, []string{}, "Short Title", "Short Title"}, // Use title directly
{patternType: models.PatternTypeBug, title: "", wantPrefix: "Bug Pattern:", signature: []string{"nil", "error"}},
{patternType: models.PatternTypeRefactor, title: "", wantPrefix: "Refactor Pattern:", signature: []string{"extract"}},
{patternType: models.PatternTypeArchitecture, title: "", wantPrefix: "Architecture Pattern:", signature: []string{"service"}},
{patternType: models.PatternTypeAntiPattern, title: "", wantPrefix: "Anti-Pattern:", signature: []string{"god-class"}},
{patternType: models.PatternTypeBestPractice, title: "", wantPrefix: "Best Practice:", signature: []string{"testing"}},
{patternType: models.PatternTypeBug, title: "Short Title", wantPrefix: "Short Title", signature: []string{}}, // Use title directly
}
for _, tt := range tests {