Skip to content

Domain Layer

The domain layer contains business logic and domain entities extracted from the execution engine. This layer provides clean abstractions for tasks, parameters, and project configuration with clear separation of concerns.

Package Structure

internal/domain/
├── task/
│   ├── task.go           # Task entity with operations
│   ├── registry.go       # Task registration and lookup
│   └── dependencies.go   # Dependency resolution logic
├── parameter/
│   ├── parameter.go      # Parameter entity
│   └── validation.go     # Parameter validation & constraints
└── project/
    ├── project.go        # Project entity
    └── settings.go       # Settings management

Domain Entities

Task Domain

The task domain manages task entities, their registration, and dependency resolution:

  • Task: Represents a drun task with metadata, parameters, dependencies, and body
  • Registry: Thread-safe task registration and lookup with namespace support
  • DependencyResolver: Handles circular dependency detection and topological sorting

Parameter Domain

The parameter domain provides parameter validation with advanced constraints:

  • Parameter: Parameter entity with type information and constraints
  • Validator: Validates parameter values against data types, patterns, and ranges

Project Domain

The project domain manages project-level configuration:

  • Project: Project entity with settings, shell configs, and lifecycle hooks
  • SettingsManager: Manages project settings with defaults

Design Principles

  1. Domain-Driven Design: Business logic separated from infrastructure
  2. Single Responsibility: Each package has one clear purpose
  3. Testability: Domain logic can be tested in isolation
  4. Thread Safety: Registry provides concurrent access support
  5. Type Safety: Strong typing with validation

Usage

The domain layer is ready for integration with the engine. Currently, it exists as standalone packages that can be used independently or integrated into the execution flow.

Example: Task Registry

import "github.com/phillarmonic/drun/v2/internal/domain/task"

// Create registry
registry := task.NewRegistry()

// Register task
domainTask := task.NewTask(astTask, "namespace", "source.drun")
err := registry.Register(domainTask)

// Lookup task
foundTask, err := registry.Get("taskName")

// List all tasks
allTasks := registry.List()

Example: Parameter Validation

import "github.com/phillarmonic/drun/v2/internal/domain/parameter"

// Create validator
validator := parameter.NewValidator()

// Define parameter with constraints
param := &parameter.Parameter{
    Name:       "port",
    DataType:   "number",
    MinValue:   &minVal,  // 1
    MaxValue:   &maxVal,  // 65535
}

// Validate value
value := types.NewValue(types.NumberType, "8080")
err := validator.Validate(param, value)

Engine Integration

The domain layer is fully integrated with the execution engine:

Task Execution:

  • Engine uses task.Registry for task registration and lookup
  • task.DependencyResolver provides dependency ordering
  • Tasks execute using domain statements, not AST nodes

Parameter Validation:

  • parameter.Validator validates all parameter values
  • Supports advanced constraints (patterns, ranges, enums)
  • Type-safe parameter handling throughout execution

Project Management:

  • project.Project manages project-level configuration
  • Lifecycle hooks use domain statements
  • Project settings integration

Domain Statement System

The statement package (internal/domain/statement/) provides:

Statement Types:

  • Core: Action, Shell, Variable, Parameter
  • Control: Conditional, Loop, Try/Catch, Break, Continue
  • Operations: File, Docker, Git, HTTP, Network, Download
  • Advanced: Detection, TaskCall, TaskFromTemplate, UseSnippet

Converter:

  • FromAST() - Unidirectional converter from AST to domain (one-way only)
  • All execution uses pure domain types (no AST conversion during runtime)

Benefits:

  • Clean separation from parser internals
  • Type-safe domain entities
  • Easier testing and validation
  • Future-proof for engine improvements

Created: October 2025 Status: Complete & Integrated Usage: Production (all examples passing)