Skip to main content
The packages/core directory houses the central business logic, decoupled from any specific UI implementation.
FolderResponsibilityKey Technologies / Patterns
actions/Server-side functions callable from client. Validates input, instantiates and starts the appropriate XState machine, awaits its final result.Next.js Server Actions
machines/Define and manage complex stateful workflows (State Pattern). Orchestrates the business logic flow, preparing DTOs, invoking methods on resolved Service implementations, and processing output DTOs.XState
services/Encapsulate discrete domain operations via a structured Service Layer (Strategy Pattern). Implements specific tasks (DB interaction, API calls) invoked by machines, using the contract defined by its interface and method DTOs.TypeScript Interfaces/Classes. Interface & Method DTOs defined in services/[domain]/domain/. Implementations in services/[domain]/implementations/.
types/Define shared base data structures (Entities), common utility types, and types for XState machines, organized into subdirectories (common/, entities/, machines/). Excludes service method DTOs.TypeScript
validation/Define data validation schemas, primarily used by actions/ before starting a machine.Yup (InferType)
For the standard flow connecting these layers, see the Core Workflow Guide.

Service Layer Structure (packages/core/services/[domain]/)

Services provide concrete implementations of specific business operations, invoked by state machines. The structure within each service domain directory (e.g., packages/core/services/user/) follows a clear pattern promoting the separation of abstraction from implementation:
  1. domain/: This directory defines the Abstraction Layer for the service. It contains only:
    • [Domain]Service.ts: The TypeScript interface defining the service contract (e.g., UserService). This specifies what operations the service provides.
    • [Domain]Types.ts: Defines the Data Transfer Objects (DTOs) – the specific TypeScript types/interfaces for the input parameters and return values of each method declared in the [Domain]Service.ts interface (e.g., CreateUserMethodInput, CreateUserMethodOutput). This specifies the shape of the data the service works with at its boundary.
    • Crucially, this folder does not contain any implementation logic or reference types from other layers like validation directly.
  2. implementations/: Contains the concrete Strategy classes that implement the [Domain]Service.ts interface. Each file typically represents a different strategy or version of the service logic (e.g., DefaultUserService.ts, AdminUserService.ts). This is how the service operations are performed, potentially mapping input DTOs to internal types if needed.
  3. serviceMap.ts: Implements a Factory Method or Service Locator pattern. It typically exports a function (e.g., getUserService) that takes criteria (like a client ID, user role, feature flag) and returns the appropriate concrete service instance from the implementations/ directory. This map or its getter function needs to be accessible to the XState machine (e.g., passed via context or imported directly if appropriate).
  4. index.ts: A simple barrel file that exports the public API of the service module, primarily the factory/locator function from serviceMap.ts (e.g., export { getUserService } from './serviceMap';).

Core Types (packages/core/types/)

The types/ directory is crucial for maintaining consistency and enabling static analysis across the core logic.
packages/core/types/ Structure
types/
├── common/         # Truly generic types (e.g., PaginationResult)
├── entities/       # Core data models/entities (e.g., User, Document)
│   ├── User.ts
│   └── Document.ts
│   └── ...
├── machines/       # XState machine types (Context, Events), organized by machine/domain
│   ├── user/       # e.g., types for user machines
│   │   └── UserCreationMachineTypes.ts
│   ├── radicacion/ # e.g., types for radicacion machines
│   │   └── DocumentIntakeMachineTypes.ts
│   └── ...
└── index.ts        # Optional: Re-export key types
  • Entities: Represent the core data structures of the application (e.g., a User object matching the database schema).
  • Machine Types: Define the Context shape and possible Events for each XState machine, ensuring type safety during state transitions and logic execution. These are kept separate from Service DTOs.
  • Common Types: Utility types used across different domains (e.g., standardized API response wrappers, pagination structures).

Validation (packages/core/validation/)

All input coming from the client into a Server Action must be validated before processing.
  • Uses Yup for schema definition and validation.
  • Schemas are defined in packages/core/validation/, typically organized by domain (e.g., userSchema.ts).
  • Server Actions import and use these schemas to validate input.
  • Use yup.InferType<typeof yourSchema> to derive TypeScript types directly from schemas for use in Actions and potentially as the initial input type for Machines (validatedInput).
  • Validation errors should result in an early return from the Action with a structured error response (see ActionResult in the Core Workflow Guide).