inquirex-tty 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.envrc +3 -0
- data/.relaxed_rubocop.yml +153 -0
- data/.secrets.baseline +127 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +530 -0
- data/Rakefile +36 -0
- data/docs/badges/coverage_badge.svg +21 -0
- data/examples/01_hello_world.rb +32 -0
- data/examples/02_yes_or_no.rb +33 -0
- data/examples/03_food_preferences.png +0 -0
- data/examples/03_food_preferences.rb +65 -0
- data/examples/04_event_registration.rb +86 -0
- data/examples/05_job_application.rb +122 -0
- data/examples/06_health_assessment.rb +173 -0
- data/examples/07_loan_application.rb +217 -0
- data/examples/08_tax_preparer.rb +195 -0
- data/examples/09_tax_preparer_llm.rb +151 -0
- data/examples/10_answers.json +53 -0
- data/examples/10_real_tax_preparer.rb +604 -0
- data/examples/README.md +50 -0
- data/exe/inquirex +24 -0
- data/justfile +56 -0
- data/lefthook.yml +36 -0
- data/lib/inquirex/tty/commands/export.rb +81 -0
- data/lib/inquirex/tty/commands/graph.rb +116 -0
- data/lib/inquirex/tty/commands/run.rb +193 -0
- data/lib/inquirex/tty/commands/validate.rb +108 -0
- data/lib/inquirex/tty/commands/version.rb +19 -0
- data/lib/inquirex/tty/commands.rb +19 -0
- data/lib/inquirex/tty/flow_loader.rb +41 -0
- data/lib/inquirex/tty/output_path.rb +66 -0
- data/lib/inquirex/tty/renderer.rb +245 -0
- data/lib/inquirex/tty/ui_helper.rb +58 -0
- data/lib/inquirex/tty/version.rb +7 -0
- data/lib/inquirex/tty.rb +41 -0
- data/sig/inquirex/tty.rbs +6 -0
- metadata +197 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example 3: Food Preferences
|
|
4
|
+
#
|
|
5
|
+
# Multiple independent branches from a single multi_enum step.
|
|
6
|
+
# Each selection may activate a different follow-up question.
|
|
7
|
+
# Demonstrates: multi_enum, contains rule, multiple transitions.
|
|
8
|
+
#
|
|
9
|
+
# Run: bundle exec exe/inquirex-tty run examples/03_food_preferences.rb
|
|
10
|
+
|
|
11
|
+
Inquirex.define id: "food-preferences", version: "1.0.0" do
|
|
12
|
+
meta title: "Food Preferences", subtitle: "Tell us what you enjoy"
|
|
13
|
+
|
|
14
|
+
start :diet
|
|
15
|
+
|
|
16
|
+
ask :diet do
|
|
17
|
+
type :multi_enum
|
|
18
|
+
question "Which food categories do you enjoy?"
|
|
19
|
+
options %w[Meat Seafood Vegetarian Vegan Dessert]
|
|
20
|
+
widget target: :tty, type: :multi_select
|
|
21
|
+
widget target: :desktop, type: :checkbox_group
|
|
22
|
+
widget target: :mobile, type: :checkbox_group
|
|
23
|
+
transition to: :meat_preference, if_rule: contains(:diet, "Meat")
|
|
24
|
+
transition to: :seafood_preference, if_rule: contains(:diet, "Seafood")
|
|
25
|
+
transition to: :dessert_preference, if_rule: contains(:diet, "Dessert")
|
|
26
|
+
transition to: :summary
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
ask :meat_preference do
|
|
30
|
+
type :enum
|
|
31
|
+
question "What is your favorite type of meat?"
|
|
32
|
+
options %w[Beef Chicken Pork Lamb]
|
|
33
|
+
widget target: :tty, type: :select
|
|
34
|
+
widget target: :desktop, type: :radio_group
|
|
35
|
+
widget target: :mobile, type: :dropdown
|
|
36
|
+
transition to: :seafood_preference, if_rule: contains(:diet, "Seafood")
|
|
37
|
+
transition to: :dessert_preference, if_rule: contains(:diet, "Dessert")
|
|
38
|
+
transition to: :summary
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
ask :seafood_preference do
|
|
42
|
+
type :enum
|
|
43
|
+
question "What is your favorite type of seafood?"
|
|
44
|
+
options %w[Salmon Tuna Shrimp Lobster Crab]
|
|
45
|
+
widget target: :tty, type: :select
|
|
46
|
+
widget target: :desktop, type: :radio_group
|
|
47
|
+
widget target: :mobile, type: :dropdown
|
|
48
|
+
transition to: :dessert_preference, if_rule: contains(:diet, "Dessert")
|
|
49
|
+
transition to: :summary
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
ask :dessert_preference do
|
|
53
|
+
type :enum
|
|
54
|
+
question "What is your favorite dessert?"
|
|
55
|
+
options %w[Cake IceCream Pie Cookies Fruit]
|
|
56
|
+
widget target: :tty, type: :select
|
|
57
|
+
widget target: :desktop, type: :radio_group
|
|
58
|
+
widget target: :mobile, type: :dropdown
|
|
59
|
+
transition to: :summary
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
say :summary do
|
|
63
|
+
text "Thanks! We've noted your food preferences."
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example 4: Event Registration
|
|
4
|
+
#
|
|
5
|
+
# Two levels of conditional logic. The ticket type determines the first
|
|
6
|
+
# branch; within VIP there is a further branch based on whether the guest
|
|
7
|
+
# wants a plus-one.
|
|
8
|
+
# Demonstrates: enum, confirm, equals rule, two-level branching.
|
|
9
|
+
#
|
|
10
|
+
# Run: bundle exec exe/inquirex-tty run examples/04_event_registration.rb
|
|
11
|
+
|
|
12
|
+
Inquirex.define id: "event-registration", version: "1.0.0" do
|
|
13
|
+
meta title: "Event Registration", subtitle: "Register for the conference"
|
|
14
|
+
|
|
15
|
+
start :attendee_name
|
|
16
|
+
|
|
17
|
+
ask :attendee_name do
|
|
18
|
+
type :string
|
|
19
|
+
question "What is your full name?"
|
|
20
|
+
widget target: :tty, type: :text_input
|
|
21
|
+
transition to: :ticket_type
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ask :ticket_type do
|
|
25
|
+
type :enum
|
|
26
|
+
question "Select your ticket type:"
|
|
27
|
+
options %w[General VIP Speaker]
|
|
28
|
+
widget target: :tty, type: :select
|
|
29
|
+
widget target: :desktop, type: :radio_group
|
|
30
|
+
widget target: :mobile, type: :dropdown
|
|
31
|
+
transition to: :vip_options, if_rule: equals(:ticket_type, "VIP")
|
|
32
|
+
transition to: :talk_title, if_rule: equals(:ticket_type, "Speaker")
|
|
33
|
+
transition to: :dietary
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# --- VIP branch (level 1) ---
|
|
37
|
+
|
|
38
|
+
confirm :vip_options do
|
|
39
|
+
question "Would you like to bring a plus-one?"
|
|
40
|
+
widget target: :tty, type: :yes_no
|
|
41
|
+
transition to: :plus_one_name, if_rule: equals(:vip_options, true)
|
|
42
|
+
transition to: :dietary
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# VIP plus-one sub-branch (level 2)
|
|
46
|
+
ask :plus_one_name do
|
|
47
|
+
type :string
|
|
48
|
+
question "What is your plus-one's name?"
|
|
49
|
+
widget target: :tty, type: :text_input
|
|
50
|
+
transition to: :dietary
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# --- Speaker branch (level 1) ---
|
|
54
|
+
|
|
55
|
+
ask :talk_title do
|
|
56
|
+
type :string
|
|
57
|
+
question "What is the title of your talk?"
|
|
58
|
+
widget target: :tty, type: :text_input
|
|
59
|
+
transition to: :av_needs
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
ask :av_needs do
|
|
63
|
+
type :multi_enum
|
|
64
|
+
question "What A/V equipment do you need?"
|
|
65
|
+
options %w[Projector Microphone Whiteboard ScreenShare None]
|
|
66
|
+
widget target: :tty, type: :multi_select
|
|
67
|
+
widget target: :desktop, type: :checkbox_group
|
|
68
|
+
transition to: :dietary
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# --- Common path ---
|
|
72
|
+
|
|
73
|
+
ask :dietary do
|
|
74
|
+
type :enum
|
|
75
|
+
question "Any dietary restrictions?"
|
|
76
|
+
options %w[None Vegetarian Vegan GlutenFree Halal Kosher]
|
|
77
|
+
widget target: :tty, type: :select
|
|
78
|
+
widget target: :desktop, type: :radio_group
|
|
79
|
+
widget target: :mobile, type: :dropdown
|
|
80
|
+
transition to: :confirmation
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
say :confirmation do
|
|
84
|
+
text "You're registered! See you at the event."
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example 5: Job Application Intake
|
|
4
|
+
#
|
|
5
|
+
# Two levels of branching with composed rules (all/any).
|
|
6
|
+
# The role determines the first branch; experience level and
|
|
7
|
+
# specific answers open deeper sub-branches.
|
|
8
|
+
# Demonstrates: all(), any(), greater_than, contains, two-level branching.
|
|
9
|
+
#
|
|
10
|
+
# Run: bundle exec exe/inquirex-tty run examples/05_job_application.rb
|
|
11
|
+
|
|
12
|
+
Inquirex.define id: "job-application", version: "1.0.0" do
|
|
13
|
+
meta title: "Job Application", subtitle: "Tell us about yourself"
|
|
14
|
+
|
|
15
|
+
start :applicant_name
|
|
16
|
+
|
|
17
|
+
ask :applicant_name do
|
|
18
|
+
type :string
|
|
19
|
+
question "What is your full name?"
|
|
20
|
+
widget target: :tty, type: :text_input
|
|
21
|
+
transition to: :role
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
ask :role do
|
|
25
|
+
type :enum
|
|
26
|
+
question "Which role are you applying for?"
|
|
27
|
+
options %w[Engineering Design ProductManagement Sales]
|
|
28
|
+
widget target: :tty, type: :select
|
|
29
|
+
widget target: :desktop, type: :radio_group
|
|
30
|
+
widget target: :mobile, type: :dropdown
|
|
31
|
+
transition to: :engineering_skills, if_rule: equals(:role, "Engineering")
|
|
32
|
+
transition to: :design_portfolio, if_rule: equals(:role, "Design")
|
|
33
|
+
transition to: :years_experience
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# --- Engineering branch (level 1) ---
|
|
37
|
+
|
|
38
|
+
ask :engineering_skills do
|
|
39
|
+
type :multi_enum
|
|
40
|
+
question "Select your primary skills:"
|
|
41
|
+
options %w[Ruby Python JavaScript Go Rust Java]
|
|
42
|
+
widget target: :tty, type: :multi_select
|
|
43
|
+
widget target: :desktop, type: :checkbox_group
|
|
44
|
+
transition to: :years_experience
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# --- Design branch (level 1) ---
|
|
48
|
+
|
|
49
|
+
ask :design_portfolio do
|
|
50
|
+
type :string
|
|
51
|
+
question "Please provide a link to your portfolio:"
|
|
52
|
+
widget target: :tty, type: :text_input
|
|
53
|
+
transition to: :years_experience
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# --- Common: experience (feeds level 2 branching) ---
|
|
57
|
+
|
|
58
|
+
ask :years_experience do
|
|
59
|
+
type :integer
|
|
60
|
+
question "How many years of professional experience do you have?"
|
|
61
|
+
widget target: :tty, type: :number_input
|
|
62
|
+
transition to: :leadership_experience, if_rule: greater_than(:years_experience, 7)
|
|
63
|
+
transition to: :education
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Level 2 branch: senior applicants
|
|
67
|
+
confirm :leadership_experience do
|
|
68
|
+
question "Have you managed a team of 5 or more people?"
|
|
69
|
+
widget target: :tty, type: :yes_no
|
|
70
|
+
transition to: :management_style, if_rule: equals(:leadership_experience, true)
|
|
71
|
+
transition to: :education
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Level 2 sub-branch: managers
|
|
75
|
+
ask :management_style do
|
|
76
|
+
type :enum
|
|
77
|
+
question "How would you describe your management style?"
|
|
78
|
+
options %w[Collaborative Directive Coaching Delegative]
|
|
79
|
+
widget target: :tty, type: :select
|
|
80
|
+
widget target: :desktop, type: :radio_group
|
|
81
|
+
widget target: :mobile, type: :dropdown
|
|
82
|
+
transition to: :education
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
ask :education do
|
|
86
|
+
type :enum
|
|
87
|
+
question "What is your highest level of education?"
|
|
88
|
+
options %w[HighSchool Bachelors Masters PhD Bootcamp SelfTaught]
|
|
89
|
+
widget target: :tty, type: :select
|
|
90
|
+
widget target: :desktop, type: :radio_group
|
|
91
|
+
widget target: :mobile, type: :dropdown
|
|
92
|
+
transition to: :availability
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
ask :availability do
|
|
96
|
+
type :enum
|
|
97
|
+
question "When can you start?"
|
|
98
|
+
options %w[Immediately TwoWeeks OneMonth ThreeMonths]
|
|
99
|
+
widget target: :tty, type: :select
|
|
100
|
+
widget target: :desktop, type: :radio_group
|
|
101
|
+
widget target: :mobile, type: :dropdown
|
|
102
|
+
transition to: :referral
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
confirm :referral do
|
|
106
|
+
question "Were you referred by a current employee?"
|
|
107
|
+
widget target: :tty, type: :yes_no
|
|
108
|
+
transition to: :referral_name, if_rule: equals(:referral, true)
|
|
109
|
+
transition to: :thanks
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
ask :referral_name do
|
|
113
|
+
type :string
|
|
114
|
+
question "Who referred you?"
|
|
115
|
+
widget target: :tty, type: :text_input
|
|
116
|
+
transition to: :thanks
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
say :thanks do
|
|
120
|
+
text "Application submitted! We'll be in touch within 5 business days."
|
|
121
|
+
end
|
|
122
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example 6: Health Risk Assessment
|
|
4
|
+
#
|
|
5
|
+
# Three levels of conditional branching with composed rules.
|
|
6
|
+
#
|
|
7
|
+
# Level 1: Lifestyle choices branch into exercise, smoking, or diet paths.
|
|
8
|
+
# Level 2: Within exercise, intensity level opens a sub-branch.
|
|
9
|
+
# Within smoking, pack count opens a sub-branch.
|
|
10
|
+
# Level 3: Heavy smokers with additional risk factors get a deeper follow-up.
|
|
11
|
+
#
|
|
12
|
+
# Demonstrates: all(), any(), greater_than, less_than, contains, equals,
|
|
13
|
+
# three-level deep conditional logic.
|
|
14
|
+
#
|
|
15
|
+
# Run: bundle exec exe/inquirex-tty run examples/06_health_assessment.rb
|
|
16
|
+
|
|
17
|
+
Inquirex.define id: "health-assessment", version: "1.0.0" do
|
|
18
|
+
meta title: "Health Assessment", subtitle: "Let's assess your health risks"
|
|
19
|
+
|
|
20
|
+
start :patient_info
|
|
21
|
+
|
|
22
|
+
ask :patient_info do
|
|
23
|
+
type :string
|
|
24
|
+
question "Patient name and date of birth (e.g., Jane Doe, 1985-03-15):"
|
|
25
|
+
widget target: :tty, type: :text_input
|
|
26
|
+
transition to: :lifestyle
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
ask :lifestyle do
|
|
30
|
+
type :multi_enum
|
|
31
|
+
question "Select all that apply to your lifestyle:"
|
|
32
|
+
options %w[Exercise Smoking Alcohol HighStress PoorDiet]
|
|
33
|
+
widget target: :tty, type: :multi_select
|
|
34
|
+
widget target: :desktop, type: :checkbox_group
|
|
35
|
+
transition to: :exercise_frequency, if_rule: contains(:lifestyle, "Exercise")
|
|
36
|
+
transition to: :smoking_details, if_rule: contains(:lifestyle, "Smoking")
|
|
37
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
38
|
+
transition to: :sleep_quality
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# ============================================================
|
|
42
|
+
# LEVEL 1 — Exercise branch
|
|
43
|
+
# ============================================================
|
|
44
|
+
|
|
45
|
+
ask :exercise_frequency do
|
|
46
|
+
type :integer
|
|
47
|
+
question "How many days per week do you exercise?"
|
|
48
|
+
widget target: :tty, type: :number_input
|
|
49
|
+
transition to: :exercise_intensity, if_rule: greater_than(:exercise_frequency, 3)
|
|
50
|
+
transition to: :smoking_details, if_rule: contains(:lifestyle, "Smoking")
|
|
51
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
52
|
+
transition to: :sleep_quality
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# LEVEL 2 — Intense exerciser sub-branch
|
|
56
|
+
ask :exercise_intensity do
|
|
57
|
+
type :enum
|
|
58
|
+
question "What best describes your typical workout intensity?"
|
|
59
|
+
options %w[Moderate Vigorous Extreme]
|
|
60
|
+
widget target: :tty, type: :select
|
|
61
|
+
widget target: :desktop, type: :radio_group
|
|
62
|
+
transition to: :injury_history, if_rule: equals(:exercise_intensity, "Extreme")
|
|
63
|
+
transition to: :smoking_details, if_rule: contains(:lifestyle, "Smoking")
|
|
64
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
65
|
+
transition to: :sleep_quality
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# LEVEL 3 — Extreme exerciser injury check
|
|
69
|
+
confirm :injury_history do
|
|
70
|
+
question "Have you had any exercise-related injuries in the past year?"
|
|
71
|
+
widget target: :tty, type: :yes_no
|
|
72
|
+
transition to: :smoking_details, if_rule: contains(:lifestyle, "Smoking")
|
|
73
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
74
|
+
transition to: :sleep_quality
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# ============================================================
|
|
78
|
+
# LEVEL 1 — Smoking branch
|
|
79
|
+
# ============================================================
|
|
80
|
+
|
|
81
|
+
ask :smoking_details do
|
|
82
|
+
type :integer
|
|
83
|
+
question "How many packs per day do you smoke?"
|
|
84
|
+
widget target: :tty, type: :number_input
|
|
85
|
+
transition to: :smoking_duration, if_rule: greater_than(:smoking_details, 1)
|
|
86
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
87
|
+
transition to: :sleep_quality
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# LEVEL 2 — Heavy smoker sub-branch
|
|
91
|
+
ask :smoking_duration do
|
|
92
|
+
type :integer
|
|
93
|
+
question "How many years have you been smoking?"
|
|
94
|
+
widget target: :tty, type: :number_input
|
|
95
|
+
transition to: :smoking_cessation,
|
|
96
|
+
if_rule: all(
|
|
97
|
+
greater_than(:smoking_duration, 10),
|
|
98
|
+
greater_than(:smoking_details, 1)
|
|
99
|
+
)
|
|
100
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
101
|
+
transition to: :sleep_quality
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# LEVEL 3 — Long-term heavy smoker: cessation counseling
|
|
105
|
+
confirm :smoking_cessation do
|
|
106
|
+
question "Have you tried a cessation program before?"
|
|
107
|
+
widget target: :tty, type: :yes_no
|
|
108
|
+
transition to: :cessation_details, if_rule: equals(:smoking_cessation, true)
|
|
109
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
110
|
+
transition to: :sleep_quality
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
ask :cessation_details do
|
|
114
|
+
type :string
|
|
115
|
+
question "Please describe what programs you tried and when:"
|
|
116
|
+
widget target: :tty, type: :text_input
|
|
117
|
+
transition to: :diet_details, if_rule: contains(:lifestyle, "PoorDiet")
|
|
118
|
+
transition to: :sleep_quality
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# ============================================================
|
|
122
|
+
# LEVEL 1 — Diet branch
|
|
123
|
+
# ============================================================
|
|
124
|
+
|
|
125
|
+
ask :diet_details do
|
|
126
|
+
type :multi_enum
|
|
127
|
+
question "Which of these describe your typical diet?"
|
|
128
|
+
options %w[HighSugar HighSodium LowFiber SkipsMeals FastFood ProcessedFoods]
|
|
129
|
+
widget target: :tty, type: :multi_select
|
|
130
|
+
widget target: :desktop, type: :checkbox_group
|
|
131
|
+
transition to: :sleep_quality
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# ============================================================
|
|
135
|
+
# Common tail
|
|
136
|
+
# ============================================================
|
|
137
|
+
|
|
138
|
+
ask :sleep_quality do
|
|
139
|
+
type :enum
|
|
140
|
+
question "How would you rate your sleep quality?"
|
|
141
|
+
options %w[Excellent Good Fair Poor]
|
|
142
|
+
widget target: :tty, type: :select
|
|
143
|
+
widget target: :desktop, type: :radio_group
|
|
144
|
+
transition to: :mental_health,
|
|
145
|
+
if_rule: any(
|
|
146
|
+
equals(:sleep_quality, "Fair"),
|
|
147
|
+
equals(:sleep_quality, "Poor")
|
|
148
|
+
)
|
|
149
|
+
transition to: :family_history
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
ask :mental_health do
|
|
153
|
+
type :multi_enum
|
|
154
|
+
question "Do any of these apply to you?"
|
|
155
|
+
options %w[Anxiety Depression Insomnia ChronicFatigue None]
|
|
156
|
+
widget target: :tty, type: :multi_select
|
|
157
|
+
widget target: :desktop, type: :checkbox_group
|
|
158
|
+
transition to: :family_history
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
ask :family_history do
|
|
162
|
+
type :multi_enum
|
|
163
|
+
question "Select any conditions that run in your family:"
|
|
164
|
+
options %w[HeartDisease Diabetes Cancer Hypertension None]
|
|
165
|
+
widget target: :tty, type: :multi_select
|
|
166
|
+
widget target: :desktop, type: :checkbox_group
|
|
167
|
+
transition to: :risk_summary
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
say :risk_summary do
|
|
171
|
+
text "Assessment complete. Your responses have been recorded for review by your provider."
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Example 7: Loan Application
|
|
4
|
+
#
|
|
5
|
+
# Three levels of conditional branching with composed rules (all, any).
|
|
6
|
+
#
|
|
7
|
+
# Level 1: Loan type (Personal / Mortgage / Business) splits into paths.
|
|
8
|
+
# Level 2: Within Mortgage, property value triggers a high-value branch.
|
|
9
|
+
# Within Business, revenue level triggers sub-branches.
|
|
10
|
+
# Level 3: Investment property jumbo loan review; established corp expansion.
|
|
11
|
+
#
|
|
12
|
+
# Note: The original flowengine example used number_matrix for collecting
|
|
13
|
+
# structured numeric data. Inquirex uses :string steps for the same steps
|
|
14
|
+
# since number_matrix is not part of the Inquirex DSL.
|
|
15
|
+
#
|
|
16
|
+
# Demonstrates: all(), any(), greater_than, less_than, equals,
|
|
17
|
+
# three-level deep conditional logic.
|
|
18
|
+
#
|
|
19
|
+
# Run: bundle exec exe/inquirex-tty run examples/07_loan_application.rb
|
|
20
|
+
|
|
21
|
+
Inquirex.define id: "loan-application", version: "1.0.0" do
|
|
22
|
+
meta title: "Loan Application", subtitle: "Let's find the right loan for you"
|
|
23
|
+
|
|
24
|
+
start :applicant_info
|
|
25
|
+
|
|
26
|
+
ask :applicant_info do
|
|
27
|
+
type :string
|
|
28
|
+
question "Full legal name:"
|
|
29
|
+
widget target: :tty, type: :text_input
|
|
30
|
+
transition to: :loan_type
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
ask :loan_type do
|
|
34
|
+
type :enum
|
|
35
|
+
question "What type of loan are you applying for?"
|
|
36
|
+
options %w[Personal Mortgage Business]
|
|
37
|
+
widget target: :tty, type: :select
|
|
38
|
+
widget target: :desktop, type: :radio_group
|
|
39
|
+
widget target: :mobile, type: :dropdown
|
|
40
|
+
transition to: :personal_amount, if_rule: equals(:loan_type, "Personal")
|
|
41
|
+
transition to: :mortgage_property, if_rule: equals(:loan_type, "Mortgage")
|
|
42
|
+
transition to: :business_info, if_rule: equals(:loan_type, "Business")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# ============================================================
|
|
46
|
+
# LEVEL 1 — Personal loan (simple path)
|
|
47
|
+
# ============================================================
|
|
48
|
+
|
|
49
|
+
ask :personal_amount do
|
|
50
|
+
type :currency
|
|
51
|
+
question "How much would you like to borrow (in dollars)?"
|
|
52
|
+
widget target: :tty, type: :number_input
|
|
53
|
+
transition to: :personal_purpose
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
ask :personal_purpose do
|
|
57
|
+
type :enum
|
|
58
|
+
question "What is the primary purpose of this loan?"
|
|
59
|
+
options %w[DebtConsolidation HomeImprovement Medical Travel Education Other]
|
|
60
|
+
widget target: :tty, type: :select
|
|
61
|
+
widget target: :desktop, type: :radio_group
|
|
62
|
+
widget target: :mobile, type: :dropdown
|
|
63
|
+
transition to: :credit_check
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# ============================================================
|
|
67
|
+
# LEVEL 1 — Mortgage branch
|
|
68
|
+
# ============================================================
|
|
69
|
+
|
|
70
|
+
ask :mortgage_property do
|
|
71
|
+
type :enum
|
|
72
|
+
question "What type of property is this for?"
|
|
73
|
+
options %w[SingleFamily Condo Townhouse MultiFamily Commercial]
|
|
74
|
+
widget target: :tty, type: :select
|
|
75
|
+
widget target: :desktop, type: :radio_group
|
|
76
|
+
widget target: :mobile, type: :dropdown
|
|
77
|
+
transition to: :mortgage_amount
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
ask :mortgage_amount do
|
|
81
|
+
type :currency
|
|
82
|
+
question "What is the estimated property value (in dollars)?"
|
|
83
|
+
widget target: :tty, type: :number_input
|
|
84
|
+
transition to: :mortgage_high_value, if_rule: greater_than(:mortgage_amount, 750_000)
|
|
85
|
+
transition to: :down_payment
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# LEVEL 2 — High-value mortgage
|
|
89
|
+
confirm :mortgage_high_value do
|
|
90
|
+
question "Will this be your primary residence?"
|
|
91
|
+
widget target: :tty, type: :yes_no
|
|
92
|
+
transition to: :jumbo_review,
|
|
93
|
+
if_rule: all(
|
|
94
|
+
equals(:mortgage_high_value, false),
|
|
95
|
+
greater_than(:mortgage_amount, 750_000)
|
|
96
|
+
)
|
|
97
|
+
transition to: :down_payment
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# LEVEL 3 — Investment property jumbo loan details
|
|
101
|
+
ask :jumbo_review do
|
|
102
|
+
type :string
|
|
103
|
+
question "Provide details about your existing properties " \
|
|
104
|
+
"(OwnedProperties, RentalProperties, MortgagesOwed — comma-separated counts):"
|
|
105
|
+
widget target: :tty, type: :text_input
|
|
106
|
+
transition to: :down_payment
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
ask :down_payment do
|
|
110
|
+
type :currency
|
|
111
|
+
question "How much is your down payment (in dollars)?"
|
|
112
|
+
widget target: :tty, type: :number_input
|
|
113
|
+
transition to: :credit_check
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# ============================================================
|
|
117
|
+
# LEVEL 1 — Business loan branch
|
|
118
|
+
# ============================================================
|
|
119
|
+
|
|
120
|
+
ask :business_info do
|
|
121
|
+
type :string
|
|
122
|
+
question "Business name and EIN:"
|
|
123
|
+
widget target: :tty, type: :text_input
|
|
124
|
+
transition to: :business_type
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
ask :business_type do
|
|
128
|
+
type :enum
|
|
129
|
+
question "Business structure:"
|
|
130
|
+
options %w[SoleProprietor LLC SCorp CCorp Partnership]
|
|
131
|
+
widget target: :tty, type: :select
|
|
132
|
+
widget target: :desktop, type: :radio_group
|
|
133
|
+
widget target: :mobile, type: :dropdown
|
|
134
|
+
transition to: :annual_revenue
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
ask :annual_revenue do
|
|
138
|
+
type :currency
|
|
139
|
+
question "What is your annual revenue (in dollars)?"
|
|
140
|
+
widget target: :tty, type: :number_input
|
|
141
|
+
transition to: :startup_details, if_rule: less_than(:annual_revenue, 100_000)
|
|
142
|
+
transition to: :established_details, if_rule: greater_than(:annual_revenue, 500_000)
|
|
143
|
+
transition to: :business_loan_amount
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# LEVEL 2 — Startup path
|
|
147
|
+
ask :startup_details do
|
|
148
|
+
type :integer
|
|
149
|
+
question "How many months has the business been operating?"
|
|
150
|
+
widget target: :tty, type: :number_input
|
|
151
|
+
transition to: :startup_funding, if_rule: less_than(:startup_details, 12)
|
|
152
|
+
transition to: :business_loan_amount
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# LEVEL 3 — Very new startup
|
|
156
|
+
ask :startup_funding do
|
|
157
|
+
type :multi_enum
|
|
158
|
+
question "What funding sources have you used so far?"
|
|
159
|
+
options %w[PersonalSavings FriendsFamily AngelInvestor VentureCapital Grant CreditCards None]
|
|
160
|
+
widget target: :tty, type: :multi_select
|
|
161
|
+
widget target: :desktop, type: :checkbox_group
|
|
162
|
+
transition to: :business_loan_amount
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# LEVEL 2 — Established business path
|
|
166
|
+
ask :established_details do
|
|
167
|
+
type :string
|
|
168
|
+
question "Provide key financial figures " \
|
|
169
|
+
"(Employees, AnnualExpenses, OutstandingDebt — comma-separated values):"
|
|
170
|
+
widget target: :tty, type: :text_input
|
|
171
|
+
transition to: :established_expansion,
|
|
172
|
+
if_rule: all(
|
|
173
|
+
greater_than(:annual_revenue, 500_000),
|
|
174
|
+
any(
|
|
175
|
+
equals(:business_type, "CCorp"),
|
|
176
|
+
equals(:business_type, "SCorp")
|
|
177
|
+
)
|
|
178
|
+
)
|
|
179
|
+
transition to: :business_loan_amount
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# LEVEL 3 — Corp expansion review
|
|
183
|
+
ask :established_expansion do
|
|
184
|
+
type :multi_enum
|
|
185
|
+
question "What will the loan fund?"
|
|
186
|
+
options %w[Hiring Equipment RealEstate Acquisition Marketing RAndD]
|
|
187
|
+
widget target: :tty, type: :multi_select
|
|
188
|
+
widget target: :desktop, type: :checkbox_group
|
|
189
|
+
transition to: :business_loan_amount
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
ask :business_loan_amount do
|
|
193
|
+
type :currency
|
|
194
|
+
question "How much funding are you requesting (in dollars)?"
|
|
195
|
+
widget target: :tty, type: :number_input
|
|
196
|
+
transition to: :credit_check
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# ============================================================
|
|
200
|
+
# Common tail
|
|
201
|
+
# ============================================================
|
|
202
|
+
|
|
203
|
+
confirm :credit_check do
|
|
204
|
+
question "Do you authorize a credit check?"
|
|
205
|
+
widget target: :tty, type: :yes_no
|
|
206
|
+
transition to: :review, if_rule: equals(:credit_check, true)
|
|
207
|
+
transition to: :declined
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
say :declined do
|
|
211
|
+
text "A credit check is required to proceed. Your application has been saved as a draft."
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
say :review do
|
|
215
|
+
text "Application submitted! You will receive a decision within 3-5 business days."
|
|
216
|
+
end
|
|
217
|
+
end
|