Documentation
¶
Overview ¶
Package go_dynamic_questionnaire provides a flexible, condition-based questionnaire system for Go applications.
This package allows you to create dynamic questionnaires where the questions shown to users depend on their previous answers. Questions can have conditional logic using expressions, and the system supports progress tracking and closing remarks.
Basic Usage ¶
See README.md for a quick start guide. For more examples and advanced usage, see the examples/ directory.
Thread Safety ¶
All operations are thread-safe. The same questionnaire instance can be used concurrently by multiple goroutines without any synchronization.
Error Handling ¶
The package provides rich error information through custom error types. Validation errors include context about what went wrong and suggestions for fixing the issue.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ClosingRemark ¶
type ClosingRemark struct { Id string `json:"id"` // Unique identifier for the remark Text string `json:"text"` // The message text to display }
ClosingRemark represents a message shown to users when the questionnaire is completed. Multiple remarks can be shown based on the user's answers and conditional logic.
Example usage in JSON:
{ "id": "thank_you", "text": "Thank you for your feedback!" }
type Progress ¶
type Progress struct { Current int `json:"current"` // Number of questions answered so far Total int `json:"total"` // Total number of questions that could be answered }
Progress represents the user's progress through the questionnaire. It provides information about how many questions have been processed and how many remain, useful for displaying progress bars or indicators.
The progress calculation is based on available questions at each step, taking into account conditional logic. Questions that cannot be reached due to user answers are not counted in the total.
Note: Progress is nil when the questionnaire is completed.
type Question ¶
type Question struct { Id string `json:"id"` // Unique identifier for the question Text string `json:"text"` // The question text to display Answers []string `json:"answers"` // List of answer choices (1-indexed when referenced) }
Question represents a question that should be presented to the user. This is the external representation used in API responses.
type Questionnaire ¶
type Questionnaire interface { // Next processes the provided answers and returns the next set of questions, // progress information, and completion status. // // Parameters: // answers: A map where keys are question IDs and values are 1-indexed answer choices. // For example, if a question has answers ["Yes", "No", "Maybe"], // a value of 1 means "Yes", 2 means "No", and 3 means "Maybe". // // Returns: // *Response: Contains the next questions to show, completion status, // progress information, and closing remarks (if completed). // error: Returns validation errors for invalid question IDs, out-of-range answers, // or condition evaluation errors. // // The method validates all provided answers before processing. If any answer // is invalid, the entire operation fails and returns a validation error with // details about what went wrong. Next(answers map[string]int) (*Response, error) }
Questionnaire represents a dynamic questionnaire that can process user answers and determine the next questions to show based on conditional logic.
All methods are thread-safe and can be called concurrently from multiple goroutines. The questionnaire instance is stateless - all state is passed through the answers parameter.
Example usage:
q, err := gdq.New("questionnaire.yaml") if err != nil { return err } answers := map[string]int{"q1": 2, "q2": 1} response, err := q.Next(answers) if err != nil { return err } if response.Completed { // Handle completion and closing remarks } else { // Present next questions to user }
func New ¶
func New[T config](config T) (Questionnaire, error)
New creates a new Questionnaire instance from either a file path or YAML content.
The function accepts two types of input:
- string: Path to a YAML configuration file
- []byte: Raw YAML content as bytes
Parameters:
config: Either a file path (string) or YAML content ([]byte). The YAML must contain 'questions' and optionally 'closing_remarks' sections.
Returns:
Questionnaire: A fully configured questionnaire instance ready for use. The instance is immutable and thread-safe. error: Returns configuration errors, file reading errors, YAML parsing errors, or validation errors if the questionnaire structure is invalid.
Example usage with file path:
q, err := gdq.New("surveys/customer-feedback.yaml") if err != nil { log.Fatalf("Failed to load questionnaire: %v", err) }
Example usage with YAML content:
yamlData := []byte(` questions: - id: "satisfaction" text: "How satisfied are you with our service?" answers: ["Very satisfied", "Satisfied", "Neutral", "Dissatisfied"] - id: "recommend" text: "Would you recommend us?" answers: ["Yes", "No"] condition: 'answers["satisfaction"] <= 2' closing_remarks: - id: "thanks" text: "Thank you for your feedback!" `) q, err := gdq.New(yamlData) if err != nil { return fmt.Errorf("questionnaire creation failed: %w", err) }
The function validates the questionnaire structure during creation, checking for:
- Duplicate question IDs
- Empty question IDs
- Questions without answer options
- Invalid YAML syntax
type Response ¶
type Response struct { Questions []Question `json:"questions"` // Next questions to show (empty if completed) ClosingRemarks []ClosingRemark `json:"closing_remarks,omitempty"` // Closing remarks (only when completed) Completed bool `json:"completed"` // Whether the questionnaire is finished Progress *Progress `json:"progress,omitempty"` // Progress information (nil when completed) }
Response represents the complete response from processing a questionnaire step. It contains all information needed to either continue the questionnaire or handle completion.
The response structure allows clients to:
- Display the next questions to users (Questions field)
- Show progress information (Progress field)
- Handle questionnaire completion (Completed field)
- Display closing messages (ClosingRemarks field)
Example JSON output:
{ "questions": [{"id": "q1", "text": "...", "answers": ["Yes", "No"]}], "completed": false, "progress": {"current": 2, "total": 5} }