Skip to content

Delta Migration | 1.0.0 | In Drupal Assets are not getting attached to entries - #1149

Merged
umesh-more-cstk merged 4 commits into
devfrom
feature/cmg-774
Aug 24, 2026
Merged

umesh-more-cstk merged 4 commits into
devfrom
feature/cmg-774

Conversation

@aishwarya-cstk

Copy link
Copy Markdown
Contributor

🔗 Jira Ticket

Replace with your ticket link — required before requesting review.

[CMG-774


📋 PR Type

  • ✨ Feature
  • 🐛 Bug Fix
  • 🔥 Hotfix
  • ♻️ Refactor
  • 🧹 Chore / Dependency Update
  • 📝 Documentation

📝 Description

What changed?

  • Fixed processFieldByType's file and reference cases in api/src/services/drupal/entries.service.ts.

  • Added handling for values that are already resolved into asset/reference objects identified by a .uid.

  • Already-resolved objects are now passed through as-is instead of attempting to derive:

    • assets_${value}
    • content_type_entries_title_${value}
  • Applied the fix to both single-value and multiple array branches.

Why?

Drupal image/file fields such as field_image_target_id were being resolved twice:

  1. processFieldData correctly resolves the raw target_id into a Contentstack asset reference object.
  2. The already-resolved object is then passed to processFieldByType's file case, which assumes the value is still a raw numeric ID.
  3. The code attempts to look up the object as assets_[object Object].
  4. The lookup fails, causing the field to be silently removed from the migrated entry.

As a result, field_image and other asset/reference fields resolved earlier in the migration pipeline were missing from the final migrated entry.

Fix

The fix short-circuits processing when the value is already a resolved object containing a .uid.

This is additive and does not change the existing raw-ID flow, including:

  • Numeric asset/reference IDs
  • Comma-separated GROUP_CONCAT arrays
  • Missing-asset error handling
  • Existing reference resolution logic

The fix also works correctly for delta re-runs because Drupal entries are fully re-fetched and re-processed on every migration run rather than incrementally patched.


🧩 Affected Areas

  • api — Node.js backend
  • ui — React frontend
  • upload-api — Upload API server
  • docker / docker-compose
  • CI / GitHub Actions workflows
  • Environment variables / config
  • Other:

🧪 How to Test

  1. Run a Drupal migration against a content type containing:

    • An image/file field such as field_image
    • At least one entity/reference field
  2. Inspect the generated entry JSON under:
    data/<stack_id>/entries/<content_type>/<locale>/<locale>.json

  3. Confirm that the image/file and reference fields are present in the generated entry.

  4. Verify that the fields contain valid Contentstack uid references.

  5. Re-run the same migration as a second iteration/delta run.

  6. Confirm that the fields remain present and correctly resolved after the second run.

  7. Verify that no "Asset ... not found or invalid, removing field" errors are logged for valid assets.

Expected Result

field_image and other asset/reference fields should:

  • Be present in the final migrated entry.
  • Contain the correct Contentstack asset/entry UID.
  • Work correctly on both the initial migration and subsequent delta re-runs.
  • Not generate "Asset ... not found or invalid, removing field" errors for valid assets.

📸 Screenshots / Recordings

Before After
N/A — backend field-mapping fix N/A — backend field-mapping fix

🔗 Related PRs / Dependencies

  • N/A

✅ Author Checklist

Complete this before moving the PR out of Draft.

  • Branch follows naming convention: feature/, bugfix/, or hotfix/ + 5–30 lowercase characters
  • Jira ticket linked above
  • Self-reviewed the diff — no debug logs, commented-out code, or TODOs left in
  • .env / example.env updated if new environment variables were added
  • No sensitive credentials or secrets committed
  • Existing tests pass locally (npm test)
  • New tests written, or not applicable — explain why
  • README.md / documentation updated if behavior changed
  • Talisman pre-push scan passes with no secrets flagged

👀 Reviewer Notes

  • The guard relies on the presence of .uid to identify an already-resolved asset/reference object.

  • The .uid field is always set when asset references are constructed in api/src/services/drupal/assets.service.ts.

  • Please flag if there is any known resolved-object shape that does not contain .uid.

  • No automated test was added directly to the existing test suite because api/src/services/drupal currently does not have field-processing unit tests to extend.

  • The fix was manually verified using a standalone script covering both:

    • A first migration run
    • A second/delta migration run
  • A Vitest unit test for processFieldByType can be added if required.


Migration v2 · [Docs](https://github.com/contentstack/migration-v2#readme) · [Issues](https://github.com/contentstack/migration-v2/issues)

@aishwarya-cstk
aishwarya-cstk requested a review from a team as a code owner August 24, 2026 08:31
@aishwarya-cstk
aishwarya-cstk requested a lite review from Copilot August 24, 2026 08:31
@snyk-io

snyk-io Bot commented Aug 24, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 15 378 25 ✅ Passed
🟡 Medium Severity 19 11 500 ✅ Passed
🔵 Low Severity 2 0 1000 ✅ Passed

⏱️ SLA Breach Summary

⚠️ Warning: The following vulnerabilities have exceeded their SLA thresholds (days since publication).

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 371 30 / 120 days ⚠️ Warning
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

ℹ️ Vulnerabilities Without Available Fixes (Informational Only)

The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:

  • Critical without fixes: 0
  • High without fixes: 378
  • Medium without fixes: 11
  • Low without fixes: 0

⚠️ BUILD PASSED WITH WARNINGS - SLA breaches detected for issues without available fixes

Consider reviewing these vulnerabilities when fixes become available.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes Drupal migration field-type processing so that asset (file) and entry (reference) fields don’t get incorrectly re-processed when earlier pipeline steps have already resolved them into Contentstack-style reference objects (identified by a .uid). This prevents valid assets/references from being dropped from migrated entries during both initial runs and delta re-runs.

Changes:

  • Added pass-through handling in processFieldByType for already-resolved asset objects (file case) for both single and multiple values.
  • Added pass-through handling in processFieldByType for already-resolved reference objects (reference case) for both single and multiple values.
  • Preserved existing raw-ID lookup behavior for unresolved values (e.g., assets_${id} and content_type_entries_title_${id} flows).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread api/src/services/drupal/entries.service.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 15 378 25 ✅ Passed
🟡 Medium Severity 19 11 500 ✅ Passed
🔵 Low Severity 2 0 1000 ✅ Passed

⏱️ SLA Breach Summary

⚠️ Warning: The following vulnerabilities have exceeded their SLA thresholds (days since publication).

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 371 30 / 120 days ⚠️ Warning
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

ℹ️ Vulnerabilities Without Available Fixes (Informational Only)

The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:

  • Critical without fixes: 0
  • High without fixes: 378
  • Medium without fixes: 11
  • Low without fixes: 0

⚠️ BUILD PASSED WITH WARNINGS - SLA breaches detected for issues without available fixes

Consider reviewing these vulnerabilities when fixes become available.

@umesh-more-cstk umesh-more-cstk left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — Drupal processFieldByType already-resolved asset/reference pass-through

Reviewed at head 5676adb (all 3 commits; no prior review of mine on this PR). Comment-only — leaving the merge gate to a human.

Scope: 1 file, api/src/services/drupal/entries.service.ts, +28/-4. Matches the single api box in Affected Areas. No lockfile or generated churn, not a draft. Scope is clean.

The fix's core premise checks out

Your reviewer note asks whether any resolved-object shape lacks .uid. I traced both maps and the answer is no:

  • AssetsassetId is loaded from assets/index.json (ASSETS_SCHEMA_FILE), which is the assetData map written by saveAsset. Every entry is created with uid: + "assets_${safeFid}" + wheresafeFid is explicitly validated non-empty (assets.service.ts, if (!safeFid) throw`).
  • Referencesreference/reference.json entries are { uid: + "content_type_entries_title_${nid}" + , _content_type_uid } (references.service.ts:112-116), guarded by if (!entry?.nid) return.

So .uid is always a non-empty string on both, and the truthiness guard is safe from the empty-string / 0 optional-chaining trap. I also confirmed the pre-existing single-reference shape really was the [[{uid,...}]] double-wrap, so the Array.isArray early return is a genuine fix, and that the raw-ID paths (numeric IDs, GROUP_CONCAT arrays, existing reference resolution) are untouched as claimed.

Findings

1 blocker, 2 questions.

  • blockercase 'file', line 452: for asset fields processFieldData only ever produces a single object, never an array, so the new multiple guard is unreachable; and an advanced.multiple file mapping falls through both inner branches to return value, emitting a bare object where Contentstack needs an array. Multi-asset fields therefore still don't attach. Suggested normalization inline.
  • questioncase 'reference' single branch, line 507: the array early return doesn't resolve raw IDs, asymmetric with the multiple branch 8 lines above. Probably unreachable via processFieldData, but _tid fields build raw-ID arrays in the ctValue loop. Suggested one-line mirror inline.
  • question — line 474: the Asset ... not found or invalid, removing field log is now unreachable for *_target_id asset fields, which makes test-plan step 7 unable to fail. Missing assets are dropped silently upstream in processFieldData with no log at all.

Non-blocking

  • Jira link is malformed and inconsistent. The description has [[CMG-774](https://contentstack.atlassian.net/browse/CMG-1114) — unbalanced [[, and the label (CMG-774, matching branch feature/cmg-774) disagrees with the URL (CMG-1114). Worth fixing so the ticket trail is correct.
  • On the missing unit test: processFieldByType is a pure function of (value, fieldMapping, assetId, referenceId) — no DB, no filesystem. A Vitest test with literal assetId / referenceId maps covers all four file/reference branches in a few lines, and the multiple + single-object case above is exactly what it would have caught. I'd push for adding it rather than deferring, given api/src/services/drupal has no field-processing coverage today.
  • Author checklist still has Self-reviewed the diff, Existing tests pass locally, and Branch follows naming convention unchecked.

Generated by Claude Code

Comment thread api/src/services/drupal/entries.service.ts
Comment thread api/src/services/drupal/entries.service.ts
Comment thread api/src/services/drupal/entries.service.ts
@github-actions

Copy link
Copy Markdown

🔒 Security Scan Results

ℹ️ Note: Only vulnerabilities with available fixes (upgrades or patches) are counted toward thresholds.

Check Type Count (with fixes) Without fixes Threshold Result
🔴 Critical Severity 0 0 10 ✅ Passed
🟠 High Severity 15 378 25 ✅ Passed
🟡 Medium Severity 19 11 500 ✅ Passed
🔵 Low Severity 2 0 1000 ✅ Passed

⏱️ SLA Breach Summary

⚠️ Warning: The following vulnerabilities have exceeded their SLA thresholds (days since publication).

Severity Breaches (with fixes) Breaches (no fixes) SLA Threshold (with/no fixes) Status
🔴 Critical 0 0 15 / 30 days ✅ Passed
🟠 High 0 371 30 / 120 days ⚠️ Warning
🟡 Medium 0 0 90 / 365 days ✅ Passed
🔵 Low 0 0 180 / 365 days ✅ Passed

ℹ️ Vulnerabilities Without Available Fixes (Informational Only)

The following vulnerabilities were detected but do not have fixes available (no upgrade or patch). These are excluded from failure thresholds:

  • Critical without fixes: 0
  • High without fixes: 378
  • Medium without fixes: 11
  • Low without fixes: 0

⚠️ BUILD PASSED WITH WARNINGS - SLA breaches detected for issues without available fixes

Consider reviewing these vulnerabilities when fixes become available.

@umesh-more-cstk
umesh-more-cstk merged commit daf875e into dev Aug 24, 2026
10 checks passed
@umesh-more-cstk
umesh-more-cstk deleted the feature/cmg-774 branch August 24, 2026 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants