synthra 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.
Files changed (302) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +4 -0
  3. data/.rubocop.yml +40 -0
  4. data/.yardopts +18 -0
  5. data/ACCESS_DOCS.md +116 -0
  6. data/ADVANCED_FEATURES_SUMMARY.md +245 -0
  7. data/CHANGELOG.md +498 -0
  8. data/CODE_OF_CONDUCT.md +122 -0
  9. data/CONTRIBUTING.md +307 -0
  10. data/DOCUMENTATION.md +204 -0
  11. data/DOCUMENTATION_GUIDE.md +194 -0
  12. data/LICENSE +22 -0
  13. data/README.md +1458 -0
  14. data/Rakefile +128 -0
  15. data/benchmark/README.md +591 -0
  16. data/benchmark/batch_generation.rb +63 -0
  17. data/benchmark/engine_comparison.rb +295 -0
  18. data/benchmark/single_record.rb +108 -0
  19. data/benchmark/streaming.rb +74 -0
  20. data/docs/ACTIVERECORD_INFERENCE.md +524 -0
  21. data/docs/API_SERVER.md +278 -0
  22. data/docs/CONFIG_FILE.md +315 -0
  23. data/docs/DATA_CONTRACTS.md +312 -0
  24. data/docs/ENHANCED_REPL.md +304 -0
  25. data/docs/FACTORY_BOT.md +271 -0
  26. data/docs/GITHUB_ACTION.md +420 -0
  27. data/docs/GRAPHQL_EXPORT.md +303 -0
  28. data/docs/GRAPHQL_FEDERATION.md +651 -0
  29. data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
  30. data/docs/LSP.md +189 -0
  31. data/docs/MIGRATION_GENERATOR.md +547 -0
  32. data/docs/MOCK_SERVER.md +280 -0
  33. data/docs/NATIVE_ENGINE.md +298 -0
  34. data/docs/OPENAPI_EXPORT.md +252 -0
  35. data/docs/PERFORMANCE_MODE.md +228 -0
  36. data/docs/PERSONAS.md +547 -0
  37. data/docs/PROPERTY_TESTING.md +284 -0
  38. data/docs/PROTOBUF_EXPORT.md +276 -0
  39. data/docs/QUALITY_METRICS.md +555 -0
  40. data/docs/QUICK_REFERENCE.md +88 -0
  41. data/docs/RAILS_ENGINE.md +404 -0
  42. data/docs/RAILS_INTEGRATION.md +454 -0
  43. data/docs/README.md +175 -0
  44. data/docs/REPL_QUICK_REFERENCE.md +149 -0
  45. data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
  46. data/docs/SCENARIOS.md +576 -0
  47. data/docs/SECURITY_TESTING.md +318 -0
  48. data/docs/SNAPSHOT_TESTING.md +308 -0
  49. data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
  50. data/docs/TERRAFORM_EXPORT.md +447 -0
  51. data/docs/TIME_TRAVEL.md +507 -0
  52. data/docs/USAGE_GUIDE.md +980 -0
  53. data/docs/WEBHOOK_SIMULATOR.md +579 -0
  54. data/docs/advanced_features.md +183 -0
  55. data/docs/api_reference.md +153 -0
  56. data/docs/behaviors.md +138 -0
  57. data/docs/best_practices.md +191 -0
  58. data/docs/dsl_reference.md +172 -0
  59. data/docs/examples.md +162 -0
  60. data/docs/generation_modes.md +125 -0
  61. data/docs/getting_started.md +92 -0
  62. data/docs/index.html +177 -0
  63. data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
  64. data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
  65. data/docs/troubleshooting.md +215 -0
  66. data/docs/type_reference.md +224 -0
  67. data/examples/hostile_mode_demo.rb +64 -0
  68. data/exe/synthra +6 -0
  69. data/ext/synthra_native/Cargo.lock +972 -0
  70. data/ext/synthra_native/Cargo.toml +46 -0
  71. data/ext/synthra_native/extconf.rb +41 -0
  72. data/ext/synthra_native/src/generator.rs +397 -0
  73. data/ext/synthra_native/src/lib.rs +229 -0
  74. data/ext/synthra_native/src/types.rs +1485 -0
  75. data/lib/generators/synthra/install_generator.rb +86 -0
  76. data/lib/generators/synthra/templates/api_response.dsl +15 -0
  77. data/lib/generators/synthra/templates/fake_data.rake +116 -0
  78. data/lib/generators/synthra/templates/synthra.yml +31 -0
  79. data/lib/generators/synthra/templates/synthra_support.rb +19 -0
  80. data/lib/generators/synthra/templates/user.dsl +11 -0
  81. data/lib/synthra/activerecord_inference.rb +394 -0
  82. data/lib/synthra/api.rb +381 -0
  83. data/lib/synthra/api_server.rb +718 -0
  84. data/lib/synthra/behaviors/applicator.rb +165 -0
  85. data/lib/synthra/behaviors/base.rb +155 -0
  86. data/lib/synthra/behaviors/close_connection.rb +60 -0
  87. data/lib/synthra/behaviors/deprecated.rb +100 -0
  88. data/lib/synthra/behaviors/failure.rb +69 -0
  89. data/lib/synthra/behaviors/latency.rb +103 -0
  90. data/lib/synthra/behaviors/partial_data.rb +83 -0
  91. data/lib/synthra/behaviors/randomize_order.rb +74 -0
  92. data/lib/synthra/behaviors/registry.rb +238 -0
  93. data/lib/synthra/behaviors/simulate_error.rb +79 -0
  94. data/lib/synthra/cli/commands/base.rb +105 -0
  95. data/lib/synthra/cli/commands/diff.rb +227 -0
  96. data/lib/synthra/cli/commands/docs.rb +67 -0
  97. data/lib/synthra/cli/commands/export.rb +150 -0
  98. data/lib/synthra/cli/commands/generate.rb +72 -0
  99. data/lib/synthra/cli/commands/import.rb +80 -0
  100. data/lib/synthra/cli/commands/lint.rb +53 -0
  101. data/lib/synthra/cli/commands/live.rb +57 -0
  102. data/lib/synthra/cli/commands/seed.rb +99 -0
  103. data/lib/synthra/cli/commands/validate.rb +28 -0
  104. data/lib/synthra/cli.rb +2471 -0
  105. data/lib/synthra/config_file.rb +129 -0
  106. data/lib/synthra/configuration.rb +281 -0
  107. data/lib/synthra/contracts_registry.rb +408 -0
  108. data/lib/synthra/database_seeder.rb +268 -0
  109. data/lib/synthra/deterministic_ids.rb +218 -0
  110. data/lib/synthra/documentation_generator.rb +414 -0
  111. data/lib/synthra/engine.rb +251 -0
  112. data/lib/synthra/errors.rb +1169 -0
  113. data/lib/synthra/export/base.rb +85 -0
  114. data/lib/synthra/export/csv.rb +101 -0
  115. data/lib/synthra/export/graphql.rb +266 -0
  116. data/lib/synthra/export/graphql_federation.rb +377 -0
  117. data/lib/synthra/export/graphviz.rb +258 -0
  118. data/lib/synthra/export/javascript.rb +327 -0
  119. data/lib/synthra/export/json_data.rb +61 -0
  120. data/lib/synthra/export/json_schema.rb +290 -0
  121. data/lib/synthra/export/openapi.rb +514 -0
  122. data/lib/synthra/export/protobuf.rb +483 -0
  123. data/lib/synthra/export/python.rb +560 -0
  124. data/lib/synthra/export/sql.rb +381 -0
  125. data/lib/synthra/export/sql_insert.rb +152 -0
  126. data/lib/synthra/export/terraform.rb +501 -0
  127. data/lib/synthra/export/type_mapping.rb +389 -0
  128. data/lib/synthra/export/typescript.rb +300 -0
  129. data/lib/synthra/export/xml_data.rb +104 -0
  130. data/lib/synthra/export/yaml_data.rb +56 -0
  131. data/lib/synthra/export.rb +404 -0
  132. data/lib/synthra/factory_bot_integration.rb +157 -0
  133. data/lib/synthra/field.rb +440 -0
  134. data/lib/synthra/functions/registry.rb +104 -0
  135. data/lib/synthra/generator/context.rb +372 -0
  136. data/lib/synthra/generator/engine.rb +336 -0
  137. data/lib/synthra/generator/faker_adapter.rb +425 -0
  138. data/lib/synthra/generator/modes.rb +444 -0
  139. data/lib/synthra/generator/resolver.rb +256 -0
  140. data/lib/synthra/generator/rng.rb +273 -0
  141. data/lib/synthra/generator/streamer.rb +63 -0
  142. data/lib/synthra/generator/uniqueness.rb +118 -0
  143. data/lib/synthra/initializer.rb +97 -0
  144. data/lib/synthra/limits.rb +279 -0
  145. data/lib/synthra/live_preview.rb +518 -0
  146. data/lib/synthra/loader_config.rb +78 -0
  147. data/lib/synthra/lsp/server.rb +689 -0
  148. data/lib/synthra/migration_generator.rb +301 -0
  149. data/lib/synthra/mixin.rb +174 -0
  150. data/lib/synthra/mock_server.rb +458 -0
  151. data/lib/synthra/native_engine.rb +304 -0
  152. data/lib/synthra/openapi_importer.rb +228 -0
  153. data/lib/synthra/output/json_formatter.rb +40 -0
  154. data/lib/synthra/output/ndjson_formatter.rb +55 -0
  155. data/lib/synthra/parser/ast.rb +1287 -0
  156. data/lib/synthra/parser/lexer.rb +1152 -0
  157. data/lib/synthra/parser/parser.rb +1664 -0
  158. data/lib/synthra/parser/tokens.rb +461 -0
  159. data/lib/synthra/performance_mode.rb +364 -0
  160. data/lib/synthra/personas.rb +397 -0
  161. data/lib/synthra/property_testing.rb +172 -0
  162. data/lib/synthra/quality_metrics.rb +405 -0
  163. data/lib/synthra/rails_test_helper.rb +248 -0
  164. data/lib/synthra/registry.rb +533 -0
  165. data/lib/synthra/relationships.rb +193 -0
  166. data/lib/synthra/repl/enhanced_repl.rb +607 -0
  167. data/lib/synthra/repl/formatter.rb +191 -0
  168. data/lib/synthra/scenarios.rb +423 -0
  169. data/lib/synthra/schema.rb +605 -0
  170. data/lib/synthra/schema_inheritance.rb +104 -0
  171. data/lib/synthra/schema_versioning.rb +212 -0
  172. data/lib/synthra/snapshot_testing.rb +199 -0
  173. data/lib/synthra/time_travel.rb +338 -0
  174. data/lib/synthra/type_definitions.rb +274 -0
  175. data/lib/synthra/types/address_location/addresses.rb +125 -0
  176. data/lib/synthra/types/address_location/airports.rb +200 -0
  177. data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
  178. data/lib/synthra/types/address_location/locations.rb +406 -0
  179. data/lib/synthra/types/base.rb +48 -0
  180. data/lib/synthra/types/commerce_products/commerce.rb +119 -0
  181. data/lib/synthra/types/commerce_products/companies.rb +71 -0
  182. data/lib/synthra/types/commerce_products/construction.rb +126 -0
  183. data/lib/synthra/types/commerce_products/products.rb +205 -0
  184. data/lib/synthra/types/core/collections.rb +513 -0
  185. data/lib/synthra/types/core/defaults.rb +76 -0
  186. data/lib/synthra/types/core/enums.rb +102 -0
  187. data/lib/synthra/types/core/identifiers.rb +445 -0
  188. data/lib/synthra/types/core/primitives.rb +586 -0
  189. data/lib/synthra/types/core/references.rb +466 -0
  190. data/lib/synthra/types/core/sequences.rb +304 -0
  191. data/lib/synthra/types/crypto/crypto.rb +162 -0
  192. data/lib/synthra/types/date_time/dates.rb +387 -0
  193. data/lib/synthra/types/finance_banking/banking.rb +424 -0
  194. data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
  195. data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
  196. data/lib/synthra/types/formula.rb +184 -0
  197. data/lib/synthra/types/health_medical/medical.rb +150 -0
  198. data/lib/synthra/types/hostile_payloads.rb +122 -0
  199. data/lib/synthra/types/json_array.rb +51 -0
  200. data/lib/synthra/types/media_entertainment/media.rb +62 -0
  201. data/lib/synthra/types/naughty_string.rb +30 -0
  202. data/lib/synthra/types/personal_names/chinese.rb +41 -0
  203. data/lib/synthra/types/personal_names/identifiers.rb +187 -0
  204. data/lib/synthra/types/personal_names/names.rb +246 -0
  205. data/lib/synthra/types/personal_names/national_id.rb +89 -0
  206. data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
  207. data/lib/synthra/types/regex.rb +248 -0
  208. data/lib/synthra/types/registry.rb +182 -0
  209. data/lib/synthra/types/repeating_element.rb +50 -0
  210. data/lib/synthra/types/scenario.rb +29 -0
  211. data/lib/synthra/types/technology_internet/apps.rb +67 -0
  212. data/lib/synthra/types/technology_internet/communication.rb +162 -0
  213. data/lib/synthra/types/technology_internet/devices.rb +80 -0
  214. data/lib/synthra/types/technology_internet/formats.rb +139 -0
  215. data/lib/synthra/types/technology_internet/networking.rb +143 -0
  216. data/lib/synthra/types/template.rb +92 -0
  217. data/lib/synthra/types/text_content/business.rb +128 -0
  218. data/lib/synthra/types/text_content/colors.rb +70 -0
  219. data/lib/synthra/types/text_content/misc.rb +237 -0
  220. data/lib/synthra/types/text_content/security.rb +130 -0
  221. data/lib/synthra/types/text_content/text_generation.rb +532 -0
  222. data/lib/synthra/types/travel/travel.rb +150 -0
  223. data/lib/synthra/utils/string_distance.rb +133 -0
  224. data/lib/synthra/validator/dsl_validator.rb +339 -0
  225. data/lib/synthra/validator/path_validator.rb +615 -0
  226. data/lib/synthra/version.rb +35 -0
  227. data/lib/synthra/webhook_simulator.rb +341 -0
  228. data/lib/synthra.rb +259 -0
  229. data/schemas/address.dsl +16 -0
  230. data/schemas/api_response.dsl +8 -0
  231. data/schemas/error_payload.dsl +9 -0
  232. data/schemas/order.dsl +10 -0
  233. data/schemas/order_item.dsl +8 -0
  234. data/schemas/payment.dsl +11 -0
  235. data/schemas/social_post.dsl +13 -0
  236. data/schemas/user.dsl +10 -0
  237. data/scripts/batch_fix_all.rb +96 -0
  238. data/scripts/delete_old_files.rb +32 -0
  239. data/scripts/fix_all_grouped_files.rb +137 -0
  240. data/scripts/fix_all_indentation.rb +48 -0
  241. data/scripts/fix_all_syntax.rb +124 -0
  242. data/scripts/fix_grouped_files.rb +184 -0
  243. data/scripts/fix_syntax_errors.rb +108 -0
  244. data/scripts/group_domain_types.rb +112 -0
  245. data/scripts/group_domain_types_fixed.rb +150 -0
  246. data/scripts/merge_domains_to_one_file.rb +68 -0
  247. data/scripts/move_existing_types.rb +130 -0
  248. data/scripts/split_grouped_types.rb +142 -0
  249. data/tech_docs/README.md +134 -0
  250. data/tech_docs/advanced/streaming.md +405 -0
  251. data/tech_docs/advanced/thread_safety.md +253 -0
  252. data/tech_docs/api/overview.md +485 -0
  253. data/tech_docs/appendices/type_chart.md +193 -0
  254. data/tech_docs/basic_concepts.md +383 -0
  255. data/tech_docs/behaviors/overview.md +346 -0
  256. data/tech_docs/dsl/complex_types.md +790 -0
  257. data/tech_docs/dsl/core_types.md +464 -0
  258. data/tech_docs/dsl/datetime_types.md +325 -0
  259. data/tech_docs/dsl/field_modifiers.md +414 -0
  260. data/tech_docs/dsl/grammar.md +431 -0
  261. data/tech_docs/dsl/schema_definition.md +399 -0
  262. data/tech_docs/export/README.md +276 -0
  263. data/tech_docs/installation.md +273 -0
  264. data/tech_docs/integration/ci_cd.md +707 -0
  265. data/tech_docs/integration/ci_cd_guide.md +579 -0
  266. data/tech_docs/integration/factory_bot.md +485 -0
  267. data/tech_docs/integration/rails.md +630 -0
  268. data/tech_docs/integration/rspec.md +449 -0
  269. data/tech_docs/modes/overview.md +350 -0
  270. data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
  271. data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
  272. data/tech_docs/quick_start.md +256 -0
  273. data/tech_docs/templates/README.md +805 -0
  274. data/tech_docs/tutorials/advanced.md +371 -0
  275. data/tech_docs/tutorials/getting_started.md +189 -0
  276. data/tech_docs/tutorials/intermediate.md +231 -0
  277. data/tech_docs/tutorials/template_gallery.md +569 -0
  278. data/tech_example/01_basic_usage.rb +238 -0
  279. data/tech_example/02_types_demo.rb +336 -0
  280. data/tech_example/04_cli_usage.md +429 -0
  281. data/tech_example/05_database_seeding.rb +283 -0
  282. data/tech_example/07_rspec_integration.rb +359 -0
  283. data/tech_example/10_custom_types.rb +387 -0
  284. data/tech_example/12_behaviors.rb +372 -0
  285. data/tech_example/13_twitter_dm_example.rb +120 -0
  286. data/tech_example/14_exact_json_structure.rb +253 -0
  287. data/tech_example/16_lsp_server.rb +56 -0
  288. data/tech_example/17_property_testing.rb +92 -0
  289. data/tech_example/18_enhanced_repl.rb +120 -0
  290. data/tech_example/19_security_fuzzing.rb +145 -0
  291. data/tech_example/NEW_FEATURES.md +169 -0
  292. data/tech_example/README.md +118 -0
  293. data/tech_example/schemas/api_response.dsl +123 -0
  294. data/tech_example/schemas/ecommerce.dsl +121 -0
  295. data/tech_example/schemas/twitter_dm.dsl +109 -0
  296. data/tech_example/schemas/user.dsl +36 -0
  297. data/vscode-extension/README.md +246 -0
  298. data/vscode-extension/language-configuration.json +31 -0
  299. data/vscode-extension/package.json +55 -0
  300. data/vscode-extension/snippets/fakedatadsl.json +198 -0
  301. data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
  302. metadata +478 -0
@@ -0,0 +1,555 @@
1
+ # Data Quality Metrics
2
+
3
+ FakeDataDSL's Quality Metrics feature analyzes your generated data for **realism, uniqueness, distribution, and completeness**. Get actionable insights into how realistic and diverse your test data is.
4
+
5
+ ## Quick Start
6
+
7
+ ```ruby
8
+ # Generate data with quality report
9
+ result = FakeDataDSL.generate_with_quality("User", count: 1000)
10
+
11
+ # Access the data
12
+ result.data # => Array of 1000 user records
13
+
14
+ # Access the quality report
15
+ result.quality_report
16
+ # => {
17
+ # uniqueness: { id: 100%, email: 100%, name: 85% },
18
+ # distribution: { role: { admin: 5%, user: 95% } },
19
+ # completeness: 98.5%,
20
+ # realism_score: 94
21
+ # }
22
+ ```
23
+
24
+ ## Basic Usage
25
+
26
+ ### Generate with Quality Analysis
27
+
28
+ ```ruby
29
+ result = FakeDataDSL::QualityMetrics.generate_with_quality("Order",
30
+ count: 500,
31
+ seed: 42
32
+ )
33
+
34
+ puts result.quality_report.summary
35
+ # Uniqueness: 98.2%
36
+ # Completeness: 96.5%
37
+ # Distribution: balanced
38
+ # Realism: 92/100
39
+ ```
40
+
41
+ ### Analyze Existing Data
42
+
43
+ ```ruby
44
+ # Analyze data you've already generated
45
+ data = FakeDataDSL.generate_many("Product", 1000)
46
+ report = FakeDataDSL::QualityMetrics.analyze(data, schema: "Product")
47
+
48
+ report.issues # => Array of quality issues
49
+ report.suggestions # => How to improve data quality
50
+ ```
51
+
52
+ ## Quality Metrics
53
+
54
+ ### Uniqueness
55
+
56
+ Measures how unique values are across records:
57
+
58
+ ```ruby
59
+ report.uniqueness
60
+ # => {
61
+ # id: 100.0, # 100% unique (good for IDs)
62
+ # email: 100.0, # 100% unique (as expected)
63
+ # name: 85.3, # 85% unique (some duplicates)
64
+ # country: 12.5, # 12.5% unique (expected for enums)
65
+ # status: 3.3 # 3.3% unique (only 3 possible values)
66
+ # }
67
+
68
+ # Check specific field
69
+ report.uniqueness_for(:email) # => 100.0
70
+
71
+ # Fields that should be unique
72
+ report.uniqueness_violations
73
+ # => [:name] # name has @unique annotation but has duplicates
74
+ ```
75
+
76
+ ### Distribution
77
+
78
+ Analyzes value distribution for enum-like fields:
79
+
80
+ ```ruby
81
+ report.distribution
82
+ # => {
83
+ # role: {
84
+ # "user" => 0.85, # 85% are regular users
85
+ # "admin" => 0.10, # 10% are admins
86
+ # "moderator" => 0.05 # 5% are moderators
87
+ # },
88
+ # status: {
89
+ # "active" => 0.70,
90
+ # "pending" => 0.20,
91
+ # "suspended" => 0.10
92
+ # }
93
+ # }
94
+
95
+ # Check if distribution matches expected
96
+ report.distribution_balanced?(:role) # => true/false
97
+
98
+ # Get distribution statistics
99
+ report.distribution_stats(:role)
100
+ # => {
101
+ # entropy: 0.85, # Information entropy (higher = more diverse)
102
+ # chi_squared: 2.34, # Chi-squared statistic
103
+ # is_uniform: false, # Whether uniformly distributed
104
+ # dominant_value: "user" # Most common value
105
+ # }
106
+ ```
107
+
108
+ ### Completeness
109
+
110
+ Measures how many optional fields are populated:
111
+
112
+ ```ruby
113
+ report.completeness
114
+ # => 98.5 # 98.5% of optional fields have values
115
+
116
+ report.completeness_by_field
117
+ # => {
118
+ # bio: 95.0, # 95% of records have bio
119
+ # avatar_url: 88.2, # 88.2% have avatar
120
+ # phone: 72.0, # 72% have phone
121
+ # middle_name: 45.5 # 45.5% have middle name
122
+ # }
123
+
124
+ # Fields with low completeness
125
+ report.sparse_fields(threshold: 50)
126
+ # => [:middle_name] # Less than 50% populated
127
+ ```
128
+
129
+ ### Realism Score
130
+
131
+ Overall assessment of how realistic the data looks:
132
+
133
+ ```ruby
134
+ report.realism_score # => 94 (out of 100)
135
+
136
+ report.realism_breakdown
137
+ # => {
138
+ # email_format: 100, # Emails look real
139
+ # name_format: 95, # Names are realistic
140
+ # phone_format: 90, # Phones follow patterns
141
+ # date_consistency: 98, # Dates are logically consistent
142
+ # numeric_ranges: 85, # Numbers in expected ranges
143
+ # text_quality: 92 # Text is coherent
144
+ # }
145
+
146
+ # Specific realism checks
147
+ report.realism_issues
148
+ # => [
149
+ # { field: :age, issue: "5% of values are negative" },
150
+ # { field: :price, issue: "Values exceed expected range" }
151
+ # ]
152
+ ```
153
+
154
+ ## Quality Thresholds
155
+
156
+ ### Define Quality Standards
157
+
158
+ ```ruby
159
+ FakeDataDSL::QualityMetrics.configure do |config|
160
+ config.thresholds = {
161
+ uniqueness: {
162
+ id: 100, # Must be 100% unique
163
+ email: 100, # Must be 100% unique
164
+ name: 80 # At least 80% unique
165
+ },
166
+ completeness: {
167
+ minimum: 90, # At least 90% of optional fields filled
168
+ required: 100 # Required fields must always be present
169
+ },
170
+ realism: {
171
+ minimum: 85 # Minimum realism score
172
+ }
173
+ }
174
+ end
175
+ ```
176
+
177
+ ### Validate Against Thresholds
178
+
179
+ ```ruby
180
+ result = FakeDataDSL.generate_with_quality("User", count: 1000)
181
+
182
+ if result.quality_report.meets_thresholds?
183
+ puts "Data quality is acceptable"
184
+ else
185
+ puts "Quality issues:"
186
+ result.quality_report.threshold_violations.each do |violation|
187
+ puts " - #{violation[:field]}: #{violation[:message]}"
188
+ end
189
+ end
190
+ ```
191
+
192
+ ### CI Integration
193
+
194
+ ```ruby
195
+ # In your test suite
196
+ RSpec.describe "Data Quality" do
197
+ it "generates high-quality user data" do
198
+ result = FakeDataDSL.generate_with_quality("User", count: 1000)
199
+
200
+ expect(result.quality_report.realism_score).to be >= 90
201
+ expect(result.quality_report.uniqueness[:email]).to eq(100)
202
+ expect(result.quality_report.completeness).to be >= 95
203
+ end
204
+ end
205
+ ```
206
+
207
+ ## Detailed Analysis
208
+
209
+ ### Field-Level Analysis
210
+
211
+ ```ruby
212
+ report = FakeDataDSL::QualityMetrics.analyze(data, schema: "User")
213
+
214
+ # Analyze specific field
215
+ field_report = report.field_analysis(:email)
216
+ # => {
217
+ # type: "email",
218
+ # total_values: 1000,
219
+ # unique_values: 1000,
220
+ # uniqueness: 100.0,
221
+ # null_count: 0,
222
+ # format_valid: 1000,
223
+ # format_invalid: 0,
224
+ # sample_values: ["john@example.com", "jane@test.org", ...],
225
+ # patterns: {
226
+ # "gmail.com" => 230,
227
+ # "yahoo.com" => 180,
228
+ # "example.com" => 590
229
+ # }
230
+ # }
231
+ ```
232
+
233
+ ### Correlation Analysis
234
+
235
+ ```ruby
236
+ # Find correlations between fields
237
+ report.correlations
238
+ # => {
239
+ # [:age, :retirement_status] => 0.95, # Strong correlation
240
+ # [:country, :phone_prefix] => 0.88, # Expected correlation
241
+ # [:name, :email] => 0.02 # No correlation (good)
242
+ # }
243
+
244
+ # Check for unexpected correlations
245
+ report.suspicious_correlations
246
+ # => [
247
+ # { fields: [:id, :created_at], correlation: 0.99,
248
+ # message: "ID and created_at are highly correlated - may indicate sequential generation" }
249
+ # ]
250
+ ```
251
+
252
+ ### Outlier Detection
253
+
254
+ ```ruby
255
+ # Find outliers in numeric fields
256
+ report.outliers
257
+ # => {
258
+ # age: {
259
+ # outliers: [150, -5, 999],
260
+ # outlier_percentage: 0.3,
261
+ # expected_range: 0..120
262
+ # },
263
+ # price: {
264
+ # outliers: [0.001, 999999.99],
265
+ # outlier_percentage: 0.1,
266
+ # expected_range: 0.01..10000
267
+ # }
268
+ # }
269
+ ```
270
+
271
+ ## Quality Reports
272
+
273
+ ### Summary Report
274
+
275
+ ```ruby
276
+ report = FakeDataDSL.generate_with_quality("User", count: 1000).quality_report
277
+
278
+ puts report.summary
279
+ # ═══════════════════════════════════════════════
280
+ # Data Quality Report: User (1000 records)
281
+ # ═══════════════════════════════════════════════
282
+ #
283
+ # Overall Score: 94/100 ✓
284
+ #
285
+ # Uniqueness: 98.2% ✓
286
+ # - id: 100% ✓
287
+ # - email: 100% ✓
288
+ # - name: 85.3% ⚠ (expected: 80%)
289
+ #
290
+ # Completeness: 96.5% ✓
291
+ # - bio: 95.0%
292
+ # - avatar: 88.2%
293
+ #
294
+ # Distribution: Balanced ✓
295
+ # - role: { user: 85%, admin: 10%, mod: 5% }
296
+ #
297
+ # Realism: 92/100 ✓
298
+ # - 2 minor issues detected
299
+ # ═══════════════════════════════════════════════
300
+ ```
301
+
302
+ ### JSON Report
303
+
304
+ ```ruby
305
+ report.to_json
306
+ # => {
307
+ # "schema": "User",
308
+ # "record_count": 1000,
309
+ # "generated_at": "2026-01-24T10:30:00Z",
310
+ # "overall_score": 94,
311
+ # "metrics": {
312
+ # "uniqueness": { ... },
313
+ # "completeness": { ... },
314
+ # "distribution": { ... },
315
+ # "realism": { ... }
316
+ # },
317
+ # "issues": [ ... ],
318
+ # "suggestions": [ ... ]
319
+ # }
320
+ ```
321
+
322
+ ### HTML Report
323
+
324
+ ```ruby
325
+ # Generate visual HTML report
326
+ report.to_html("quality_report.html")
327
+
328
+ # Or get HTML string
329
+ html = report.to_html_string
330
+ ```
331
+
332
+ ### Export for Monitoring
333
+
334
+ ```ruby
335
+ # Export metrics for monitoring systems
336
+ report.to_prometheus
337
+ # => [
338
+ # 'fake_data_quality_uniqueness{schema="User",field="email"} 100.0',
339
+ # 'fake_data_quality_completeness{schema="User"} 96.5',
340
+ # ...
341
+ # ]
342
+
343
+ report.to_datadog
344
+ # => { metrics: [...], tags: [...] }
345
+ ```
346
+
347
+ ## Quality Improvement Suggestions
348
+
349
+ ```ruby
350
+ report.suggestions
351
+ # => [
352
+ # {
353
+ # field: :name,
354
+ # issue: "Low uniqueness (85%)",
355
+ # suggestion: "Consider using more diverse name patterns or adding middle names",
356
+ # priority: :medium
357
+ # },
358
+ # {
359
+ # field: :phone,
360
+ # issue: "28% null values",
361
+ # suggestion: "Increase phone generation probability or make required",
362
+ # priority: :low
363
+ # }
364
+ # ]
365
+
366
+ # Auto-apply suggestions
367
+ improved_schema = FakeDataDSL::QualityMetrics.improve_schema(
368
+ FakeDataDSL.schema("User"),
369
+ based_on: report
370
+ )
371
+ ```
372
+
373
+ ## Comparison Reports
374
+
375
+ ### Compare Generations
376
+
377
+ ```ruby
378
+ # Compare quality across different generations
379
+ report1 = FakeDataDSL.generate_with_quality("User", count: 1000, seed: 1)
380
+ report2 = FakeDataDSL.generate_with_quality("User", count: 1000, seed: 2)
381
+
382
+ comparison = FakeDataDSL::QualityMetrics.compare(
383
+ report1.quality_report,
384
+ report2.quality_report
385
+ )
386
+
387
+ comparison.differences
388
+ # => {
389
+ # uniqueness: { name: [-2.3, "seed 1 had higher name uniqueness"] },
390
+ # realism: [+3, "seed 2 produced more realistic data"]
391
+ # }
392
+ ```
393
+
394
+ ### Compare Against Baseline
395
+
396
+ ```ruby
397
+ # Save a baseline
398
+ baseline = FakeDataDSL.generate_with_quality("User", count: 1000)
399
+ baseline.quality_report.save_as_baseline("user_baseline")
400
+
401
+ # Later, compare against baseline
402
+ current = FakeDataDSL.generate_with_quality("User", count: 1000)
403
+ diff = current.quality_report.compare_to_baseline("user_baseline")
404
+
405
+ diff.regressions
406
+ # => [{ metric: :uniqueness, field: :email, change: -5.0 }]
407
+ ```
408
+
409
+ ## API Reference
410
+
411
+ ### QualityMetrics.generate_with_quality
412
+
413
+ ```ruby
414
+ FakeDataDSL::QualityMetrics.generate_with_quality(schema_name, options = {})
415
+ ```
416
+
417
+ **Parameters:**
418
+ - `schema_name` - Name of the schema
419
+ - `options[:count]` - Number of records (default: 100)
420
+ - `options[:seed]` - Random seed
421
+ - `options[:mode]` - Generation mode
422
+ - `options[:analyze_fields]` - Specific fields to analyze (default: all)
423
+
424
+ **Returns:** `QualityResult` with `data` and `quality_report`
425
+
426
+ ### QualityMetrics.analyze
427
+
428
+ ```ruby
429
+ FakeDataDSL::QualityMetrics.analyze(data, options = {})
430
+ ```
431
+
432
+ **Parameters:**
433
+ - `data` - Array of records to analyze
434
+ - `options[:schema]` - Schema name for context
435
+ - `options[:thresholds]` - Quality thresholds to validate against
436
+
437
+ **Returns:** `QualityReport`
438
+
439
+ ### QualityReport Methods
440
+
441
+ ```ruby
442
+ report.uniqueness # Hash of field => uniqueness percentage
443
+ report.completeness # Overall completeness percentage
444
+ report.distribution # Distribution analysis for enum fields
445
+ report.realism_score # Overall realism score (0-100)
446
+ report.issues # Array of detected issues
447
+ report.suggestions # Array of improvement suggestions
448
+ report.meets_thresholds? # Boolean - passes all thresholds?
449
+ report.summary # Human-readable summary string
450
+ report.to_json # JSON representation
451
+ report.to_html(path) # Generate HTML report file
452
+ ```
453
+
454
+ ## Configuration
455
+
456
+ ```ruby
457
+ FakeDataDSL::QualityMetrics.configure do |config|
458
+ # Default thresholds
459
+ config.default_thresholds = {
460
+ uniqueness: { default: 80, id: 100, email: 100 },
461
+ completeness: { minimum: 90 },
462
+ realism: { minimum: 85 }
463
+ }
464
+
465
+ # Analysis options
466
+ config.analyze_distributions = true
467
+ config.detect_outliers = true
468
+ config.correlation_threshold = 0.8
469
+
470
+ # Sampling for large datasets
471
+ config.max_sample_size = 10000
472
+ config.sample_strategy = :random # :random, :stratified
473
+
474
+ # Report options
475
+ config.include_sample_values = true
476
+ config.max_sample_values = 5
477
+ end
478
+ ```
479
+
480
+ ## Best Practices
481
+
482
+ ### 1. Set Appropriate Thresholds
483
+
484
+ ```ruby
485
+ # Strict for critical fields
486
+ config.thresholds[:uniqueness][:id] = 100
487
+ config.thresholds[:uniqueness][:email] = 100
488
+
489
+ # Relaxed for non-unique fields
490
+ config.thresholds[:uniqueness][:name] = 70
491
+ config.thresholds[:uniqueness][:city] = 10
492
+ ```
493
+
494
+ ### 2. Monitor Quality Over Time
495
+
496
+ ```ruby
497
+ # Track quality metrics in CI
498
+ after(:suite) do
499
+ report = aggregate_quality_reports
500
+ QualityMetricsDashboard.record(report)
501
+ end
502
+ ```
503
+
504
+ ### 3. Use Quality Gates
505
+
506
+ ```ruby
507
+ # Fail CI if quality drops
508
+ RSpec.configure do |config|
509
+ config.after(:suite) do
510
+ report = FakeDataDSL::QualityMetrics.session_report
511
+ if report.realism_score < 85
512
+ raise "Data quality below threshold: #{report.realism_score}"
513
+ end
514
+ end
515
+ end
516
+ ```
517
+
518
+ ## Troubleshooting
519
+
520
+ ### Low Uniqueness
521
+
522
+ ```ruby
523
+ # Issue: email uniqueness is only 95%
524
+ # Solution: Increase domain variety
525
+ override "User", email: -> { Faker::Internet.email(domain: random_domain) }
526
+
527
+ # Or use @unique annotation
528
+ # User:
529
+ # email: email @unique
530
+ ```
531
+
532
+ ### Poor Distribution
533
+
534
+ ```ruby
535
+ # Issue: role distribution is skewed (99% user, 1% admin)
536
+ # Solution: Use weighted enum
537
+ # role: enum(user:70%, admin:20%, moderator:10%)
538
+ ```
539
+
540
+ ### Low Realism
541
+
542
+ ```ruby
543
+ # Issue: phone numbers don't look realistic
544
+ # Solution: Use locale-specific formats
545
+ FakeDataDSL.configure do |c|
546
+ c.locale = :en_US # US phone format
547
+ end
548
+ ```
549
+
550
+ ## See Also
551
+
552
+ - [Generation Modes](generation_modes.md)
553
+ - [Behaviors](behaviors.md)
554
+ - [Testing Best Practices](best_practices.md)
555
+ - [Snapshot Testing](SNAPSHOT_TESTING.md)
@@ -0,0 +1,88 @@
1
+ # Quick Reference
2
+
3
+ Quick reference card for FakeDataDSL.
4
+
5
+ ## Basic Syntax
6
+
7
+ ```ruby
8
+ SchemaName:
9
+ field_name: type
10
+ field_name: type(args)
11
+ field_name: type? # Nullable
12
+ field_name: type optional # Optional
13
+ field_name: type unique # Unique
14
+ field_name: type if condition # Conditional
15
+ ```
16
+
17
+ ## Common Types
18
+
19
+ | Type | Example | Description |
20
+ |------|---------|-------------|
21
+ | `uuid` | `id: uuid` | UUID identifier |
22
+ | `name` | `name: name` | Person name |
23
+ | `email` | `email: email` | Email address |
24
+ | `number` | `age: number(18..65)` | Number in range |
25
+ | `boolean` | `active: boolean` | True/false |
26
+ | `text` | `bio: text(100..500)` | Text with length |
27
+ | `date` | `birth_date: date` | Calendar date |
28
+ | `array` | `tags: array(text, 3..10)` | Array of values |
29
+ | `enum` | `status: enum(active, inactive)` | Enumeration |
30
+
31
+ ## Behaviors
32
+
33
+ ```ruby
34
+ @latency 100ms # Add delay
35
+ @failure 5% # Failure probability
36
+ @partial_data 20% # Omit fields sometimes
37
+ @randomize_order # Randomize field order
38
+ ```
39
+
40
+ ## Generation Modes
41
+
42
+ ```ruby
43
+ schema.generate(mode: :random) # Default: realistic data
44
+ schema.generate(mode: :edge) # Edge cases
45
+ schema.generate(mode: :invalid) # Invalid data
46
+ schema.generate(mode: :mixed) # Mix of all
47
+ ```
48
+
49
+ ## Code Examples
50
+
51
+ ### Basic Usage
52
+
53
+ ```ruby
54
+ require 'fake_data_dsl'
55
+
56
+ registry = FakeDataDSL::Registry.new
57
+ registry.load_file('schema.dsl')
58
+ schema = registry.schema('User')
59
+ record = schema.generate
60
+ ```
61
+
62
+ ### Multiple Records
63
+
64
+ ```ruby
65
+ records = schema.generate_many(10)
66
+ ```
67
+
68
+ ### Streaming
69
+
70
+ ```ruby
71
+ schema.generate_many_stream(1000).each do |record|
72
+ process(record)
73
+ end
74
+ ```
75
+
76
+ ### Deterministic
77
+
78
+ ```ruby
79
+ FakeDataDSL.configure { |c| c.seed = 12345 }
80
+ record = schema.generate # Same data every time
81
+ ```
82
+
83
+ ## See Also
84
+
85
+ - [Getting Started](getting_started.md) - Full guide
86
+ - [DSL Reference](dsl_reference.md) - Complete syntax
87
+ - [Type Reference](type_reference.md) - All types
88
+