Skip to content

Commit

Permalink
Merge dev into main
Browse files Browse the repository at this point in the history
  • Loading branch information
DinisCruz committed Jan 9, 2025
2 parents 75c61ad + 3e97b7f commit 1f57060
Show file tree
Hide file tree
Showing 106 changed files with 2,946 additions and 519 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ Repo for MGraph-AI

## Repo details

![Current Release](https://img.shields.io/badge/release-v0.3.0-blue)
![Current Release](https://img.shields.io/badge/release-v0.3.3-blue)

240 changes: 240 additions & 0 deletions docs/architecture-doc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# MGraph Architecture Documentation

## Design Philosophy

MGraph implements a strict layered architecture with unidirectional dependencies:

```
Domain Layer (Top)
Model Layer
Schema Layer (Bottom)
```

### Layer Responsibilities

#### 1. Schema Layer
- Defines data structures and type definitions
- Has no dependencies on other layers
- Uses only primitive types and other schema classes
- Enforces type safety through static typing
- Example: `Schema__MGraph__Node`, `Schema__MGraph__Edge`

#### 2. Model Layer
- Implements business logic and data manipulation
- Depends only on Schema layer
- Returns only Model objects
- Encapsulates Schema objects
- Handles validation and type conversion
- Example: `Model__MGraph__Node`, `Model__MGraph__Edge`

#### 3. Domain Layer
- Implements high-level application logic
- Depends only on Model layer
- Returns only Domain objects
- Handles domain-specific operations and workflows
- Example: `MGraph__Node`, `MGraph__Edge`

### Key Design Principles

1. **Unidirectional Dependencies**
- Lower layers must not know about higher layers
- Schema layer is self-contained
- Model layer only knows about Schema
- Domain layer only knows about Model

2. **Type Isolation**
- Each layer only returns objects of its own level
- Schema → Schema objects
- Model → Model objects (never Schema objects)
- Domain → Domain objects (never Model or Schema objects)
- Higher layers encapsulate lower layer objects

3. **Clear Boundaries**
- Explicit interfaces between layers
- No leaking of implementation details
- Strong encapsulation within each layer

### Component Organization

1. **Schema Components**
```python
class Schema__MGraph__Node(Type_Safe):
# Only primitive types and other schemas
node_id: Random_Guid
value: Any
```

2. **Model Components**
```python
class Model__MGraph__Node:
# Only schema dependencies
data: Schema__MGraph__Node

def value(self) -> Any:
return self.data.value
```

3. **Domain Components**
```python
class MGraph__Node:
# Only model dependencies
node: Model__MGraph__Node

def value(self) -> Any:
return self.node.value()
```

### Implementation Guidelines

1. **Schema Layer**
- No business logic
- Only type definitions and basic validation
- No external dependencies except for type definitions
- Must be serializable

2. **Model Layer**
- Basic business logic
- Data validation and manipulation
- Depends only on Schema layer
- Returns only Model objects
- Encapsulates Schema objects internally
- Handles type conversion

3. **Domain Layer**
- Complex business logic
- High-level operations
- Workflow orchestration
- External system integration

### Testing Strategy

1. **Schema Tests**
- Focus on type validation
- Test serialization/deserialization
- Verify constraints

2. **Model Tests**
- Test business logic
- Verify data manipulation
- Test validation rules

3. **Domain Tests**
- Test workflows
- Verify high-level operations
- Test integration scenarios

### Error Handling

1. **Schema Layer**
- Type validation errors
- Constraint violations
- Serialization errors

2. **Model Layer**
- Business rule violations
- Data validation errors
- State transition errors

3. **Domain Layer**
- Workflow errors
- Integration errors
- Business process errors

### Benefits

1. **Maintainability**
- Clear separation of concerns
- Isolated changes
- Easy to understand dependencies

2. **Testability**
- Each layer can be tested independently
- Clear boundaries for mocking
- Isolated test scenarios

3. **Flexibility**
- Easy to modify implementation details
- Simple to add new features
- Clear upgrade paths

### Common Pitfalls to Avoid

1. **Breaking Layer Isolation**
```python
# BAD: Domain layer using Schema directly
class MGraph__Node:
def __init__(self, schema: Schema__MGraph__Node): ...

# GOOD: Domain layer using Model
class MGraph__Node:
def __init__(self, node: Model__MGraph__Node): ...
```

2. **Leaking Implementation Details**
```python
# BAD: Exposing schema internals
class Model__MGraph__Node:
def get_raw_data(self) -> Schema__MGraph__Node: ...

# GOOD: Maintaining abstraction
class Model__MGraph__Node:
def value(self) -> Any: ...
```

3. **Circular Dependencies**
```python
# BAD: Cross-layer dependencies
class Schema__MGraph__Node:
model: Model__MGraph__Node # WRONG!

# GOOD: Maintaining hierarchy
class Schema__MGraph__Node:
node_id: Random_Guid
```

### Best Practices

1. **Clear Naming**
- Schema classes: `Schema__*`
- Model classes: `Model__*`
- Domain classes: `MGraph__*`

2. **Type Safety**
- Use type hints consistently
- Validate at layer boundaries
- Document type constraints

3. **Error Handling**
- Define clear error hierarchies
- Handle errors at appropriate layers
- Maintain error context

4. **Documentation**
- Document layer responsibilities
- Specify type contracts
- Explain validation rules

### Migration Path

When adding new features:

1. Start with Schema layer
- Define data structures
- Add type definitions
- Implement validation

2. Build Model layer
- Implement business logic
- Add data manipulation
- Handle validation

3. Create Domain layer
- Add high-level operations
- Implement workflows
- Handle integration

### Conclusion

This architecture provides a robust foundation for building maintainable and scalable graph-based applications. The strict layering and clear responsibilities make it easy to understand, test, and extend the system while maintaining code quality and type safety.
110 changes: 110 additions & 0 deletions docs/formatting-philosophy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Code Formatting Philosophy and Principles

## Core Principles

### 1. Visual Pattern Recognition
The human brain excels at pattern recognition. This formatting prioritizes creating clear visual patterns that make code structure immediately apparent:
- Aligned equals signs create vertical lanes that guide the eye
- Consistent comma placement creates predictable rhythm
- Grouped imports with aligned elements form distinct visual blocks

### 2. Information Density vs Readability
While PEP-8 often spreads code across many lines for "readability", this approach recognizes that excessive vertical spread can actually harm comprehension by:

- Forcing more scrolling
- Breaking mental context
- Making patterns harder to spot
- Reducing the amount of code visible at once

### 3. Contextual Proximity
Related information should be visually close to enhance understanding:
- Method documentation appears on the same line as the method definition
- Constructor parameters align vertically to show relationships
- Dictionary key-value pairs maintain close horizontal proximity

## Departures from PEP-8

### Why We Differ

PEP-8's formatting guidelines, while well-intentioned, can create several practical issues:

1. Vertical Space Inefficiency
```python
# PEP-8 style
self.method_call(
parameter_one="value",
parameter_two="value",
parameter_three="value"
)

# This style
self.method_call(parameter_one = "value",
parameter_two = "value",
parameter_three = "value")
```

2. Loss of Visual Patterns
```python
# PEP-8 style
assert something.value == expected_value
assert something_else.other_value == other_expected_value
assert third_thing.final_value == final_expected_value

# This style
assert something.value == expected_value
assert something_else.value == other_expected_value
assert third_thing.final_value == final_expected_value
```

3. Broken Visual Context
```python
# PEP-8 style - related elements separated
class SomeClass:

def __init__(
self,
param_one,
param_two
):
self.param_one = param_one
self.param_two = param_two

# This style - related elements together
class SomeClass:
def __init__(self, param_one,
param_two ):
self.param_one = param_one
self.param_two = param_two
```

## Benefits of Our Approach

1. Enhanced Scanning
- Column alignment makes it easy to scan for specific elements
- Consistent patterns reduce cognitive load
- Related information stays visually grouped

2. Better Maintainability
- Alignment makes inconsistencies immediately visible
- Format violations stand out visually
- Pattern adherence encourages consistent updates

3. Improved Debugging
- Clear visual structure helps spot logical errors
- Aligned comparisons make value mismatches obvious
- Grouped information reduces context switching

4. Code Review Efficiency
- Structured patterns make changes more apparent
- Consistent formatting reduces noise in diffs
- Visual grouping helps reviewers understand intent

## Real-World Impact

This formatting approach has proven particularly valuable in:
- Large codebases where pattern recognition becomes crucial
- Test files where structure and relationships matter more than PEP-8 conformity
- Code review processes where visual clarity speeds up reviews
- Debugging sessions where quick scanning and pattern recognition are essential

Our philosophy prioritizes human factors and practical utility over strict adherence to style guidelines, recognizing that code is read far more often than it is written.
Loading

0 comments on commit 1f57060

Please sign in to comment.