ddd_pod_cli

A robust, enterprise-grade Dart & Flutter CLI tool that scaffolds complete Domain-Driven Design (DDD) Feature-First architecture code structures. It generates Riverpod 2.0 controllers/states, Freezed models, type-safe DTOs with fpdart Either, and full DIO data-source layers directly from a single JSON configuration file or a live cURL command.


Key Features

  • ๐Ÿ—๏ธ Feature-First DDD Scaffolding: Automatically generates a clean layer structure (domain, infrastructure, application, and optional presentation).
  • โšก Riverpod 2.0 Integration: Generates modern notifier classes (Notifier, AsyncNotifier, or FutureProvider) using the latest generator annotations.
  • โ„๏ธ Freezed Model Generation: Scaffolds immutable domain models and DTOs with full fromJson/toJson support.
  • ๐ŸŒ cURL-to-DDD Generation: Paste any cURL request, and the CLI will hit the endpoint, perform type inference on the response JSON, and build the entire architecture on the fly.
  • ๐Ÿ—’๏ธ Form & Validation Generation: Define declarative field validation rules in JSON to auto-scaffold Freezed form states, validation controllers, and inputs.
  • ๐Ÿ“ฆ Re-usable Core Models: Scans your project to detect and reuse existing domain models to avoid duplicate file generation.
  • ๐Ÿ’พ Offline Caching: Scaffolds a SharedPreferences-backed offline cache layer automatically with a single config flag.
  • ๐Ÿงช Unit Test Scaffolding: Generates pre-wired unit tests with mock repositories for the application layer.

Installation

Activate the CLI globally via pub.dev:

dart pub global activate ddd_pod_cli

Make sure your system PATH includes the Dart SDK cache bin directory.


Flutter Project Setup

Before generating code or using the generated structures, ensure your Flutter project has the correct dependencies installed. The generated code relies on packages like Riverpod 2.0, Freezed, fpdart, and Dio.

1. Add Dependencies

Run the following commands in your target Flutter project directory:

# Add application dependencies
flutter pub add flutter_riverpod riverpod_annotation freezed_annotation json_annotation fpdart dio shared_preferences

# Add development dependencies (code generators)
flutter pub add dev:build_runner dev:riverpod_generator dev:freezed dev:json_serializable

2. Verify pubspec.yaml

Your pubspec.yaml should include these dependencies under their respective sections:

dependencies:
  flutter:
    sdk: flutter
  flutter_riverpod: ^2.5.1
  riverpod_annotation: ^2.3.5
  freezed_annotation: ^2.4.4
  json_annotation: ^4.9.0
  fpdart: ^1.1.0
  dio: ^5.5.0
  shared_preferences: ^2.2.3 # Required for offline cache generation

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.9
  riverpod_generator: ^2.4.0
  freezed: ^2.5.2
  json_serializable: ^6.8.0

Quick Start

Step 1: Initialize Configuration

Run init in your project root to generate a template configuration file:

ddd init

This creates a pre-configured config.json with instructions on custom configurations.

Step 2: Configure & Generate

Edit the generated config.json to define your feature schema, then run:

ddd generate

This will:

  1. Parse the JSON schema configuration.
  2. Scaffold all directories in lib/features/your_feature/.
  3. Auto-generate all required DTOs, models, notifier controllers, repository contracts, and network layers.
  4. Auto-run build_runner to compile Freezed and Riverpod files.

CLI Commands Reference

ddd init

Creates a documented template config.json file in the current or specified directory.

  • Options:
    • -o, --output <DIR>: Directory to write the template file into (defaults to .).

ddd generate

Generates a DDD feature from a JSON configuration file.

  • Options:
    • -c, --config <FILE>: Path to the JSON configuration file (defaults to config.json).
    • -f, --force: Overwrite existing files without prompting.
    • --skip-build-runner: Skip running build_runner after code generation.
    • --debug-view: Generate a mock debug/presentation page.

ddd curl

Executes a live API request and scaffolds a DDD feature directly from the live response JSON.

  • Usage:
    ddd curl "curl -X GET https://api.example.com/v1/users" --feature-name User
    
  • Options:
    • -n, --feature-name <NAME>: PascalCase name of the feature (required).
    • --provider-type <TYPE>: Riverpod provider type (notifier | async_notifier | future_provider).
    • -f, --force: Overwrite existing files without prompting.
    • --skip-build-runner: Skip running build_runner after generation.
    • --debug-view: Generate a mock debug/presentation page.

ddd delete

Removes all generated files and directories for a given feature.

  • Usage:
    ddd delete MyFeature
    
  • Options:
    • --dry-run: Prints what would be deleted without removing files.
    • --skip-build-runner: Skip running build_runner after deletion.

ddd version

Prints the CLI package version.


Configuration File Structure (config.json)

Here is an explanation of the core configuration parameters:

{
  "feature_name": "UserProfile",         // PascalCase feature name used as prefix
  "api_path": "/api/v1/users/:id",       // API endpoint path (interpolates :param)
  "methods": ["GET", "PUT"],            // Supported HTTP methods
  "provider_type": "async_notifier",     // Riverpod provider type: async_notifier | notifier | future_provider
  "get_response_dto": {                  // Response JSON structure for type-inference
    "id": 1,
    "name": "Jane Doe",
    "is_premium": true
  },
  "post_request_body": {                 // Request body JSON structure for POST/PUT requests
    "name": "Jane Doe"
  },
  "type_overrides": {                    // Manually override inferred types
    "created_at": "DateTime"
  },
  "field_mapping": {                     // Rename JSON payload keys to custom Dart fields
    "is_premium": "isPremiumUser"
  },
  "is_paginated_list": false,            // Scaffolds paginated lists (fetchNextPage, hasMore)
  "offline_cache": true,                 // Scaffolds SharedPreferences database caching
  "validation_rules": {                  // Form input validation rules
    "name": {
      "required": true,
      "min_length": 3,
      "error_msg": "Name must be at least 3 characters"
    }
  }
}

Generated Directory Structure

A generated feature (e.g. UserProfile) follows this structure:

lib/features/user_profile/
โ”œโ”€โ”€ domain/
โ”‚   โ”œโ”€โ”€ failures.dart               // Custom business logic network/caching failures
โ”‚   โ”œโ”€โ”€ user_profile.dart          // Immutable Freezed domain entity
โ”‚   โ””โ”€โ”€ user_profile_repository.dart // Abstract repository interface contract
โ”œโ”€โ”€ infrastructure/
โ”‚   โ”œโ”€โ”€ datasources/
โ”‚   โ”‚   โ”œโ”€โ”€ user_profile_local_datasource.dart // (Optional) SharedPreferences cache layer
โ”‚   โ”‚   โ””โ”€โ”€ user_profile_remote_datasource.dart // DIO network request client
โ”‚   โ”œโ”€โ”€ dtos/
โ”‚   โ”‚   โ””โ”€โ”€ user_profile_dto.dart   // JSON serializers and toDomain/fromDomain converters
โ”‚   โ””โ”€โ”€ user_profile_repository_impl.dart // Concrete repository implementation
โ””โ”€โ”€ application/
    โ”œโ”€โ”€ user_profile_notifier.dart  // Riverpod StateNotifier/Notifier logic
    โ”œโ”€โ”€ user_profile_state.dart     // UI/Application state representation
    โ””โ”€โ”€ user_profile_provider.dart  // Auto-wired Riverpod providers

License

This project is licensed under the MIT License - see the LICENSE file for details.

Libraries

ddd_pod_cli
ddd_pod_cli โ€” Professional DDD + Riverpod + Freezed Code Generator.