skytab_sandbox_simulator 0.1.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/Gemfile +10 -0
- data/bin/simulate +433 -0
- data/lib/skytab_sandbox_simulator/configuration.rb +205 -0
- data/lib/skytab_sandbox_simulator/data/bar_nightclub/categories.json +9 -0
- data/lib/skytab_sandbox_simulator/data/bar_nightclub/items.json +28 -0
- data/lib/skytab_sandbox_simulator/data/bar_nightclub/tenders.json +19 -0
- data/lib/skytab_sandbox_simulator/data/cafe_bakery/categories.json +9 -0
- data/lib/skytab_sandbox_simulator/data/cafe_bakery/items.json +30 -0
- data/lib/skytab_sandbox_simulator/data/cafe_bakery/tenders.json +17 -0
- data/lib/skytab_sandbox_simulator/data/fine_dining/categories.json +9 -0
- data/lib/skytab_sandbox_simulator/data/fine_dining/items.json +30 -0
- data/lib/skytab_sandbox_simulator/data/fine_dining/tenders.json +18 -0
- data/lib/skytab_sandbox_simulator/data/pizzeria/categories.json +9 -0
- data/lib/skytab_sandbox_simulator/data/pizzeria/items.json +28 -0
- data/lib/skytab_sandbox_simulator/data/pizzeria/tenders.json +18 -0
- data/lib/skytab_sandbox_simulator/data/restaurant/categories.json +44 -0
- data/lib/skytab_sandbox_simulator/data/restaurant/items.json +59 -0
- data/lib/skytab_sandbox_simulator/data/restaurant/tenders.json +22 -0
- data/lib/skytab_sandbox_simulator/database.rb +192 -0
- data/lib/skytab_sandbox_simulator/db/factories/business_types.rb +102 -0
- data/lib/skytab_sandbox_simulator/db/factories/categories.rb +243 -0
- data/lib/skytab_sandbox_simulator/db/factories/items.rb +976 -0
- data/lib/skytab_sandbox_simulator/db/factories/simulated_orders.rb +120 -0
- data/lib/skytab_sandbox_simulator/db/factories/simulated_payments.rb +75 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000000_enable_pgcrypto.rb +7 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000001_create_business_types.rb +18 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000002_create_categories.rb +18 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000003_create_items.rb +23 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000004_create_simulated_orders.rb +35 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000005_create_simulated_payments.rb +26 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000006_create_api_requests.rb +27 -0
- data/lib/skytab_sandbox_simulator/db/migrate/20260316000007_create_daily_summaries.rb +24 -0
- data/lib/skytab_sandbox_simulator/generators/data_loader.rb +125 -0
- data/lib/skytab_sandbox_simulator/generators/entity_generator.rb +107 -0
- data/lib/skytab_sandbox_simulator/generators/order_generator.rb +390 -0
- data/lib/skytab_sandbox_simulator/models/api_request.rb +43 -0
- data/lib/skytab_sandbox_simulator/models/business_type.rb +25 -0
- data/lib/skytab_sandbox_simulator/models/category.rb +17 -0
- data/lib/skytab_sandbox_simulator/models/daily_summary.rb +67 -0
- data/lib/skytab_sandbox_simulator/models/item.rb +32 -0
- data/lib/skytab_sandbox_simulator/models/record.rb +14 -0
- data/lib/skytab_sandbox_simulator/models/simulated_order.rb +40 -0
- data/lib/skytab_sandbox_simulator/models/simulated_payment.rb +28 -0
- data/lib/skytab_sandbox_simulator/seeder.rb +167 -0
- data/lib/skytab_sandbox_simulator/services/base_service.rb +227 -0
- data/lib/skytab_sandbox_simulator/services/skytab/catalog_service.rb +130 -0
- data/lib/skytab_sandbox_simulator/services/skytab/location_service.rb +54 -0
- data/lib/skytab_sandbox_simulator/services/skytab/order_service.rb +139 -0
- data/lib/skytab_sandbox_simulator/services/skytab/payment_service.rb +94 -0
- data/lib/skytab_sandbox_simulator/services/skytab/service_manager.rb +62 -0
- data/lib/skytab_sandbox_simulator/version.rb +5 -0
- data/lib/skytab_sandbox_simulator.rb +45 -0
- metadata +305 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
FactoryBot.define do
|
|
4
|
+
factory :business_type, class: "SkytabSandboxSimulator::Models::BusinessType" do
|
|
5
|
+
sequence(:key) { |n| "business_type_#{n}" }
|
|
6
|
+
name { "Test Business Type" }
|
|
7
|
+
industry { "food" }
|
|
8
|
+
order_profile { {} }
|
|
9
|
+
|
|
10
|
+
# ── Food (5) ──────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
trait :restaurant do
|
|
13
|
+
key { "restaurant" }
|
|
14
|
+
name { "Restaurant" }
|
|
15
|
+
industry { "food" }
|
|
16
|
+
description { "Full-service casual dining restaurant" }
|
|
17
|
+
order_profile do
|
|
18
|
+
{
|
|
19
|
+
"avg_order_value_cents" => 2500,
|
|
20
|
+
"avg_items_per_order" => 3,
|
|
21
|
+
"peak_hours" => %w[11:30 12:30 18:00 19:30],
|
|
22
|
+
"meal_periods" => %w[breakfast lunch dinner],
|
|
23
|
+
"revenue_classes" => %w[DINE_IN TAKEOUT DELIVERY BAR CATERING],
|
|
24
|
+
"tip_percentage_range" => [15, 25],
|
|
25
|
+
"tax_rate" => 8.25
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
trait :cafe_bakery do
|
|
31
|
+
key { "cafe_bakery" }
|
|
32
|
+
name { "Cafe & Bakery" }
|
|
33
|
+
industry { "food" }
|
|
34
|
+
description { "Coffee shop with fresh-baked pastries and light fare" }
|
|
35
|
+
order_profile do
|
|
36
|
+
{
|
|
37
|
+
"avg_order_value_cents" => 1200,
|
|
38
|
+
"avg_items_per_order" => 2,
|
|
39
|
+
"peak_hours" => %w[07:00 08:30 12:00],
|
|
40
|
+
"meal_periods" => %w[breakfast lunch],
|
|
41
|
+
"revenue_classes" => %w[DINE_IN TAKEOUT],
|
|
42
|
+
"tip_percentage_range" => [10, 20],
|
|
43
|
+
"tax_rate" => 8.25
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
trait :bar_nightclub do
|
|
49
|
+
key { "bar_nightclub" }
|
|
50
|
+
name { "Bar & Nightclub" }
|
|
51
|
+
industry { "food" }
|
|
52
|
+
description { "Full bar with cocktails, spirits, and bar snacks" }
|
|
53
|
+
order_profile do
|
|
54
|
+
{
|
|
55
|
+
"avg_order_value_cents" => 3500,
|
|
56
|
+
"avg_items_per_order" => 4,
|
|
57
|
+
"peak_hours" => %w[17:00 21:00 23:00],
|
|
58
|
+
"meal_periods" => %w[happy_hour dinner late_night],
|
|
59
|
+
"revenue_classes" => %w[BAR DINE_IN TAKEOUT],
|
|
60
|
+
"tip_percentage_range" => [15, 25],
|
|
61
|
+
"tax_rate" => 10.0
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
trait :pizzeria do
|
|
67
|
+
key { "pizzeria" }
|
|
68
|
+
name { "Pizzeria" }
|
|
69
|
+
industry { "food" }
|
|
70
|
+
description { "Pizza restaurant with dine-in and delivery" }
|
|
71
|
+
order_profile do
|
|
72
|
+
{
|
|
73
|
+
"avg_order_value_cents" => 2200,
|
|
74
|
+
"avg_items_per_order" => 3,
|
|
75
|
+
"peak_hours" => %w[11:30 12:30 18:00 19:30],
|
|
76
|
+
"meal_periods" => %w[lunch dinner late_night],
|
|
77
|
+
"revenue_classes" => %w[DINE_IN TAKEOUT DELIVERY],
|
|
78
|
+
"tip_percentage_range" => [12, 20],
|
|
79
|
+
"tax_rate" => 8.25
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
trait :fine_dining do
|
|
85
|
+
key { "fine_dining" }
|
|
86
|
+
name { "Fine Dining" }
|
|
87
|
+
industry { "food" }
|
|
88
|
+
description { "Upscale restaurant with multi-course tasting menus" }
|
|
89
|
+
order_profile do
|
|
90
|
+
{
|
|
91
|
+
"avg_order_value_cents" => 12000,
|
|
92
|
+
"avg_items_per_order" => 5,
|
|
93
|
+
"peak_hours" => %w[18:00 19:30 20:30],
|
|
94
|
+
"meal_periods" => %w[dinner],
|
|
95
|
+
"revenue_classes" => %w[DINE_IN BAR],
|
|
96
|
+
"tip_percentage_range" => [18, 25],
|
|
97
|
+
"tax_rate" => 8.25
|
|
98
|
+
}
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
FactoryBot.define do
|
|
4
|
+
factory :category, class: "SkytabSandboxSimulator::Models::Category" do
|
|
5
|
+
association :business_type
|
|
6
|
+
sequence(:name) { |n| "Category #{n}" }
|
|
7
|
+
sort_order { 0 }
|
|
8
|
+
|
|
9
|
+
# ── Restaurant ────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
trait :appetizers do
|
|
12
|
+
name { "Appetizers" }
|
|
13
|
+
sort_order { 1 }
|
|
14
|
+
description { "Starters and shareables" }
|
|
15
|
+
tax_group { "food" }
|
|
16
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
trait :entrees do
|
|
20
|
+
name { "Entrees" }
|
|
21
|
+
sort_order { 2 }
|
|
22
|
+
description { "Main courses" }
|
|
23
|
+
tax_group { "food" }
|
|
24
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
trait :sides do
|
|
28
|
+
name { "Sides" }
|
|
29
|
+
sort_order { 3 }
|
|
30
|
+
description { "Side dishes" }
|
|
31
|
+
tax_group { "food" }
|
|
32
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
trait :desserts do
|
|
36
|
+
name { "Desserts" }
|
|
37
|
+
sort_order { 4 }
|
|
38
|
+
description { "Sweet finishes" }
|
|
39
|
+
tax_group { "food" }
|
|
40
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
trait :beverages do
|
|
44
|
+
name { "Beverages" }
|
|
45
|
+
sort_order { 5 }
|
|
46
|
+
description { "Non-alcoholic drinks" }
|
|
47
|
+
tax_group { "beverage" }
|
|
48
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
trait :alcohol do
|
|
52
|
+
name { "Alcohol" }
|
|
53
|
+
sort_order { 6 }
|
|
54
|
+
description { "Beer, wine, and cocktails" }
|
|
55
|
+
tax_group { "alcohol" }
|
|
56
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
trait :kids_menu do
|
|
60
|
+
name { "Kids Menu" }
|
|
61
|
+
sort_order { 7 }
|
|
62
|
+
description { "For our younger guests" }
|
|
63
|
+
tax_group { "food" }
|
|
64
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
trait :specials do
|
|
68
|
+
name { "Specials" }
|
|
69
|
+
sort_order { 8 }
|
|
70
|
+
description { "Chef's daily specials" }
|
|
71
|
+
tax_group { "food" }
|
|
72
|
+
association :business_type, factory: [:business_type, :restaurant]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# ── Cafe & Bakery ────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
trait :coffee_espresso do
|
|
78
|
+
name { "Coffee & Espresso" }
|
|
79
|
+
sort_order { 1 }
|
|
80
|
+
description { "Hot and cold coffee drinks" }
|
|
81
|
+
tax_group { "beverage" }
|
|
82
|
+
association :business_type, factory: [:business_type, :cafe_bakery]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
trait :pastries do
|
|
86
|
+
name { "Pastries" }
|
|
87
|
+
sort_order { 2 }
|
|
88
|
+
description { "Fresh-baked goods" }
|
|
89
|
+
tax_group { "food" }
|
|
90
|
+
association :business_type, factory: [:business_type, :cafe_bakery]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
trait :breakfast_items do
|
|
94
|
+
name { "Breakfast" }
|
|
95
|
+
sort_order { 3 }
|
|
96
|
+
description { "Morning favorites" }
|
|
97
|
+
tax_group { "food" }
|
|
98
|
+
association :business_type, factory: [:business_type, :cafe_bakery]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
trait :sandwiches_wraps do
|
|
102
|
+
name { "Sandwiches & Wraps" }
|
|
103
|
+
sort_order { 4 }
|
|
104
|
+
description { "Lunch fare" }
|
|
105
|
+
tax_group { "food" }
|
|
106
|
+
association :business_type, factory: [:business_type, :cafe_bakery]
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
trait :smoothies_juice do
|
|
110
|
+
name { "Smoothies & Juice" }
|
|
111
|
+
sort_order { 5 }
|
|
112
|
+
description { "Fresh blended drinks" }
|
|
113
|
+
tax_group { "beverage" }
|
|
114
|
+
association :business_type, factory: [:business_type, :cafe_bakery]
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# ── Bar & Nightclub ──────────────────────────────────────
|
|
118
|
+
|
|
119
|
+
trait :draft_beer do
|
|
120
|
+
name { "Draft Beer" }
|
|
121
|
+
sort_order { 1 }
|
|
122
|
+
description { "On tap" }
|
|
123
|
+
tax_group { "alcohol" }
|
|
124
|
+
association :business_type, factory: [:business_type, :bar_nightclub]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
trait :cocktails do
|
|
128
|
+
name { "Cocktails" }
|
|
129
|
+
sort_order { 2 }
|
|
130
|
+
description { "Handcrafted cocktails" }
|
|
131
|
+
tax_group { "alcohol" }
|
|
132
|
+
association :business_type, factory: [:business_type, :bar_nightclub]
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
trait :spirits do
|
|
136
|
+
name { "Spirits" }
|
|
137
|
+
sort_order { 3 }
|
|
138
|
+
description { "Premium spirits" }
|
|
139
|
+
tax_group { "alcohol" }
|
|
140
|
+
association :business_type, factory: [:business_type, :bar_nightclub]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
trait :wine_list do
|
|
144
|
+
name { "Wine" }
|
|
145
|
+
sort_order { 4 }
|
|
146
|
+
description { "By the glass or bottle" }
|
|
147
|
+
tax_group { "alcohol" }
|
|
148
|
+
association :business_type, factory: [:business_type, :bar_nightclub]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
trait :bar_snacks do
|
|
152
|
+
name { "Bar Snacks" }
|
|
153
|
+
sort_order { 5 }
|
|
154
|
+
description { "Shareable bites" }
|
|
155
|
+
tax_group { "food" }
|
|
156
|
+
association :business_type, factory: [:business_type, :bar_nightclub]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# ── Pizzeria ─────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
trait :pizzas do
|
|
162
|
+
name { "Pizzas" }
|
|
163
|
+
sort_order { 1 }
|
|
164
|
+
description { "Hand-tossed pizzas" }
|
|
165
|
+
tax_group { "food" }
|
|
166
|
+
association :business_type, factory: [:business_type, :pizzeria]
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
trait :calzones do
|
|
170
|
+
name { "Calzones" }
|
|
171
|
+
sort_order { 2 }
|
|
172
|
+
description { "Folded and baked" }
|
|
173
|
+
tax_group { "food" }
|
|
174
|
+
association :business_type, factory: [:business_type, :pizzeria]
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
trait :pizza_sides do
|
|
178
|
+
name { "Sides" }
|
|
179
|
+
sort_order { 3 }
|
|
180
|
+
description { "Perfect with pizza" }
|
|
181
|
+
tax_group { "food" }
|
|
182
|
+
association :business_type, factory: [:business_type, :pizzeria]
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
trait :pizza_drinks do
|
|
186
|
+
name { "Drinks" }
|
|
187
|
+
sort_order { 4 }
|
|
188
|
+
description { "Beverages" }
|
|
189
|
+
tax_group { "beverage" }
|
|
190
|
+
association :business_type, factory: [:business_type, :pizzeria]
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
trait :pizza_desserts do
|
|
194
|
+
name { "Desserts" }
|
|
195
|
+
sort_order { 5 }
|
|
196
|
+
description { "Sweet endings" }
|
|
197
|
+
tax_group { "food" }
|
|
198
|
+
association :business_type, factory: [:business_type, :pizzeria]
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# ── Fine Dining ──────────────────────────────────────────
|
|
202
|
+
|
|
203
|
+
trait :first_course do
|
|
204
|
+
name { "First Course" }
|
|
205
|
+
sort_order { 1 }
|
|
206
|
+
description { "Opening courses" }
|
|
207
|
+
tax_group { "food" }
|
|
208
|
+
association :business_type, factory: [:business_type, :fine_dining]
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
trait :main_course do
|
|
212
|
+
name { "Main Course" }
|
|
213
|
+
sort_order { 2 }
|
|
214
|
+
description { "Principal courses" }
|
|
215
|
+
tax_group { "food" }
|
|
216
|
+
association :business_type, factory: [:business_type, :fine_dining]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
trait :fine_desserts do
|
|
220
|
+
name { "Desserts" }
|
|
221
|
+
sort_order { 3 }
|
|
222
|
+
description { "Artisan desserts" }
|
|
223
|
+
tax_group { "food" }
|
|
224
|
+
association :business_type, factory: [:business_type, :fine_dining]
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
trait :fine_wines do
|
|
228
|
+
name { "Wine List" }
|
|
229
|
+
sort_order { 4 }
|
|
230
|
+
description { "Curated wine selection" }
|
|
231
|
+
tax_group { "alcohol" }
|
|
232
|
+
association :business_type, factory: [:business_type, :fine_dining]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
trait :fine_cocktails do
|
|
236
|
+
name { "Cocktails" }
|
|
237
|
+
sort_order { 5 }
|
|
238
|
+
description { "Signature cocktails" }
|
|
239
|
+
tax_group { "alcohol" }
|
|
240
|
+
association :business_type, factory: [:business_type, :fine_dining]
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|