Added content import ledger tables#28771
Conversation
ref https://linear.app/ghost/issue/MIG-1435/ Creates persisted working-state tables for CSV content import runs and row outcomes so later milestones can record results, resume work, and render reports.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
WalkthroughThe PR adds two new database tables to Ghost's schema: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
It looks like this PR contains a migration 👀 General requirements
Schema changes
|
|
Here's a breakdown of what each table & column will store
|
| Column | Type | Source | Notes |
|---|---|---|---|
| id | string(24), primary | Generated when import is created | Used as the parent import id and basis for #Import-{id}. |
| created_at | datetime, not null | Server clock | Created before row processing starts. |
| updated_at | datetime, not null | Server clock | Updated on status/progress changes. |
| started_at | datetime, nullable | Import job engine | Set when row processing starts. |
| finished_at | datetime, nullable | Import job engine | Set when import completes or fails. |
| status | string(50), not null, default pending | Import lifecycle | Valid values: pending, running, completed, failed. |
| source_filename | string(255), nullable | Uploaded file metadata | Original CSV filename for debugging/report context. |
| source_path | string(2000), not null | CSV prepare/storage step | Stored/prepared CSV path used by M6 recovery to re-run from the start. |
| mapping | text, nullable | Upload form data | Serialized JSON for mapping[csvHeader] = ghostField; nullable for the M2 exact/minimal import path. |
| user_id | string(24), not null, FK users.id | Authenticated admin user, or Owner fallback | Used later to resolve report recipient email. Use default FK restrict/no-action behavior, not cascade/set-null. |
content_import_rows
| Column | Type | Source | Notes |
|---|---|---|---|
| id | string(24), primary | Generated per parsed row | Normal Ghost object id. |
| import_id | string(24), not null, FK content_imports.id | Parent import record | cascadeDelete: true; clearing an import clears row ledger state. |
| source_index | integer unsigned, not null | CSV parser | 0-based parsed data-row index, excluding header. |
| original_data | long text, not null | Raw parsed CSV row | Serialized JSON using original CSV headers, before mapping/coercion. |
| outcome | string(50), not null, default pending | Row processor | Valid values: pending, created, updated, skipped, failed. |
| reason | string(2000), nullable | Row processor | Human-readable skip/failure reason. |
| warnings | text, nullable | Row processor | Serialized JSON array for non-fatal notes, e.g. author fallback. |
| post_id | string(24), nullable, FK posts.id | Created/updated/matched post | setNullDelete: true; report can still use resulting_url. |
| resulting_url | string(2000), nullable | URL generation after row result | Used by M7 report/email. |
| created_at | datetime, not null | Server clock | Row ledger insert time. |
| updated_at | datetime, not null | Server clock | Updated when row outcome changes. |
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 6s | View ↗ |
nx run ghost:test:ci:integration:no-coverage |
✅ Succeeded | 2m 17s | View ↗ |
nx run ghost:test:ci:e2e |
✅ Succeeded | 7m 47s | View ↗ |
nx run ghost:test:ci:e2e:no-coverage |
✅ Succeeded | 7m 8s | View ↗ |
nx run ghost:test:ci:legacy |
✅ Succeeded | 3m 7s | View ↗ |
nx build @tryghost/comments-ui |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/portal |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/sodo-search |
✅ Succeeded | <1s | View ↗ |
Additional runs (11) |
✅ Succeeded | ... | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-06-21 20:06:44 UTC
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #28771 +/- ##
==========================================
- Coverage 73.76% 73.75% -0.02%
==========================================
Files 1552 1552
Lines 134208 134210 +2
Branches 16108 16104 -4
==========================================
- Hits 99004 98987 -17
+ Misses 34225 34214 -11
- Partials 979 1009 +30
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|

ref https://linear.app/ghost/issue/MIG-1435/
Creates persisted working-state tables for CSV content import runs and row outcomes so later milestones can record results, resume work, and render reports.