Skip to content

[ENHANCEMENT] Refactor imperative shell business logic to functional core with Effect.ts

[ENHANCEMENT] Refactor imperative shell business logic to functional core with Effect.ts

🎯 Enhancement Overview

Refactor pure business logic currently residing in the imperative shell to the functional core, following Effect.ts patterns and functional programming principles. This enhancement will improve testability, maintainability, and architectural consistency.

🤔 Problem Statement

The imperative shell currently contains significant pure business logic that violates architectural boundaries. Specifically:

  • http-monitoring-functional.ts has pure functions mixed with imperative code
  • Authentication logic in http-server.ts could be pure functions
  • Timing and health check calculations are embedded in I/O operations
  • Global mutable state is used instead of Effect Services

🔧 Technical Requirements

High Priority: HTTP Monitoring Module (src/imperative-shell/http-monitoring-functional.ts)

Current Issues:

  • Lines 60-113: Pure functions (generateRequestId, extractClientIp, updateMetricsWithRequest) in imperative shell
  • Lines 46-54, 133-182: Global mutable state using let and Map
  • Lines 249-274: Pure metrics calculations mixed with imperative data access

Refactoring Targets:

  1. Create src/functional-core/http/monitoring-service.ts - Service interface with Effect
  2. Create src/functional-core/http/metrics-calculator.ts - Pure metrics calculations
  3. Create src/functional-core/http/monitoring-service-live.ts - Service implementation

Medium Priority: Authentication Logic (src/imperative-shell/http-server.ts)

Current Issues:

  • Lines 220-317: Authentication logic that could be pure functions
  • Token validation and bearer token parsing mixed with I/O

Refactoring Targets:

  1. Create src/functional-core/auth/authentication-service.ts
  2. Move validateBearerToken() as pure function
  3. Create tagged union AuthResult type for auth outcomes

Medium Priority: Timing and Health (src/imperative-shell/health-check.ts)

Current Issues:

  • Lines 181-191: Timing logic using imperative approach
  • Lines 63-76: Server metadata creation mixed with I/O

Refactoring Targets:

  1. Create src/functional-core/utils/timing-service.ts
  2. Use Effect Clock for pure timing measurements
  3. Move health metrics calculations to functional core

🏗️ Architecture Analysis

Service Design Pattern

// Example: Monitoring Service Interface
export interface HttpMonitoringService {
  readonly startRequest: (requestInfo: RequestInfo) => Effect.Effect<string, never, never>;
  readonly completeRequest: (requestId: string, statusCode: number) => Effect.Effect<void, never, never>;
  readonly getMetrics: Effect.Effect<HttpMetrics, never, never>;
  readonly getHealthMetrics: Effect.Effect<HttpHealthMetrics, never, never>;
}

State Management Transformation

  • Current: Global mutable Maps and variables
  • Target: Effect Ref with immutable data structures
  • Benefits: Referential transparency, easier testing, no race conditions

Error Handling Pattern

// Tagged union for authentication results
export type AuthResult = 
  | { readonly _tag: 'Success'; readonly token: string }
  | { readonly _tag: 'MissingToken' }
  | { readonly _tag: 'InvalidToken'; readonly received: string }
  | { readonly _tag: 'MissingEnvToken' };

Acceptance Criteria

Phase 1: HTTP Monitoring Refactor

  • All pure functions moved from http-monitoring-functional.ts to functional core
  • Monitoring Service created with Effect Services pattern
  • Global mutable state replaced with Effect Ref
  • All metrics calculations are pure functions
  • Imperative shell only handles MCP protocol interaction
  • Tests written for all pure functions (≥80% coverage)
  • ESLint boundary rules pass (no functional-core → imperative-shell imports)

Phase 2: Authentication Refactor

  • Authentication validation is pure function in functional core
  • Bearer token parsing moved to functional core
  • AuthResult tagged union implemented
  • Error responses created through pure functions
  • Authentication service properly injected via Effect

Phase 3: Timing and Health Refactor

  • Timing measurements use Effect Clock primitives
  • Health metrics calculations are pure functions
  • Server metadata creation is pure
  • Response time calculations use functional approach
  • All timing logic removed from imperative shell

Code Quality Requirements

  • No ESLint errors or warnings
  • TypeScript strict mode passes
  • All Effect patterns properly implemented
  • No class usage in functional core
  • No mutations in functional core
  • No void returns in functional core

🧪 Testing Strategy

Unit Tests (Functional Core)

// Pure function tests
test('updateMetricsWithRequest correctly updates metrics', async () => {
  const initial = createInitialMetrics();
  const updated = updateMetricsWithRequest(initial, 'GET', 200, 100);
  expect(updated.requests.total).toBe(1);
  expect(updated.performance.averageResponseTime).toBe(100);
});

// Service tests with mocked layers
test('HttpMonitoringService tracks requests', async () => {
  const service = await Effect.runPromise(
    HttpMonitoringServiceLive.pipe(Effect.provide(testLayer))
  );
  const requestId = await Effect.runPromise(service.startRequest(mockRequest));
  expect(requestId).toMatch(/^req_/);
});

Integration Tests

  • Test imperative shell correctly uses functional services
  • Verify MCP protocol compliance
  • Ensure proper error handling across boundaries

📊 Success Metrics

  • Test Coverage: ≥80% for functional core modules
  • Performance: No regression in response times
  • Build Time: ESLint and TypeScript checks complete in <30s
  • Code Quality: Zero ESLint violations
  • Architecture: Clear separation between layers

📋 Implementation Phases

Week 1: HTTP Monitoring Service

  1. Create monitoring schemas in functional-core/schemas.ts
  2. Implement pure metrics calculation functions
  3. Create Effect Service for HTTP monitoring
  4. Update imperative shell to use functional service
  5. Write comprehensive tests

Week 2: Authentication Service

  1. Create authentication service interface
  2. Move token validation logic
  3. Update HTTP server to use functional auth
  4. Add error handling with Effect channels

Week 3: Timing and Final Cleanup

  1. Create timing service with Effect Clock
  2. Refactor health check timing
  3. Move server metadata logic
  4. Clean up imperative wrappers
  5. Final testing and documentation

🔗 Dependencies

  • Effect.ts for functional programming patterns
  • No new external dependencies required
  • Existing MCP SDK continues to work as-is

📚 References

🎯 Definition of Done

  • All acceptance criteria met
  • Code review completed and approved
  • CI/CD pipeline passes (lint, typecheck, tests)
  • No performance regression
  • Documentation updated if needed
  • Architectural boundaries enforced by ESLint