247 lines
11 KiB
Markdown
247 lines
11 KiB
Markdown
# Import Map Analysis: interfaces ↔ connectors ↔ security
|
|
|
|
## Overview
|
|
This document maps all imports between `modules/interfaces`, `modules/connectors`, and `modules/security` to identify structural issues, circular dependencies, and architectural concerns.
|
|
|
|
**Architectural Principle:**
|
|
- ✅ Connectors (infrastructure) can import from Security (infrastructure)
|
|
- ✅ Interfaces (business logic) can import from Security (infrastructure)
|
|
- ✅ Interfaces (business logic) can import from Connectors (infrastructure)
|
|
- ❌ Connectors should NOT import from Interfaces (business logic)
|
|
|
|
---
|
|
|
|
## Import Dependencies Map
|
|
|
|
### **CONNECTORS → SECURITY**
|
|
|
|
#### `connectorDbPostgre.py`
|
|
- **Imports from security:**
|
|
- `from modules.security.rbac import RbacClass` (line 13)
|
|
- **Usage:**
|
|
- **Runtime instantiation:** `RbacClass(self)` in `getRecordsetWithRBAC()` (line 1073)
|
|
- Creates `RbacClass` instance to get user permissions
|
|
- **Status:** ✅ **ARCHITECTURALLY CORRECT** - Connectors can import from security module
|
|
|
|
---
|
|
|
|
### **SECURITY → CONNECTORS**
|
|
|
|
#### `security/rbac.py` (moved from `interfaces/interfaceRbac.py`)
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorDbPostgre import DatabaseConnector` (line 11, inside TYPE_CHECKING)
|
|
- **Usage:** Type hint only (`db: "DatabaseConnector"`)
|
|
- **Status:** ✅ Fixed with TYPE_CHECKING to avoid circular import
|
|
- **Architecture:** ✅ Correct - Security module can import from connectors (infrastructure layer)
|
|
|
|
### **INTERFACES → CONNECTORS**
|
|
|
|
#### `interfaceBootstrap.py`
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorDbPostgre import DatabaseConnector` (line 9)
|
|
- **Usage:** Function parameter types (`initBootstrap(db: DatabaseConnector)`)
|
|
|
|
#### `interfaceDbAppObjects.py`
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorDbPostgre import DatabaseConnector` (line 12)
|
|
- **Usage:** Class initialization (`self.db: DatabaseConnector`)
|
|
- **Imports from security:**
|
|
- `from modules.security.rbac import RbacClass` (line 17)
|
|
- **Usage:** RBAC permission checking
|
|
- **Architecture:** ✅ Correct - Interfaces can import from security (infrastructure layer)
|
|
|
|
#### `interfaceDbChatObjects.py`
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorDbPostgre import DatabaseConnector` (line 29)
|
|
- **Usage:** Class initialization
|
|
|
|
#### `interfaceDbComponentObjects.py`
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorDbPostgre import DatabaseConnector` (line 13)
|
|
- **Usage:** Class initialization
|
|
|
|
#### `interfaceVoiceObjects.py`
|
|
- **Imports from connectors:**
|
|
- `from modules.connectors.connectorVoiceGoogle import ConnectorGoogleSpeech` (line 10)
|
|
- **Usage:** Class initialization
|
|
|
|
---
|
|
|
|
## Circular Dependency Analysis
|
|
|
|
### **CIRCULAR DEPENDENCY #1: RESOLVED** ✅
|
|
```
|
|
connectorDbPostgre.py (line 13)
|
|
└─> imports RbacClass from security.rbac
|
|
└─> Uses: RbacClass(self) at runtime (line 1073)
|
|
|
|
security/rbac.py (line 11, inside TYPE_CHECKING)
|
|
└─> imports DatabaseConnector (type hint only)
|
|
```
|
|
|
|
**Status:** ✅ **RESOLVED** by moving RBAC to security module + `TYPE_CHECKING`
|
|
|
|
**Architectural Fix:**
|
|
- Moved `interfaceRbac.py` → `security/rbac.py`
|
|
- Connectors can import from security (infrastructure layer)
|
|
- Interfaces can import from security (business logic layer)
|
|
- No architectural violation: security is shared infrastructure
|
|
|
|
**Solution Applied:**
|
|
```python
|
|
# security/rbac.py
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from modules.connectors.connectorDbPostgre import DatabaseConnector
|
|
|
|
class RbacClass:
|
|
def __init__(self, db: "DatabaseConnector"): # String annotation
|
|
self.db = db # Uses db at runtime, but import is deferred
|
|
```
|
|
|
|
**Why This Works:**
|
|
1. At **import time**: `connectorDbPostgre` imports `RbacClass` ✅
|
|
2. `RbacClass` tries to import `DatabaseConnector` but it's inside `TYPE_CHECKING`, so **no actual import occurs** ✅
|
|
3. At **runtime**: When `getRecordsetWithRBAC()` calls `RbacClass(self)`, `DatabaseConnector` is already fully loaded ✅
|
|
4. Runtime circular reference is safe because Python objects can reference each other once loaded
|
|
|
|
---
|
|
|
|
## Architecture Analysis
|
|
|
|
### **Current Structure**
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ CONNECTORS │
|
|
│ (Database, External Services) │
|
|
│ │
|
|
│ connectorDbPostgre.py │
|
|
│ └─> Uses: RbacClass (runtime instantiation) ⚠️ │
|
|
│ │
|
|
│ connectorVoiceGoogle.py │
|
|
│ connectorTicketsClickup.py │
|
|
│ connectorTicketsJira.py │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
▲
|
|
│ imports
|
|
│
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ INTERFACES │
|
|
│ (Business Logic, Data Access Layer) │
|
|
│ │
|
|
│ security/rbac.py (moved from interfaces) │
|
|
│ └─> Uses: DatabaseConnector (type hint only) ✅ │
|
|
│ └─> Can be imported by both connectors and interfaces │
|
|
│ │
|
|
│ interfaceBootstrap.py │
|
|
│ └─> Uses: DatabaseConnector │
|
|
│ │
|
|
│ interfaceDbAppObjects.py │
|
|
│ └─> Uses: DatabaseConnector │
|
|
│ └─> Uses: security.rbac.RbacClass │
|
|
│ └─> Uses: interfaceBootstrap.initBootstrap │
|
|
│ │
|
|
│ interfaceDbChatObjects.py │
|
|
│ └─> Uses: DatabaseConnector │
|
|
│ │
|
|
│ interfaceDbComponentObjects.py │
|
|
│ └─> Uses: DatabaseConnector │
|
|
│ │
|
|
│ interfaceVoiceObjects.py │
|
|
│ └─> Uses: connectorVoiceGoogle.ConnectorGoogleSpeech │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Potential Issues & Recommendations
|
|
|
|
### ✅ **RESOLVED ISSUES**
|
|
|
|
1. **Circular Import: security.rbac ↔ connectorDbPostgre**
|
|
- **Status:** ✅ Resolved by moving to security module + TYPE_CHECKING
|
|
- **Impact:** None - Proper architectural layering maintained
|
|
|
|
### ⚠️ **POTENTIAL ISSUES**
|
|
|
|
1. **Tight Coupling: Interfaces depend on specific connectors**
|
|
- **Issue:** `interfaceDbAppObjects.py` directly imports `DatabaseConnector`
|
|
- **Impact:** Makes it harder to swap database implementations
|
|
- **Recommendation:** Consider dependency injection or abstract base class
|
|
|
|
2. **Connector importing from Security (connectorDbPostgre → security.rbac)** ✅
|
|
- **Status:** ✅ **RESOLVED** - Moved RBAC to security module
|
|
- **Current Usage:** Runtime instantiation in `getRecordsetWithRBAC()` (line 1073)
|
|
- **Code:**
|
|
```python
|
|
RbacInstance = RbacClass(self)
|
|
permissions = RbacInstance.getUserPermissions(...)
|
|
```
|
|
- **Architecture:** ✅ Correct - Connectors can import from security (infrastructure layer)
|
|
- **Rationale:** Security is shared infrastructure, not business logic
|
|
|
|
3. **Multiple interfaces importing same connector**
|
|
- **Files importing DatabaseConnector:**
|
|
- `interfaceBootstrap.py`
|
|
- `interfaceDbAppObjects.py`
|
|
- `interfaceDbChatObjects.py`
|
|
- `interfaceDbComponentObjects.py`
|
|
- **Impact:** Medium - creates coupling
|
|
- **Recommendation:** Consider a shared database interface abstraction
|
|
|
|
---
|
|
|
|
## Recommendations
|
|
|
|
### **1. Move RBAC Logic Out of Connector**
|
|
**Current:** `connectorDbPostgre.getRecordsetWithRBAC()` instantiates `RbacClass(self)` at runtime
|
|
**Recommendation:**
|
|
- ~~Move `getRecordsetWithRBAC()` to `interfaceRbac.py` or `interfaceDbAppObjects.py`~~ ✅ **RESOLVED** - RBAC moved to security module
|
|
- Connector should only handle raw database operations
|
|
- Interface layer handles RBAC filtering
|
|
|
|
### **2. Use Dependency Injection**
|
|
**Current:** Interfaces directly import `DatabaseConnector`
|
|
**Recommendation:**
|
|
- Create abstract base class `DatabaseConnectorBase`
|
|
- Interfaces depend on abstraction, not concrete implementation
|
|
- Allows easier testing and swapping implementations
|
|
|
|
### **3. Consider Layered Architecture**
|
|
```
|
|
┌─────────────────────────────────────┐
|
|
│ Interfaces (Business Logic) │
|
|
│ - Uses connectors via abstraction │
|
|
└─────────────────────────────────────┘
|
|
▲
|
|
│
|
|
┌─────────────────────────────────────┐
|
|
│ Connectors (Infrastructure) │
|
|
│ - No knowledge of interfaces │
|
|
└─────────────────────────────────────┘
|
|
```
|
|
|
|
### **4. Use TYPE_CHECKING for All Type-Only Imports**
|
|
**Current:** `security/rbac.py` uses TYPE_CHECKING (moved from interfaces)
|
|
**Recommendation:** Use TYPE_CHECKING for all type-only imports between layers
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
### **Current State:**
|
|
- ✅ 1 circular dependency **RESOLVED** (moved to security module)
|
|
- ✅ Architectural violation **FIXED** (RBAC moved to security)
|
|
- ⚠️ Multiple tight couplings to `DatabaseConnector` (acceptable for now)
|
|
|
|
### **Architectural Health:**
|
|
- **Overall:** 🟢 **Good** - Proper layering maintained
|
|
- **Architecture:** ✅ Connectors → Security (infrastructure) ✅ Interfaces → Security (infrastructure)
|
|
- **Risk Level:** Low - Clean separation of concerns
|
|
|
|
### **Completed Actions:**
|
|
1. ✅ **DONE:** Fixed circular import with TYPE_CHECKING
|
|
2. ✅ **DONE:** Moved RBAC to security module (proper architectural layering)
|
|
3. 🔄 **OPTIONAL:** Introduce abstraction layer for database connector (future improvement)
|