Skip to content

Honour the id specified when importing a layout - #4330

Merged
rajithacharith merged 1 commit into
thunder-id:mainfrom
rajithacharith:fix-layout-import-id
Jul 24, 2026
Merged

Honour the id specified when importing a layout#4330
rajithacharith merged 1 commit into
thunder-id:mainfrom
rajithacharith:fix-layout-import-id

Conversation

@rajithacharith

@rajithacharith rajithacharith commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Purpose

When a layout is imported via the declarative import flow, the id specified in the YAML was silently discarded and a fresh UUID was generated instead. The imported layout therefore never got the intended id, which breaks references to it (e.g. layoutId on organization units) and makes imports non-idempotent by id.

Themes and every other importable resource (organization unit, entity type, role, user, agent) already honor the incoming id; layout was the only outlier.

Approach

Mirror the theme pattern for layouts:

  • Add a CreateLayoutRequestWithID service request type that carries an optional id.
  • CreateLayout now honors layout.ID when non-empty and only generates a UUID when it is empty, then builds a plain CreateLayoutRequest for the store (the store signature is unchanged).
  • The public create HTTP handler wraps the request into the WithID form without an id, so the public API still cannot set a client-supplied id (same as themes).
  • The layout import adapter passes ID: req.ID through to CreateLayout.

Related Issues

Related PRs

  • N/A

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
    • Ran Vale and fixed all errors and warnings
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Layout creation now supports optional client-provided IDs.
    • Layout imports preserve IDs specified in imported layout data.
    • When no ID is provided, new IDs are generated automatically.
  • Bug Fixes
    • Improved consistency between layout creation and layout import behavior, including ID-aware request handling.
  • Tests
    • Added/expanded coverage for ID preservation and layout import upsert/create scenarios.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Layout creation now accepts an optional ID, preserves provided IDs, generates UUIDv7 values when absent, and propagates YAML IDs through declarative imports. Handlers, importer interfaces, mocks, and tests were updated for the new request type.

Changes

Layout ID-aware creation

Layer / File(s) Summary
Layout creation ID handling
backend/internal/design/layout/mgt/model.go, backend/internal/design/layout/mgt/service.go, backend/internal/design/layout/mgt/service_test.go, backend/internal/design/layout/mgt/LayoutMgtServiceInterface_mock_test.go
Adds CreateLayoutRequestWithID, preserves supplied IDs, generates UUIDv7 values when omitted, and updates service tests and mocks.
Handler and test contract updates
backend/internal/design/layout/mgt/handler.go, backend/internal/design/layout/mgt/handler_test.go, backend/internal/design/layout/mgt/init_test.go
Maps public create requests to the ID-aware request type and updates handler test callbacks.
Declarative import ID propagation
backend/internal/system/importer/service.go, backend/internal/system/importer/service_adapters.go, backend/internal/system/importer/service_test.go
Passes YAML layout IDs through the importer interface and importLayout, with coverage for create, update, upsert, and error outcomes.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Importer
  participant LayoutService
  participant LayoutStore
  Importer->>LayoutService: CreateLayout(request with YAML ID)
  LayoutService->>LayoutService: Preserve ID or generate UUIDv7
  LayoutService->>LayoutStore: CreateLayout(id, store request)
Loading

Suggested reviewers: brionmario, thamindudilshan

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The code changes match #4316 by preserving imported layout IDs and updating the service, handler, importer, and tests accordingly.
Out of Scope Changes check ✅ Passed No clear unrelated changes are introduced beyond the layout ID import fix and its supporting refactors and tests.
Title check ✅ Passed The title accurately summarizes the main change: preserving the layout ID during import.
Description check ✅ Passed The description follows the required template and covers Purpose, Approach, Related Issues, Checklist, and Security checks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/internal/system/importer/service_adapters.go`:
- Around line 620-632: Update the applicable declarative layouts guide under
docs/content/guides/ to document that YAML id values are preserved during layout
import, including behavior for explicit-ID creation and upsert operations.
Ensure the documentation accurately reflects the import behavior implemented
around CreateLayoutRequestWithID and UpdateLayoutRequest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f1f37862-e2e2-4d08-a2c7-38672c6303fd

📥 Commits

Reviewing files that changed from the base of the PR and between 00091d3 and 3d2f73e.

⛔ Files ignored due to path filters (1)
  • backend/tests/mocks/design/layoutmock/LayoutMgtServiceInterface_mock.go is excluded by !**/*_mock.go
📒 Files selected for processing (9)
  • backend/internal/design/layout/mgt/LayoutMgtServiceInterface_mock_test.go
  • backend/internal/design/layout/mgt/handler.go
  • backend/internal/design/layout/mgt/handler_test.go
  • backend/internal/design/layout/mgt/init_test.go
  • backend/internal/design/layout/mgt/model.go
  • backend/internal/design/layout/mgt/service.go
  • backend/internal/design/layout/mgt/service_test.go
  • backend/internal/system/importer/service.go
  • backend/internal/system/importer/service_adapters.go

Comment on lines +620 to 632
createReq := layoutmgt.CreateLayoutRequestWithID{
ID: req.ID,
Handle: req.Handle,
DisplayName: req.DisplayName,
Description: req.Description,
Layout: layoutBytes,
}
updateReq := layoutmgt.UpdateLayoutRequest{
Handle: req.Handle,
DisplayName: req.DisplayName,
Description: req.Description,
Layout: layoutBytes,
}

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.

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🔴 Documentation Required
This PR introduces user-facing changes that are not covered by documentation updates under docs/.
Please update the relevant documentation before merging.

Missing documentation:

  • Declarative layout YAML IDs: document that id is preserved during layout import, including explicit-ID create and upsert behavior, in the applicable guide under docs/content/guides/.

As per path instructions, declarative user-facing changes require corresponding documentation updates under docs/.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/internal/system/importer/service_adapters.go` around lines 620 - 632,
Update the applicable declarative layouts guide under docs/content/guides/ to
document that YAML id values are preserved during layout import, including
behavior for explicit-ID creation and upsert operations. Ensure the
documentation accurately reflects the import behavior implemented around
CreateLayoutRequestWithID and UpdateLayoutRequest.

Source: Path instructions

@rajithacharith rajithacharith added trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes Type/Bug labels Jul 24, 2026
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.16667% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ckend/internal/system/importer/service_adapters.go 75.00% 6 Missing and 1 partial ⚠️
backend/internal/design/layout/mgt/service.go 78.57% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@rajithacharith rajithacharith changed the title Honor the id specified when importing a layout Honour the id specified when importing a layout Jul 24, 2026

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

🧹 Nitpick comments (2)
backend/internal/system/importer/service_test.go (1)

1830-1996: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add dry-run test coverage for layout import.

The new tests cover upsert/create/update/error paths but none exercise DryRun: true, even though importLayout's dry-run branch (GetLayout existence check, no actual mutation) is new/changed logic with its own bug surface separate from the real-run path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/internal/system/importer/service_test.go` around lines 1830 - 1996,
Add dry-run coverage alongside the layout import tests, targeting
ImportResources with DryRun set to true and exercising both an existing layout
and a missing layout. Verify the dry-run results reflect the expected
operation/status while fakeLayoutService records no created or updated
mutations, covering importLayout’s GetLayout existence-check branch.
backend/internal/system/importer/service_adapters.go (1)

620-673: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Consider a generic import helper to avoid duplicating this branching across resource types.

importLayout duplicates the dry-run/upsert/create/update branching already present in importTheme almost verbatim, and this pattern will likely repeat for future declarative resource types now that the shared importDesignResource helper is gone. A small Go-generics-based helper (parameterized over create/update request types and the create/get/update calls) could collapse this into one implementation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/internal/system/importer/service_adapters.go` around lines 620 - 673,
Introduce a reusable generic import helper for the branching currently
duplicated by importLayout and importTheme, covering dry-run, upsert lookup,
update, not-found fallback to create, and direct create flows. Parameterize the
helper over each resource’s request and response types and service operations,
then refactor importLayout and importTheme to delegate to it while preserving
their existing outcomes and error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@backend/internal/system/importer/service_adapters.go`:
- Around line 620-673: Introduce a reusable generic import helper for the
branching currently duplicated by importLayout and importTheme, covering
dry-run, upsert lookup, update, not-found fallback to create, and direct create
flows. Parameterize the helper over each resource’s request and response types
and service operations, then refactor importLayout and importTheme to delegate
to it while preserving their existing outcomes and error handling.

In `@backend/internal/system/importer/service_test.go`:
- Around line 1830-1996: Add dry-run coverage alongside the layout import tests,
targeting ImportResources with DryRun set to true and exercising both an
existing layout and a missing layout. Verify the dry-run results reflect the
expected operation/status while fakeLayoutService records no created or updated
mutations, covering importLayout’s GetLayout existence-check branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d3e66c56-5e74-4a41-ab5e-b2e4188bda10

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2f73e and ea8ab84.

⛔ Files ignored due to path filters (1)
  • backend/tests/mocks/design/layoutmock/LayoutMgtServiceInterface_mock.go is excluded by !**/*_mock.go
📒 Files selected for processing (10)
  • backend/internal/design/layout/mgt/LayoutMgtServiceInterface_mock_test.go
  • backend/internal/design/layout/mgt/handler.go
  • backend/internal/design/layout/mgt/handler_test.go
  • backend/internal/design/layout/mgt/init_test.go
  • backend/internal/design/layout/mgt/model.go
  • backend/internal/design/layout/mgt/service.go
  • backend/internal/design/layout/mgt/service_test.go
  • backend/internal/system/importer/service.go
  • backend/internal/system/importer/service_adapters.go
  • backend/internal/system/importer/service_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • backend/internal/design/layout/mgt/handler.go
  • backend/internal/system/importer/service.go
  • backend/internal/design/layout/mgt/service.go
  • backend/internal/design/layout/mgt/handler_test.go
  • backend/internal/design/layout/mgt/model.go
  • backend/internal/design/layout/mgt/LayoutMgtServiceInterface_mock_test.go
  • backend/internal/design/layout/mgt/service_test.go

@rajithacharith
rajithacharith added this pull request to the merge queue Jul 24, 2026
Merged via the queue into thunder-id:main with commit 20f85d6 Jul 24, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes Type/Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Layout import does not honor the id specified in the YAML

2 participants