Skip to content

Feat/delta aem#1092

Open
umesh-more-cstk wants to merge 8 commits into
devfrom
feat/delta-aem
Open

Feat/delta aem#1092
umesh-more-cstk wants to merge 8 commits into
devfrom
feat/delta-aem

Conversation

@umesh-more-cstk

@umesh-more-cstk umesh-more-cstk commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

🔗 Jira Ticket

MIGRATION-1001


📋 PR Type

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

📝 Description

What changed?

  • Delta migration for AEM (api): per-iteration asset snapshot (saveAssetMetadata), reuse/update dedup (removeExistingAssets), entry subtraction + update config (removeEntriesFromDatabase, enrichConfig*), and the entry-update-script.cjs update path (cm:stacks:migration).
  • Asset/Entry Mapper UI (ui): per-asset reuse vs update-in-place and per-entry update decisions, with content-type status reflection; pure logic extracted into assetMapper.utils.ts / entryMapper.utils.ts.
  • Fix — JSON-RTE import crash (aem.service.ts): json fields are always created as JSON-RTE, so the importer walks value.children; the AEM-component fallback now emits a valid RTE doc or null instead of a childless object (which crashed cm:stacks:import with "Cannot read properties of undefined (reading 'forEach')").
  • Fix — path traversal / CWE-23 (migration.service.ts): the delta step built database/<projectId>/… config paths from the raw HTTP projectId and later readFileSync'd them; now sanitized via sanitizeProjectId with an early bail on invalid input.
  • Fix — EntryMapper wiring (index.tsx): use the existing isDeltaIteration flag instead of an undefined iteration, and pass the required handleStepChange prop.
  • Tests: api delta utils + entry-reference rewrite + entry-update-script.cjs; ui mapper utils; fixed stale mocks/assertions in contentMapper.routes, uid-mapper.utils, and aem.controller.

Why?

Enables re-running an AEM migration without duplicating already-migrated content, and hardens the delta path (crash + security) that the feature introduced.


🧩 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 fresh AEM migration (iteration 1) → content tyd.
  2. Re-run the migration (iteration 2): open the Asset Mapper (choose reuse vs update-in-place) and the Entry Mapper (mark entries to update), then continue.
  3. Confirm matched assets/entries are **updated/reused,tination stack.

Expected result: No duplicate content on re-run; the delta Entry Mapper screen renders and navigates; no forEach crash during entry
import.


📸 Screenshots / Recordings

Before After

🔗 Related PRs / Dependencies

  • Merges latest dev into the branch (no external PR d

✅ Author Checklist

  • Branch follows naming convention: feature/, bugfix/, or hotfix/ + 5–30 lowercase chars
  • 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 (none added)
  • No sensitive credentials or secrets committed
  • Existing tests pass locally (npm test) — api 655, ui 352, upload-api 300
  • New tests written
  • README.md / docs updated if behaviour changed n Confluence -->
  • Talisman pre-push scan passes (no secrets flagged)

👀 Reviewer Notes

  • Manually verify the delta Entry Mapper screen (iteration ≥ 2) — it was crashing before the index.tsx wiring fix.
  • The uid-mapper.utils test assertion was updatedwrite behavior — confirm that behavior is intended.
  • Security: migration.service.ts now sanitizes projectId before any database/<projectId>/… file path (CWE-23 fix).

@umesh-more-cstk umesh-more-cstk requested a review from a team as a code owner June 15, 2026 12:22
- api: add unit tests for the delta Asset Mapper decision branches
  (isUpdate reuse vs in-place update), saveAssetMetadata/
  loadPreviousAssetMetadata, ensureUpdateConfigFile/
  enrichConfigWithAssetUpdates, and the entry-update-script.cjs helpers
  (isAssetField, resolveAssetField 3-way, mergeFlatPayloadIntoEntry,
  task runner). Expose the cjs helpers for testing.
- api: fix stale contentMapper.routes mock (add getAssetMapping,
  getSingleContentTypes, getSingleGlobalField, updateAssetStatus) and
  uid-mapper assertion to match the current always-write behavior.
- upload-api: add extractEntries/extractAssets to the migration-aem mock
  in aem.controller.test so createAemMapper makes both API calls.
…fix EntryMapper wiring

- Extract pure logic from assetMapper.tsx and entryMapper.tsx into
  assetMapper.utils.ts / entryMapper.utils.ts (row mapping, selection
  build/apply, changed-uid diff, content-type status filtering) and add
  unit tests for both.
- Fix two pre-existing bugs in the delta EntryMapper render in index.tsx:
  reference the existing isDeltaIteration flag instead of an undefined
  'iteration' variable, and pass the required handleStepChange prop
  instead of tableHeight/selectedContentTypeId (which EntryMapper ignores).
@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 10 338 25 ✅ Passed
🟡 Medium Severity 26 2 500 ✅ Passed
🔵 Low Severity 0 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 0 30 / 120 days ✅ Passed
🟡 Medium 0 2 90 / 365 days ⚠️ Warning
🔵 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: 338
  • Medium without fixes: 2
  • Low without fixes: 0

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

Consider reviewing these vulnerabilities when fixes become available.

Add a removeExistingAssets test that drives the entry-JSON reference
rewrite path (entriesDir present -> content-type/locale/chunk walk ->
replaceAssetRefsInObject). This covers the four previously-uncovered
functions in asset-update.utils.ts, raising api function coverage from
79.9% to 80.82% (above the 80% CI threshold).
@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 10 338 25 ✅ Passed
🟡 Medium Severity 26 2 500 ✅ Passed
🔵 Low Severity 0 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 0 30 / 120 days ✅ Passed
🟡 Medium 0 2 90 / 365 days ⚠️ Warning
🔵 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: 338
  • Medium without fixes: 2
  • Low without fixes: 0

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

Consider reviewing these vulnerabilities when fixes become available.

…-23)

The delta update step built database/<projectId>/<iteration>/ config paths
from the raw, HTTP-derived projectId and later read them with
fs.readFileSync (enrichConfigWithAssetMapping/enrichConfigWithAssetUpdates),
allowing path traversal. Reuse the existing sanitizeProjectId result
(safePid) — which rebuilds the value from a char allowlist and rejects
'..', '/', '\' — for saveAssetMetadata, removeExistingAssets,
removeEntriesFromDatabase, ensureUpdateConfigFile and
enrichConfigWithAssetMapping, and bail out when the id is invalid.
@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 11 338 25 ✅ Passed
🟡 Medium Severity 29 2 500 ✅ Passed
🔵 Low Severity 0 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 0 30 / 120 days ✅ Passed
🟡 Medium 0 2 90 / 365 days ⚠️ Warning
🔵 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: 338
  • Medium without fixes: 2
  • 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.

⚠️ Not ready to approve

There are confirmed correctness issues in the new asset-mapper API/UI (including a guaranteed-200 toggle response and crash-prone search filtering) plus a committed machine-specific config path that should be fixed before merge.

Pull request overview

Adds delta-migration support for AEM by generating stable asset/entry mapping inputs at upload time, exposing delta decision UIs (asset reuse vs update-in-place; entry update selection), and updating backend delta utilities + CLI update script to carry mappings forward and apply in-place asset replacements.

Changes:

  • Upload-api AEM mapper generation now extracts entry + asset mapping and sends it to the API for delta decision storage.
  • UI adds Asset Mapper + pure utility modules with unit tests; Content Mapper can switch between Entry/Asset delta decisions.
  • API adds asset-mapper storage/endpoints, improves delta asset handling + update script, and merges uid-maps across iterations; includes AEM importer robustness fixes and a projectId sanitization guard in delta flow.
File summaries
File Description
upload-api/tests/unit/controllers/aem.controller.test.ts Updates mocks for new migration-aem exports used by the controller.
upload-api/src/controllers/aem/index.ts Calls new extractEntries/extractAssets during AEM mapper creation.
upload-api/src/config/index.ts Adds a TS config module (in addition to existing JSON config).
upload-api/src/config/index.json Adjusts default config values for upload-api.
upload-api/migration-aem/libs/entries/index.ts New entry mapping extraction for delta decisions.
upload-api/migration-aem/libs/contentType/createContentTypes.ts Adds JSON fallback fields and hardens schema generation logic.
upload-api/migration-aem/libs/assets/index.ts New asset mapping extraction for delta decisions.
upload-api/migration-aem/index.ts Exports new extraction helpers from migration-aem package.
ui/src/services/api/migration.service.ts Adds UI API calls for asset mapping list + status updates.
ui/src/components/ContentMapper/index.tsx Integrates AssetMapper/EntryMapper views into ContentMapper.
ui/src/components/ContentMapper/index.scss Adds styling for the mapper view toggle.
ui/src/components/ContentMapper/entryMapper.utils.ts Extracts pure entry-mapper logic for unit testing.
ui/src/components/ContentMapper/entryMapper.tsx Refactors to use extracted pure helpers/shared selection helpers.
ui/src/components/ContentMapper/contentMapper.interface.ts Adds AssetMapperType interface.
ui/src/components/ContentMapper/assetMapper.utils.ts New pure helper functions for AssetMapper (formatting/selection).
ui/src/components/ContentMapper/assetMapper.tsx New AssetMapper component (infinite table + save decisions).
ui/src/components/ContentMapper/tests/entryMapper.utils.test.ts Adds unit tests for EntryMapper pure helpers.
ui/src/components/ContentMapper/tests/assetMapper.utils.test.ts Adds unit tests for AssetMapper pure helpers.
api/tests/unit/utils/uid-mapper.utils.test.ts Updates test expectations for carry-forward uid-mapper behavior.
api/tests/unit/utils/entry-update.enrich.test.ts Adds tests for new config enrichment helpers.
api/tests/unit/utils/entry-update-script.test.ts Adds tests for entry-update script helpers and asset-update task.
api/tests/unit/utils/asset-update.decisions.test.ts Adds tests covering delta asset decision branches + metadata helpers.
api/tests/unit/routes/contentMapper.routes.test.ts Extends route mocks for new asset mapping endpoints.
api/src/utils/uid-mapper.utils.ts Carries uid mappings forward by merging previous iteration maps.
api/src/utils/entry-update.utils.ts Adds helpers to ensure/update config for asset updates and mapping injection.
api/src/utils/entry-update-script.cjs Adds optional “Update Assets” task and exposes helpers for tests.
api/src/utils/content-type-creator.utils.ts Treats AEM component fallback JSON as JSON schema in creator utils.
api/src/utils/asset-update.utils.ts Implements asset decision processing + in-place replace queue + ref rewriting.
api/src/services/migration.service.ts Wires delta asset updates into update-config and runs update CLI; adds projectId sanitization guard in delta step.
api/src/services/contentMapper.service.ts Stores/serves/toggles asset mapper rows; enriches asset rows with uid-mapper and change detection.
api/src/services/aem.service.ts Stabilizes asset/entry UIDs across runs, improves locale mapping, and hardens JSON-RTE fallback behavior.
api/src/routes/contentMapper.routes.ts Adds asset mapping list + status update routes.
api/src/models/assetMapper.ts New lowdb model for asset-mapper persistence.
api/src/controllers/projects.contentMapper.controller.ts Exposes new asset mapping controller methods.
api/src/constants/index.ts Adds ASSET_MAPPER database file constant.

Copilot's findings

  • Files reviewed: 35/35 changed files
  • Comments generated: 10

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread upload-api/src/config/index.json Outdated
Comment thread upload-api/src/controllers/aem/index.ts
Comment thread upload-api/migration-aem/libs/entries/index.ts
Comment thread api/src/services/contentMapper.service.ts Outdated
Comment thread api/src/services/contentMapper.service.ts
Comment thread api/src/models/assetMapper.ts Outdated
Comment thread ui/src/components/ContentMapper/assetMapper.tsx Outdated
Comment thread ui/src/components/ContentMapper/assetMapper.tsx Outdated
Comment thread ui/src/components/ContentMapper/index.tsx
Comment thread upload-api/src/config/index.json Outdated
- contentMapper.service: updateAssetStatus now returns 404 when no rows
  match instead of always returning 200 (foundAssets array was truthy)
- assetMapper model: sanitize HTTP-derived projectId before using it as a
  path segment to prevent path traversal (CWE-23)
- assetMapper UI: use API total count for counts/pagination and merge each
  fetched page at its offset so loadMoreItems no longer drops loaded rows
- upload-api config: replace machine-specific localPath and AEM-specific
  cmsType with neutral defaults (overridable via CMS_LOCAL_PATH/CMS_TYPE)
@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 11 338 25 ✅ Passed
🟡 Medium Severity 31 2 500 ✅ Passed
🔵 Low Severity 0 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 0 30 / 120 days ✅ Passed
🟡 Medium 0 2 90 / 365 days ⚠️ Warning
🔵 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: 338
  • Medium without fixes: 2
  • Low without fixes: 0

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

Consider reviewing these vulnerabilities when fixes become available.

1 similar comment
@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 11 338 25 ✅ Passed
🟡 Medium Severity 31 2 500 ✅ Passed
🔵 Low Severity 0 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 0 30 / 120 days ✅ Passed
🟡 Medium 0 2 90 / 365 days ⚠️ Warning
🔵 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: 338
  • Medium without fixes: 2
  • Low without fixes: 0

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

Consider reviewing these vulnerabilities when fixes become available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants