Skip to content

feat: instance contextual layout fetching#1544

Open
Jondyr wants to merge 16 commits intomainfrom
feat/instance-contextual-layout-fetching
Open

feat: instance contextual layout fetching#1544
Jondyr wants to merge 16 commits intomainfrom
feat/instance-contextual-layout-fetching

Conversation

@Jondyr
Copy link
Member

@Jondyr Jondyr commented Oct 29, 2025

Description

Related PR: Altinn/app-frontend-react#3818

Adds new service ICustomLayoutForInstance, and endpoint in ResourcesController.
When used together with the featureFlag AddInstanceIdentifierToLayoutRequests, the frontend uses this new endpoint to fetch layouts. If the app implements ICustomLayoutForInstance this service is called instead of IAppResources, giving access to instance information when returning layouts.

Related Issue(s)

  • #{issue number}

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing done (required)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)
  • All tests run green

Documentation

  • User documentation is updated with a separate linked PR in altinn-studio-docs. (if applicable)

Summary by CodeRabbit

  • New Features

    • Two instance-context API endpoints to fetch layouts and layout settings; apps can provide per-instance overrides or fall back to defaults.
    • Frontend metadata exposes a feature flag to toggle instance-aware layout requests.
    • Public contract added so apps can implement per-instance layout providers.
  • Tests

    • Added tests covering behavior with and without an instance-specific layout provider; updated OpenAPI and metadata snapshots.
  • Bug Fixes

    • Improved null-handling for data element identifiers and related PDF filename logic.

✏️ Tip: You can customize this high-level summary in your review settings.

@Jondyr Jondyr changed the title Feat/instance contextual layout fetching feat: instance contextual layout fetching Oct 29, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 29, 2025

Warning

Rate limit exceeded

@bjorntore has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 5 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📝 Walkthrough

Walkthrough

Adds a frontend feature flag, a new app-implementable interface for per-instance layouts, two instance-scoped layout endpoints in ResourceController wired via AppImplementationFactory, changes to data identifier null-handling and PDF filename logic, and accompanying tests, OpenAPI and metadata snapshot updates.

Changes

Cohort / File(s) Summary
Feature flags
src/Altinn.App.Core/Features/FeatureFlags.cs
Added public constant AddInstanceIdentifierToLayoutRequests.
Frontend features
src/Altinn.App.Core/Internal/App/FrontendFeatures.cs, test/Altinn.App.Core.Tests/Internal/App/FrontendFeaturesTest.cs
Runtime evaluation of AddInstanceIdentifierToLayoutRequests and exposure as addInstanceIdentifierToLayoutRequests in frontend features; tests updated to cover enabled/disabled cases.
Per-instance layout interface
src/Altinn.App.Core/Internal/App/ICustomLayoutForInstance.cs
New [ImplementableByApps] interface ICustomLayoutForInstance with Task<string?> GetCustomLayoutForInstance(string, int, Guid) and Task<string?> GetCustomLayoutSettingsForInstance(string, int, Guid).
Resource controller
src/Altinn.App.Api/Controllers/ResourceController.cs
Constructor updated to accept IServiceProvider, initialize AppImplementationFactory; added GetInstanceLayouts(...) and GetInstanceLayoutSettings(...) endpoints that prefer ICustomLayoutForInstance and fall back to IAppResources (parses instanceId to GUID).
OpenAPI / public API & metadata snapshots
test/Altinn.App.Api.Tests/OpenApi/...SaveJsonSwagger.verified.json, test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt, test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt, test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/*, test/Altinn.App.Integration.Tests/PartyTypesAllowed/_snapshots/*
Added two instance-scoped GET paths for layouts and layoutsettings; updated public API snapshots for constructor signature, new endpoints, interface and constant; metadata snapshots updated with required-scope entries.
Data identifier null-handling
src/Altinn.App.Core/Models/DataElementIdentifier.cs, test/Altinn.App.Core.Tests/Models/DataElementIdentifierTests.cs
Implicit conversions changed: non-nullable conversion now throws on null; nullable conversion returns null; added comprehensive unit tests covering conversions, equality, and string representation.
PDF filename / subform handling
src/Altinn.App.Core/Internal/Pdf/PdfService.cs
Adjusted DataElementIdentifier assignment for subform handling to use explicit nullable DataElementIdentifier? instead of default instance when subformDataElementId is null.
Resource controller tests
test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
New test class with a sample ICustomLayoutForInstance implementation and four tests covering presence/absence of the service for both new endpoints.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.59% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: instance contextual layout fetching' accurately describes the main change: adding support for instance-aware layout retrieval via new endpoints and ICustomLayoutForInstance interface.

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

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/instance-contextual-layout-fetching

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 and usage tips.

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 03c5d90 to 1f10c35 Compare October 30, 2025 06:39
@Jondyr Jondyr added feature Label Pull requests with new features. Used when generation releasenotes backport-ignore This PR is a new feature and should not be cherry-picked onto release branches squad/utforming Issues that belongs to the named squad. labels Oct 30, 2025
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch 2 times, most recently from e8df578 to e56150a Compare October 30, 2025 07:14
@Jondyr Jondyr linked an issue Oct 30, 2025 that may be closed by this pull request
4 tasks
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch 2 times, most recently from 21399d0 to 3dffd17 Compare November 6, 2025 10:24
Copy link
Member

@ivarne ivarne left a comment

Choose a reason for hiding this comment

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

Siden dette er en applikasjons konfigurasjon for frontend, så ville jeg droppet FeatureManager og heller bare bedt brukerene gå direkte til appsettings.json og legge til "FrontendSettings": {"AddInstanceIdentifierToLayoutRequests": true} uten at det krever noe videre konfigurasjon i backend.

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 3dffd17 to 271ca38 Compare November 10, 2025 08:23
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from f307242 to 301807c Compare November 10, 2025 10:17
@Jondyr Jondyr moved this to 👷 In progress in Team Altinn Studio Nov 10, 2025
@Jondyr Jondyr self-assigned this Nov 10, 2025
@Jondyr Jondyr added the squad/data Issues that belongs to the named squad. label Nov 10, 2025
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 69d0c68 to 733ec02 Compare November 10, 2025 11:53
@Jondyr Jondyr moved this from 👷 In progress to 🔎 In review in Team Altinn Studio Nov 10, 2025
@Jondyr Jondyr removed their assignment Nov 10, 2025
@Jondyr Jondyr marked this pull request as ready for review November 10, 2025 12:36
@Jondyr
Copy link
Member Author

Jondyr commented Dec 16, 2025

/publish

@github-actions
Copy link

github-actions bot commented Dec 16, 2025

PR release:

⚙️ Building...
✅ Done!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (2)
src/Altinn.App.Api/Controllers/ResourceController.cs (2)

99-111: Unaddressed issues: Missing Guid validation and null-fallback logic.

Two issues from previous reviews remain unaddressed:

  1. Guid.Parse(instanceId) at line 105 throws FormatException on invalid input, resulting in a 500 instead of 400.
  2. When customLayoutService.GetCustomLayoutForInstance returns null (indicating "use default"), the code returns Ok(customLayout) with a null body instead of falling through to the fallback.

Apply this diff:

+        if (!Guid.TryParse(instanceId, out var instanceGuid))
+        {
+            return BadRequest("Invalid instanceId format");
+        }
+
         ICustomLayoutForInstance? customLayoutService = _appImplementationFactory.Get<ICustomLayoutForInstance>();
         if (customLayoutService is not null)
         {
             string? customLayout = await customLayoutService.GetCustomLayoutForInstance(
                 layoutSetId,
                 instanceOwnerPartyId,
-                Guid.Parse(instanceId)
+                instanceGuid
             );
-            return Ok(customLayout);
+            if (!string.IsNullOrEmpty(customLayout))
+            {
+                return Ok(customLayout);
+            }
         }
         string layouts = _appResourceService.GetLayoutsForSet(layoutSetId);
         return Ok(layouts);

149-161: Same issues present in GetInstanceLayoutSettings.

The same two issues exist here: unsafe Guid.Parse at line 155 and missing null-fallback logic at line 157.

Apply this diff:

+        if (!Guid.TryParse(instanceId, out var instanceGuid))
+        {
+            return BadRequest("Invalid instanceId format");
+        }
+
         ICustomLayoutForInstance? customLayoutService = _appImplementationFactory.Get<ICustomLayoutForInstance>();
         if (customLayoutService is not null)
         {
             string? customLayoutSettings = await customLayoutService.GetCustomLayoutSettingsForInstance(
                 layoutSetId,
                 instanceOwnerPartyId,
-                Guid.Parse(instanceId)
+                instanceGuid
             );
-            return Ok(customLayoutSettings);
+            if (!string.IsNullOrEmpty(customLayoutSettings))
+            {
+                return Ok(customLayoutSettings);
+            }
         }
         string? settings = _appResourceService.GetLayoutSettingsStringForSet(layoutSetId);
         return Ok(settings);
🧹 Nitpick comments (1)
test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs (1)

16-31: Test helper implementation is simple and effective.

The CustomLayoutForInstance class provides a straightforward test double. Consider making it sealed per coding guidelines for classes that don't need inheritance.

-    private class CustomLayoutForInstance : ICustomLayoutForInstance
+    private sealed class CustomLayoutForInstance : ICustomLayoutForInstance
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3265bc4 and 1b4246a.

📒 Files selected for processing (6)
  • src/Altinn.App.Api/Controllers/ResourceController.cs (4 hunks)
  • src/Altinn.App.Core/Internal/App/ICustomLayoutForInstance.cs (1 hunks)
  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs (1 hunks)
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2 hunks)
  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1 hunks)
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Altinn.App.Core/Internal/App/ICustomLayoutForInstance.cs
  • test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: Use CSharpier for code formatting (required before commits). Formatting happens automatically when building due to CSharpier.MSBuild
Use internal accessibility on types by default
Use sealed for classes unless inheritance is considered a valid use-case
Use Nullable Reference Types in C#
Remember to dispose IDisposable/IAsyncDisposable instances
For HTTP APIs, define ...Request and ...Response DTOs (e.g., LookupPersonRequest.cs and corresponding response)
Types meant to be implemented by apps should be marked with the ImplementableByApps attribute
Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task
Don't use Async suffix for async methods
Write efficient code: Don't allocate unnecessarily (e.g., avoid calling ToString twice in a row, store in a variable; sometimes a for loop is better than LINQ)
Don't invoke the same async operation multiple times in the same codepath unless necessary
Don't await async operations in a loop (prefer batching, but maintain an upper bound on parallelism that makes sense)
Use strongly-typed configuration classes instead of untyped configuration
Register services in DI container properly following existing patterns

Files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
**/test/**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/test/**/*.cs: Prefer xUnit asserts over FluentAssertions in tests
Mock external dependencies with Moq in tests

Files:

  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
🧠 Learnings (13)
📓 Common learnings
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: New features should follow the established pattern in /src/Altinn.App.Core/Features/ with feature-specific folders, DI registration, telemetry, and test coverage

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-25T08:15:25.624Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:3656-3671
Timestamp: 2025-09-25T08:15:25.624Z
Learning: In PR Altinn/app-lib-dotnet#745, the team decided to defer adding idempotency documentation, enriched ServiceTaskFailedResult (code/title/message), and additional OTel spans for service tasks. Do not re-suggest these changes within this PR; propose a follow-up issue instead if needed.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn.App.Integration.Tests project, xUnit attributes like [Fact] are available without explicit "using Xunit;" directives, likely through global usings or implicit usings configuration. The code compiles and works as-is.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T10:45:57.158Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/Tests.cs:3-4
Timestamp: 2025-08-29T10:45:57.158Z
Learning: In Altinn app-lib-dotnet projects, ImplicitUsings is enabled in Directory.Build.props, which automatically includes common using statements including Xunit namespace for test projects. This eliminates the need for explicit "using Xunit;" statements in test files.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
📚 Learning: 2025-09-29T08:34:53.864Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 745
File: src/Altinn.App.Core/EFormidling/Interface/IEFormidlingService.cs:18-30
Timestamp: 2025-09-29T08:34:53.864Z
Learning: Altinn.App.Core project targets net8.0, not netstandard2.0, which fully supports default interface methods.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
📚 Learning: 2025-10-17T07:45:15.474Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1474
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:233-237
Timestamp: 2025-10-17T07:45:15.474Z
Learning: In Altinn/app-lib-dotnet, maintainers accept source compatibility without guaranteeing binary compatibility across versions because consumers upgrade via NuGet and rebuild. Adding optional parameters to public extension methods (e.g., CancellationToken) is acceptable provided release notes document the change.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T09:04:43.977Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: src/Altinn.App.Core/Features/IInstanceDataAccessor.cs:36-41
Timestamp: 2025-09-21T09:04:43.977Z
Learning: The IInstanceDataAccessor interface in Altinn.App.Core is designed for consumption only - users are not expected to implement this interface themselves, only use framework-provided implementations.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-07T20:03:48.030Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1463
File: test/Altinn.App.SourceGenerator.Tests/DiagnosticTests.RunJsonError.verified.txt:1-21
Timestamp: 2025-09-07T20:03:48.030Z
Learning: In Altinn.App.SourceGenerator.Tests, the path C:\temp\config\applicationmetadata.json is a hardcoded test fixture path required by Roslyn and is used consistently across all operating systems, not an actual filesystem path that varies by OS.

Applied to files:

  • src/Altinn.App.Api/Controllers/ResourceController.cs
📚 Learning: 2025-11-28T08:07:52.106Z
Learnt from: CR
Repo: Altinn/app-lib-dotnet PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T08:07:52.106Z
Learning: Applies to **/test/**/*.cs : Prefer xUnit asserts over FluentAssertions in tests

Applied to files:

  • test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs
📚 Learning: 2025-08-22T13:46:43.017Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Full_auth=ServiceOwner_testCase=MultipartXmlPrefill_7_Logs.verified.txt:41-42
Timestamp: 2025-08-22T13:46:43.017Z
Learning: In Altinn App Integration Tests, OldUser and OldServiceOwner test snapshots intentionally preserve the legacy "AuthMethod: localtest" authentication method as part of a migration strategy, while new User and ServiceOwner tests use updated authentication methods like BankID and maskinporten. The "Old*" variants should not be updated to remove localtest references.

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-09-21T08:19:43.290Z
Learnt from: ivarne
Repo: Altinn/app-lib-dotnet PR: 1473
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:1414-1414
Timestamp: 2025-09-21T08:19:43.290Z
Learning: In Altinn/app-lib-dotnet, *.verified.txt files (e.g., test/**/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt) are verification snapshots for guarding public API. Do not generate review suggestions based on these files; ignore them when assessing code changes.

Applied to files:

  • test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
  • test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (2)
src/Altinn.App.Api/Controllers/ResourceController.cs (3)
src/Altinn.App.Api/Controllers/EventsReceiverController.cs (1)
  • Route (12-86)
src/Altinn.App.Core/Internal/App/ICustomLayoutForInstance.cs (2)
  • Task (17-17)
  • Task (25-25)
src/Altinn.App.Core/Interface/IAppResources.cs (4)
  • Task (38-38)
  • Task (135-135)
  • GetLayoutsForSet (152-152)
  • GetLayoutSettingsStringForSet (165-165)
test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs (2)
src/Altinn.App.Core/Internal/App/ICustomLayoutForInstance.cs (2)
  • Task (17-17)
  • Task (25-25)
test/Altinn.App.Api.Tests/Data/TestData.cs (1)
  • PrepareInstance (147-174)
🔇 Additional comments (5)
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (2)

1151-1155: Public API snapshot – no action here

This file is a generated public API snapshot used by PublicApiTests. The added AddInstanceIdentifierToLayoutRequests constant is correctly captured, and no manual changes or review actions are needed in this snapshot itself. Any design review should target the actual FeatureFlags source file instead.


2937-2941: Public API snapshot for ICustomLayoutForInstance – review in source, not snapshot

These lines just record the new ICustomLayoutForInstance interface in the public API snapshot. Per project guidelines, this file should not be edited directly or used as the basis for API design feedback; review and changes belong in the corresponding source interface file.

src/Altinn.App.Api/Controllers/ResourceController.cs (1)

1-26: Constructor and field additions look good.

The injection of IServiceProvider and resolution of AppImplementationFactory follows the established pattern seen in other controllers like EventsReceiverController. This is the correct approach for obtaining app-specific implementations.

test/Altinn.App.Api.Tests/Controllers/ResourceController_CustomLayoutTests.cs (2)

33-83: Good test coverage for both custom service and fallback paths.

The tests properly verify:

  • Custom service returns the expected value when registered
  • Fallback to IAppResources returns valid JSON structure when no custom service exists

Using xUnit asserts as per coding guidelines.


85-130: Layout settings tests look good.

Tests appropriately cover both the custom service path and the fallback path for layout settings.

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 1b4246a to 9fb5195 Compare December 17, 2025 10:45
@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from 9fb5195 to 0bfe1ba Compare December 17, 2025 10:54
@JamalAlabdullah JamalAlabdullah moved this from 🔎 In review to 🧪 Test in Team Altinn Studio Dec 18, 2025
@JamalAlabdullah JamalAlabdullah self-assigned this Dec 18, 2025
Copy link

@JamalAlabdullah JamalAlabdullah left a comment

Choose a reason for hiding this comment

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

👍

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from b443d20 to 668ffdc Compare January 16, 2026 09:13
@Jondyr Jondyr enabled auto-merge (squash) January 16, 2026 09:44
@Jondyr
Copy link
Member Author

Jondyr commented Jan 28, 2026

/publish

@github-actions
Copy link

github-actions bot commented Jan 28, 2026

PR release:

⚙️ Building...
✅ Done!

@Jondyr Jondyr force-pushed the feat/instance-contextual-layout-fetching branch from ca5dfe8 to 33b9d3f Compare January 29, 2026 08:32
@Jondyr
Copy link
Member Author

Jondyr commented Jan 29, 2026

/publish

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

PR release:

⚙️ Building...
✅ Done!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/Altinn.App.Core/Features/FeatureFlags.cs`:
- Around line 16-21: The XML summary for the public constant
AddInstanceIdentifierToLayoutRequests contains a TODO; replace it with a
concise, concrete summary describing the flag's behavior (e.g., that enabling
this feature changes the backend layout endpoint to include the instance
identifier in requests), update the <summary> tag text accordingly so generated
API docs are complete, and ensure wording is clear and present-tense without
TODO markers.
🧹 Nitpick comments (2)
src/Altinn.App.Api/Controllers/ResourceController.cs (2)

22-25: Consider injecting AppImplementationFactory directly.

Using IServiceProvider.GetRequiredService<T>() in the constructor is a service locator pattern. Prefer direct constructor injection for better testability and clearer dependencies.

♻️ Proposed refactor
-    /// <param name="serviceProvider">The service provider</param>
-    public ResourceController(IAppResources appResourcesService, IServiceProvider serviceProvider)
+    /// <param name="appImplementationFactory">The app implementation factory</param>
+    public ResourceController(IAppResources appResourcesService, AppImplementationFactory appImplementationFactory)
     {
         _appResourceService = appResourcesService;
-        _appImplementationFactory = serviceProvider.GetRequiredService<AppImplementationFactory>();
+        _appImplementationFactory = appImplementationFactory;
     }

90-90: Consider adding GUID route constraint for consistency and early validation.

The route uses {instanceId} as a string, but existing instance endpoints in this codebase use {instanceGuid:guid} with a GUID constraint. Adding the constraint would reject invalid GUIDs at the routing level (returning 404) and maintain consistency with other instance-scoped endpoints.

♻️ Proposed change
-    [Route("{org}/{app}/instances/{instanceOwnerPartyId:int}/{instanceId}/layouts/{layoutSetId}")]
+    [Route("{org}/{app}/instances/{instanceOwnerPartyId:int}/{instanceGuid:guid}/layouts/{layoutSetId}")]

Note: This would also require renaming the parameter in the method signature from instanceId to instanceGuid and updating the XML documentation accordingly.

Comment on lines +16 to +21
// TODO: write a better summary here
/// <summary>
/// Enabling this feature changes backend endpoint used for layouts to
/// add instance identifier.
/// </summary>
public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Replace the TODO with a concrete summary before release.

Leaving a TODO in a public API constant’s XML doc makes the documentation incomplete and leaks into generated docs.

📝 Suggested update
-    // TODO: write a better summary here
-    /// <summary>
-    /// Enabling this feature changes backend endpoint used for layouts to
-    /// add instance identifier.
-    /// </summary>
+    /// <summary>
+    /// When enabled, layout fetches use instance-scoped endpoints so layout requests
+    /// include the instance identifier.
+    /// </summary>
     public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// TODO: write a better summary here
/// <summary>
/// Enabling this feature changes backend endpoint used for layouts to
/// add instance identifier.
/// </summary>
public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests";
/// <summary>
/// When enabled, layout fetches use instance-scoped endpoints so layout requests
/// include the instance identifier.
/// </summary>
public const string AddInstanceIdentifierToLayoutRequests = "AddInstanceIdentifierToLayoutRequests";
🤖 Prompt for AI Agents
In `@src/Altinn.App.Core/Features/FeatureFlags.cs` around lines 16 - 21, The XML
summary for the public constant AddInstanceIdentifierToLayoutRequests contains a
TODO; replace it with a concise, concrete summary describing the flag's behavior
(e.g., that enabling this feature changes the backend layout endpoint to include
the instance identifier in requests), update the <summary> tag text accordingly
so generated API docs are complete, and ensure wording is clear and
present-tense without TODO markers.

@bjorntore
Copy link
Contributor

/publish

@github-actions
Copy link

github-actions bot commented Jan 29, 2026

PR release:

⚙️ Building...
✅ Done!

@sonarqubecloud
Copy link

@Jondyr Jondyr moved this from 🧪 Test to ⚠️ Blocked in Team Altinn Studio Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-ignore This PR is a new feature and should not be cherry-picked onto release branches feature Label Pull requests with new features. Used when generation releasenotes squad/data Issues that belongs to the named squad. squad/utforming Issues that belongs to the named squad.

Projects

Status: ⚠️ Blocked

Development

Successfully merging this pull request may close these issues.

Add Instance contextual layout fetching/resource interface

4 participants