Skip to content

Added content import ledger tables#28771

Open
PaulAdamDavis wants to merge 1 commit into
mainfrom
csv-import-tables
Open

Added content import ledger tables#28771
PaulAdamDavis wants to merge 1 commit into
mainfrom
csv-import-tables

Conversation

@PaulAdamDavis

Copy link
Copy Markdown
Member

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.

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.
@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 72ba4bb4-df77-42b7-b749-9fbcda6ecfde

📥 Commits

Reviewing files that changed from the base of the PR and between f32a14f and 81eea24.

📒 Files selected for processing (7)
  • ghost/admin/package.json
  • ghost/core/core/server/data/exporter/table-lists.js
  • ghost/core/core/server/data/migrations/versions/6.47/2026-06-21-19-30-38-add-content-import-ledger-tables.js
  • ghost/core/core/server/data/schema/schema.js
  • ghost/core/package.json
  • ghost/core/test/integration/exporter/exporter.test.js
  • ghost/core/test/unit/server/data/schema/integrity.test.js

Walkthrough

The PR adds two new database tables to Ghost's schema: content_imports, which tracks import job metadata including status, source file details, mapping payload, and a user_id foreign key; and content_import_rows, which stores per-row import data including original content, outcome/reason/warnings, optional post_id linkage, and a unique constraint on (import_id, source_index). A non-transactional migration creates both tables with their indexes and constraints. Both tables are registered in BACKUP_TABLES for export inclusion. The exporter integration test and schema integrity hash are updated accordingly. Package versions in ghost/admin and ghost/core are bumped to 6.47.0-rc.0.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding content import ledger tables to the codebase.
Description check ✅ Passed The description is directly related to the changeset, referencing the Linear issue and explaining that the tables enable recording results, resuming work, and generating reports.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch csv-import-tables
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch csv-import-tables

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the migration [pull request] Includes migration for review label Jun 21, 2026
@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

It looks like this PR contains a migration 👀
Here's the checklist for reviewing migrations:

General requirements

  • ⚠️ Tested performance on staging database servers, as performance on local machines is not comparable to a production environment
  • Satisfies idempotency requirement (both up() and down())
  • Does not reference models
  • Filename is in the correct format (and correctly ordered)
  • Targets the next minor version
  • All code paths have appropriate log messages
  • Uses the correct utils
  • Contains a minimal changeset
  • Does not mix DDL/DML operations
  • Tested in MySQL and SQLite

Schema changes

  • Both schema change and related migration have been implemented
  • For index changes: has been performance tested for large tables
  • For new tables/columns: fields use the appropriate predefined field lengths
  • For new tables/columns: field names follow the appropriate conventions
  • Does not drop a non-alpha table outside of a major version

### Data changes (not relevant here)

- [ ] Mass updates/inserts are batched appropriately
- [ ] Does not loop over large tables/datasets
- [ ] Defends against missing or invalid data
- [ ] For settings updates: follows the appropriate guidelines

@PaulAdamDavis

Copy link
Copy Markdown
Member Author

Here's a breakdown of what each table & column will store

content_imports

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.

@nx-cloud

nx-cloud Bot commented Jun 21, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 81eea24

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

codecov Bot commented Jun 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.75%. Comparing base (624d136) to head (81eea24).
⚠️ Report is 62 commits behind head on main.

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     
Flag Coverage Δ
admin-tests 55.16% <ø> (ø)
e2e-tests 75.85% <100.00%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@PaulAdamDavis PaulAdamDavis marked this pull request as ready for review June 23, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

migration [pull request] Includes migration for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant