205 lines
6.0 KiB
Plaintext
205 lines
6.0 KiB
Plaintext
"""
|
|
Questionnaire Schema
|
|
|
|
Defines interactive questionnaires for completing infrastructure specifications.
|
|
Uses conditional logic and decision trees to ask only relevant questions.
|
|
|
|
Features:
|
|
- Conditional questions (only ask if certain conditions met)
|
|
- Smart defaults from AI suggestions
|
|
- Validation rules per question
|
|
- Decision tree navigation
|
|
- Multi-select and single-select support
|
|
"""
|
|
|
|
import regex
|
|
|
|
# ============================================================================
|
|
# Expression Evaluation
|
|
# ============================================================================
|
|
|
|
schema Expression:
|
|
"""
|
|
Boolean expression for conditional logic
|
|
|
|
Examples:
|
|
- "deployment_mode == 'HA'"
|
|
- "has_database and deployment_mode in ['prod', 'staging']"
|
|
- "postgres_version >= '15.0'"
|
|
"""
|
|
expr: str
|
|
|
|
check:
|
|
len(expr) > 0, "Expression cannot be empty"
|
|
|
|
|
|
# ============================================================================
|
|
# Question Types and Validation
|
|
# ============================================================================
|
|
|
|
schema ValidationRule:
|
|
"""
|
|
Validation rule for question answers
|
|
"""
|
|
required: bool = False
|
|
pattern?: str # Regex pattern for validation
|
|
min_value?: int
|
|
max_value?: int
|
|
choices?: [str] # Valid choices (for select/multiselect)
|
|
custom_validator?: str # Name of custom validator function
|
|
|
|
|
|
schema Question:
|
|
"""
|
|
Single question in questionnaire
|
|
"""
|
|
id: str # Unique identifier
|
|
kind: "text" | "select" | "multiselect" | "confirm" | "number"
|
|
message: str # Question text
|
|
help?: str # Help text/description
|
|
default?: str # Default value
|
|
|
|
# Conditional display
|
|
when?: Expression # Only ask if this expression is true
|
|
depends_on?: [str] # Other question IDs this depends on
|
|
|
|
# Validation
|
|
validation: ValidationRule = {}
|
|
|
|
# AI assistance
|
|
ai_suggest: bool = False # Enable AI suggestions?
|
|
ai_context?: str # Context for AI suggestion
|
|
|
|
check:
|
|
len(id) > 0, "Question ID required"
|
|
len(message) > 0, "Message required"
|
|
# Validate choices if kind is select/multiselect
|
|
kind not in ["select", "multiselect"] or validation.choices != None, \
|
|
"Choices required for select/multiselect questions"
|
|
|
|
|
|
# ============================================================================
|
|
# Decision Tree Nodes
|
|
# ============================================================================
|
|
|
|
schema DecisionNode:
|
|
"""
|
|
Single node in decision tree
|
|
"""
|
|
question_id: str # Which question to ask
|
|
next_nodes?: {str: str} # answer -> next_question_id
|
|
default_next?: str # Default next question if no match
|
|
|
|
|
|
schema DecisionTree:
|
|
"""
|
|
Decision tree for intelligent questionnaire flow
|
|
"""
|
|
root: str # Starting question ID
|
|
nodes: {str: DecisionNode} # ID -> Node mapping
|
|
|
|
check:
|
|
len(root) > 0, "Root question required"
|
|
len(nodes) > 0, "At least one node required"
|
|
|
|
|
|
# ============================================================================
|
|
# Metadata
|
|
# ============================================================================
|
|
|
|
schema Metadata:
|
|
"""
|
|
Questionnaire metadata
|
|
"""
|
|
name: str
|
|
version: str
|
|
description?: str
|
|
|
|
check:
|
|
len(name) > 0, "Name required"
|
|
len(version) > 0, "Version required"
|
|
|
|
|
|
# ============================================================================
|
|
# Complete Questionnaire
|
|
# ============================================================================
|
|
|
|
schema Questionnaire:
|
|
"""
|
|
Complete questionnaire with questions and decision tree
|
|
|
|
Example:
|
|
postgres_questionnaire = Questionnaire {
|
|
metadata: {
|
|
name: "PostgreSQL Setup"
|
|
version: "1.0.0"
|
|
}
|
|
|
|
questions: [
|
|
Question {
|
|
id: "pg_version"
|
|
kind: "text"
|
|
message: "PostgreSQL version?"
|
|
default: "16.0"
|
|
validation: {
|
|
pattern: r"^\d+\.\d+$"
|
|
}
|
|
ai_suggest: True
|
|
ai_context: "Suggest latest stable PostgreSQL"
|
|
}
|
|
Question {
|
|
id: "enable_backup"
|
|
kind: "confirm"
|
|
message: "Enable automated backups?"
|
|
default: "true"
|
|
when: Expression { expr: "deployment_mode in ['prod', 'staging']" }
|
|
}
|
|
]
|
|
|
|
decision_tree: {
|
|
root: "pg_version"
|
|
nodes: {
|
|
"pg_version": {
|
|
question_id: "pg_version"
|
|
next_nodes: { "*": "enable_backup" }
|
|
}
|
|
"enable_backup": {
|
|
question_id: "enable_backup"
|
|
next_nodes: { "true": "backup_strategy", "false": "END" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"""
|
|
|
|
metadata: Metadata
|
|
questions: [Question] = []
|
|
decision_tree: DecisionTree
|
|
|
|
check:
|
|
len(questions) > 0, "At least one question required"
|
|
|
|
|
|
# ============================================================================
|
|
# Question Answer
|
|
# ============================================================================
|
|
|
|
schema Answer:
|
|
"""
|
|
User answer to a question
|
|
"""
|
|
question_id: str
|
|
value: str | bool | int # Answer value
|
|
timestamp: str # ISO 8601 when answered
|
|
|
|
|
|
schema QuestionnaireResponse:
|
|
"""
|
|
Complete questionnaire response
|
|
"""
|
|
questionnaire_name: str
|
|
questionnaire_version: str
|
|
answers: [Answer] = []
|
|
completed: bool = False
|
|
completion_time?: str # ISO 8601
|