Architecture Overview
Framework Philosophy
This framework is built around the principle of Explicit Service Architecture with clear separation of concerns and comprehensive service coverage for all domain entities.
Core Principles
- Service-Driven Design - Every domain entity has a complete suite of specialized services
- Maestro Pattern - Business logic orchestrated through sequential step execution
- Explicit Dependencies - Clear dependency injection with no hidden dependencies
- Database Abstraction - Support for multiple databases through consistent interfaces
- Type Safety - Strong typing throughout with compile-time guarantees
High-Level Architecture
┌─────────────────────────────────────────────────────────────┐
│ HTTP Layer (Gin) │
├─────────────────────────────────────────────────────────────┤
│ Controllers & Binders │ HTML Views │ JSON Views │
├─────────────────────────────────────────────────────────────┤
│ Business Logic (Mae) │
├─────────────────────────────────────────────────────────────┤
│ Service Layer (srv) │
│ Fetchers │ Handlers │ Hydrators │ Molders │ Serializers │
├─────────────────────────────────────────────────────────────┤
│ Domain Models (mdl) & Data (dat) │
├─────────────────────────────────────────────────────────────┤
│ Shared Libraries (lib) │
├─────────────────────────────────────────────────────────────┤
│ Database Layer (SQLite/PostgreSQL) │
└─────────────────────────────────────────────────────────────┘
Layer Responsibilities
HTTP Layer
- Gin Router - HTTP request routing and middleware
- Controllers - Request handling and response formatting
- Binders - HTTP request data binding to forms
- Views - HTML and JSON response generation
Business Logic Layer (Mae)
- Maestro Modules - Orchestrate complex business operations
- Sequential Steps - Execute business logic in defined order
- Cross-Entity Operations - Handle operations spanning multiple entities
- Validation & Rules - Enforce business rules and constraints
Service Layer (srv)
- Fetchers - Data retrieval with filtering and pagination
- Handlers - CRUD operations with transaction support
- Hydrators - Relationship loading with preset configurations
- Molders - Form-to-entity transformation with change tracking
- Serializers - Entity-to-JSON conversion for APIs
- Tables - Database-to-entity mapping with ESO pattern
Domain Layer
- Models (mdl) - Core domain entities with business rules
- Data Structures (dat) - Forms, constants, and Mae input/output types
- Relationships - Entity associations and constraints
Shared Libraries (lib)
- Framework Core - Maestro pattern implementation
- Database Abstraction - Multi-database support layer
- Utilities - Common functionality (validation, time, logging)
- Middleware - HTTP middleware components
Service Architecture Pattern
Complete Service Suite
Every domain entity receives a complete service suite:
// For each Entity (e.g., Garden)
type Services struct {
GardenFetcher *fetchers.GardenFetcher // Data retrieval
GardenHandler *handlers.GardenHandler // CRUD operations
GardenHydrator *hydrators.GardenHydrator // Relationship loading
GardenMolder *molders.GardenFormMolder // Form transformation
GardenSerializer *serializers.GardenSerializer // JSON conversion
GardenStringer *stringers.GardenStringer // String representation
GardenTable *tables.GardenTable // Database mapping
GardenRelationer *relationers.GardenRelationer // Relationship management
}
Service Interactions
Form Data → Binder → Molder → Mae → Handler → Database
↓ ↓
Validation Fetcher ← Hydrator ← Relationer
↓ ↓
Controller ← Serializer ← Entity ← Table
Data Flow Patterns
Request Processing Flow
- HTTP Request arrives at Gin router
- Controller receives request and extracts parameters
- Binder extracts form data from request
- Mae orchestrates business logic execution
- Services perform data operations (Fetch, Handle, Hydrate)
- View formats response (HTML template or JSON)
Entity Lifecycle
- Form Creation - User input structured as form objects
- Validation - Form validation and business rule checking
- Transformation - Molder converts form to entity
- Persistence - Handler saves entity to database via Table
- Retrieval - Fetcher loads entity from database
- Hydration - Hydrator loads related entities
- Serialization - Serializer converts to JSON for API responses
Dependency Injection Architecture
Container Pattern
type Container struct {
// Database
SqlDb *sql_db.SqlDb
// Tables
GardenTable *tables.GardenTable
UserTable *tables.UserTable
// Services
GardenFetcher *fetchers.GardenFetcher
GardenHandler *handlers.GardenHandler
// Business Logic
CreateGardenMae *mae.CreateGardenMae
}
func (c *Container) Build() {
// Wire dependencies
c.GardenFetcher = &fetchers.GardenFetcher{
Fetcher: c.Fetcher,
GardenTable: c.GardenTable,
}
}
Service Resolution
- Explicit Wiring - All dependencies declared in container
- Compile-Time Safety - Missing dependencies cause build failures
- Clear Dependencies - Service dependencies are visible and traceable
- No Magic - No reflection or runtime dependency resolution
Database Architecture
Multi-Database Support
type SqlDb interface {
Query(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
Exec(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
Create(ctx context.Context, tx *sql.Tx, table string, columns []string, values []interface{}) (string, int, error)
}
// Implementations
type SQLiteDb struct { /* SQLite-specific */ }
type PostgreSQLDb struct { /* PostgreSQL-specific */ }
ESO (Entity Storage Object) Pattern
// Domain Entity
type Garden struct {
Id string
CreatedAt time.Time
Name string
}
// Entity Storage Object (database-compatible)
type GardenEso struct {
Id string
CreatedAt sql.NullTime // Handles NULL values
Name string
}
// Conversion methods
func (table *GardenTable) EsoToEntity(eso *GardenEso) *Garden
func (table *GardenTable) EntityToValues(entity *Garden) []interface{}
Error Handling Architecture
Error Propagation
- Mae Level - Business logic errors with context
- Service Level - Operation-specific errors
- Database Level - Connection and query errors
- HTTP Level - Request/response errors
Error Types
// Business Logic Errors
type MaeError struct {
Operation string
Message string
Context map[string]interface{}
}
// Validation Errors
type ValidationError struct {
Field string
Message string
}
// Database Errors
type DatabaseError struct {
Query string
Operation string
Cause error
}
Performance Architecture
Query Optimization
- Batch Loading - Relationers prevent N+1 queries
- Selective Hydration - Load only requested relationships
- Pagination - Built-in pagination support in Fetchers
- Indexing - Database index management
Caching Strategy
- Entity Caching - Configurable entity-level caching
- Query Result Caching - Fetcher result caching
- Search Index Caching - In-memory search indices
- Session Caching - HTTP session state caching
Testing Architecture
Layer Testing
- Mae Testing - Business logic unit tests
- Service Testing - Service integration tests
- HTTP Testing - Controller and route tests
- Database Testing - Repository pattern tests
Test Structure
func TestCreateGardenMae(t *testing.T) {
// Arrange - Setup test dependencies
// Act - Execute Mae operation
// Assert - Verify results and side effects
}
LLM Architecture Notes
When working with this architecture:
- Service Generation - Create complete service suite for new entities
- Mae Pattern - Use Mae modules for multi-step business operations
- ESO Mapping - Follow ESO pattern for database operations
- Dependency Injection - Wire services explicitly in container
- Error Handling - Propagate errors with appropriate context
- Testing Strategy - Test at Mae level for business logic validation
The architecture prioritizes explicitness and type safety over convenience, resulting in more code but with better maintainability and fewer runtime errors.