As a qctl user, I want my input validated against prompt rules so that I get immediate feedback on invalid values before template rendering fails.
Design
Validation Rules in Manifest
prompts:- name:packageNamemessage:"Java package"type:stringrequired:truevalidation:pattern:"^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"message:"Must be a valid Java package name (e.g., com.example.myapp)"- name:portmessage:"Server port"type:integervalidation:min:1024max:65535message:"Port must be between 1024 and 65535"- name:appNamemessage:"Application name"type:stringrequired:truevalidation:minLength:2maxLength:50pattern:"^[a-zA-Z][a-zA-Z0-9]*$"
Validation Types
Type
Rules Available
string
pattern, minLength, maxLength, enum
integer
min, max
boolean
(no additional validation)
choice
Value must match one of choices
Interactive Retry
When validation fails, re-prompt with error message:
? Java package [com.example.myapp]: 123invalid
✗ Must be a valid Java package name (e.g., com.example.myapp)
? Java package [com.example.myapp]: com.acme.orders
✓
CLI Override Validation
--var overrides are also validated:
$ qctl qqq init qqq-web-api myapp --var packageName=123
Error: Invalid value for'packageName': Must be a valid Java package name
Files to Create/Modify
File
Action
Description
PromptValidation.java
Create
Validation rule record
PromptValidator.java
Create
Validates values against rules
ConsoleUI.java
Modify
Re-prompt on validation failure
InitCommand.java
Modify
Validate --var overrides
TemplateManifest.java
Modify
Add validation to Prompt record
Implementation Tasks
Create PromptValidation record with all rule fields
Add validation field to Prompt record
Create PromptValidator class
Implement pattern validation (regex)
Implement minLength/maxLength validation
Implement min/max validation for integers
Implement enum validation (value in list)
Implement required field validation
Update PromptRunner to retry on validation failure
Add validation for --var command-line overrides
Show clear error messages with examples
Add unit tests for all validation types - 20 tests in PromptValidatorTest
Test edge cases (empty values, whitespace)
Acceptance Criteria
Invalid input triggers re-prompt with error message
Pattern validation works with regex
Length validation works for strings
Range validation works for integers
Required fields cannot be skipped
--var overrides are validated (falls back to interactive prompt if invalid)
Error messages are helpful with examples
All prompt types validate correctly
Part of #12
## User Story
As a **qctl user**, I want my input validated against prompt rules so that I get immediate feedback on invalid values before template rendering fails.
## Design
### Validation Rules in Manifest
```yaml
prompts:
- name: packageName
message: "Java package"
type: string
required: true
validation:
pattern: "^[a-z][a-z0-9]*(\\.[a-z][a-z0-9]*)*$"
message: "Must be a valid Java package name (e.g., com.example.myapp)"
- name: port
message: "Server port"
type: integer
validation:
min: 1024
max: 65535
message: "Port must be between 1024 and 65535"
- name: appName
message: "Application name"
type: string
required: true
validation:
minLength: 2
maxLength: 50
pattern: "^[a-zA-Z][a-zA-Z0-9]*$"
```
### Validation Types
| Type | Rules Available |
|------|-----------------|
| `string` | `pattern`, `minLength`, `maxLength`, `enum` |
| `integer` | `min`, `max` |
| `boolean` | (no additional validation) |
| `choice` | Value must match one of `choices` |
### Interactive Retry
When validation fails, re-prompt with error message:
```
? Java package [com.example.myapp]: 123invalid
✗ Must be a valid Java package name (e.g., com.example.myapp)
? Java package [com.example.myapp]: com.acme.orders
✓
```
### CLI Override Validation
`--var` overrides are also validated:
```bash
$ qctl qqq init qqq-web-api myapp --var packageName=123
Error: Invalid value for 'packageName': Must be a valid Java package name
```
## Files to Create/Modify
| File | Action | Description |
|------|--------|-------------|
| `PromptValidation.java` | Create | Validation rule record |
| `PromptValidator.java` | Create | Validates values against rules |
| `ConsoleUI.java` | Modify | Re-prompt on validation failure |
| `InitCommand.java` | Modify | Validate --var overrides |
| `TemplateManifest.java` | Modify | Add validation to Prompt record |
## Implementation Tasks
- [x] Create `PromptValidation` record with all rule fields
- [x] Add `validation` field to `Prompt` record
- [x] Create `PromptValidator` class
- [x] Implement pattern validation (regex)
- [x] Implement minLength/maxLength validation
- [x] Implement min/max validation for integers
- [x] Implement enum validation (value in list)
- [x] Implement required field validation
- [x] Update `PromptRunner` to retry on validation failure
- [x] Add validation for `--var` command-line overrides
- [x] Show clear error messages with examples
- [x] Add unit tests for all validation types - 20 tests in PromptValidatorTest
- [x] Test edge cases (empty values, whitespace)
## Acceptance Criteria
- [x] Invalid input triggers re-prompt with error message
- [x] Pattern validation works with regex
- [x] Length validation works for strings
- [x] Range validation works for integers
- [x] Required fields cannot be skipped
- [x] `--var` overrides are validated (falls back to interactive prompt if invalid)
- [x] Error messages are helpful with examples
- [x] All prompt types validate correctly
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #12
User Story
As a qctl user, I want my input validated against prompt rules so that I get immediate feedback on invalid values before template rendering fails.
Design
Validation Rules in Manifest
Validation Types
stringpattern,minLength,maxLength,enumintegermin,maxbooleanchoicechoicesInteractive Retry
When validation fails, re-prompt with error message:
CLI Override Validation
--varoverrides are also validated:Files to Create/Modify
PromptValidation.javaPromptValidator.javaConsoleUI.javaInitCommand.javaTemplateManifest.javaImplementation Tasks
PromptValidationrecord with all rule fieldsvalidationfield toPromptrecordPromptValidatorclassPromptRunnerto retry on validation failure--varcommand-line overridesAcceptance Criteria
--varoverrides are validated (falls back to interactive prompt if invalid)Implementation Complete
Files Created
PromptValidation.java- Record for validation rules (pattern, minLength, maxLength, min, max, values, message)PromptValidator.java- Validates values against prompt rules with ValidationResult recordPromptValidatorTest.java- 20 unit tests covering all validation typesFiles Modified
TemplateManifest.java- Addedvalidationfield (PromptValidation) to Prompt record, addedisRequired()helperPromptRunner.java- Integrated validator with retry loop, validates --var overridesConsoleUI.java- AddedvalidationError(),validationSuccess(),warning()methodsValidation Types Supported
User Experience
CLI Override Validation
Invalid
--varvalues trigger interactive re-prompt with warning.Commit:
a2e85f7