Skip to content

Add JSON Output to Create Command #349

@josecelano

Description

@josecelano

Overview

Add machine-readable JSON output format (--json flag) to the create command. This enables automation workflows to programmatically extract environment creation details like paths, configuration references, and initial state.

Specification

See detailed specification: docs/issues/add-json-output-to-create-command.md

(Link will be updated after file rename with issue number)

🏗️ Architecture Requirements

DDD Layer: Presentation (src/presentation/)
Module Path: src/presentation/views/commands/create/
Pattern: MVC - View layer with format switching

Prerequisites

⚠️ Refactoring Required First: The create command currently violates MVC separation by embedding output formatting in the controller. Before adding JSON support, we must extract the view layer to match the pattern used by provision, list, and show commands.

Module Structure Requirements

  • Extract view layer for create command (Phase 0)
  • Follow DDD layer separation (see docs/codebase-architecture.md)
  • Match architecture pattern from other commands (provision, list, show)
  • Respect dependency flow rules (dependencies flow toward domain)

Architectural Constraints

  • No business logic in presentation layer
  • Output formatting logic belongs in view layer, not controller
  • Error handling follows project conventions (see docs/contributing/error-handling.md)
  • Testing strategy aligns with layer responsibilities

Anti-Patterns to Avoid

  • ❌ Adding JSON support without extracting view layer first
  • ❌ Mixing format switching logic into controller
  • ❌ Creating technical debt by entrenching mixed concerns

Implementation Plan

Phase 0: Refactor - Extract View Layer (Prerequisite)

Purpose: Separate output formatting from controller logic to enable clean format switching.

  • Create view module structure: src/presentation/views/commands/create/
  • Create EnvironmentDetailsData struct (presentation DTO)
  • Implement From<&Environment<Created>> for data conversion
  • Create EnvironmentDetailsView with render_human_readable() method
  • Update controller to use view instead of direct formatting
  • Run golden test to verify output unchanged
  • Commit refactoring (preserving behavior)

Phase 1: Add CLI Flag

  • Add --json flag to create subcommand argument parser
  • Pass format flag through to presentation layer
  • No business logic changes

Phase 2: Add JSON Output Method to View

  • Add render_json() method to EnvironmentDetailsView
  • Implement JSON serialization using serde_json
  • Add Serialize derive to EnvironmentDetailsData
  • Include timestamp field (created_at) in JSON output

Phase 3: Implement Format Switching

  • Add conditional logic based on --json flag in controller
  • Call EnvironmentDetailsView::render_json() when flag set
  • Call EnvironmentDetailsView::render_human_readable() otherwise (default)
  • Handle JSON serialization errors appropriately

Phase 4: Documentation

  • Update user guide with JSON output examples
  • Document JSON schema
  • Add usage examples for automation

Phase 5: Testing

  • Manual testing: verify JSON is valid with --json flag
  • Manual testing: verify default output unchanged without flag
  • Manual testing: pipe to jq to verify parsability

Acceptance Criteria

Note for Contributors: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations.

Architecture

  • View layer extracted for create command (Phase 0 complete)
  • Controller delegates output formatting to view
  • View module structure matches provision, list, show commands
  • Golden test passes after refactoring (output unchanged)
  • Commit 1: Refactoring (behavior preserved)
  • Commit 2: JSON support (new feature)

Functionality

  • --json flag is accepted by create command
  • With --json flag, command outputs valid JSON to stdout
  • JSON contains all specified fields with correct values
  • JSON is parsable by standard tools (jq, serde_json, etc.)
  • Without --json flag, output is unchanged (human-readable format)
  • Errors are still output to stderr (not to stdout)

Code Quality

  • Pre-commit checks pass: ./scripts/pre-commit.sh
  • All linters pass (clippy, rustfmt)
  • No unused dependencies added
  • Code follows existing patterns in presentation layer
  • No changes to application or domain layers

Documentation

  • User guide updated with JSON output section
  • JSON schema documented with field descriptions
  • At least one usage example provided
  • Automation use case documented

User Experience

  • Default behavior (no flag) is identical to before
  • JSON output is pretty-printed for readability
  • Timestamps use ISO 8601 format
  • Paths use forward slashes (cross-platform)

Related Issues

Additional Context

UX Research

The dual-channel output strategy (stdout for results, stderr for progress) is based on documented research:

Golden Test Configuration

Test configuration available at: envs/golden-test-json-create.json

This ensures backward compatibility verification during refactoring.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions