Files

28 KiB

RedFlag Duplication Cleanup Implementation Plan

Date: 2025-11-10 Version: v0.1.23.4 → v0.1.24 Author: GLM-4.6 Status: Ready for Implementation


Executive Summary

This plan provides a systematic approach to eliminate the 30-40% code redundancy identified in the RedFlag codebase. The cleanup is organized by risk level and dependency order to ensure system stability while reducing maintenance burden.

Target Impact:

  • Code reduction: ~4,650 duplicate lines removed
  • File consolidation: 20+ files → 8-10 core files
  • Maintenance complexity: 60% reduction
  • Risk mitigation: Eliminate inconsistencies between duplicate implementations

Phase 1: Critical Cleanup (Week 1) - Low Risk, High Impact

1.1 Backup File Removal - Immediate Win

Files to Remove:

aggregator-server/internal/api/handlers/downloads.go.backup.current
aggregator-server/internal/api/handlers/downloads.go.backup2
aggregator-server/temp_downloads.go

Implementation Steps:

# Verify active downloads.go is correct version
git diff HEAD -- aggregator-server/internal/api/handlers/downloads.go

# Remove backup files
rm aggregator-server/internal/api/handlers/downloads.go.backup.current
rm aggregator-server/internal/api/handlers/downloads.go.backup2
rm aggregator-server/temp_downloads.go

# Commit cleanup
git add -A
git commit -m "cleanup: remove duplicate download handler backup files"

Risk Level: Very Low

  • Backup files not referenced in code
  • Active downloads.go confirmed working
  • Rollback trivial with git

Impact: 2,200+ lines removed instantly

1.2 Legacy Scanner Function Removal

Target: aggregator-agent/cmd/agent/main.go:985-1153

Analysis Required Before Removal:

// Check if handleScanUpdates is still referenced
grep -r "handleScanUpdates" aggregator-agent/cmd/

// Verify command routing uses new system
# main.go:864-882 should route to handleScanUpdatesV2

Removal Steps:

// Remove entire function (lines 985-1153)
// Confirm new subsystem scanners are properly registered
// Test that all scanner subsystems work correctly

Verification Tests:

  1. Storage scanner → calls ReportMetrics()
  2. System scanner → calls ReportMetrics()
  3. Package scanners (APT, DNF, Docker) → call ReportUpdates()
  4. No routing to old handleScanUpdates

Risk Level: Low

  • Function not in command routing
  • New subsystem architecture active
  • Easy rollback if issues found

1.3 AgentSetupRequest Struct Consolidation

Current Duplicates Found In:

  • agent_setup.go
  • build_orchestrator.go
  • agent_builder.go

Consolidation Strategy:

// Create: aggregator-server/internal/services/types.go
package services

type AgentSetupRequest struct {
    AgentID     string `json:"agent_id" binding:"required"`
    Version     string `json:"version" binding:"required"`
    Platform    string `json:"platform" binding:"required"`
    MachineID   string `json:"machine_id" binding:"required"`
    ConfigJSON  string `json:"config_json,omitempty"`
    CallbackURL string `json:"callback_url,omitempty"`

    // Security fields
    ServerPublicKey string `json:"server_public_key,omitempty"`
    SigningRequired bool   `json:"signing_required"`

    // Build options
    ForceRebuild bool `json:"force_rebuild,omitempty"`
    SkipCache    bool `json:"skip_cache,omitempty"`

    // Metadata
    CreatedBy string `json:"created_by,omitempty"`
    CreatedAt time.Time `json:"created_at,omitempty"`
}

// Add validation method
func (r *AgentSetupRequest) Validate() error {
    if r.AgentID == "" {
        return fmt.Errorf("agent_id is required")
    }
    if r.Version == "" {
        return fmt.Errorf("version is required")
    }
    if r.Platform == "" {
        return fmt.Errorf("platform is required")
    }
    // ... additional validation
    return nil
}

Migration Steps:

  1. Create shared types.go with consolidated struct
  2. Update imports in all handler files
  3. Remove duplicate struct definitions
  4. Add comprehensive validation
  5. Update tests to use shared struct

Risk Level: Low

  • Struct changes are backward compatible
  • Validation addition improves security
  • Easy to test and verify

Phase 2: Build System Unification (Week 2) - Medium Risk, High Impact

2.1 Build Handler Consolidation Strategy

Current Handlers Analysis:

Handler Current Location Primary Responsibility Duplicated Logic
SetupAgent agent_setup.go New agent registration Configuration building
NewAgentBuild build_orchestrator.go Build artifacts for new agents File generation
UpgradeAgentBuild build_orchestrator.go Build artifacts for upgrades Artifact management
BuildAgent agent_build.go Generic build operations Common build logic

Proposed Unified Architecture:

aggregator-server/internal/services/
├── agent_manager.go (NEW - unified handler)
├── build_service.go (consolidated build logic)
├── config_service.go (consolidated configuration)
└── artifact_service.go (consolidated artifact management)

2.2 Create Unified AgentManager

New File: aggregator-server/internal/services/agent_manager.go

package services

import (
    "fmt"
    "github.com/google/uuid"
    "github.com/gin-gonic/gin"
)

type AgentManager struct {
    buildService   *BuildService
    configService  *ConfigService
    artifactService *ArtifactService
    db            *sqlx.DB
    logger        *log.Logger
}

type AgentOperation struct {
    Type      string // "new" | "upgrade" | "rebuild"
    AgentID   string
    Version   string
    Platform  string
    Config    *AgentConfiguration
    Requester string
}

func NewAgentManager(db *sqlx.DB, logger *log.Logger) *AgentManager {
    return &AgentManager{
        buildService:    NewBuildService(db, logger),
        configService:   NewConfigService(db, logger),
        artifactService: NewArtifactService(db, logger),
        db:             db,
        logger:         logger,
    }
}

// Unified handler for all agent operations
func (am *AgentManager) ProcessAgentOperation(c *gin.Context, op *AgentOperation) (*AgentSetupResponse, error) {
    // Step 1: Validate operation
    if err := op.Validate(); err != nil {
        return nil, fmt.Errorf("operation validation failed: %w", err)
    }

    // Step 2: Generate configuration
    config, err := am.configService.GenerateConfiguration(op)
    if err != nil {
        return nil, fmt.Errorf("config generation failed: %w", err)
    }

    // Step 3: Check if build needed
    needBuild, err := am.buildService.IsBuildRequired(op)
    if err != nil {
        return nil, fmt.Errorf("build check failed: %w", err)
    }

    var artifacts *BuildArtifacts
    if needBuild {
        // Step 4: Build artifacts
        artifacts, err = am.buildService.BuildAgentArtifacts(op, config)
        if err != nil {
            return nil, fmt.Errorf("build failed: %w", err)
        }

        // Step 5: Store artifacts
        err = am.artifactService.StoreArtifacts(artifacts)
        if err != nil {
            return nil, fmt.Errorf("artifact storage failed: %w", err)
        }
    } else {
        // Step 4b: Use existing artifacts
        artifacts, err = am.artifactService.GetExistingArtifacts(op.Version, op.Platform)
        if err != nil {
            return nil, fmt.Errorf("existing artifacts not found: %w", err)
        }
    }

    // Step 6: Setup agent registration
    err = am.setupAgentRegistration(op, config)
    if err != nil {
        return nil, fmt.Errorf("agent setup failed: %w", err)
    }

    // Step 7: Return unified response
    return &AgentSetupResponse{
        AgentID:      op.AgentID,
        ConfigURL:    fmt.Sprintf("/api/v1/config/%s", op.AgentID),
        BinaryURL:    fmt.Sprintf("/api/v1/downloads/%s?version=%s", op.Platform, op.Version),
        Signature:    artifacts.Signature,
        Version:      op.Version,
        Platform:     op.Platform,
        NextSteps:    am.generateNextSteps(op.Type, op.Platform),
        CreatedAt:    time.Now(),
    }, nil
}

func (op *AgentOperation) Validate() error {
    switch op.Type {
    case "new":
        return op.ValidateNewAgent()
    case "upgrade":
        return op.ValidateUpgrade()
    case "rebuild":
        return op.ValidateRebuild()
    default:
        return fmt.Errorf("unknown operation type: %s", op.Type)
    }
}

2.3 Consolidate BuildService

New File: aggregator-server/internal/services/build_service.go

package services

type BuildService struct {
    signingService *SigningService
    db            *sqlx.DB
    logger        *log.Logger
}

func (bs *BuildService) IsBuildRequired(op *AgentOperation) (bool, error) {
    // Check if signed binary exists for version/platform
    query := `SELECT id FROM agent_update_packages
              WHERE version = $1 AND platform = $2 AND agent_id IS NULL`

    var id string
    err := bs.db.Get(&id, query, op.Version, op.Platform)
    if err == sql.ErrNoRows {
        return true, nil
    }
    if err != nil {
        return false, err
    }

    // Check if rebuild forced
    if op.Config.ForceRebuild {
        return true, nil
    }

    return false, nil
}

func (bs *BuildService) BuildAgentArtifacts(op *AgentOperation, config *AgentConfiguration) (*BuildArtifacts, error) {
    // Step 1: Copy generic binary
    genericPath := fmt.Sprintf("/app/binaries/%s/redflag-agent", op.Platform)
    tempPath := fmt.Sprintf("/tmp/agent-build-%s/redflag-agent", op.AgentID)

    if err := copyFile(genericPath, tempPath); err != nil {
        return nil, fmt.Errorf("binary copy failed: %w", err)
    }

    // Step 2: Sign binary (per-version, not per-agent)
    signature, err := bs.signingService.SignFile(tempPath)
    if err != nil {
        return nil, fmt.Errorf("signing failed: %w", err)
    }

    // Step 3: Generate config separately (not embedded)
    configJSON, err := json.Marshal(config)
    if err != nil {
        return nil, fmt.Errorf("config serialization failed: %w", err)
    }

    return &BuildArtifacts{
        AgentID:    "", // Empty for generic packages
        ConfigJSON: string(configJSON),
        BinaryPath: tempPath,
        Signature:  signature,
        Platform:   op.Platform,
        Version:    op.Version,
    }, nil
}

2.4 Handler Migration Plan

Step 1: Create new unified handlers

// aggregator-server/internal/api/handlers/agent_manager.go

type AgentManagerHandler struct {
    agentManager *services.AgentManager
}

func NewAgentManagerHandler(agentManager *services.AgentManager) *AgentManagerHandler {
    return &AgentManagerHandler{agentManager: agentManager}
}

// Single handler for all agent operations
func (h *AgentManagerHandler) ProcessAgent(c *gin.Context) {
    operation := c.Param("operation") // "new" | "upgrade" | "rebuild"

    var req services.AgentSetupRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    op := &services.AgentOperation{
        Type:      operation,
        AgentID:   req.AgentID,
        Version:   req.Version,
        Platform:  req.Platform,
        Config:    &services.AgentConfiguration{/*...*/},
        Requester: c.GetString("user_id"),
    }

    response, err := h.agentManager.ProcessAgentOperation(c, op)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    c.JSON(http.StatusOK, response)
}

Step 2: Update routing

// aggregator-server/cmd/server/main.go

// OLD routes:
// POST /api/v1/setup/agent
// POST /api/v1/build/new
// POST /api/v1/build/upgrade
// POST /api/v1/build/agent

// NEW unified routes:
agentHandler := handlers.NewAgentManagerHandler(agentManager)
api.POST("/agents/:operation", agentHandler.ProcessAgent)  // :operation = new|upgrade|rebuild

Step 3: Deprecate old handlers

// Keep old handlers during transition with deprecation warnings
func (h *OldAgentSetupHandler) SetupAgent(c *gin.Context) {
    h.logger.Println("DEPRECATED: Use /agents/new instead of /api/v1/setup/agent")
    // Redirect to new handler
    c.Redirect(http.StatusTemporaryRedirect, "/agents/new")
}

Risk Level: Medium

  • Requires extensive testing
  • API changes for clients
  • Database schema impact
  • Migration period needed

Mitigation Strategy:

  1. Parallel operation during transition
  2. Comprehensive testing before deactivation
  3. Rollback plan with git branches
  4. Client migration timeline

Phase 3: Detection Logic Unification (Week 2-3) - Medium Risk

3.1 Migration vs Build Detection Consolidation

Problem: Identical AgentFile struct in two locations with similar logic

Files Affected:

aggregator-agent/internal/migration/detection.go (lines 14-24)
aggregator-server/internal/services/build_types.go (lines 69-79)

Solution: Create shared file detection service

New File: aggregator/internal/common/file_detection.go

package common

import (
    "crypto/sha256"
    "encoding/hex"
    "os"
    "path/filepath"
    "time"
)

type AgentFile struct {
    Path         string    `json:"path"`
    Size         int64     `json:"size"`
    ModifiedTime time.Time `json:"modified_time"`
    Version      string    `json:"version,omitempty"`
    Checksum     string    `json:"checksum"`
    Required     bool      `json:"required"`
    Migrate      bool      `json:"migrate"`
    Description  string    `json:"description"`
}

type FileDetectionService struct {
    logger *log.Logger
}

func NewFileDetectionService(logger *log.Logger) *FileDetectionService {
    return &FileDetectionService{logger: logger}
}

// Scan directory and return file inventory
func (fds *FileDetectionService) ScanDirectory(basePath string, version string) ([]AgentFile, error) {
    var files []AgentFile

    err := filepath.Walk(basePath, func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        if info.IsDir() {
            return nil
        }

        // Calculate checksum
        checksum, err := fds.calculateChecksum(path)
        if err != nil {
            fds.logger.Printf("Warning: Could not checksum %s: %v", path, err)
            checksum = ""
        }

        file := AgentFile{
            Path:         path,
            Size:         info.Size(),
            ModifiedTime: info.ModTime(),
            Version:      version,
            Checksum:     checksum,
            Required:     fds.isRequiredFile(path),
            Migrate:      fds.shouldMigrateFile(path),
            Description:  fds.getFileDescription(path),
        }

        files = append(files, file)
        return nil
    })

    return files, err
}

func (fds *FileDetectionService) calculateChecksum(filePath string) (string, error) {
    data, err := os.ReadFile(filePath)
    if err != nil {
        return "", err
    }

    hash := sha256.Sum256(data)
    return hex.EncodeToString(hash[:]), nil
}

func (fds *FileDetectionService) isRequiredFile(path string) bool {
    requiredFiles := []string{
        "/etc/redflag/config.json",
        "/usr/local/bin/redflag-agent",
        "/etc/systemd/system/redflag-agent.service",
    }

    for _, required := range requiredFiles {
        if path == required {
            return true
        }
    }
    return false
}

func (fds *FileDetectionService) shouldMigrateFile(path string) bool {
    // Business logic for migration requirements
    return strings.HasPrefix(path, "/etc/redflag/") ||
           strings.HasPrefix(path, "/var/lib/redflag/")
}

func (fds *FileDetectionService) getFileDescription(path string) string {
    descriptions := map[string]string{
        "/etc/redflag/config.json":          "Agent configuration file",
        "/usr/local/bin/redflag-agent":      "Main agent executable",
        "/etc/systemd/system/redflag-agent.service": "Systemd service definition",
    }
    return descriptions[path]
}

Migration Steps:

  1. Create common package with shared detection service
  2. Update migration detection to use common service
  3. Update build types to import and use common structs
  4. Remove duplicate AgentFile structs
  5. Update imports across both systems
  6. Test both migration and build flows

Risk Level: Medium

  • Cross-package dependencies
  • Testing required for both systems
  • Potential behavioral changes

Testing Strategy:

  1. Unit tests for file detection service
  2. Integration tests for migration flow
  3. Integration tests for build flow
  4. Comparison tests between old and new implementations

Phase 4: Update Handler Consolidation (Week 3) - Low Risk

4.1 Updates Endpoint Analysis

Current Duplicates:

aggregator-server/internal/api/handlers/updates.go
aggregator-server/internal/api/handlers/agent_updates.go

Overlap Analysis:

  • Update validation logic (70% similar)
  • Command processing (65% similar)
  • Response formatting (80% identical)
  • Error handling (75% similar)

Consolidation Strategy:

// New unified handler: aggregator-server/internal/api/handlers/updates.go

type UpdateHandler struct {
    db              *sqlx.DB
    config          *config.Config
    logger          *log.Logger
    updateService   *services.UpdateService
    commandService  *services.CommandService
}

func (h *UpdateHandler) ProcessUpdate(c *gin.Context) {
    updateType := c.Param("type") // "agent" | "system" | "package"

    switch updateType {
    case "agent":
        h.processAgentUpdate(c)
    case "system":
        h.processSystemUpdate(c)
    case "package":
        h.processPackageUpdate(c)
    default:
        c.JSON(http.StatusBadRequest, gin.H{"error": "unknown update type"})
    }
}

func (h *UpdateHandler) processAgentUpdate(c *gin.Context) {
    agentID := c.Param("agent_id")

    var req AgentUpdateRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }

    // Unified validation
    if err := h.updateService.ValidateAgentUpdate(agentID, &req); err != nil {
        c.JSON(http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
        return
    }

    // Unified processing
    result, err := h.updateService.ProcessAgentUpdate(agentID, &req)
    if err != nil {
        c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
        return
    }

    // Unified response formatting
    c.JSON(http.StatusOK, h.formatUpdateResponse(result))
}

Service Layer Extraction:

// aggregator-server/internal/services/update_service.go

type UpdateService struct {
    db             *sqlx.DB
    logger         *log.Logger
    buildService   *BuildService
    commandService *CommandService
}

func (us *UpdateService) ValidateAgentUpdate(agentID string, req *AgentUpdateRequest) error {
    // Consolidated validation logic from both handlers
    if req.TargetVersion == "" {
        return fmt.Errorf("target_version is required")
    }

    // Check agent exists
    agent, err := us.getAgent(agentID)
    if err != nil {
        return fmt.Errorf("agent not found: %w", err)
    }

    // Version comparison logic
    if !us.isValidVersionTransition(agent.CurrentVersion, req.TargetVersion) {
        return fmt.Errorf("invalid version transition: %s -> %s",
            agent.CurrentVersion, req.TargetVersion)
    }

    return nil
}

Migration Steps:

  1. Extract common logic into update service
  2. Create unified handler with routing by type
  3. Update routing configuration
  4. Keep old handlers with deprecation warnings
  5. Update API documentation
  6. Client migration timeline

Risk Level: Low

  • Handler consolidation is straightforward
  • API changes minimal
  • Easy rollback if issues

Phase 5: Configuration Standardization (Week 3-4) - Low Risk

5.1 Configuration Builder Unification

Current Implementations:

  • config_builder.go - Primary configuration builder
  • agent_builder.go - Build-specific configuration
  • build_orchestrator.go - Orchestrator configuration
  • Migration system configuration detection

Unified Configuration Service:

// aggregator-server/internal/services/configuration_service.go

type ConfigurationService struct {
    db            *sqlx.DB
    logger        *log.Logger
    validator     *ConfigValidator
    templates     map[string]*ConfigTemplate
}

type ConfigurationTemplate struct {
    Name        string
    Platform    string
    Version     string
    DefaultVars map[string]interface{}
    Required    []string
    Optional    []string
}

func (cs *ConfigurationService) GenerateConfiguration(op *AgentOperation) (*AgentConfiguration, error) {
    // Step 1: Load template
    template, err := cs.getTemplate(op.Platform, op.Version)
    if err != nil {
        return nil, err
    }

    // Step 2: Apply base configuration
    config := &AgentConfiguration{
        AgentID:    op.AgentID,
        Version:    op.Version,
        Platform:   op.Platform,
        ServerURL:  cs.getDefaultServerURL(),
        CreatedAt:  time.Now(),
    }

    // Step 3: Apply template defaults
    cs.applyTemplateDefaults(config, template)

    // Step 4: Apply operation-specific overrides
    cs.applyOperationOverrides(config, op)

    // Step 5: Validate final configuration
    if err := cs.validator.Validate(config); err != nil {
        return nil, fmt.Errorf("configuration validation failed: %w", err)
    }

    return config, nil
}

func (cs *ConfigurationService) applyTemplateDefaults(config *AgentConfiguration, template *ConfigTemplate) {
    for key, value := range template.DefaultVars {
        cs.setConfigField(config, key, value)
    }
}

func (cs *ConfigurationService) applyOperationOverrides(config *AgentConfiguration, op *AgentOperation) {
    switch op.Type {
    case "new":
        config.MachineID = op.MachineID
        config.RegistrationToken = cs.generateRegistrationToken()
    case "upgrade":
        // Preserve existing settings during upgrade
        existing := cs.getExistingConfiguration(op.AgentID)
        cs.preserveSettings(config, existing)
    case "rebuild":
        // Rebuild with same configuration
        existing := cs.getExistingConfiguration(op.AgentID)
        *config = *existing
        config.Version = op.Version
    }
}

Configuration Templates:

// aggregator-server/internal/services/config_templates.go

var defaultTemplates = map[string]*ConfigTemplate{
    "linux-amd64-v0.1.23": {
        Name:     "Linux x64 v0.1.23",
        Platform: "linux-amd64",
        Version:  "0.1.23",
        DefaultVars: map[string]interface{}{
            "log_level":           "info",
            "metrics_interval":    300,
            "update_interval":     3600,
            "subsystems_enabled":  []string{"updates", "storage", "system"},
            "max_retries":         3,
            "timeout_seconds":     30,
        },
        Required: []string{"server_url", "agent_id", "machine_id"},
        Optional: []string{"log_level", "proxy_url", "custom_headers"},
    },
    "windows-amd64-v0.1.23": {
        Name:     "Windows x64 v0.1.23",
        Platform: "windows-amd64",
        Version:  "0.1.23",
        DefaultVars: map[string]interface{}{
            "log_level":           "info",
            "metrics_interval":    300,
            "update_interval":     3600,
            "service_name":        "redflag-agent",
            "install_path":        "C:\\Program Files\\RedFlag\\",
        },
        Required: []string{"server_url", "agent_id", "machine_id"},
        Optional: []string{"log_level", "service_user", "install_path"},
    },
}

Migration Steps:

  1. Create unified configuration service
  2. Define configuration templates
  3. Migrate existing builders to use unified service
  4. Remove duplicate configuration logic
  5. Update all imports and references
  6. Test configuration generation

Risk Level: Low

  • Configuration generation is internal API
  • No breaking changes to external interfaces
  • Easy to test and validate

Testing Strategy

Unit Testing Requirements

# Test coverage requirements
go test ./... -cover -v
# Target: >85% coverage on refactored packages

# Specific tests needed:
go test ./internal/services/agent_manager_test.go -v
go test ./internal/services/build_service_test.go -v
go test ./internal/services/config_service_test.go -v
go test ./internal/common/file_detection_test.go -v

Integration Testing

# Test scenarios:
1. New agent registration flow
2. Agent upgrade flow
3. Agent rebuild flow
4. Configuration generation
5. File detection and migration
6. Update processing (all types)
7. Download functionality
8. Error handling and rollback

End-to-End Testing

# Full workflow tests:
1. Agent registration → build → download → installation
2. Agent upgrade → configuration migration → validation
3. Multiple agents with same version → shared artifacts
4. Error scenarios → rollback → recovery
5. Load testing with concurrent operations

Rollback Plan

Immediate Rollback (Critical Issues)

# Phase 1 changes (backup files):
git checkout HEAD~1 -- aggregator-server/internal/api/handlers/
git checkout HEAD~1 -- aggregator-agent/cmd/agent/main.go

# Phase 2+ changes (feature branch):
git checkout main
git checkout -b rollback-duplication-cleanup

Partial Rollback (Specific Components)

# Rollback build system only:
git checkout main -- aggregator-server/internal/services/
# Keep backup file cleanup

Gradual Rollback

# Re-enable deprecated handlers with routing changes
# Keep new services available for gradual migration

Success Metrics

Quantitative Targets

  • Lines of code: Reduce from 7,600 to 4,500 (41% reduction)
  • Files: Reduce from 22 to 11 (50% reduction)
  • Functions: Eliminate 45+ duplicate functions
  • Build time: Reduce compilation time by 25%
  • Test coverage: Maintain >85% on refactored code

Qualitative Improvements

  • Developer understanding: New developers onboard 50% faster
  • Bug fix time: Single location to fix issues
  • Feature development: Clear patterns for new features
  • Code reviews: Focus on logic, not duplicate detection
  • Technical debt: Eliminated major duplication sources

Performance Improvements

  • Memory usage: 15% reduction (duplicate structs removed)
  • Binary size: 20% reduction (duplicate code removed)
  • API response time: 10% improvement (unified processing)
  • Database queries: 25% reduction (consolidated operations)

Implementation Timeline

Week 1: Critical Cleanup (Low Risk)

  • Day 1-2: Remove backup files, legacy scanner function
  • Day 3-4: Consolidate AgentSetupRequest structs
  • Day 5: Testing and validation

Week 2: Build System Unification (Medium Risk)

  • Day 1-2: Create unified AgentManager service
  • Day 3-4: Implement BuildService and ConfigService
  • Day 5: Handler migration and testing

Week 3: Detection & Update Consolidation (Medium Risk)

  • Day 1-2: File detection service unification
  • Day 3-4: Update handler consolidation
  • Day 5: End-to-end testing

Week 4: Configuration & Polish (Low Risk)

  • Day 1-2: Configuration service unification
  • Day 3-4: Documentation updates and final testing
  • Day 5: Performance validation and deployment prep

Document Version: 1.0 Created: 2025-11-10 Status: Ready for Review Next Step: Comparison with second opinion and implementation approval


Dependencies and Prerequisites

Before Starting

  1. Full database backup of production environment
  2. Comprehensive test suite passing on current codebase
  3. Performance baseline measurements
  4. API documentation current state
  5. Client applications inventory for impact assessment

During Implementation

  1. Feature branch isolation for each phase
  2. Automated testing on each commit
  3. Performance monitoring during changes
  4. Rollback verification before merging
  5. Documentation updates with each change

After Completion

  1. Client migration plan for API changes
  2. Monitoring setup for new unified services
  3. Training materials for development team
  4. Maintenance procedures for unified architecture
  5. Performance benchmarking against baseline