# Forge Library

This directory contains the core business logic and data layers for the Forge framework, organized into modular, reusable crates that follow clean architecture principles.

## Architecture Overview

The library follows a **layered architecture** pattern, ensuring separation of concerns and maintainability:

```mermaid
graph TD
    Extension[Extension Layer<br/>#40;ArmA 3 Interface#41;]
    Services[Services Layer<br/>#40;Business Logic#41;]
    Repositories[Repositories Layer<br/>#40;Data Persistence#41;]
    Models[Models Layer<br/>#40;Data Structures#41;]

    Extension --> Services
    Services --> Repositories
    Repositories --> Models
```

## Modules

### Models (`lib/models`)

**Purpose**: Defines strict data structures and validation rules for domain entities.

**Responsibilities**:
- Define entity structures (`Actor`, `Org`)
- Implement validation logic
- Handle serialization/deserialization (JSON, Arma)
- Enforce business rules at the data level

**Key Features**:
- Strong typing with Rust structs
- Built-in validation on creation and updates
- Automatic email generation for actors
- Arma-specific type conversions

**Documentation**: [models/README.md](models/README.md)

### Repositories (`lib/repositories`)

**Purpose**: Manages data persistence and retrieval using Redis.

**Responsibilities**:
- Abstract database operations
- Implement CRUD operations
- Handle data serialization to Redis formats
- Manage Redis keys and data structures

**Key Features**:
- Generic over Redis client implementations
- Hash-based storage for structured data
- Set-based storage for collections (e.g., org members)
- Thread-safe operations (`Send + Sync`)

**Documentation**: [repositories/README.md](repositories/README.md)

### Services (`lib/services`)

**Purpose**: Implements business logic, validation, and orchestration of operations.

**Responsibilities**:
- Coordinate between repositories
- Enforce business rules
- Handle complex workflows
- Provide high-level APIs for the extension layer

**Key Features**:
- Generic over repository implementations
- Stateless service design
- Get-or-create patterns for entities
- Comprehensive error handling

**Documentation**: [services/README.md](services/README.md)

### Shared (`lib/shared`)

**Purpose**: Provides common utilities, traits, and helper functions used across all layers.

**Responsibilities**:
- Define shared traits (`RedisClient`)
- Provide utility functions
- Common type definitions
- Cross-cutting concerns

**Key Features**:
- `RedisClient` trait for repository abstraction
- JSON/Redis value parsing utilities
- Arma value conversion helpers
- Reusable helper functions

## How It All Works Together

### Example: Creating an Actor

Here's how the layers interact when creating a new actor:

1. **Extension Layer** receives SQF command:
   ```rust
   // arma/server/extension/src/actor.rs
   pub fn create_actor(key: String, data: String) -> String {
       // Parse JSON and call service
       ACTOR_SERVICE.create_actor(uid, json_data)
   }
   ```

2. **Service Layer** validates and orchestrates:
   ```rust
   // lib/services/src/actor.rs
   impl<R: ActorRepository> ActorService<R> {
       pub fn create_actor(&self, uid: String, data: String) -> Result<Actor, String> {
           // Create actor model (validates data)
           let actor = Actor::new(uid, data)?;

           // Persist via repository
           self.repository.create(&actor)?;

           Ok(actor)
       }
   }
   ```

3. **Repository Layer** persists to Redis:
   ```rust
   // lib/repositories/src/actor.rs
   impl<C: RedisClient> ActorRepository for RedisActorRepository<C> {
       fn create(&self, actor: &Actor) -> Result<(), String> {
           // Convert actor to Redis hash
           let fields = actor.to_redis_fields();

           // Store in Redis
           self.client.hash_mset(format!("actor:{}", actor.uid), fields)
       }
   }
   ```

4. **Model Layer** ensures data integrity:
   ```rust
   // lib/models/src/actor.rs
   impl Actor {
       pub fn new(uid: String, data: String) -> Result<Self, String> {
           // Validate all fields
           Self::validate(&uid, &data)?;

           // Create actor with validated data
           Ok(Actor { uid, /* ... */ })
       }
   }
   ```

## Contributing

We welcome contributions to the Forge library! Follow these guidelines to maintain consistency and quality.

### Adding a New Model

See [models/README.md - Contributing](models/README.md#contributing)

**Summary**:
1. Define struct with validation rules
2. Implement `new` and `validate` methods
3. Add serialization traits (`Serialize`, `Deserialize`)
4. Implement Arma conversions (`FromArma`, `IntoArma`)

### Adding a New Repository

See [repositories/README.md - Contributing](repositories/README.md#contributing)

**Summary**:
1. Define repository trait with `Send + Sync`
2. Implement trait for `RedisXRepository<C: RedisClient>`
3. Use `forge_shared::RedisClient` for operations
4. Register module in `lib.rs`

### Adding a New Service

See [services/README.md - Contributing](services/README.md#contributing)

**Summary**:
1. Create service struct generic over repository
2. Implement constructor and business logic methods
3. Delegate data operations to repository
4. Register module in `lib.rs`

### Best Practices

#### Separation of Concerns
- **Models**: Only data structures and validation
- **Repositories**: Only data persistence logic
- **Services**: Only business logic and orchestration
- **Shared**: Only common utilities and traits

#### Error Handling
- Use `Result<T, String>` for all fallible operations
- Provide descriptive error messages
- Propagate errors up the stack with `?`

#### Testing
- **Models**: Test validation rules
- **Repositories**: Test with mock Redis clients
- **Services**: Test with mock repositories
- **Integration**: Test full stack in extension layer

#### Dependencies
- Models should have minimal dependencies
- Repositories depend on models and shared
- Services depend on repositories and models
- Avoid circular dependencies

#### Thread Safety
- All repository traits require `Send + Sync`
- Services are stateless and thread-safe
- Use appropriate synchronization primitives when needed

## Module Dependencies

```mermaid
graph TD
    Shared[Shared<br/>#40;No Dependencies#41;]
    Models[Models<br/>#40;Depends on Shared#41;]
    Repositories[Repositories<br/>#40;Depends on Models, Shared#41;]
    Services[Services<br/>#40;Depends on Repositories, Models#41;]
    Extension[Extension<br/>#40;Depends on Services, Repositories, Models, Shared#41;]

    Shared --> Services
    Services --> Repositories
    Repositories --> Models
    Models --> Extension
```

## Development Workflow

1. **Define Model**: Start with data structure and validation
2. **Create Repository**: Implement persistence layer
3. **Build Service**: Add business logic
4. **Expose in Extension**: Create SQF-callable commands
5. **Test**: Verify each layer independently and together

## Additional Resources

- [Extension Documentation](../arma/server/extension/README.md)
- [Redis Operations](../arma/server/extension/src/redis/README.md)
- [Adapters](../arma/server/extension/src/adapters/README.md)
