vandor.
CLI Reference

vandor add

Add domain layer components to your Vandor project

vandor add

Add bounded contexts, domains, use cases, services, and value objects to your project.

Synopsis

vandor add <component-type> <args...> [flags]

Description

The vandor add command creates domain layer components following Domain-Driven Design principles. Every subcommand uses space-separated positional arguments -- not slash notation. After adding a component, Vandor automatically triggers a sync to keep your wiring code up to date.

Auto-sync on add. You do not need to manually run vandor sync after every vandor add. The add command takes care of it. If you want to skip the automatic sync, you can use the --tidy never flag.

Subcommands

context       Add a new bounded context
domain        Add a domain to an existing context
usecase       Add a use case to a context
service       Add a domain service to a context
valueobject   Add a value object to a context

vandor add context

Create a new bounded context. A context is a self-contained area of your application that groups related domains, use cases, and services together.

Usage

vandor add context <name> [flags]

Flags

--minimal              Create a minimal context (fewer generated files)
--full                 Create a full context with all directories (default)
--with-builder         Include a builder pattern for the context module
--without-read-repo    Skip generating the read repository port
--tidy auto|always|never   When to run go mod tidy (default: auto)

Examples

# Create a context with default settings
vandor add context order

# Create a minimal context
vandor add context notification --minimal

# Full context with builder pattern
vandor add context identity --full --with-builder

# Context without read repository
vandor add context analytics --without-read-repo

What Gets Created

internal/context/order/
  core/
    domain/            Domain models
    port/              Port interfaces (repository, services)
    service/           Domain services
  usecase/             Use cases
  module.go            FX module wiring (your code)
  module_gen.go        Generated FX module wiring (auto-generated)

vandor add domain

Add a domain model to an existing context. Domains represent your core business entities -- the things your application manages and the rules around them.

Usage

vandor add domain <context> <name> [flags]

Note the space-separated arguments: the context name comes first, then the domain name.

Flags

--with-builder         Include a builder pattern for the domain

Examples

# Add an Order domain to the order context
vandor add domain order Order

# Add a User domain to the identity context
vandor add domain identity User

# Add a domain with builder pattern
vandor add domain order Order --with-builder

# Add multiple domains to the same context
vandor add domain catalog Product
vandor add domain catalog Category

What Gets Created

internal/context/order/core/domain/
  order.go              Domain model with fields and constructor

If --with-builder is used, a builder file is also created for fluent construction of the domain object.

Domains are business capabilities, not database tables. Do not create a domain for every table in your database. Instead, think about what business concepts your application manages. An order context might contain Order, OrderItem, and ShippingAddress domains -- all part of the same business capability.


vandor add usecase

Add a use case to a context. Use cases represent application-level operations -- the things your users can do. They orchestrate domain logic and coordinate between different parts of your system.

Usage

vandor add usecase <context> <name>

Examples

# Add a CreateOrder use case to the order context
vandor add usecase order CreateOrder

# Add more use cases
vandor add usecase order CancelOrder
vandor add usecase order GetOrderByID
vandor add usecase identity RegisterUser
vandor add usecase identity AuthenticateUser

What Gets Created

internal/context/order/usecase/
  create_order.go         Use case implementation with Input/Output types

Generated Code Structure

The generated use case follows a consistent pattern:

package usecase

import "context"

type CreateOrderInput struct {
    // Define your input fields here
}

type CreateOrderOutput struct {
    // Define your output fields here
}

type CreateOrder struct {
    // Inject dependencies via constructor
}

func NewCreateOrder(/* dependencies */) *CreateOrder {
    return &CreateOrder{}
}

func (uc *CreateOrder) Execute(ctx context.Context, input CreateOrderInput) (*CreateOrderOutput, error) {
    // Implement your business logic here
    return &CreateOrderOutput{}, nil
}

vandor add service

Add a domain service to a context. Domain services handle business logic that does not naturally belong to a single domain entity -- for example, pricing calculations that depend on multiple domains or cross-cutting validation rules.

Usage

vandor add service <context> <name>

Examples

# Add a PriceCalculator service to the order context
vandor add service order PriceCalculator

# Add other services
vandor add service order ShippingCalculator
vandor add service order InventoryChecker
vandor add service identity PasswordHasher

What Gets Created

internal/context/order/core/service/
  price_calculator.go     Service implementation

Generated Code Structure

package service

import "context"

type PriceCalculator struct {
    // Dependencies
}

func NewPriceCalculator(/* dependencies */) *PriceCalculator {
    return &PriceCalculator{}
}

func (s *PriceCalculator) Calculate(ctx context.Context /* params */) (float64, error) {
    // Domain logic here
    return 0.0, nil
}

vandor add valueobject

Add a value object to a context. Value objects are immutable types that represent concepts in your domain -- things like status codes, currency amounts, email addresses, or any typed constant.

Usage

vandor add valueobject <context> <name> [flags]

Flags

--kind string              Underlying Go type: string, int, float64, bool, time (default: string)
--enum A,B,C               Comma-separated enum values for this value object

Examples

# String-based enum value object
vandor add valueobject order Status --kind string --enum pending,processing,completed,cancelled

# Integer-based value object
vandor add valueobject order Priority --kind int --enum 1,2,3

# Boolean value object
vandor add valueobject identity IsVerified --kind bool

# Simple string value object without enum
vandor add valueobject identity Email --kind string

# Time-based value object
vandor add valueobject order ShipByDate --kind time

What Gets Created

For a string enum value object:

internal/context/order/core/domain/
  order_status.go         Value object with enum values and validation

Generated Code (String Enum Example)

package domain

type OrderStatus string

const (
    OrderStatusPending    OrderStatus = "pending"
    OrderStatusProcessing OrderStatus = "processing"
    OrderStatusCompleted  OrderStatus = "completed"
    OrderStatusCancelled  OrderStatus = "cancelled"
)

func (s OrderStatus) IsValid() bool {
    switch s {
    case OrderStatusPending, OrderStatusProcessing, OrderStatusCompleted, OrderStatusCancelled:
        return true
    default:
        return false
    }
}

func (s OrderStatus) String() string {
    return string(s)
}

Component Naming Conventions

ComponentNaming StyleExample
Contextlowercaseorder, identity, catalog
DomainPascalCaseOrder, User, Product
Use casePascalCaseCreateOrder, RegisterUser
ServicePascalCasePriceCalculator, PasswordHasher
Value objectPascalCaseStatus, PaymentMethod, Email

The --tidy Flag

The --tidy flag controls when go mod tidy runs after adding a component:

  • auto (default): Runs go mod tidy when it appears necessary.
  • always: Always runs go mod tidy.
  • never: Skips go mod tidy.

Workflow Example

Here is a typical workflow for building out a new feature area:

# 1. Create the bounded context
vandor add context order

# 2. Add domain models
vandor add domain order Order --with-builder
vandor add domain order OrderItem

# 3. Add value objects
vandor add valueobject order Status --kind string --enum pending,processing,completed,cancelled
vandor add valueobject order PaymentMethod --kind string --enum credit_card,debit_card,bank_transfer

# 4. Add domain services
vandor add service order PriceCalculator

# 5. Add use cases
vandor add usecase order CreateOrder
vandor add usecase order CancelOrder
vandor add usecase order GetOrderByID

# 6. Install infrastructure packages
vandor vpkg add @official/http-humachi
vandor vpkg add @official/entgo

# 7. Start developing
vandor dev:app

Troubleshooting

Context not found

Error: context "catalog" not found

You need to create the context before adding components to it:

vandor add context catalog
vandor add domain catalog Product

Invalid naming

Error: invalid component name "create-order"

Use PascalCase for domains, use cases, services, and value objects. Use lowercase for context names.

Domain already exists

Error: domain "Order" already exists in context "order"

Choose a different name, or remove the existing domain file manually if you want to recreate it.