data_porter 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 (159) hide show
  1. checksums.yaml +7 -0
  2. data/.claude/commands/blog-status.md +10 -0
  3. data/.claude/commands/blog.md +109 -0
  4. data/.claude/commands/task-done.md +27 -0
  5. data/.claude/commands/tm/add-dependency.md +58 -0
  6. data/.claude/commands/tm/add-subtask.md +79 -0
  7. data/.claude/commands/tm/add-task.md +81 -0
  8. data/.claude/commands/tm/analyze-complexity.md +124 -0
  9. data/.claude/commands/tm/analyze-project.md +100 -0
  10. data/.claude/commands/tm/auto-implement-tasks.md +100 -0
  11. data/.claude/commands/tm/command-pipeline.md +80 -0
  12. data/.claude/commands/tm/complexity-report.md +120 -0
  13. data/.claude/commands/tm/convert-task-to-subtask.md +74 -0
  14. data/.claude/commands/tm/expand-all-tasks.md +52 -0
  15. data/.claude/commands/tm/expand-task.md +52 -0
  16. data/.claude/commands/tm/fix-dependencies.md +82 -0
  17. data/.claude/commands/tm/help.md +101 -0
  18. data/.claude/commands/tm/init-project-quick.md +49 -0
  19. data/.claude/commands/tm/init-project.md +53 -0
  20. data/.claude/commands/tm/install-taskmaster.md +118 -0
  21. data/.claude/commands/tm/learn.md +106 -0
  22. data/.claude/commands/tm/list-tasks-by-status.md +42 -0
  23. data/.claude/commands/tm/list-tasks-with-subtasks.md +30 -0
  24. data/.claude/commands/tm/list-tasks.md +46 -0
  25. data/.claude/commands/tm/next-task.md +69 -0
  26. data/.claude/commands/tm/parse-prd-with-research.md +51 -0
  27. data/.claude/commands/tm/parse-prd.md +52 -0
  28. data/.claude/commands/tm/project-status.md +67 -0
  29. data/.claude/commands/tm/quick-install-taskmaster.md +23 -0
  30. data/.claude/commands/tm/remove-all-subtasks.md +94 -0
  31. data/.claude/commands/tm/remove-dependency.md +65 -0
  32. data/.claude/commands/tm/remove-subtask.md +87 -0
  33. data/.claude/commands/tm/remove-subtasks.md +89 -0
  34. data/.claude/commands/tm/remove-task.md +110 -0
  35. data/.claude/commands/tm/setup-models.md +52 -0
  36. data/.claude/commands/tm/show-task.md +85 -0
  37. data/.claude/commands/tm/smart-workflow.md +58 -0
  38. data/.claude/commands/tm/sync-readme.md +120 -0
  39. data/.claude/commands/tm/tm-main.md +147 -0
  40. data/.claude/commands/tm/to-cancelled.md +58 -0
  41. data/.claude/commands/tm/to-deferred.md +50 -0
  42. data/.claude/commands/tm/to-done.md +47 -0
  43. data/.claude/commands/tm/to-in-progress.md +39 -0
  44. data/.claude/commands/tm/to-pending.md +35 -0
  45. data/.claude/commands/tm/to-review.md +43 -0
  46. data/.claude/commands/tm/update-single-task.md +122 -0
  47. data/.claude/commands/tm/update-task.md +75 -0
  48. data/.claude/commands/tm/update-tasks-from-id.md +111 -0
  49. data/.claude/commands/tm/validate-dependencies.md +72 -0
  50. data/.claude/commands/tm/view-models.md +52 -0
  51. data/.env.example +12 -0
  52. data/.mcp.json +24 -0
  53. data/.taskmaster/CLAUDE.md +435 -0
  54. data/.taskmaster/config.json +44 -0
  55. data/.taskmaster/docs/prd.txt +2044 -0
  56. data/.taskmaster/state.json +6 -0
  57. data/.taskmaster/tasks/task_001.md +19 -0
  58. data/.taskmaster/tasks/task_002.md +19 -0
  59. data/.taskmaster/tasks/task_003.md +19 -0
  60. data/.taskmaster/tasks/task_004.md +19 -0
  61. data/.taskmaster/tasks/task_005.md +19 -0
  62. data/.taskmaster/tasks/task_006.md +19 -0
  63. data/.taskmaster/tasks/task_007.md +19 -0
  64. data/.taskmaster/tasks/task_008.md +19 -0
  65. data/.taskmaster/tasks/task_009.md +19 -0
  66. data/.taskmaster/tasks/task_010.md +19 -0
  67. data/.taskmaster/tasks/task_011.md +19 -0
  68. data/.taskmaster/tasks/task_012.md +19 -0
  69. data/.taskmaster/tasks/task_013.md +19 -0
  70. data/.taskmaster/tasks/task_014.md +19 -0
  71. data/.taskmaster/tasks/task_015.md +19 -0
  72. data/.taskmaster/tasks/task_016.md +19 -0
  73. data/.taskmaster/tasks/task_017.md +19 -0
  74. data/.taskmaster/tasks/task_018.md +19 -0
  75. data/.taskmaster/tasks/task_019.md +19 -0
  76. data/.taskmaster/tasks/task_020.md +19 -0
  77. data/.taskmaster/tasks/tasks.json +299 -0
  78. data/.taskmaster/templates/example_prd.txt +47 -0
  79. data/.taskmaster/templates/example_prd_rpg.txt +511 -0
  80. data/CHANGELOG.md +29 -0
  81. data/CLAUDE.md +65 -0
  82. data/CODE_OF_CONDUCT.md +10 -0
  83. data/CONTRIBUTING.md +49 -0
  84. data/LICENSE +21 -0
  85. data/README.md +463 -0
  86. data/Rakefile +12 -0
  87. data/app/assets/stylesheets/data_porter/application.css +646 -0
  88. data/app/channels/data_porter/import_channel.rb +10 -0
  89. data/app/controllers/data_porter/imports_controller.rb +68 -0
  90. data/app/javascript/data_porter/progress_controller.js +33 -0
  91. data/app/jobs/data_porter/dry_run_job.rb +12 -0
  92. data/app/jobs/data_porter/import_job.rb +12 -0
  93. data/app/jobs/data_porter/parse_job.rb +12 -0
  94. data/app/models/data_porter/data_import.rb +49 -0
  95. data/app/views/data_porter/imports/index.html.erb +142 -0
  96. data/app/views/data_porter/imports/new.html.erb +88 -0
  97. data/app/views/data_porter/imports/show.html.erb +49 -0
  98. data/config/database.yml +3 -0
  99. data/config/routes.rb +12 -0
  100. data/docs/SPEC.md +2012 -0
  101. data/docs/UI.md +32 -0
  102. data/docs/blog/001-why-build-a-data-import-engine.md +166 -0
  103. data/docs/blog/002-scaffolding-a-rails-engine.md +188 -0
  104. data/docs/blog/003-configuration-dsl.md +222 -0
  105. data/docs/blog/004-store-model-jsonb.md +237 -0
  106. data/docs/blog/005-target-dsl.md +284 -0
  107. data/docs/blog/006-parsing-csv-sources.md +300 -0
  108. data/docs/blog/007-orchestrator.md +247 -0
  109. data/docs/blog/008-actioncable-stimulus.md +376 -0
  110. data/docs/blog/009-phlex-ui-components.md +446 -0
  111. data/docs/blog/010-controllers-routing.md +374 -0
  112. data/docs/blog/011-generators.md +364 -0
  113. data/docs/blog/012-json-api-sources.md +323 -0
  114. data/docs/blog/013-testing-rails-engine.md +618 -0
  115. data/docs/blog/014-dry-run.md +307 -0
  116. data/docs/blog/015-publishing-retro.md +264 -0
  117. data/docs/blog/016-erb-view-templates.md +431 -0
  118. data/docs/blog/017-showcase-final-retro.md +220 -0
  119. data/docs/blog/BACKLOG.md +8 -0
  120. data/docs/blog/SERIES.md +154 -0
  121. data/docs/screenshots/index-with-previewing.jpg +0 -0
  122. data/docs/screenshots/index.jpg +0 -0
  123. data/docs/screenshots/modal-new-import.jpg +0 -0
  124. data/docs/screenshots/preview.jpg +0 -0
  125. data/lib/data_porter/broadcaster.rb +29 -0
  126. data/lib/data_porter/components/base.rb +10 -0
  127. data/lib/data_porter/components/failure_alert.rb +20 -0
  128. data/lib/data_porter/components/preview_table.rb +54 -0
  129. data/lib/data_porter/components/progress_bar.rb +33 -0
  130. data/lib/data_porter/components/results_summary.rb +19 -0
  131. data/lib/data_porter/components/status_badge.rb +16 -0
  132. data/lib/data_porter/components/summary_cards.rb +30 -0
  133. data/lib/data_porter/components.rb +14 -0
  134. data/lib/data_porter/configuration.rb +25 -0
  135. data/lib/data_porter/dsl/api_config.rb +25 -0
  136. data/lib/data_porter/dsl/column.rb +17 -0
  137. data/lib/data_porter/engine.rb +15 -0
  138. data/lib/data_porter/orchestrator.rb +141 -0
  139. data/lib/data_porter/record_validator.rb +32 -0
  140. data/lib/data_porter/registry.rb +33 -0
  141. data/lib/data_porter/sources/api.rb +49 -0
  142. data/lib/data_porter/sources/base.rb +35 -0
  143. data/lib/data_porter/sources/csv.rb +43 -0
  144. data/lib/data_porter/sources/json.rb +45 -0
  145. data/lib/data_porter/sources.rb +20 -0
  146. data/lib/data_porter/store_models/error.rb +13 -0
  147. data/lib/data_porter/store_models/import_record.rb +52 -0
  148. data/lib/data_porter/store_models/report.rb +21 -0
  149. data/lib/data_porter/target.rb +89 -0
  150. data/lib/data_porter/type_validator.rb +46 -0
  151. data/lib/data_porter/version.rb +5 -0
  152. data/lib/data_porter.rb +32 -0
  153. data/lib/generators/data_porter/install/install_generator.rb +33 -0
  154. data/lib/generators/data_porter/install/templates/create_data_porter_imports.rb.erb +21 -0
  155. data/lib/generators/data_porter/install/templates/initializer.rb +30 -0
  156. data/lib/generators/data_porter/target/target_generator.rb +44 -0
  157. data/lib/generators/data_porter/target/templates/target.rb.tt +20 -0
  158. data/sig/data_porter.rbs +4 -0
  159. metadata +274 -0
@@ -0,0 +1,511 @@
1
+ <rpg-method>
2
+ # Repository Planning Graph (RPG) Method - PRD Template
3
+
4
+ This template teaches you (AI or human) how to create structured, dependency-aware PRDs using the RPG methodology from Microsoft Research. The key insight: separate WHAT (functional) from HOW (structural), then connect them with explicit dependencies.
5
+
6
+ ## Core Principles
7
+
8
+ 1. **Dual-Semantics**: Think functional (capabilities) AND structural (code organization) separately, then map them
9
+ 2. **Explicit Dependencies**: Never assume - always state what depends on what
10
+ 3. **Topological Order**: Build foundation first, then layers on top
11
+ 4. **Progressive Refinement**: Start broad, refine iteratively
12
+
13
+ ## How to Use This Template
14
+
15
+ - Follow the instructions in each `<instruction>` block
16
+ - Look at `<example>` blocks to see good vs bad patterns
17
+ - Fill in the content sections with your project details
18
+ - The AI reading this will learn the RPG method by following along
19
+ - Task Master will parse the resulting PRD into dependency-aware tasks
20
+
21
+ ## Recommended Tools for Creating PRDs
22
+
23
+ When using this template to **create** a PRD (not parse it), use **code-context-aware AI assistants** for best results:
24
+
25
+ **Why?** The AI needs to understand your existing codebase to make good architectural decisions about modules, dependencies, and integration points.
26
+
27
+ **Recommended tools:**
28
+ - **Claude Code** (claude-code CLI) - Best for structured reasoning and large contexts
29
+ - **Cursor/Windsurf** - IDE integration with full codebase context
30
+ - **Gemini CLI** (gemini-cli) - Massive context window for large codebases
31
+ - **Codex/Grok CLI** - Strong code generation with context awareness
32
+
33
+ **Note:** Once your PRD is created, `task-master parse-prd` works with any configured AI model - it just needs to read the PRD text itself, not your codebase.
34
+ </rpg-method>
35
+
36
+ ---
37
+
38
+ <overview>
39
+ <instruction>
40
+ Start with the problem, not the solution. Be specific about:
41
+ - What pain point exists?
42
+ - Who experiences it?
43
+ - Why existing solutions don't work?
44
+ - What success looks like (measurable outcomes)?
45
+
46
+ Keep this section focused - don't jump into implementation details yet.
47
+ </instruction>
48
+
49
+ ## Problem Statement
50
+ [Describe the core problem. Be concrete about user pain points.]
51
+
52
+ ## Target Users
53
+ [Define personas, their workflows, and what they're trying to achieve.]
54
+
55
+ ## Success Metrics
56
+ [Quantifiable outcomes. Examples: "80% task completion via autopilot", "< 5% manual intervention rate"]
57
+
58
+ </overview>
59
+
60
+ ---
61
+
62
+ <functional-decomposition>
63
+ <instruction>
64
+ Now think about CAPABILITIES (what the system DOES), not code structure yet.
65
+
66
+ Step 1: Identify high-level capability domains
67
+ - Think: "What major things does this system do?"
68
+ - Examples: Data Management, Core Processing, Presentation Layer
69
+
70
+ Step 2: For each capability, enumerate specific features
71
+ - Use explore-exploit strategy:
72
+ * Exploit: What features are REQUIRED for core value?
73
+ * Explore: What features make this domain COMPLETE?
74
+
75
+ Step 3: For each feature, define:
76
+ - Description: What it does in one sentence
77
+ - Inputs: What data/context it needs
78
+ - Outputs: What it produces/returns
79
+ - Behavior: Key logic or transformations
80
+
81
+ <example type="good">
82
+ Capability: Data Validation
83
+ Feature: Schema validation
84
+ - Description: Validate JSON payloads against defined schemas
85
+ - Inputs: JSON object, schema definition
86
+ - Outputs: Validation result (pass/fail) + error details
87
+ - Behavior: Iterate fields, check types, enforce constraints
88
+
89
+ Feature: Business rule validation
90
+ - Description: Apply domain-specific validation rules
91
+ - Inputs: Validated data object, rule set
92
+ - Outputs: Boolean + list of violated rules
93
+ - Behavior: Execute rules sequentially, short-circuit on failure
94
+ </example>
95
+
96
+ <example type="bad">
97
+ Capability: validation.js
98
+ (Problem: This is a FILE, not a CAPABILITY. Mixing structure into functional thinking.)
99
+
100
+ Capability: Validation
101
+ Feature: Make sure data is good
102
+ (Problem: Too vague. No inputs/outputs. Not actionable.)
103
+ </example>
104
+ </instruction>
105
+
106
+ ## Capability Tree
107
+
108
+ ### Capability: [Name]
109
+ [Brief description of what this capability domain covers]
110
+
111
+ #### Feature: [Name]
112
+ - **Description**: [One sentence]
113
+ - **Inputs**: [What it needs]
114
+ - **Outputs**: [What it produces]
115
+ - **Behavior**: [Key logic]
116
+
117
+ #### Feature: [Name]
118
+ - **Description**:
119
+ - **Inputs**:
120
+ - **Outputs**:
121
+ - **Behavior**:
122
+
123
+ ### Capability: [Name]
124
+ ...
125
+
126
+ </functional-decomposition>
127
+
128
+ ---
129
+
130
+ <structural-decomposition>
131
+ <instruction>
132
+ NOW think about code organization. Map capabilities to actual file/folder structure.
133
+
134
+ Rules:
135
+ 1. Each capability maps to a module (folder or file)
136
+ 2. Features within a capability map to functions/classes
137
+ 3. Use clear module boundaries - each module has ONE responsibility
138
+ 4. Define what each module exports (public interface)
139
+
140
+ The goal: Create a clear mapping between "what it does" (functional) and "where it lives" (structural).
141
+
142
+ <example type="good">
143
+ Capability: Data Validation
144
+ → Maps to: src/validation/
145
+ ├── schema-validator.js (Schema validation feature)
146
+ ├── rule-validator.js (Business rule validation feature)
147
+ └── index.js (Public exports)
148
+
149
+ Exports:
150
+ - validateSchema(data, schema)
151
+ - validateRules(data, rules)
152
+ </example>
153
+
154
+ <example type="bad">
155
+ Capability: Data Validation
156
+ → Maps to: src/utils.js
157
+ (Problem: "utils" is not a clear module boundary. Where do I find validation logic?)
158
+
159
+ Capability: Data Validation
160
+ → Maps to: src/validation/everything.js
161
+ (Problem: One giant file. Features should map to separate files for maintainability.)
162
+ </example>
163
+ </instruction>
164
+
165
+ ## Repository Structure
166
+
167
+ ```
168
+ project-root/
169
+ ├── src/
170
+ │ ├── [module-name]/ # Maps to: [Capability Name]
171
+ │ │ ├── [file].js # Maps to: [Feature Name]
172
+ │ │ └── index.js # Public exports
173
+ │ └── [module-name]/
174
+ ├── tests/
175
+ └── docs/
176
+ ```
177
+
178
+ ## Module Definitions
179
+
180
+ ### Module: [Name]
181
+ - **Maps to capability**: [Capability from functional decomposition]
182
+ - **Responsibility**: [Single clear purpose]
183
+ - **File structure**:
184
+ ```
185
+ module-name/
186
+ ├── feature1.js
187
+ ├── feature2.js
188
+ └── index.js
189
+ ```
190
+ - **Exports**:
191
+ - `functionName()` - [what it does]
192
+ - `ClassName` - [what it does]
193
+
194
+ </structural-decomposition>
195
+
196
+ ---
197
+
198
+ <dependency-graph>
199
+ <instruction>
200
+ This is THE CRITICAL SECTION for Task Master parsing.
201
+
202
+ Define explicit dependencies between modules. This creates the topological order for task execution.
203
+
204
+ Rules:
205
+ 1. List modules in dependency order (foundation first)
206
+ 2. For each module, state what it depends on
207
+ 3. Foundation modules should have NO dependencies
208
+ 4. Every non-foundation module should depend on at least one other module
209
+ 5. Think: "What must EXIST before I can build this module?"
210
+
211
+ <example type="good">
212
+ Foundation Layer (no dependencies):
213
+ - error-handling: No dependencies
214
+ - config-manager: No dependencies
215
+ - base-types: No dependencies
216
+
217
+ Data Layer:
218
+ - schema-validator: Depends on [base-types, error-handling]
219
+ - data-ingestion: Depends on [schema-validator, config-manager]
220
+
221
+ Core Layer:
222
+ - algorithm-engine: Depends on [base-types, error-handling]
223
+ - pipeline-orchestrator: Depends on [algorithm-engine, data-ingestion]
224
+ </example>
225
+
226
+ <example type="bad">
227
+ - validation: Depends on API
228
+ - API: Depends on validation
229
+ (Problem: Circular dependency. This will cause build/runtime issues.)
230
+
231
+ - user-auth: Depends on everything
232
+ (Problem: Too many dependencies. Should be more focused.)
233
+ </example>
234
+ </instruction>
235
+
236
+ ## Dependency Chain
237
+
238
+ ### Foundation Layer (Phase 0)
239
+ No dependencies - these are built first.
240
+
241
+ - **[Module Name]**: [What it provides]
242
+ - **[Module Name]**: [What it provides]
243
+
244
+ ### [Layer Name] (Phase 1)
245
+ - **[Module Name]**: Depends on [[module-from-phase-0], [module-from-phase-0]]
246
+ - **[Module Name]**: Depends on [[module-from-phase-0]]
247
+
248
+ ### [Layer Name] (Phase 2)
249
+ - **[Module Name]**: Depends on [[module-from-phase-1], [module-from-foundation]]
250
+
251
+ [Continue building up layers...]
252
+
253
+ </dependency-graph>
254
+
255
+ ---
256
+
257
+ <implementation-roadmap>
258
+ <instruction>
259
+ Turn the dependency graph into concrete development phases.
260
+
261
+ Each phase should:
262
+ 1. Have clear entry criteria (what must exist before starting)
263
+ 2. Contain tasks that can be parallelized (no inter-dependencies within phase)
264
+ 3. Have clear exit criteria (how do we know phase is complete?)
265
+ 4. Build toward something USABLE (not just infrastructure)
266
+
267
+ Phase ordering follows topological sort of dependency graph.
268
+
269
+ <example type="good">
270
+ Phase 0: Foundation
271
+ Entry: Clean repository
272
+ Tasks:
273
+ - Implement error handling utilities
274
+ - Create base type definitions
275
+ - Setup configuration system
276
+ Exit: Other modules can import foundation without errors
277
+
278
+ Phase 1: Data Layer
279
+ Entry: Phase 0 complete
280
+ Tasks:
281
+ - Implement schema validator (uses: base types, error handling)
282
+ - Build data ingestion pipeline (uses: validator, config)
283
+ Exit: End-to-end data flow from input to validated output
284
+ </example>
285
+
286
+ <example type="bad">
287
+ Phase 1: Build Everything
288
+ Tasks:
289
+ - API
290
+ - Database
291
+ - UI
292
+ - Tests
293
+ (Problem: No clear focus. Too broad. Dependencies not considered.)
294
+ </example>
295
+ </instruction>
296
+
297
+ ## Development Phases
298
+
299
+ ### Phase 0: [Foundation Name]
300
+ **Goal**: [What foundational capability this establishes]
301
+
302
+ **Entry Criteria**: [What must be true before starting]
303
+
304
+ **Tasks**:
305
+ - [ ] [Task name] (depends on: [none or list])
306
+ - Acceptance criteria: [How we know it's done]
307
+ - Test strategy: [What tests prove it works]
308
+
309
+ - [ ] [Task name] (depends on: [none or list])
310
+
311
+ **Exit Criteria**: [Observable outcome that proves phase complete]
312
+
313
+ **Delivers**: [What can users/developers do after this phase?]
314
+
315
+ ---
316
+
317
+ ### Phase 1: [Layer Name]
318
+ **Goal**:
319
+
320
+ **Entry Criteria**: Phase 0 complete
321
+
322
+ **Tasks**:
323
+ - [ ] [Task name] (depends on: [[tasks-from-phase-0]])
324
+ - [ ] [Task name] (depends on: [[tasks-from-phase-0]])
325
+
326
+ **Exit Criteria**:
327
+
328
+ **Delivers**:
329
+
330
+ ---
331
+
332
+ [Continue with more phases...]
333
+
334
+ </implementation-roadmap>
335
+
336
+ ---
337
+
338
+ <test-strategy>
339
+ <instruction>
340
+ Define how testing will be integrated throughout development (TDD approach).
341
+
342
+ Specify:
343
+ 1. Test pyramid ratios (unit vs integration vs e2e)
344
+ 2. Coverage requirements
345
+ 3. Critical test scenarios
346
+ 4. Test generation guidelines for Surgical Test Generator
347
+
348
+ This section guides the AI when generating tests during the RED phase of TDD.
349
+
350
+ <example type="good">
351
+ Critical Test Scenarios for Data Validation module:
352
+ - Happy path: Valid data passes all checks
353
+ - Edge cases: Empty strings, null values, boundary numbers
354
+ - Error cases: Invalid types, missing required fields
355
+ - Integration: Validator works with ingestion pipeline
356
+ </example>
357
+ </instruction>
358
+
359
+ ## Test Pyramid
360
+
361
+ ```
362
+ /\
363
+ /E2E\ ← [X]% (End-to-end, slow, comprehensive)
364
+ /------\
365
+ /Integration\ ← [Y]% (Module interactions)
366
+ /------------\
367
+ / Unit Tests \ ← [Z]% (Fast, isolated, deterministic)
368
+ /----------------\
369
+ ```
370
+
371
+ ## Coverage Requirements
372
+ - Line coverage: [X]% minimum
373
+ - Branch coverage: [X]% minimum
374
+ - Function coverage: [X]% minimum
375
+ - Statement coverage: [X]% minimum
376
+
377
+ ## Critical Test Scenarios
378
+
379
+ ### [Module/Feature Name]
380
+ **Happy path**:
381
+ - [Scenario description]
382
+ - Expected: [What should happen]
383
+
384
+ **Edge cases**:
385
+ - [Scenario description]
386
+ - Expected: [What should happen]
387
+
388
+ **Error cases**:
389
+ - [Scenario description]
390
+ - Expected: [How system handles failure]
391
+
392
+ **Integration points**:
393
+ - [What interactions to test]
394
+ - Expected: [End-to-end behavior]
395
+
396
+ ## Test Generation Guidelines
397
+ [Specific instructions for Surgical Test Generator about what to focus on, what patterns to follow, project-specific test conventions]
398
+
399
+ </test-strategy>
400
+
401
+ ---
402
+
403
+ <architecture>
404
+ <instruction>
405
+ Describe technical architecture, data models, and key design decisions.
406
+
407
+ Keep this section AFTER functional/structural decomposition - implementation details come after understanding structure.
408
+ </instruction>
409
+
410
+ ## System Components
411
+ [Major architectural pieces and their responsibilities]
412
+
413
+ ## Data Models
414
+ [Core data structures, schemas, database design]
415
+
416
+ ## Technology Stack
417
+ [Languages, frameworks, key libraries]
418
+
419
+ **Decision: [Technology/Pattern]**
420
+ - **Rationale**: [Why chosen]
421
+ - **Trade-offs**: [What we're giving up]
422
+ - **Alternatives considered**: [What else we looked at]
423
+
424
+ </architecture>
425
+
426
+ ---
427
+
428
+ <risks>
429
+ <instruction>
430
+ Identify risks that could derail development and how to mitigate them.
431
+
432
+ Categories:
433
+ - Technical risks (complexity, unknowns)
434
+ - Dependency risks (blocking issues)
435
+ - Scope risks (creep, underestimation)
436
+ </instruction>
437
+
438
+ ## Technical Risks
439
+ **Risk**: [Description]
440
+ - **Impact**: [High/Medium/Low - effect on project]
441
+ - **Likelihood**: [High/Medium/Low]
442
+ - **Mitigation**: [How to address]
443
+ - **Fallback**: [Plan B if mitigation fails]
444
+
445
+ ## Dependency Risks
446
+ [External dependencies, blocking issues]
447
+
448
+ ## Scope Risks
449
+ [Scope creep, underestimation, unclear requirements]
450
+
451
+ </risks>
452
+
453
+ ---
454
+
455
+ <appendix>
456
+ ## References
457
+ [Papers, documentation, similar systems]
458
+
459
+ ## Glossary
460
+ [Domain-specific terms]
461
+
462
+ ## Open Questions
463
+ [Things to resolve during development]
464
+ </appendix>
465
+
466
+ ---
467
+
468
+ <task-master-integration>
469
+ # How Task Master Uses This PRD
470
+
471
+ When you run `task-master parse-prd <file>.txt`, the parser:
472
+
473
+ 1. **Extracts capabilities** → Main tasks
474
+ - Each `### Capability:` becomes a top-level task
475
+
476
+ 2. **Extracts features** → Subtasks
477
+ - Each `#### Feature:` becomes a subtask under its capability
478
+
479
+ 3. **Parses dependencies** → Task dependencies
480
+ - `Depends on: [X, Y]` sets task.dependencies = ["X", "Y"]
481
+
482
+ 4. **Orders by phases** → Task priorities
483
+ - Phase 0 tasks = highest priority
484
+ - Phase N tasks = lower priority, properly sequenced
485
+
486
+ 5. **Uses test strategy** → Test generation context
487
+ - Feeds test scenarios to Surgical Test Generator during implementation
488
+
489
+ **Result**: A dependency-aware task graph that can be executed in topological order.
490
+
491
+ ## Why RPG Structure Matters
492
+
493
+ Traditional flat PRDs lead to:
494
+ - ❌ Unclear task dependencies
495
+ - ❌ Arbitrary task ordering
496
+ - ❌ Circular dependencies discovered late
497
+ - ❌ Poorly scoped tasks
498
+
499
+ RPG-structured PRDs provide:
500
+ - ✅ Explicit dependency chains
501
+ - ✅ Topological execution order
502
+ - ✅ Clear module boundaries
503
+ - ✅ Validated task graph before implementation
504
+
505
+ ## Tips for Best Results
506
+
507
+ 1. **Spend time on dependency graph** - This is the most valuable section for Task Master
508
+ 2. **Keep features atomic** - Each feature should be independently testable
509
+ 3. **Progressive refinement** - Start broad, use `task-master expand` to break down complex tasks
510
+ 4. **Use research mode** - `task-master parse-prd --research` leverages AI for better task generation
511
+ </task-master-integration>
data/CHANGELOG.md ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-02-06
11
+
12
+ ### Added
13
+
14
+ - **Target DSL** -- Declarative class-level DSL (`label`, `model_name`, `columns`, `csv_mapping`, `deduplicate_by`, `dry_run_enabled`) with auto-registration via `Registry`
15
+ - **CSV source** -- Parse CSV files via ActiveStorage with header mapping and custom separators
16
+ - **JSON source** -- Parse JSON files with configurable `json_root` path extraction
17
+ - **API source** -- Fetch records from HTTP endpoints with dynamic `endpoint` and `headers` lambdas and `response_root` extraction
18
+ - **Orchestrator** -- Coordinates parse, import, and dry run workflows with per-record error handling
19
+ - **Dry run mode** -- Transaction-based validation that rolls back after testing all records against the database
20
+ - **Real-time progress** -- ActionCable broadcaster with Stimulus controller for live progress updates
21
+ - **Phlex UI components** -- StatusBadge, SummaryCards, PreviewTable, ProgressBar, ResultsSummary, FailureAlert (pure Ruby, no phlex-rails dependency)
22
+ - **ERB view templates** -- Index (with modal form and dropzone), new, and show pages composing Phlex components via `.call`
23
+ - **Plain CSS stylesheet** -- `dp-*` prefixed classes with CSS custom properties (`--dp-*`) for theming, auto-precompiled via Sprockets
24
+ - **StoreModel JSONB columns** -- ImportRecord, Error, and Report models stored as JSONB on the DataImport model
25
+ - **Install generator** -- Creates migration, initializer, routes mount, and `app/importers/` directory
26
+ - **Target generator** -- Scaffolds target classes with column parsing from CLI arguments
27
+ - **Configuration DSL** -- `DataPorter.configure` block with `parent_controller`, `queue_name`, `storage_service`, `cable_channel_prefix`, `context_builder`, `preview_limit`, `enabled_sources`
28
+ - **ActiveJob integration** -- ParseJob, ImportJob, DryRunJob with configurable queue name
29
+ - **221 RSpec examples** covering models, sources, orchestrator, jobs, channels, components, controllers, routes, generators, and views
data/CLAUDE.md ADDED
@@ -0,0 +1,65 @@
1
+ # CLAUDE.md
2
+
3
+ ## Project
4
+ DataPorter - Mountable Rails engine for 3-step data import workflows.
5
+
6
+ ## Stack
7
+ - Ruby >= 3.2, Rails >= 7.0
8
+ - store_model, phlex, turbo-rails, stimulus
9
+ - Tailwind CSS (prefixed `dp-`, scoped `.data-porter`)
10
+ - RSpec for testing
11
+
12
+ ## Language
13
+ - ALL code, comments, commits, docs, specs, error messages in English
14
+ - NO French anywhere in the codebase
15
+
16
+ ## Conventions
17
+ - NO COMMENTS in generated code
18
+ - Conventional Commits (feat, fix, test, refactor, chore, docs)
19
+ - Frozen string literals (`# frozen_string_literal: true` in every .rb file)
20
+
21
+ ## Development Constraints
22
+
23
+ ### TDD
24
+ - Always write specs BEFORE implementation code
25
+ - Red -> Green -> Refactor cycle
26
+ - Run `bundle exec rspec` to validate before moving on
27
+
28
+ ### Code Quality
29
+ - One file = one class/module
30
+ - Max 10 lines per method (excluding private keyword lines)
31
+ - Single Responsibility Principle: each class does one thing
32
+ - No `class_eval`, no monkey-patching
33
+ - No implicit dependencies between modules (explicit requires)
34
+ - Everything namespaced under `DataPorter::`
35
+ - Run `bundle exec rubocop` before every commit
36
+
37
+ ### Commits
38
+ - Small, focused commits (one concern per commit)
39
+ - Never commit large chunks of unrelated code together
40
+ - Each commit should pass specs and rubocop
41
+
42
+ ### Design Principles
43
+ - Balance simplicity and extensibility: simple code that can evolve
44
+ - The gem MUST remain business-agnostic (no domain logic, no hardcoded model names)
45
+ - All business logic belongs in Targets defined by the host app
46
+ - Prefer composition over inheritance
47
+ - Expose hooks and configuration, not internal state
48
+
49
+ ## Blog Series Automation
50
+ After completing a task, ALWAYS check `docs/blog/SERIES.md` to see if all tasks
51
+ for a blog part are now done. If yes:
52
+ 1. Immediately generate the article draft following the `/blog` command process
53
+ 2. Update `docs/blog/BACKLOG.md` and `docs/blog/SERIES.md`
54
+ 3. Commit the draft, then resume development
55
+
56
+ ## Architecture
57
+ See docs/SPEC.md for full specification.
58
+
59
+ ## Commands
60
+ - `bundle exec rspec` - run tests
61
+ - `bundle exec rubocop` - lint
62
+
63
+ ## Task Master AI Instructions
64
+ **Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**
65
+ @./.taskmaster/CLAUDE.md
@@ -0,0 +1,10 @@
1
+ # Code of Conduct
2
+
3
+ "data_porter" follows [The Ruby Community Conduct Guideline](https://www.ruby-lang.org/en/conduct) in all "collaborative space", which is defined as community communications channels (such as mailing lists, submitted patches, commit comments, etc.):
4
+
5
+ * Participants will be tolerant of opposing views.
6
+ * Participants must ensure that their language and actions are free of personal attacks and disparaging personal remarks.
7
+ * When interpreting the words and actions of others, participants should always assume good intentions.
8
+ * Behaviour which can be reasonably considered harassment will not be tolerated.
9
+
10
+ If you have any concerns about behaviour within this project, please contact us at ["seryllounis@outlook.fr"](mailto:"seryllounis@outlook.fr").
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,49 @@
1
+ # Contributing to DataPorter
2
+
3
+ Thank you for considering contributing to DataPorter!
4
+
5
+ ## Bug Reports
6
+
7
+ Open an issue on [GitHub](https://github.com/SerylLns/data_porter/issues) with:
8
+
9
+ - Ruby and Rails versions
10
+ - Steps to reproduce
11
+ - Expected vs actual behavior
12
+ - Relevant logs or error messages
13
+
14
+ ## Pull Requests
15
+
16
+ 1. Fork the repo and create your branch from `main`
17
+ 2. Write specs first (TDD -- red, green, refactor)
18
+ 3. Ensure `bundle exec rspec` passes (221+ examples, 0 failures)
19
+ 4. Ensure `bundle exec rubocop` passes (0 offenses)
20
+ 5. One concern per commit, using [Conventional Commits](https://www.conventionalcommits.org/) (`feat:`, `fix:`, `test:`, `refactor:`, `chore:`, `docs:`)
21
+ 6. Open a PR against `main`
22
+
23
+ ## Development Setup
24
+
25
+ ```bash
26
+ git clone https://github.com/SerylLns/data_porter.git
27
+ cd data_porter
28
+ bin/setup
29
+ bundle exec rspec
30
+ bundle exec rubocop
31
+ ```
32
+
33
+ ## Code Style
34
+
35
+ - `# frozen_string_literal: true` in every `.rb` file
36
+ - Max 10 lines per method
37
+ - No comments in code -- code should be self-explanatory
38
+ - Everything namespaced under `DataPorter::`
39
+ - All English (code, commits, docs, specs, error messages)
40
+ - `dp-` CSS prefix, scoped under `.data-porter`
41
+
42
+ ## Architecture
43
+
44
+ - The gem must remain **business-agnostic** -- no domain logic, no hardcoded model names
45
+ - All business logic belongs in Targets defined by the host app
46
+ - Prefer composition over inheritance
47
+ - Expose hooks and configuration, not internal state
48
+
49
+ See [docs/SPEC.md](docs/SPEC.md) for the full specification.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Seryl Lounis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.