gateway/modules/BIDIRECTIONAL_IMPORTS.md

15 KiB

Bidirectional Import Analysis

Summary

After refactoring extraction functions and automation handler, ALL bidirectional dependencies have been RESOLVED:

Current Status:

  • interfaces/ → services/: RESOLVED (no imports)
  • interfaces/ → features/: RESOLVED (uses callback registry, no direct imports)
  • services/ → interfaces/: UNIDIRECTIONAL (correct dependency direction)
  • services/ → features/: NONE (no imports)
  • features/ → interfaces/: UNIDIRECTIONAL (correct dependency direction)
  • features/ → services/: 1 lazy import (correct direction)

Result: ZERO VIOLATIONS - Perfect architectural compliance achieved.


Dependency Diagram

Mermaid Diagram

graph TB
    %% Foundation Layer (no dependencies)
    shared[shared/<br/>Foundation]
    datamodels[datamodels/<br/>Foundation]
    aicore[aicore/<br/>Infrastructure]
    connectors[connectors/<br/>Infrastructure]
    
    %% Data Layer
    interfaces[interfaces/<br/>Data Access<br/>✅ No violations]
    
    %% Business Logic Layer
    services[services/<br/>Business Logic<br/>✅ Unidirectional]
    workflows[workflows/<br/>Business Logic]
    
    %% Feature Layer
    features[features/<br/>Features<br/>✅ Unidirectional]
    
    %% API Layer
    routes[routes/<br/>API Layer]
    security[security/<br/>Security]
    
    %% Foundation dependencies
    datamodels -->|imports| shared
    aicore -->|imports| datamodels
    aicore -->|imports| shared
    connectors -->|imports| datamodels
    connectors -->|imports| shared
    
    %% Interface layer (foundation only)
    interfaces -->|imports| aicore
    interfaces -->|imports| connectors
    interfaces -->|imports| datamodels
    interfaces -.->|callbackRegistry| shared
    
    %% Service layer (interfaces only)
    services -->|✅ imports| interfaces
    services -->|imports| aicore
    services -->|imports| datamodels
    services -->|imports| security
    services -->|imports| shared
    
    %% Workflow layer
    workflows -->|imports| aicore
    workflows -->|imports| datamodels
    workflows -->|imports| services
    workflows -->|imports| shared
    
    %% Feature layer (interfaces + services)
    features -->|✅ imports| interfaces
    features -->|✅ imports| services
    features -->|imports| datamodels
    features -->|imports| workflows
    features -->|imports| shared
    
    %% API layer
    routes -->|imports| interfaces
    routes -->|imports| features
    routes -->|imports| services
    routes -->|imports| security
    routes -->|imports| datamodels
    routes -->|imports| shared
    
    %% Security layer
    security -->|imports| interfaces
    security -->|imports| datamodels
    security -->|imports| shared
    
    %% Styling
    classDef foundation fill:#e1f5ff,stroke:#01579b,stroke-width:2px
    classDef data fill:#f3e5f5,stroke:#4a148c,stroke-width:3px
    classDef business fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px
    classDef feature fill:#fff3e0,stroke:#e65100,stroke-width:2px
    classDef api fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    
    class shared,datamodels,aicore,connectors foundation
    class interfaces data
    class services,workflows business
    class features feature
    class routes,security api

Draw.io Diagram

A detailed draw.io diagram is available in DEPENDENCY_DIAGRAM.drawio with:

  • Color-coded layers (Foundation, Data, Business Logic, Features, API)
  • Arrow directions showing import relationships
  • markers on correct dependency directions
  • Dashed line for callback registry pattern
  • Status box showing zero violations

Key Visual Elements:

  • Thick green arrows (): Correct dependency directions (services→interfaces, features→interfaces, features→services)
  • Dashed purple line: Callback registry pattern (interfaces→shared, decoupled from features)
  • Color coding: Each layer has distinct colors for easy identification
  • Status indicators: markers show compliance, "No violations" labels confirm architectural correctness

Detailed Analysis

1. interfaces/ → services/ RESOLVED

Current State:

  • No imports from services/ in interfaces/
  • All extraction-related functions moved to services/serviceExtraction/
  • Dependency violations resolved

Impact: Major architectural improvement - interfaces no longer depend on services.


2. interfaces/ → features/ RESOLVED

Previous State:

  • interfaceDbChatObjects.py (line 1754): Lazy import in _triggerAutomationSync() helper method
    from modules.features.automation import syncAutomationEvents
    

Current State:

  • No imports from features/ in interfaces/
  • Uses callback registry pattern (shared.callbackRegistry) for decoupled notifications
  • Interface triggers callbacks without knowing which features are listening
  • Feature registers callback in featuresLifecycle.py startup

Refactoring:

  • Created shared/callbackRegistry.py - decoupled event notification system
  • Interface calls callbackRegistry.trigger('automation.changed', self) instead of importing feature
  • Feature registers callback on startup: callbackRegistry.register('automation.changed', onAutomationChanged)

Impact: Perfect separation - interface doesn't know about features, uses shared callback registry.


3. services/ → interfaces/ CORRECT DIRECTION

Current State:

  • serviceAi/mainServiceAi.py: Imports AiObjects from interfaceAiObjects
  • serviceExtraction/mainServiceExtraction.py: Lazy import from interfaceDbComponentObjects
  • serviceUtils/mainServiceUtils.py: Lazy import from interfaceDbChatObjects
  • serviceTicket/mainServiceTicket.py: Imports from interfaceTicketObjects
  • services/__init__.py: Lazy imports from multiple interfaces

Impact: This is correct - services should use interfaces for data access. This follows the dependency rule: services/interfaces/

Note: This is unidirectional (services → interfaces), not bidirectional.


4. services/ → features/ NONE

Current State:

  • No imports from features/ in services/

Impact: Services correctly do not depend on features.


5. features/ → interfaces/ CORRECT DIRECTION

Current State:

  • features/automation/mainAutomation.py: Imports from interfaceDbChatObjects, interfaceDbAppObjects
  • features/featuresLifecycle.py: Imports from interfaceDbAppObjects, interfaceDbChatObjects (lazy)

Impact: This is correct - features should use interfaces for data access. This follows the dependency rule: features/interfaces/

Note: This is unidirectional (features → interfaces), not bidirectional.


6. features/ → services/ CORRECT DIRECTION

Current State:

  • features/neutralizePlayground/mainNeutralizePlayground.py (line 123): Lazy import from serviceSharepoint

Impact: This is correct - features can use services. This follows the dependency rule: features/services/


Complete Import Matrix (Fact-Based)

aicore/

  • Imports from: datamodels/, shared/
  • Imported by: interfaces/, services/, workflows/
  • Bidirectional: None

connectors/

  • Imports from: datamodels/, shared/
  • Imported by: interfaces/
  • Bidirectional: None

datamodels/

  • Imports from: shared/
  • Imported by: aicore/, connectors/, features/, interfaces/, routes/, security/, services/, workflows/
  • Bidirectional: None

features/

  • Imports from: datamodels/, interfaces/, services/, shared/, workflows/
  • Imported by: routes/
  • UNIDIRECTIONAL: No longer imported by interfaces/

Detailed imports:

  • From interfaces/: interfaceDbChatObjects, interfaceDbAppObjects
  • From services/: serviceSharepoint (lazy, in neutralizePlayground)
  • From features/: chatPlayground (in automation), syncDelta, chatAlthaus (in featuresLifecycle)

interfaces/

  • Imports from: aicore/, connectors/, datamodels/, shared/
  • Imported by: features/, routes/, security/, services/
  • RESOLVED: No longer imports from services/ or features/

Detailed imports:

  • From shared/: callbackRegistry (for decoupled event notifications), eventManagement (for event removal in delete), timeUtils, configuration, debugLogger
  • From interfaces/: Internal imports (interfaceDbChatAccess, interfaceDbAppAccess, interfaceDbComponentAccess)

routes/

  • Imports from: datamodels/, features/, interfaces/, security/, services/, shared/
  • Imported by: None (top-level API layer)
  • Bidirectional: None

Detailed imports:

  • From interfaces/: interfaceDbChatObjects, interfaceDbAppObjects, interfaceDbComponentObjects, interfaceVoiceObjects
  • From features/**: features.automation, features.chatPlayground, features.neutralizePlayground`

security/

  • Imports from: datamodels/, interfaces/, shared/
  • Imported by: routes/, services/
  • Bidirectional: None

Detailed imports:

  • From interfaces/**: interfaceDbAppObjects` (lazy imports)

services/

  • Imports from: aicore/, datamodels/, interfaces/, security/, shared/
  • Imported by: features/, routes/, workflows/
  • UNIDIRECTIONAL: Only imports from interfaces/ (correct direction)
  • RESOLVED: No longer imported by interfaces/

Detailed imports:

  • From interfaces/**: interfaceAiObjects, interfaceDbComponentObjects(lazy),interfaceDbChatObjects(lazy),interfaceTicketObjects`
  • From `services/**: Internal imports (service-to-service)

shared/

  • Imports from: None (foundation layer)
  • Imported by: aicore/, connectors/, datamodels/, features/, interfaces/, routes/, security/, services/, workflows/
  • Bidirectional: None

workflows/

  • Imports from: aicore/, datamodels/, services/, shared/
  • Imported by: features/
  • Bidirectional: None

Detailed imports:

  • From services/**: serviceGeneration(lazy, inmethodAi.py`)

Refactoring Impact Summary

Before Refactoring:

  • interfaces/ ↔ services/: Bidirectional (violations)
    • interfaces/ imported from services/serviceExtraction/ (6 violations)
    • services/ imported from interfaces/ (correct)
  • interfaces/ ↔ features/: Bidirectional (violation)
    • interfaces/ imported from features.chatPlayground (1 violation)
    • features/ imported from interfaces/ (correct)

After Refactoring:

  • interfaces/ → services/: RESOLVED (no imports)
  • services/ → interfaces/: UNIDIRECTIONAL (correct direction)
  • interfaces/ → features/: RESOLVED (uses callback registry pattern)
  • features/ → interfaces/: UNIDIRECTIONAL (correct direction)
  • features/ → services/: CORRECT DIRECTION (1 lazy import)

Specific Import Details

interfaces/ → features/ RESOLVED

Previous: interfaceDbChatObjects.py (line 1754) had lazy import from features.automation

from modules.features.automation import syncAutomationEvents

Current: Uses shared.callbackRegistry pattern (line 1754):

  • Interface calls: callbackRegistry.trigger('automation.changed', self)
  • Feature registers callback in featuresLifecycle.py: callbackRegistry.register('automation.changed', onAutomationChanged)
  • Zero direct imports from features in interfaces
  • Verification: grep "from modules.features" interfaces/ returns no matches

features/ → services/ (1 import, correct direction)

File: features/neutralizePlayground/mainNeutralizePlayground.py

  • Line: 123
  • Import: from modules.services.serviceSharepoint.mainServiceSharepoint import SharepointService
  • Type: Lazy import (inside method)
  • Context: Used for SharePoint file processing
  • Status: CORRECT - Features can import from services

Recommendations

Completed Improvements

  1. Resolved interfaces/ → services/ violations - Moved extraction functions to serviceExtraction/
  2. Resolved interfaces/ → features/ violations - Moved automation handler to features/automation/
  3. Eliminated ALL bidirectional dependencies - interfaces/ no longer imports from services/ or features/
  4. Implemented callback registry pattern - Decoupled event notifications using shared.callbackRegistry
  5. Follows dependency rules perfectly - All dependencies now follow correct direction:
    • services/interfaces/
    • features/interfaces/
    • features/services/
    • interfaces/shared/ only

Best Practices

  • Use lazy imports (inside functions) for dependencies when appropriate
  • Services correctly depend on interfaces (unidirectional)
  • Features correctly depend on interfaces and services (unidirectional)
  • Interfaces completely independent (only foundation layers)
  • Use callback registry for decoupled event notifications
  • Document dependency relationships clearly
  • Monitor for circular import errors

Dependency Rule Compliance

Current Rules:

  • features/services/ (correct)
  • services/interfaces/ (correct)
  • features/interfaces/ (correct)

Status:

  • interfaces/services/: RESOLVED (was violation, now compliant)
  • services/interfaces/: COMPLIANT (correct direction)
  • features/interfaces/: COMPLIANT (correct direction)
  • features/services/: COMPLIANT (correct direction)
  • interfaces/features/: RESOLVED (was violation, now uses callback registry)

Conclusion

The refactoring successfully resolved ALL bidirectional dependencies:

  • interfaces/ ↔ services/: RESOLVED
  • interfaces/ ↔ features/: RESOLVED (using callback registry pattern)

The architecture now follows the intended dependency rules perfectly:

  • interfaces/ only imports from foundation layers (aicore/, connectors/, datamodels/, shared/)
  • services/ imports from interfaces/ (correct direction)
  • features/ imports from interfaces/ and services/ (correct direction)
  • Zero violations - perfect architectural compliance achieved through callback registry pattern

Architecture Layers

The codebase follows a clean layered architecture:

  1. Foundation Layer (shared/, datamodels/)

    • No dependencies on other modules
    • Used by all layers
  2. Infrastructure Layer (aicore/, connectors/)

    • Depends only on foundation
    • Provides core capabilities
  3. Data Access Layer (interfaces/)

    • Depends only on foundation and infrastructure
    • Provides data access abstraction
  4. Business Logic Layer (services/, workflows/)

    • Depends on interfaces and foundation
    • Implements business logic
  5. Feature Layer (features/)

    • Depends on interfaces, services, and foundation
    • Implements user-facing features
  6. API Layer (routes/, security/)

    • Depends on all layers
    • Provides HTTP API endpoints