fix: reorganize struct fields and config parameters for consistency

- [x] Reorder Config struct fields alphabetically and by related functionality
- [x] Reorganize Observation model fields with archival fields grouped together
- [x] Reorder ObservationStore fields to group related members
- [x] Reorder Store struct fields with health check caching grouped
- [x] Reorganize HealthInfo and PoolMetrics struct field order
- [x] Reorder maintenance Service struct fields logically
- [x] Reorganize MCP server handler parameter structs alphabetically
- [x] Reorder pattern detector candidate tracking fields
- [x] Reorganize search Manager struct fields by functionality
- [x] Reorder vector Client struct fields with mutex protections grouped
- [x] Reorganize handler request/response struct fields
- [x] Update handlers_test.go to expect wrapped response format
- [x] Reorder middleware TokenAuth and rate limiter fields
- [x] Reorganize Service struct fields with grouped functionality
- [x] Fix RateLimiter field ordering for clarity
- [x] Reorder CircuitBreaker metrics fields
This commit is contained in:
2026-01-11 01:22:30 +00:00
parent c585ffd773
commit a270290023
18 changed files with 312 additions and 375 deletions
+7 -9
View File
@@ -53,16 +53,18 @@ type Observation struct {
Scope models.ObservationScope `gorm:"type:text;default:'project';check:scope IN ('project', 'global');index:idx_observations_scope;index:idx_observations_project_scope,priority:2"`
Type models.ObservationType `gorm:"type:text;check:type IN ('decision', 'bugfix', 'feature', 'refactor', 'discovery', 'change');index;not null"`
CreatedAt string `gorm:"not null"`
Title sql.NullString `gorm:"type:text"`
Facts models.JSONStringArray `gorm:"type:text"`
Narrative sql.NullString `gorm:"type:text"`
Concepts models.JSONStringArray `gorm:"type:text"`
FilesRead models.JSONStringArray `gorm:"type:text"`
FilesModified models.JSONStringArray `gorm:"type:text"`
Subtitle sql.NullString `gorm:"type:text"`
Facts models.JSONStringArray `gorm:"type:text"`
LastRetrievedAt sql.NullInt64 `gorm:"column:last_retrieved_at_epoch"`
PromptNumber sql.NullInt64
Title sql.NullString `gorm:"type:text"`
ArchivedReason sql.NullString
ScoreUpdatedAt sql.NullInt64 `gorm:"column:score_updated_at_epoch;index:idx_observations_score_updated"`
PromptNumber sql.NullInt64
ArchivedAt sql.NullInt64 `gorm:"column:archived_at_epoch"`
LastRetrievedAt sql.NullInt64 `gorm:"column:last_retrieved_at_epoch"`
ID int64 `gorm:"primaryKey;autoIncrement"`
ImportanceScore float64 `gorm:"type:real;default:1.0;index:idx_observations_importance,priority:1,sort:desc"`
UserFeedback int `gorm:"default:0"`
@@ -70,11 +72,7 @@ type Observation struct {
CreatedAtEpoch int64 `gorm:"index:idx_observations_created,sort:desc;index:idx_observations_project_created,priority:2,sort:desc;not null"`
DiscoveryTokens int64 `gorm:"default:0"`
IsSuperseded int `gorm:"default:0;index:idx_observations_superseded;index:idx_observations_active,priority:2"`
// Archival fields
IsArchived int `gorm:"default:0;index:idx_observations_archived;index:idx_observations_active,priority:1"`
ArchivedAt sql.NullInt64 `gorm:"column:archived_at_epoch"`
ArchivedReason sql.NullString
IsArchived int `gorm:"default:0;index:idx_observations_archived;index:idx_observations_active,priority:1"`
}
func (Observation) TableName() string { return "observations" }
+9 -11
View File
@@ -41,18 +41,16 @@ type CleanupFunc func(ctx context.Context, deletedIDs []int64)
// ObservationStore provides observation-related database operations using GORM.
type ObservationStore struct {
db *gorm.DB
rawDB *sql.DB
cleanupFunc CleanupFunc
conflictStore any // Placeholder for ConflictStore (Phase 4)
relationStore any // Placeholder for RelationStore (Phase 4)
// Cleanup queue for async observation cleanup with proper error handling
conflictStore any
relationStore any
db *gorm.DB
rawDB *sql.DB
cleanupFunc CleanupFunc
cleanupQueue chan string
stopCleanup chan struct{}
cleanupWg sync.WaitGroup
cleanupOnce sync.Once
cleanupStarted atomic.Bool // tracks if cleanup worker was started
stopCleanup chan struct{}
cleanupStarted atomic.Bool
}
// NewObservationStore creates a new observation store.
@@ -854,10 +852,10 @@ func (s *ObservationStore) GetArchivalStats(ctx context.Context, project string)
// Use a single query with conditional aggregation to get all stats at once.
// This is much faster than 4 separate queries (saves 3 round trips).
type statsResult struct {
OldestEpoch *int64
NewestEpoch *int64
TotalCount int64
ArchivedCount int64
OldestEpoch *int64 // Pointer to handle NULL
NewestEpoch *int64
}
var result statsResult
+20 -22
View File
@@ -19,15 +19,13 @@ import (
// Store represents the GORM database connection with sqlite-vec support.
type Store struct {
DB *gorm.DB
sqlDB *sql.DB // For FTS5 and sqlite-vec operations that require raw SQL
metrics *PoolMetrics
// Health check caching to reduce database load from frequent monitoring
healthCacheMu sync.RWMutex
cachedHealth *HealthInfo
healthCacheTime time.Time
healthCacheTTL time.Duration // Default: 5 seconds
DB *gorm.DB
sqlDB *sql.DB
metrics *PoolMetrics
cachedHealth *HealthInfo
healthCacheTTL time.Duration
healthCacheMu sync.RWMutex
}
// Config holds database configuration.
@@ -313,13 +311,13 @@ func (s *Store) performHealthCheck(ctx context.Context) *HealthInfo {
// HealthInfo contains database health check results.
type HealthInfo struct {
Status string `json:"status"` // healthy, degraded, unhealthy
Timestamp time.Time `json:"timestamp"`
QueryLatency time.Duration `json:"query_latency_ns"`
PoolStats PoolStats `json:"pool_stats"`
HistoricalMetrics MetricsSummary `json:"historical_metrics,omitempty"`
Status string `json:"status"`
Error string `json:"error,omitempty"`
Warning string `json:"warning,omitempty"`
HistoricalMetrics MetricsSummary `json:"historical_metrics,omitempty"`
PoolStats PoolStats `json:"pool_stats"`
QueryLatency time.Duration `json:"query_latency_ns"`
}
// PoolStats contains connection pool statistics.
@@ -345,16 +343,16 @@ const (
// PoolMetrics tracks historical connection pool metrics with a sliding window.
type PoolMetrics struct {
lastSampleTime time.Time
latencySamples []time.Duration
latencyIdx int
latencyCount int
totalQueries int64
totalWaitTime time.Duration
peakInUse int
peakWaitCount int64
windowSize int
mu sync.RWMutex
latencySamples []time.Duration // Circular buffer of latency samples
latencyIdx int // Current index in circular buffer
latencyCount int // Number of samples collected
totalQueries int64 // Total queries executed
totalWaitTime time.Duration // Cumulative wait time for connections
peakInUse int // Peak concurrent connections in use
peakWaitCount int64 // Peak wait count observed
lastSampleTime time.Time // Last time a sample was recorded
windowSize int // Size of sliding window
}
// NewPoolMetrics creates a new pool metrics collector with the given window size.
@@ -450,6 +448,7 @@ func (m *PoolMetrics) GetMetricsSummary() MetricsSummary {
// MetricsSummary contains aggregated pool metrics.
type MetricsSummary struct {
LastSampleTime time.Time `json:"last_sample_time"`
TotalQueries int64 `json:"total_queries"`
SampleCount int `json:"sample_count"`
AvgLatency time.Duration `json:"avg_latency_ns"`
@@ -459,7 +458,6 @@ type MetricsSummary struct {
PeakInUse int `json:"peak_in_use"`
PeakWaitCount int64 `json:"peak_wait_count"`
TotalWaitTime time.Duration `json:"total_wait_time_ns"`
LastSampleTime time.Time `json:"last_sample_time"`
}
// GetMetrics returns the current metrics without performing a health check.