|
| 1 | +# JSON Schema Generation for Environment Configuration |
| 2 | + |
| 3 | +**Issue**: [#229](https://github.com/torrust/torrust-tracker-deployer/issues/229) |
| 4 | +**Parent Epic**: N/A (Standalone task) |
| 5 | +**Related**: [Feature Specification](../features/json-schema-generation/) |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +Add a new CLI command `cargo run create schema [OUTPUT_PATH]` that generates a JSON Schema from the Rust `EnvironmentCreationConfig` type. This enables AI assistants, IDEs, and developers to benefit from autocomplete, validation, and inline documentation when creating environment configuration files. |
| 10 | + |
| 11 | +## Goals |
| 12 | + |
| 13 | +- [ ] Generate JSON Schema from Rust configuration types using Schemars |
| 14 | +- [ ] Support output to stdout or file |
| 15 | +- [ ] Include doc comments as schema descriptions |
| 16 | +- [ ] Update template command to inform users about schema generation |
| 17 | +- [ ] Provide high-quality AI agent support for configuration file creation |
| 18 | + |
| 19 | +## 🏗️ Architecture Requirements |
| 20 | + |
| 21 | +**DDD Layer**: Application + Infrastructure |
| 22 | +**Module Path**: |
| 23 | + |
| 24 | +- CLI: `src/presentation/input/cli/commands/create/subcommands/schema/` |
| 25 | +- Handler: `src/application/command_handlers/create/schema/` |
| 26 | +- Generator: `src/infrastructure/schema/` |
| 27 | + **Pattern**: CLI Subcommand → Command Handler → Schema Generator (Infrastructure) |
| 28 | + |
| 29 | +### Module Structure Requirements |
| 30 | + |
| 31 | +- [ ] Follow DDD layer separation (see [docs/codebase-architecture.md](../codebase-architecture.md)) |
| 32 | +- [ ] Respect dependency flow rules (Presentation → Application → Infrastructure) |
| 33 | +- [ ] Use appropriate module organization (see [docs/contributing/module-organization.md](../contributing/module-organization.md)) |
| 34 | + |
| 35 | +### Architectural Constraints |
| 36 | + |
| 37 | +- [ ] CLI parsing in Presentation layer (Clap structures) |
| 38 | +- [ ] Handler orchestration in Application layer |
| 39 | +- [ ] Schema generation in Infrastructure layer (external dependency: Schemars) |
| 40 | +- [ ] All output through `UserOutput` service (no direct `println!`) |
| 41 | +- [ ] Error handling follows project conventions (see [docs/contributing/error-handling.md](../contributing/error-handling.md)) |
| 42 | + |
| 43 | +### Anti-Patterns to Avoid |
| 44 | + |
| 45 | +- ❌ Using `println!` or `eprintln!` directly (must use `UserOutput`) |
| 46 | +- ❌ Business logic in Infrastructure layer (SchemaGenerator is pure technical mechanism) |
| 47 | +- ❌ Schemars dependency leaking into Application or Domain layers |
| 48 | + |
| 49 | +## Specifications |
| 50 | + |
| 51 | +See complete specifications in the [feature documentation](../features/json-schema-generation/specification.md), including: |
| 52 | + |
| 53 | +- Component designs (Config Types, SchemaGenerator, CommandHandler, CLI) |
| 54 | +- Architecture decisions (no Step layer, SchemaGenerator placement) |
| 55 | +- Command structure and arguments |
| 56 | +- Error handling requirements |
| 57 | +- Testing strategy |
| 58 | + |
| 59 | +### Key Design Decisions |
| 60 | + |
| 61 | +1. **No Step Layer**: This is a single-operation command (see [specification rationale](../features/json-schema-generation/specification.md#design-overview)) |
| 62 | +2. **SchemaGenerator in Infrastructure**: External dependency wrapper, technical mechanism (see [ADR on layer placement](../contributing/ddd-layer-placement.md)) |
| 63 | +3. **All Output via UserOutput**: Enforces consistent output routing pattern |
| 64 | + |
| 65 | +## Implementation Plan |
| 66 | + |
| 67 | +### Phase 1: Add Schemars Derive (30 minutes) |
| 68 | + |
| 69 | +- [ ] Add `schemars = "0.8"` to `Cargo.toml` |
| 70 | +- [ ] Add `#[derive(JsonSchema)]` to `EnvironmentCreationConfig` |
| 71 | +- [ ] Add `#[derive(JsonSchema)]` to all nested config types (provider configs, SSH config, etc.) |
| 72 | +- [ ] Add doc comments to all public fields for schema descriptions |
| 73 | +- [ ] Build to verify derives work correctly |
| 74 | + |
| 75 | +### Phase 2: Create Schema Generator (1 hour) |
| 76 | + |
| 77 | +- [ ] Create `src/infrastructure/schema/` module |
| 78 | +- [ ] Implement `SchemaGenerator` with `generate<T: JsonSchema>() -> Result<String>` method |
| 79 | +- [ ] Add error type `SchemaGenerationError` with help messages |
| 80 | +- [ ] Add unit tests for schema generation |
| 81 | +- [ ] Verify generated schema includes doc comments |
| 82 | + |
| 83 | +### Phase 3: Create Command Handler (1 hour) |
| 84 | + |
| 85 | +- [ ] Create `src/application/command_handlers/create/schema/` module |
| 86 | +- [ ] Implement `CreateSchemaCommandHandler` with `execute(output_path: Option<PathBuf>)` method |
| 87 | +- [ ] Handler calls `SchemaGenerator::generate::<EnvironmentCreationConfig>()` |
| 88 | +- [ ] Handle stdout vs file output logic |
| 89 | +- [ ] Add error type `CreateSchemaCommandHandlerError` with help messages |
| 90 | +- [ ] Add unit tests for handler logic |
| 91 | + |
| 92 | +### Phase 4: Add CLI Subcommand (1 hour) |
| 93 | + |
| 94 | +- [ ] Create `src/presentation/input/cli/commands/create/subcommands/schema/` module |
| 95 | +- [ ] Add `Schema` variant to `CreateSubcommand` enum |
| 96 | +- [ ] Define Clap structure with optional `output_path` argument |
| 97 | +- [ ] Wire up command dispatch in `presentation/controllers/create/mod.rs` |
| 98 | +- [ ] Add integration test for CLI parsing |
| 99 | + |
| 100 | +### Phase 5: Update Template Command (30 minutes) |
| 101 | + |
| 102 | +- [ ] Modify template command output to mention schema generation |
| 103 | +- [ ] Add info message: "Use `cargo run create schema` to generate JSON Schema for validation" |
| 104 | +- [ ] Update template command tests |
| 105 | + |
| 106 | +### Phase 6: Documentation (1 hour) |
| 107 | + |
| 108 | +- [ ] Add schema command to `docs/user-guide/commands/create.md` |
| 109 | +- [ ] Include examples of usage (stdout and file output) |
| 110 | +- [ ] Document how to use schema with IDEs (VS Code settings example) |
| 111 | +- [ ] Update main README with schema generation feature |
| 112 | + |
| 113 | +### Phase 7: Integration Testing (1 hour) |
| 114 | + |
| 115 | +- [ ] Add E2E test that generates schema to file |
| 116 | +- [ ] Verify schema validates example configuration files |
| 117 | +- [ ] Test schema output to stdout |
| 118 | +- [ ] Verify error handling for invalid paths |
| 119 | + |
| 120 | +## Acceptance Criteria |
| 121 | + |
| 122 | +> **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. |
| 123 | +
|
| 124 | +**Quality Checks**: |
| 125 | + |
| 126 | +- [ ] Pre-commit checks pass: `./scripts/pre-commit.sh` |
| 127 | + |
| 128 | +**Functional Requirements**: |
| 129 | + |
| 130 | +- [ ] `cargo run create schema` outputs schema to stdout |
| 131 | +- [ ] `cargo run create schema ./schema.json` writes schema to file |
| 132 | +- [ ] Schema includes all fields from `EnvironmentCreationConfig` |
| 133 | +- [ ] Schema includes doc comments as descriptions |
| 134 | +- [ ] Schema validates example configuration files correctly |
| 135 | +- [ ] Template command mentions schema generation availability |
| 136 | + |
| 137 | +**Architecture Requirements**: |
| 138 | + |
| 139 | +- [ ] All output uses `UserOutput` service (no `println!` calls) |
| 140 | +- [ ] SchemaGenerator in Infrastructure layer |
| 141 | +- [ ] Handler in Application layer |
| 142 | +- [ ] CLI in Presentation layer |
| 143 | +- [ ] Error messages are clear and actionable |
| 144 | + |
| 145 | +**Testing Requirements**: |
| 146 | + |
| 147 | +- [ ] Unit tests for SchemaGenerator |
| 148 | +- [ ] Unit tests for CreateSchemaCommandHandler |
| 149 | +- [ ] Integration test for CLI parsing |
| 150 | +- [ ] E2E test for schema generation workflow |
| 151 | + |
| 152 | +**Documentation Requirements**: |
| 153 | + |
| 154 | +- [ ] User guide updated with schema command |
| 155 | +- [ ] Examples provided for stdout and file output |
| 156 | +- [ ] IDE integration examples included |
| 157 | + |
| 158 | +## Related Documentation |
| 159 | + |
| 160 | +- **Feature Specification**: [docs/features/json-schema-generation/](../features/json-schema-generation/) |
| 161 | +- **Answered Questions**: [docs/features/json-schema-generation/questions.md](../features/json-schema-generation/questions.md) |
| 162 | +- **DDD Layer Placement**: [docs/contributing/ddd-layer-placement.md](../contributing/ddd-layer-placement.md) |
| 163 | +- **Error Handling**: [docs/contributing/error-handling.md](../contributing/error-handling.md) |
| 164 | +- **Module Organization**: [docs/contributing/module-organization.md](../contributing/module-organization.md) |
| 165 | +- **Testing Conventions**: [docs/contributing/testing/unit-testing.md](../contributing/testing/unit-testing.md) |
| 166 | +- **Schemars Documentation**: <https://graham.cool/schemars/> |
| 167 | + |
| 168 | +## Notes |
| 169 | + |
| 170 | +- **Priority**: High - AI agent support for configuration file creation |
| 171 | +- **Estimated Total Time**: 6-8 hours |
| 172 | +- **External Dependencies**: Schemars crate (well-maintained, widely used) |
| 173 | +- **Breaking Changes**: None - this is a purely additive feature |
| 174 | +- **Future Enhancements**: Consider validation command using the schema (out of scope for MVP) |
0 commit comments