src — infrastructure

Module: src-infrastructure Cohesion: 0.80 Members: 0

src — infrastructure

The src/infrastructure module is the foundational layer for dependency injection and service management within the CodeBuddy application. It centralizes the creation and provision of core application services, promoting a loosely coupled architecture, improved testability, and clear dependency management.

Purpose

The primary goal of the infrastructure module is to:

  1. Provide a Service Container: A central registry (ServiceContainer) that manages the lifecycle and dependencies of key application services.
  2. Define Core Service Contracts: Establish type-safe interfaces for essential services like settings management, checkpointing, session storage, and cost tracking. This allows for interchangeable implementations and easier mocking in tests.
  3. Facilitate Dependency Injection: Instead of services directly instantiating their dependencies, they receive them from the container, making the system more modular and testable.
  4. Standardize Service Patterns: Offer common interfaces for service lifecycle (IService), health checks (IHealthCheckable), logging (ILogger), and event handling (IEventEmitter).

Core Concept: The Service Container

The heart of this module is the ServiceContainer class, which acts as a central hub for accessing application-wide services. It implements a singleton pattern for its default instance, ensuring that all parts of the application access the same set of core services.

ServiceContainer Class

The ServiceContainer is responsible for:

Key Methods:

Accessing the Container

The recommended way to access the singleton ServiceContainer is via the getServiceContainer() convenience function:

import { getServiceContainer } from '../infrastructure';

const container = getServiceContainer();
const settingsManager = container.settings;
const checkpointManager = container.checkpoints;
class="hl-cmt">// ... and so on

Testing with the Container

The infrastructure module is designed with testability in mind. The createTestContainer() function and the createWithConfig() method are essential for unit and integration testing:

import { createTestContainer, ICheckpointManager } from '../infrastructure';

class="hl-cmt">// Create a mock checkpoint manager
const mockCheckpointManager: ICheckpointManager = {
  id: 'mock-checkpoints',
  name: 'Mock Checkpoint Manager',
  isInitialized: () => true,
  initialize: async () => {},
  dispose: async () => {},
  createCheckpoint: jest.fn(),
  checkpointBeforeEdit: jest.fn(),
  restoreCheckpoint: jest.fn(() => true),
  getCheckpoints: jest.fn(() => []),
  getCheckpoint: jest.fn(() => undefined),
  clearCheckpoints: jest.fn(),
  clearOldCheckpoints: jest.fn(),
  rewindToLast: jest.fn(() => ({ success: true, restored: [], errors: [] })),
  formatCheckpointList: jest.fn(() => 'Mock Checkpoints'),
  on: jest.fn(),
  off: jest.fn(),
  emit: jest.fn(),
  once: jest.fn(),
};

class="hl-cmt">// Create a test container with the mock
const testContainer = createTestContainer({
  checkpoints: mockCheckpointManager,
});

class="hl-cmt">// Now, testContainer.checkpoints will be your mock
testContainer.checkpoints.createCheckpoint('test');
expect(mockCheckpointManager.createCheckpoint).toHaveBeenCalledWith('test');

The module also provides default mock factory functions (createMockSettingsManager, createMockCheckpointManager, etc.) within service-container.ts that createTestContainer uses if no specific mocks are provided. These mocks offer basic, non-functional implementations suitable for tests that don't rely on the specific behavior of those services.

Service Container Architecture

The following diagram illustrates the ServiceContainer and its direct dependencies on the core service interfaces, along with how default implementations are sourced:

graph TD
    subgraph Infrastructure Module
        A[ServiceContainer] --> B(ISettingsManager)
        A --> C(ICheckpointManager)
        A --> D(ISessionStore)
        A --> E(ICostTracker)
    end
    subgraph External Modules
        F[getSettingsManager] --> B
        G[getCheckpointManager] --> C
        H[getSessionStore] --> D
        I[getCostTracker] --> E
    end

    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#ccf,stroke:#333,stroke-width:1px
    style C fill:#ccf,stroke:#333,stroke-width:1px
    style D fill:#ccf,stroke:#333,stroke-width:1px
    style E fill:#ccf,stroke:#333,stroke-width:1px

This diagram shows that ServiceContainer is constructed with instances that conform to the ISettingsManager, ICheckpointManager, ISessionStore, and ICostTracker interfaces. The default implementations for these interfaces are provided by functions (getSettingsManager, etc.) located in other modules, which are then imported and used by ServiceContainer's private factory methods.

Key Service Interfaces

The src/infrastructure/types.ts file defines the specific interfaces for the core services managed by the ServiceContainer. These interfaces ensure type safety and provide a clear contract for each service.

ISettingsManager

Manages user and project-level configuration settings.

ICheckpointManager

Handles the creation, restoration, and management of code checkpoints.

ISessionStore

Manages the lifecycle and data of user interaction sessions.

ICostTracker

Tracks token usage and calculates costs associated with AI model interactions.

General Service Contracts

The src/infrastructure/interfaces/service.interface.ts file defines a set of broader interfaces that establish common patterns for services throughout the application, regardless of their specific domain.

IService (Lifecycle)

The fundamental interface for any managed service.

IHealthCheckable (Health Checks)

For services that can report their operational status.

IDisposable / ISyncDisposable (Resource Cleanup)

For services or objects that manage resources requiring explicit cleanup.

ILogger (Logging)

A standardized interface for logging messages.

IEventEmitter (Events)

A type-safe interface for event publishing and subscription.

IConfigProvider (Configuration)

An interface for accessing configuration values.

IServiceRegistry and IServiceDescriptor (Advanced DI)

These interfaces are part of a more advanced dependency injection pattern, typically used by a full-fledged DI container to register and resolve services with specific lifetimes (singleton, transient, scoped). While exported by this module, the current ServiceContainer implementation uses a simpler, direct property-based access pattern for its core services rather than a dynamic registry. They serve as foundational types for potential future expansion of the DI system.

Module Structure and Exports

The src/infrastructure module is organized as follows:

Integration Points

The infrastructure module is designed to be a central dependency for many other parts of the CodeBuddy application.

By providing a consistent and controlled way to access core services, the infrastructure module ensures that the application remains maintainable, scalable, and robust.