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.
- checksums.yaml +7 -0
- data/.claude/commands/blog-status.md +10 -0
- data/.claude/commands/blog.md +109 -0
- data/.claude/commands/task-done.md +27 -0
- data/.claude/commands/tm/add-dependency.md +58 -0
- data/.claude/commands/tm/add-subtask.md +79 -0
- data/.claude/commands/tm/add-task.md +81 -0
- data/.claude/commands/tm/analyze-complexity.md +124 -0
- data/.claude/commands/tm/analyze-project.md +100 -0
- data/.claude/commands/tm/auto-implement-tasks.md +100 -0
- data/.claude/commands/tm/command-pipeline.md +80 -0
- data/.claude/commands/tm/complexity-report.md +120 -0
- data/.claude/commands/tm/convert-task-to-subtask.md +74 -0
- data/.claude/commands/tm/expand-all-tasks.md +52 -0
- data/.claude/commands/tm/expand-task.md +52 -0
- data/.claude/commands/tm/fix-dependencies.md +82 -0
- data/.claude/commands/tm/help.md +101 -0
- data/.claude/commands/tm/init-project-quick.md +49 -0
- data/.claude/commands/tm/init-project.md +53 -0
- data/.claude/commands/tm/install-taskmaster.md +118 -0
- data/.claude/commands/tm/learn.md +106 -0
- data/.claude/commands/tm/list-tasks-by-status.md +42 -0
- data/.claude/commands/tm/list-tasks-with-subtasks.md +30 -0
- data/.claude/commands/tm/list-tasks.md +46 -0
- data/.claude/commands/tm/next-task.md +69 -0
- data/.claude/commands/tm/parse-prd-with-research.md +51 -0
- data/.claude/commands/tm/parse-prd.md +52 -0
- data/.claude/commands/tm/project-status.md +67 -0
- data/.claude/commands/tm/quick-install-taskmaster.md +23 -0
- data/.claude/commands/tm/remove-all-subtasks.md +94 -0
- data/.claude/commands/tm/remove-dependency.md +65 -0
- data/.claude/commands/tm/remove-subtask.md +87 -0
- data/.claude/commands/tm/remove-subtasks.md +89 -0
- data/.claude/commands/tm/remove-task.md +110 -0
- data/.claude/commands/tm/setup-models.md +52 -0
- data/.claude/commands/tm/show-task.md +85 -0
- data/.claude/commands/tm/smart-workflow.md +58 -0
- data/.claude/commands/tm/sync-readme.md +120 -0
- data/.claude/commands/tm/tm-main.md +147 -0
- data/.claude/commands/tm/to-cancelled.md +58 -0
- data/.claude/commands/tm/to-deferred.md +50 -0
- data/.claude/commands/tm/to-done.md +47 -0
- data/.claude/commands/tm/to-in-progress.md +39 -0
- data/.claude/commands/tm/to-pending.md +35 -0
- data/.claude/commands/tm/to-review.md +43 -0
- data/.claude/commands/tm/update-single-task.md +122 -0
- data/.claude/commands/tm/update-task.md +75 -0
- data/.claude/commands/tm/update-tasks-from-id.md +111 -0
- data/.claude/commands/tm/validate-dependencies.md +72 -0
- data/.claude/commands/tm/view-models.md +52 -0
- data/.env.example +12 -0
- data/.mcp.json +24 -0
- data/.taskmaster/CLAUDE.md +435 -0
- data/.taskmaster/config.json +44 -0
- data/.taskmaster/docs/prd.txt +2044 -0
- data/.taskmaster/state.json +6 -0
- data/.taskmaster/tasks/task_001.md +19 -0
- data/.taskmaster/tasks/task_002.md +19 -0
- data/.taskmaster/tasks/task_003.md +19 -0
- data/.taskmaster/tasks/task_004.md +19 -0
- data/.taskmaster/tasks/task_005.md +19 -0
- data/.taskmaster/tasks/task_006.md +19 -0
- data/.taskmaster/tasks/task_007.md +19 -0
- data/.taskmaster/tasks/task_008.md +19 -0
- data/.taskmaster/tasks/task_009.md +19 -0
- data/.taskmaster/tasks/task_010.md +19 -0
- data/.taskmaster/tasks/task_011.md +19 -0
- data/.taskmaster/tasks/task_012.md +19 -0
- data/.taskmaster/tasks/task_013.md +19 -0
- data/.taskmaster/tasks/task_014.md +19 -0
- data/.taskmaster/tasks/task_015.md +19 -0
- data/.taskmaster/tasks/task_016.md +19 -0
- data/.taskmaster/tasks/task_017.md +19 -0
- data/.taskmaster/tasks/task_018.md +19 -0
- data/.taskmaster/tasks/task_019.md +19 -0
- data/.taskmaster/tasks/task_020.md +19 -0
- data/.taskmaster/tasks/tasks.json +299 -0
- data/.taskmaster/templates/example_prd.txt +47 -0
- data/.taskmaster/templates/example_prd_rpg.txt +511 -0
- data/CHANGELOG.md +29 -0
- data/CLAUDE.md +65 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/CONTRIBUTING.md +49 -0
- data/LICENSE +21 -0
- data/README.md +463 -0
- data/Rakefile +12 -0
- data/app/assets/stylesheets/data_porter/application.css +646 -0
- data/app/channels/data_porter/import_channel.rb +10 -0
- data/app/controllers/data_porter/imports_controller.rb +68 -0
- data/app/javascript/data_porter/progress_controller.js +33 -0
- data/app/jobs/data_porter/dry_run_job.rb +12 -0
- data/app/jobs/data_porter/import_job.rb +12 -0
- data/app/jobs/data_porter/parse_job.rb +12 -0
- data/app/models/data_porter/data_import.rb +49 -0
- data/app/views/data_porter/imports/index.html.erb +142 -0
- data/app/views/data_porter/imports/new.html.erb +88 -0
- data/app/views/data_porter/imports/show.html.erb +49 -0
- data/config/database.yml +3 -0
- data/config/routes.rb +12 -0
- data/docs/SPEC.md +2012 -0
- data/docs/UI.md +32 -0
- data/docs/blog/001-why-build-a-data-import-engine.md +166 -0
- data/docs/blog/002-scaffolding-a-rails-engine.md +188 -0
- data/docs/blog/003-configuration-dsl.md +222 -0
- data/docs/blog/004-store-model-jsonb.md +237 -0
- data/docs/blog/005-target-dsl.md +284 -0
- data/docs/blog/006-parsing-csv-sources.md +300 -0
- data/docs/blog/007-orchestrator.md +247 -0
- data/docs/blog/008-actioncable-stimulus.md +376 -0
- data/docs/blog/009-phlex-ui-components.md +446 -0
- data/docs/blog/010-controllers-routing.md +374 -0
- data/docs/blog/011-generators.md +364 -0
- data/docs/blog/012-json-api-sources.md +323 -0
- data/docs/blog/013-testing-rails-engine.md +618 -0
- data/docs/blog/014-dry-run.md +307 -0
- data/docs/blog/015-publishing-retro.md +264 -0
- data/docs/blog/016-erb-view-templates.md +431 -0
- data/docs/blog/017-showcase-final-retro.md +220 -0
- data/docs/blog/BACKLOG.md +8 -0
- data/docs/blog/SERIES.md +154 -0
- data/docs/screenshots/index-with-previewing.jpg +0 -0
- data/docs/screenshots/index.jpg +0 -0
- data/docs/screenshots/modal-new-import.jpg +0 -0
- data/docs/screenshots/preview.jpg +0 -0
- data/lib/data_porter/broadcaster.rb +29 -0
- data/lib/data_porter/components/base.rb +10 -0
- data/lib/data_porter/components/failure_alert.rb +20 -0
- data/lib/data_porter/components/preview_table.rb +54 -0
- data/lib/data_porter/components/progress_bar.rb +33 -0
- data/lib/data_porter/components/results_summary.rb +19 -0
- data/lib/data_porter/components/status_badge.rb +16 -0
- data/lib/data_porter/components/summary_cards.rb +30 -0
- data/lib/data_porter/components.rb +14 -0
- data/lib/data_porter/configuration.rb +25 -0
- data/lib/data_porter/dsl/api_config.rb +25 -0
- data/lib/data_porter/dsl/column.rb +17 -0
- data/lib/data_porter/engine.rb +15 -0
- data/lib/data_porter/orchestrator.rb +141 -0
- data/lib/data_porter/record_validator.rb +32 -0
- data/lib/data_porter/registry.rb +33 -0
- data/lib/data_porter/sources/api.rb +49 -0
- data/lib/data_porter/sources/base.rb +35 -0
- data/lib/data_porter/sources/csv.rb +43 -0
- data/lib/data_porter/sources/json.rb +45 -0
- data/lib/data_porter/sources.rb +20 -0
- data/lib/data_porter/store_models/error.rb +13 -0
- data/lib/data_porter/store_models/import_record.rb +52 -0
- data/lib/data_porter/store_models/report.rb +21 -0
- data/lib/data_porter/target.rb +89 -0
- data/lib/data_porter/type_validator.rb +46 -0
- data/lib/data_porter/version.rb +5 -0
- data/lib/data_porter.rb +32 -0
- data/lib/generators/data_porter/install/install_generator.rb +33 -0
- data/lib/generators/data_porter/install/templates/create_data_porter_imports.rb.erb +21 -0
- data/lib/generators/data_porter/install/templates/initializer.rb +30 -0
- data/lib/generators/data_porter/target/target_generator.rb +44 -0
- data/lib/generators/data_porter/target/templates/target.rb.tt +20 -0
- data/sig/data_porter.rbs +4 -0
- 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
|
data/CODE_OF_CONDUCT.md
ADDED
|
@@ -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.
|