-
Notifications
You must be signed in to change notification settings - Fork 24
Get library code lists directly without configuring provider and option id #1593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughAdds ADR and implements direct Altinn 3 library code-list support: new API client, service, provider, DI registrations, controller routing to accept library references, AppOption.tags model, OpenAPI updates, and extensive test additions/adjustments. No unrelated public signatures removed aside from options-related nullable changes. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
…s://github.com/Altinn/app-lib-dotnet into feature/new-way-of-fetching-library-code-lists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)
30-35: Breaking change: Instance options now nullable.The return type changed from
Task<AppOptions>toTask<AppOptions?>for the instance-based overload. This breaking change aligns with the implementation where no instance-specific provider may be available, but requires consumers to handle null results.According to retrieved learnings, the team accepts source compatibility without guaranteeing binary compatibility. Ensure this API change is documented in release notes with guidance on handling null returns.
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
3220-3265: Align options endpoint OpenAPI contract with described optionality of code list parametersFor the new route
/{org}/{app}/api/options/{optionsIdOrCreatorOrg}/{codeListId}/{version}the OpenAPI snapshot marks bothcodeListIdandversionasrequired: true, but their descriptions imply conditional/optional usage:
codeListId: “Code list id, required if creatorOrg is provided”version: “Code list version … defaults to latest if not provided”Because these are path parameters on a single route template, OpenAPI (and generated clients) will treat them as always required; there is no way for a client to “not provide” them while still hitting this path. That makes the descriptions misleading.
Consider updating the controller/attribute definitions so that, after regeneration:
- Either the descriptions clearly state that both
codeListIdandversionare always required for this endpoint, or- The routing is split (e.g., separate route for legacy
optionsIdvs library code lists, or moveversionto an optional query parameter) so the OpenAPIrequiredflags and descriptions are consistent.Also check that the “creatorOrg” terminology in the descriptions matches the actual route parameter name
optionsIdOrCreatorOrgto avoid confusion for API consumers.Also applies to: 3267-3272
🧹 Nitpick comments (8)
test/Altinn.App.Api.Tests/Program.cs (1)
49-49: Typo fix in comment.Spelling correction from "Allways" to "Always" — good catch.
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
3-3: Rename looks good; consider tightening visibility/sealing this test helperThe rename of the handler and its constructor to
Altinn3LibraryCodeListClientMessageHandlerMockmatches the new Altinn 3 code-list client naming and doesn’t change behavior. If this type is only consumed from within the test assembly and not via reflection, you could optionally align with the general guidelines by making itinternal sealed:-public class Altinn3LibraryCodeListClientMessageHandlerMock : DelegatingHandler +internal sealed class Altinn3LibraryCodeListClientMessageHandlerMock : DelegatingHandlerAlso applies to: 12-12
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
21-21: Consider making timeout configurable.The 30-second timeout is hardcoded. For better flexibility, especially in testing or environments with varying network conditions, consider making this configurable through
PlatformSettings.src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)
1-1: Consider removing unused using directive.The using directive for
Altinn3LibraryProvideris added but doesn't appear to be used in this interface file. Consider removing it unless it's needed for future changes or XML documentation references.-using Altinn.App.Core.Features.Options.Altinn3LibraryProvider; using Altinn.App.Core.Models;src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
5-5: Consider addingsealedmodifier.Per coding guidelines, classes should be sealed unless inheritance is a valid use-case. Since this is an internal implementation detail, sealing it would be appropriate.
-internal class Altinn3LibraryOptionsProvider : IAppOptionsProvider +internal sealed class Altinn3LibraryOptionsProvider : IAppOptionsProvidersrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
10-17: Consider addingCancellationTokenparameter.For async methods that may involve network calls (on cache miss), accepting a
CancellationTokenenables callers to cancel long-running requests. Based on learnings, adding optional parameters is acceptable in this codebase.-Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(string org, string codeListId, string? version); +Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync(string org, string codeListId, string? version, CancellationToken cancellationToken = default);src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
11-11: Consider making the classinternal sealed.Per coding guidelines, types should use
internalaccessibility by default, and classes should besealedunless inheritance is a valid use-case. Since this service is resolved via DI through its interface, it doesn't need to be public.-public class Altinn3LibraryCodeListService : IAltinn3LibraryCodeListService +internal sealed class Altinn3LibraryCodeListService : IAltinn3LibraryCodeListService
34-54: Consider acceptingCancellationTokenparameter.The method delegates to
HybridCache.GetOrCreateAsyncwhich provides aCancellationTokento the factory, but callers cannot cancel the overall operation. Consider adding aCancellationTokenparameter:public async Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync( string org, string codeListId, - string? version + string? version, + CancellationToken cancellationToken = default ) { version = !string.IsNullOrEmpty(version) ? version : "latest"; var result = await _hybridCache.GetOrCreateAsync( $"Altinn3Library:{org}-{codeListId}-{version}", async ct => await _altinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeLists( org, codeListId, version, ct ), - options: _defaultCacheExpiration + options: _defaultCacheExpiration, + cancellationToken: cancellationToken ); return result; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (35)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(3 hunks)src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs(2 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs(2 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs(2 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs(2 hunks)src/Altinn.App.Core/Features/Options/AppOptionsService.cs(3 hunks)src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs(1 hunks)src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs(1 hunks)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs(2 hunks)src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs(2 hunks)src/Altinn.App.Core/Features/Options/NullInstanceAppOptionsProvider.cs(0 hunks)src/Altinn.App.Core/Models/AppOption.cs(5 hunks)src/Altinn.App.Core/Models/AppOptions.cs(1 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Api.Tests/Data/apps/tdd/eformidling-app/ui/layouts/FormLayout.json(1 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(2 hunks)test/Altinn.App.Api.Tests/Program.cs(1 hunks)test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs(2 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderCacheTests.cs(0 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTestData.cs(0 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTests.cs(0 hunks)test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs(5 hunks)test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs(2 hunks)test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs(2 hunks)test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs(0 hunks)test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(5 hunks)
💤 Files with no reviewable changes (5)
- test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderCacheTests.cs
- src/Altinn.App.Core/Features/Options/NullInstanceAppOptionsProvider.cs
- test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTests.cs
- test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProviderTestData.cs
- test/Altinn.App.Core.Tests/Features/Options/NullInstanceAppOptionsProviderTests.cs
🧰 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.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cstest/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cssrc/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cssrc/Altinn.App.Core/Models/AppOption.cstest/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cssrc/Altinn.App.Core/Models/AppOptions.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Core/Features/Options/AppOptionsService.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/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
🧠 Learnings (20)
📓 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.
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.
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
📚 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.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cstest/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cssrc/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cssrc/Altinn.App.Core/Models/AppOption.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsondoc/adr/006-altinn-3-code-list.mdsrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cssrc/Altinn.App.Core/Models/AppOptions.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.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/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/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:
test/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/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/Program.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.
Applied to files:
test/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.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: 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:
test/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/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:
test/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 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:
test/Altinn.App.Api.Tests/Program.cstest/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.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:
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Api/Controllers/OptionsController.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:
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Api/Controllers/OptionsController.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.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.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 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.Core/Features/Options/IAppOptionsService.csdoc/adr/006-altinn-3-code-list.mdtest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/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.Core/Features/Options/IAppOptionsService.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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 **/*.cs : Register services in DI container properly following existing patterns
Applied to files:
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.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: Follow the AppFixture pattern for integration tests: Central orchestrator managing test lifecycle with feature-specific operations
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (13)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(60-61)
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (2)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(60-61)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
Altinn3LibraryCodeListApiClient(9-61)Altinn3LibraryCodeListApiClient(14-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (3)
Altinn3LibraryCodeListResponse(8-34)Altinn3LibraryCodeListItem(51-83)Altinn3LibraryCodeListSource(39-46)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
AppOptions(57-93)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
AppOptions(230-255)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
Func(9-20)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
PlatformSettings(7-74)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(5-10)src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
JsonSerializerPermissive(10-48)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (3)
Task(34-54)Altinn3LibraryCodeListService(11-124)Altinn3LibraryCodeListService(24-31)src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
PlatformSettings(7-74)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-54)AppOptions(57-93)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(17-17)AppOptions(25-25)src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
Task(30-44)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListItem(51-83)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(60-61)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
Altinn3LibraryCodeListApiClient(9-61)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Altinn3LibraryCodeListService(11-124)Altinn3LibraryCodeListService(24-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (7)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(60-61)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
Task(33-37)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
Task(17-25)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-54)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
Task(26-60)Altinn3LibraryCodeListApiClient(9-61)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(5-10)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListServiceTestData(7-61)Func(9-20)
src/Altinn.App.Api/Controllers/OptionsController.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-54)AppOptions(57-93)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(17-17)AppOptions(25-25)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...
(DAT)
[grammar] ~10-~10: Ensure spelling is correct
Context: ... ## Result * Not concluded ## Problem context We want to be able to get code lists thr...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~26-~26: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~34-~34: Ensure spelling is correct
Context: ...list as root * B2: Simplify application layout * B3: Keep complexity low for developers *...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~36-~36: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B5: Avoid the need to distinguish betwee...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~37-~37: Ensure spelling is correct
Context: ...guish between "secure": true/false in frontend * B6: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~40-~40: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[style] ~76-~76: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...
(ETC_PERIOD)
[grammar] ~99-~99: Ensure spelling is correct
Context: ...odeListId) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~110-~110: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ## Decision rationale
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~112-~112: Ensure spelling is correct
Context: ...ormat optionsId should be. ## Decision rationale
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (43)
test/Altinn.App.Api.Tests/Data/apps/tdd/eformidling-app/ui/layouts/FormLayout.json (1)
27-27: Test fixture formatting—trivial change.Adding the end-of-file newline is a standard formatting practice for text files and carries no functional impact on this test data file.
test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs (2)
24-24: LGTM: Nullable return handling.The change from
BeOfType<NullInstanceAppOptionsProvider>()toBe(null)correctly reflects the refactored behavior whereGetOptionsProvidernow returnsnullinstead of a null-object pattern implementation when no provider matches.
57-59: LGTM: Modern syntax.Using target-typed
new()expressions is idiomatic C# 9+ and improves readability.src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (1)
13-14: LGTM: Improved documentation clarity.The updated XML documentation better describes the provider's purpose and the relationship between the
Idproperty and the JSON filename convention.Also applies to: 22-22
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (4)
21-21: LGTM: Cleaner DI registration.Using the non-generic
AddSingletonoverload is cleaner when you already have the instance.
34-34: LGTM: Simplified test setup.Removing explicit
DefaultAppOptionsProviderregistration allows the tests to rely on the factory's default behavior, making them less brittle and more aligned with production usage.Also applies to: 46-46
62-62: LGTM: More meaningful test case.Changing the test to use
"default"makes the test more explicit about verifying that the factory throws when the default provider is requested but not available.
125-126: LGTM: Modern syntax.Target-typed
new()expressions improve readability and follow C# 9+ conventions.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
33-33: LGTM: Improved DTO robustness with proper null handling.Making
TagNamesandTagsnullable is appropriate since these are optional grouping metadata that may not be present in all code-list responses. The consuming code inMapAppOptionscorrectly guards all property accesses with explicit null checks (is not null), and comprehensive test coverage validates all null scenarios including mismatches betweenTagNamescount andTagscount.test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (8)
1670-1670: LGTM: Tags made nullable on Altinn3LibraryCodeListItem.Change aligns with optional tag presence from library. No action.
Based on learnings, snapshot files are verification artifacts.
1682-1682: LGTM: TagNames made nullable on Altinn3LibraryCodeListResponse.Consistent with optional tag taxonomy.
Based on learnings, snapshot files are verification artifacts.
1686-1691: New public service surface for Altinn3 library code lists — confirm public exposure is intentional.Interfaces and service added; ensure DI and release notes cover new APIs.
Based on learnings, snapshot files are verification artifacts.
1724-1724: Return type changed to AppOptions? — confirm nullable flow and docs.Ensure all callers handle null and add a release-note entry since public API behavior changed.
Based on learnings, source compatibility changes are acceptable when documented.
1748-1749: IAppOptionsService now returns AppOptions? for instance overload — verify callers and release notes.Please confirm null-handling at call sites and document in the changelog.
Based on learnings, source compatibility changes are acceptable when documented.
4056-4058: LGTM: AppOption gains nullable Tags with correct JSON behavior.Omit-on-null is appropriate; no compatibility risk.
Based on learnings, snapshot files are verification artifacts.
1753-1754: Null handling already properly implemented — no action required.The change to nullable return type in
InstanceAppOptionsFactory.GetOptionsProvider()is already handled in the codebase. InAppOptionsService.cs, the only production usage includes a null check:if (appOptionsProvider != null)before dereferencing. No downstream issues found.Likely an incorrect or invalid review comment.
1698-1706: Parameter nullability inconsistency between similar interface methods.In the snapshot,
IAltinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeListsdeclaresstring version = nullwhileIAltinn3LibraryCodeListService.GetCachedCodeListResponseAsyncdeclaresstring? version. For consistency within the public API surface, both should use the same nullability annotation. If the parameter is intended to accept null, usestring? version = nullin both.src/Altinn.App.Core/Models/AppOptions.cs (1)
18-18: LGTM! Target-typed new expression.The change to use
new()instead ofnew Dictionary<string, string?>()is a concise modernization that reduces verbosity while maintaining the same behavior.src/Altinn.App.Core/Models/AppOption.cs (3)
46-52: LGTM! Tags property properly defined.The Tags property is correctly defined with nullable type, appropriate JSON attributes, and clear documentation explaining its purpose for grouping with tagNames from library code lists.
94-134: LGTM! Tags deserialization correctly implemented.The JSON converter properly handles the Tags property during deserialization with appropriate null handling and case-insensitive property matching.
211-215: LGTM! Tags serialization correctly implemented.The serialization logic properly checks for null before writing the Tags property, consistent with the pattern used for other optional properties.
test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs (1)
57-62: LGTM! Test infrastructure updated for library code-list support.The additions register the necessary services (IAltinn3LibraryCodeListApiClient and HybridCache) to support the new Altinn 3 library code-list integration path in tests. This aligns with the broader architectural changes in the PR.
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)
340-343: LGTM! DI registrations follow established patterns.The registrations for Altinn 3 library code-list services are correctly placed in the AddAppOptions method and follow the established DI patterns in this codebase:
- Uses
AddHttpClientfor the API client to leverage HttpClientFactory- Uses
TryAddTransientfor the service to allow app-level overrides- Properly scoped within the options configuration section
src/Altinn.App.Core/Features/Options/AppOptionsService.cs (2)
10-10: LGTM! Typo fix.Corrected the field name from
_appOpptionsFactoryto_appOptionsFactory, fixing a spelling error.Also applies to: 23-23
40-55: The instance-based GetOptionsAsync method returns AppOptions? by design, not as a breaking change.This method overload was already designed to return null when no instance-specific options provider is found (line 54). The nullable return type is intentional and consistent across the interface and implementation. The existing caller in OptionsController already handles this correctly using the null-conditional operator (
appOptions?.Options). No action is required.Likely an incorrect or invalid review comment.
src/Altinn.App.Core/Features/Options/InstanceAppOptionsFactory.cs (1)
26-40: The claim about removing NullInstanceAppOptionsProvider is incorrect. NullInstanceAppOptionsProvider does not exist in the codebase and never did. The nullable return typeIInstanceAppOptionsProvider?appears to be the intended design, not a recent breaking change. Tests explicitly validate thatGetOptionsProvider()returnsnullwhen no matching provider is found, confirming this is the expected behavior. Note thatAppOptionsFactory.GetOptionsProvider()(a different class) returns non-nullable and provides aDefaultAppOptionsProviderfallback, whileInstanceAppOptionsFactoryis designed to return nullable by comparison.Likely an incorrect or invalid review comment.
src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs (1)
93-100: Clean refactor using the new service abstraction.The DI simplification from multiple infrastructure dependencies to a single
IAltinn3LibraryCodeListServiceis appropriate and follows the Single Responsibility Principle. This aligns with the feature pattern guidance for DI registration.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
33-37: Clean delegation to the code list service.The implementation correctly delegates to the service for both fetching cached data and mapping to
AppOptions. The unusedkeyValuePairsparameter is inherited from theIAppOptionsProviderinterface contract.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
5-26: Well-designed interface with clear responsibilities.The separation between
GetCachedCodeListResponseAsync(data fetching with caching) andMapAppOptions(transformation) follows single responsibility principle and makes testing easier.test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
34-38: Good migration to xUnit asserts.The assertion style now follows coding guidelines (preferring xUnit asserts over FluentAssertions).
170-198: Good test coverage for the new library code list path.The test properly exercises the direct library code list retrieval path, validating both the response headers (
Altinn-DownstreamParameters) and the JSON payload structure including tags support.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
57-93: LGTM!The mapping logic correctly handles the tag dictionary creation with proper count validation, applies language fallback for localized fields, and properly populates the
AppOptionsresponse with metadata parameters.
100-123: LGTM!The language fallback logic is well-designed with a clear priority chain (requested → Nb → En → alphabetical first), and the
[return: NotNullIfNotNull]attribute properly communicates nullability to callers.test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
11-27: Test structure looks good.The test follows proper AAA pattern and uses xUnit asserts as per coding guidelines.
src/Altinn.App.Api/Controllers/OptionsController.cs (3)
62-81: Consider error handling for the library code-list path.When
codeListIdis provided,GetCachedCodeListResponseAsyncmay throw (e.g.,HttpRequestExceptionfor non-200 responses). Unlike the standard options path which returnsNotFound()when options are null, the library path has no error handling—exceptions will propagate as 500 errors.Consider adding try-catch or returning appropriate error responses:
else { using var telemetry = _telemetry?.StartGetOptionsActivity(); + try + { var altinn3LibraryCodeListResponse = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync( optionsIdOrCreatorOrg, codeListId, version ); appOptions = _altinn3LibraryCodeListService.MapAppOptions(altinn3LibraryCodeListResponse, language); + } + catch (HttpRequestException) + { + return NotFound(); + } }Alternatively, this behavior may be intentional to surface upstream errors—please confirm.
30-39: LGTM!Constructor properly injects the new dependencies with appropriate nullability. The optional
Telemetry?parameter follows the established pattern in the codebase.
53-59: Verify backward compatibility of route change.The route changed from
{optionsId}to{optionsIdOrCreatorOrg}/{codeListId?}/{version?}. While the optional segments should maintain compatibility for existing callers, please verify that clients using/{org}/{app}/api/options/{optionsId}continue to work correctly.test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (6)
16-51: LGTM!Good test design verifying that different cache keys result in separate HTTP calls. The use of separate scopes to simulate real-world DI behavior is appropriate.
53-81: LGTM!Correctly verifies that the cache is hit on subsequent calls with identical parameters—only one HTTP call is made despite two invocations.
83-137: LGTM!Good coverage of edge cases for empty and null language collections, correctly verifying the distinction between empty string and null returns.
139-233: LGTM!Comprehensive coverage of language fallback scenarios: alphabetical first when no Nb/En, En fallback when only Nb is missing, and Nb as default. Tests verify the documented fallback chain.
265-407: LGTM!Thorough testing of Tags mapping logic covering:
- No TagNames present → null Tags
- TagNames without Tags → null Tags
- Mismatched counts → null Tags
- Matching counts → properly mapped dictionary
This validates the defensive count-matching logic in
MapAppOptions.
409-429: LGTM!Fixture properly wires up DI with
HybridCache, the mock HTTP handler, and required services. Clean implementation ofIAsyncDisposable.
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
Outdated
Show resolved
Hide resolved
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs
Show resolved
Hide resolved
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
Outdated
Show resolved
Hide resolved
....App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
Show resolved
Hide resolved
....Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
🧹 Nitpick comments (1)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
3-3: New library code list test and dummy service cover the new path well (with minor polish options)The new
Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvidertest plusDummyAltinn3LibraryCodeListServicegive good coverage of the Altinn3 library path, including downstream parameters and JSON payload (value/label/description/helpText/tags). A couple of minor, optional tweaks you might consider:
- In
MapAppOptions, uselibraryCodeListResponse.Source/.Versionrather than_codeListResponsefor parameters to better mirror real behavior.- If the production
MapAppOptionshonors thelanguageargument, you may want the dummy to respect it (with a sensible fallback) so tests stay aligned if language handling evolves.Not blockers, but would make the dummy service closer to the real one.
Also applies to: 170-198, 201-255
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)
🧰 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.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.
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.
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
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.
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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: 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧬 Code graph analysis (1)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
test/Altinn.App.Core.Tests/Extensions/DictionaryExtensionsTests.cs (4)
Fact(9-23)Fact(25-36)Fact(38-49)Fact(51-72)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(17-17)AppOptions(25-25)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-54)AppOptions(57-93)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListItem(51-83)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
🔇 Additional comments (2)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
34-38: OK status and header content checks look goodThe migration to
Assert.Equal/Assert.Containshere is clear and directly asserts both HTTP status and the downstream parameters; no issues.
109-113: Status code and payload assertions across existing option endpoints are solidThe added xUnit assertions for non-default language behavior, file-source options, 404 for missing lists, and type-correct serialization all look consistent and precise; they validate both HTTP status and exact JSON payloads in line with existing patterns.
Also applies to: 126-130, 144-168
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (1)
20-34: Clarify XML doc to reflect nullableAppOptionsreturnThe instance-based overload now returns
Task<AppOptions?>, but the<returns>doc still implies a non-null list of options. That makes the contract unclear about whennullis expected versus anAppOptionsinstance withOptions == null.Consider updating the doc to explicitly describe the
nullcase (e.g., when no instance-specific provider exists for the givenoptionId) so callers understand the semantics and can handle it correctly.Example:
/// <param name="keyValuePairs">Optional list of key/value pairs to use for filtering and further lookup.</param> - /// <returns>The list of options</returns> - Task<AppOptions?> GetOptionsAsync( + /// <returns> + /// The list of options, or <see langword="null" /> if no instance-specific options are available + /// for the given <paramref name="instanceIdentifier" /> and <paramref name="optionId" />. + /// </returns> + Task<AppOptions?> GetOptionsAsync(
♻️ Duplicate comments (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
3-21: Restrict interface tointernalto match usage and guidelinesThis interface appears to be used only inside
Altinn.App.Core(implemented by an internal client and consumed by internal services/tests). Exposing it aspublicunnecessarily grows the public API surface and conflicts with the “use internal accessibility on types by default” guideline; DI works fine with internal interfaces.Recommend changing the declaration to
internal:- public interface IAltinn3LibraryCodeListApiClient + internal interface IAltinn3LibraryCodeListApiClientIf the intent is to let apps implement this, then keep it public but clearly mark it as such (e.g., with the appropriate attribute and docs); otherwise, prefer
internal.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
40-43: Improve error handling with status code context.The error message doesn't include the status code or response details, making debugging difficult.
Apply this diff to include status code:
if (response.StatusCode != HttpStatusCode.OK) { - throw new HttpRequestException("Unexpected response from Altinn3Library"); + throw new HttpRequestException( + $"Unexpected response from Altinn3Library. Status: {response.StatusCode}" + ); }Alternatively, use
response.EnsureSuccessStatusCode()for built-in status code handling.
36-38: UseUri.EscapeDataString()to encode path parameters.The
org,codeListId, andversionparameters are interpolated directly into the URL without encoding, which can lead to malformed URLs or potential security issues with special characters.Apply this diff to encode the parameters:
var response = await _httpClient.GetAsync( - $"{org}/code_lists/{codeListId}/{version}.json", + $"{Uri.EscapeDataString(org)}/code_lists/{Uri.EscapeDataString(codeListId)}/{Uri.EscapeDataString(version)}.json", cancellationToken );test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
86-89: FixAssert.Containsusage - collection expression not valid as expected value.The
Assert.Contains<T>(T expected, IEnumerable<T> collection)overload expects a single expected value, not a collection expression. This will cause a compile-time error.Apply this fix to assert each expected value individually:
- Assert.Contains( - ["language=espa%C3%B1ol", "level=1", "variant=Sm%C3%A5viltjakt", "special=%2C%22.%25"], - splitHeader - ); + Assert.Contains("language=espa%C3%B1ol", splitHeader); + Assert.Contains("level=1", splitHeader); + Assert.Contains("variant=Sm%C3%A5viltjakt", splitHeader); + Assert.Contains("special=%2C%22.%25", splitHeader);
🧹 Nitpick comments (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
9-9: Consider sealing the class.Per coding guidelines, classes should be sealed unless inheritance is a valid use-case. Since this is an internal implementation of an interface, sealing would prevent unintended inheritance.
Apply this diff:
-internal class Altinn3LibraryCodeListApiClient : IAltinn3LibraryCodeListApiClient +internal sealed class Altinn3LibraryCodeListApiClient : IAltinn3LibraryCodeListApiClient
36-48: Dispose HttpResponseMessage to prevent resource leaks.
HttpResponseMessageimplementsIDisposableand should be disposed. Per coding guidelines, "Remember to dispose IDisposable/IAsyncDisposable instances."Apply this diff to add proper disposal:
+ using var response = await _httpClient.GetAsync( - var response = await _httpClient.GetAsync( $"{org}/code_lists/{codeListId}/{version}.json", cancellationToken ); if (response.StatusCode != HttpStatusCode.OK) { throw new HttpRequestException("Unexpected response from Altinn3Library"); } return await JsonSerializerPermissive.DeserializeAsync<Altinn3LibraryCodeListResponse>( response.Content, cancellationToken );test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
230-255: Minor inconsistency in MapAppOptions implementation.Lines 237-238 use the field
_codeListResponsewhile lines 244-247 use the method parameterlibraryCodeListResponse. While this works for this test double (same object), consider using the parameter consistently for clarity.Parameters = new() { - { "source", _codeListResponse.Source.Name }, - { "version", _codeListResponse.Version }, + { "source", libraryCodeListResponse.Source.Name }, + { "version", libraryCodeListResponse.Version }, },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs(1 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test/Altinn.App.Core.Tests/Features/Options/InstanceAppOptionsFactoryTests.cs
🧰 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.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/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
🧠 Learnings (19)
📓 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.
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.
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
📚 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Core/Features/Options/IAppOptionsService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.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: 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
📚 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.Core/Features/Options/IAppOptionsService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.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 **/*.cs : Use internal accessibility on types by default
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 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.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
🧬 Code graph analysis (7)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-61)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(17-17)AppOptions(25-25)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-54)AppOptions(57-93)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-61)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(17-17)AppOptions(25-25)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-54)AppOptions(57-93)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListItem(51-83)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (3)
Altinn3LibraryCodeListResponse(8-34)Altinn3LibraryCodeListItem(51-83)Altinn3LibraryCodeListSource(39-46)
src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (3)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
AppOptions(230-255)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
AppOptions(57-93)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (5)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
PlatformSettings(7-74)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
Task(221-228)Task(262-295)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
JsonSerializerPermissive(10-48)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (5)
Fact(11-27)Fact(29-56)Fixture(63-76)IAltinn3LibraryCodeListApiClient(60-61)ValueTask(78-78)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
Task(27-61)Altinn3LibraryCodeListApiClient(9-62)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (3)
Task(34-54)Altinn3LibraryCodeListService(11-124)Altinn3LibraryCodeListService(24-31)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
Task(17-25)Altinn3LibraryCodeListClientMessageHandlerMock(3-26)Altinn3LibraryCodeListClientMessageHandlerMock(12-15)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (2)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(60-61)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)
🔇 Additional comments (9)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (2)
14-24: LGTM!The constructor properly configures the HttpClient with BaseAddress and timeout, follows DI patterns, and uses strongly-typed configuration as per guidelines.
50-60: LGTM!The exception handling properly logs context (CodeListId, Version, Org) for debugging while preserving the original exception by rethrowing.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
170-198: LGTM - New test for direct library code-list path.The test correctly exercises the new route pattern
/{org}/{app}/api/options/someCreatorOrg/someCodeListId/someVersionand verifies:
- HTTP 200 status
- Altinn-DownstreamParameters header content
- JSON response structure with Tags support
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
35-60: LGTM - Well-structured test data factory.The parameterized factory method correctly handles the model's required vs. optional properties, with
labelsbeing non-nullable (matching the requiredLabelproperty onAltinn3LibraryCodeListItem) whiledescriptions,helpTexts,tagNames, andtagsare appropriately nullable.src/Altinn.App.Api/Controllers/OptionsController.cs (2)
53-60: Route design note: Potential ambiguity between optionId and creator org.The route pattern uses
optionsIdOrCreatorOrgto serve dual purposes. If a configuredoptionIdhappens to match an organization identifier, the endpoint could behave unexpectedly. This is a design trade-off that appears intentional and is documented in the remarks.Consider documenting this constraint in user-facing documentation to ensure developers don't configure option IDs that could conflict with organization names.
119-131: LGTM - Consistent pattern with first overload.The use of
varand the null check pattern are consistent with the updated first overload.test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (3)
16-51: LGTM - Good caching behavior test.The test correctly verifies that requests with different cache keys result in separate HTTP calls, while using scoped service resolution to ensure proper DI behavior.
83-137: LGTM - Good edge case coverage for empty/null language collections.These tests properly verify the behavior when language collections are empty versus null, ensuring the mapping logic handles both cases gracefully.
265-407: LGTM - Comprehensive Tags mapping test coverage.The tests thoroughly cover the Tags mapping logic including:
- No TagNames present → null Tags
- TagNames but no Tags → null Tags
- Mismatched counts → null Tags
- Matching counts → proper dictionary mapping
This aligns well with the production code's defensive check:
code.Tags.Count == libraryCodeListResponse.TagNames.Count.
...App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
Show resolved
Hide resolved
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
Fixed
Show fixed
Hide fixed
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
Fixed
Show fixed
Hide fixed
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
Fixed
Show fixed
Hide fixed
There was a problem hiding this 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.Core/Features/Options/AppOptionsFactory.cs (1)
48-50: Fix typo in exception message.The exception message contains a typo: "configures" should be "configured".
Apply this diff:
- "No app options provider found in the configured services. Please check your services configuration." + "No app options provider found in the configured services. Please check your services configuration."test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
68-81: RegisterPlatformSettingsoptions in the test fixture so the typed client can be resolvedThe
Altinn3LibraryCodeListApiClientconstructor depends onIOptions<PlatformSettings>, butFixture.Createonly callsAddHttpClientand never registersPlatformSettings. This will cause DI resolution ofIAltinn3LibraryCodeListApiClientto fail when the tests run.You can fix this by configuring
PlatformSettingsin the test ServiceCollection before building the provider, e.g.:{ var mockHandler = new Altinn3LibraryCodeListClientMessageHandlerMock(responseMessage); var serviceCollection = new ServiceCollection(); + serviceCollection.Configure<PlatformSettings>(options => + { + options.Altinn3LibraryApiEndpoint = "https://test.example.com/"; + }); serviceCollection .AddHttpClient<IAltinn3LibraryCodeListApiClient, Altinn3LibraryCodeListApiClient>() .ConfigurePrimaryHttpMessageHandler(() => mockHandler); configure?.Invoke(serviceCollection);This keeps the fixture self-contained and aligned with how the client is constructed in production.
🧹 Nitpick comments (7)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
9-9: Consider marking class as sealed.According to the coding guidelines, classes should be sealed by default unless inheritance is a valid use-case. Since
AppOptionsFactoryis a factory class with no apparent need for inheritance, marking it as sealed would align with project conventions and enable compiler optimizations.Apply this diff:
-public class AppOptionsFactory +public sealed class AppOptionsFactorysrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
41-61: Consider limiting or sanitizing logged/exception content from upstream responses and user-influenced fieldsThe flow and error handling look solid, but for non-OK responses you currently:
- Read the entire response body into
contentand embed it in theHttpRequestExceptionmessage, and- Immediately log that exception together with
org,codeListId, andversion, which all ultimately come from request input.Depending on log retention and where logs are shipped, this can leak larger payloads or user-related identifiers into logs. Consider truncating the response body before including it in the exception/logs, or logging only the status code plus a small snippet/diagnostic ID while keeping full content out of structured logs. This keeps diagnostics useful while reducing log volume and potential data-exposure surface.
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
11-27: Optional: strengthen the happy-path assertion to validate deserialized contentThe success test currently only asserts that the result is non-null. Since you already use
Altinn3LibraryCodeListServiceTestData.GetNbEnResponseMessage(), you could optionally assert on a known property (e.g., number of entries, specific code) or even compare against the expectedAltinn3LibraryCodeListResponseinstance from the same test data. This would catch subtle deserialization regressions, not just total failures.test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
178-206: Make library options header assertion order‑insensitive
Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvidercurrently asserts the entire downstream-parameters header string equals"source=test-name,version=1", which bakes in the iteration order of the parameters dictionary. To keep the test resilient to future changes in how that header is built (or the insertion order ofParameters), assert presence of both fragments instead of exact ordering.Suggested refactor:
- Assert.Equal( - "source=test-name,version=1", - string.Join(",", response.Headers.Single(x => x.Key == "Altinn-DownstreamParameters").Value) - ); + var downstreamHeader = response.Headers + .Single(x => x.Key == "Altinn-DownstreamParameters") + .Value + .Single(); + var downstreamParameters = downstreamHeader.Split(','); + + Assert.Contains("source=test-name", downstreamParameters); + Assert.Contains("version=1", downstreamParameters); + Assert.Equal(2, downstreamParameters.Length);This keeps the behavior check intact while avoiding brittle coupling to ordering.
209-265: Scope dummy Altinn3 library service to tests and use method parameterTwo small test-only cleanups:
Limit visibility and inheritance
This type is only used in tests, so it doesn’t need to be public or inheritable. Aligning with the guideline “use internal and sealed by default” makes the intent clearer.Use the
libraryCodeListResponseargument for parameters
MapAppOptionscurrently readsSourceandVersionfrom the private_codeListResponsefield, even though it receiveslibraryCodeListResponseas an argument. Using the parameter more clearly expresses that mapping is based on the provided response instance.Proposed diff:
-public class DummyAltinn3LibraryCodeListService : IAltinn3LibraryCodeListService +internal sealed class DummyAltinn3LibraryCodeListService : IAltinn3LibraryCodeListService { @@ - return new AppOptions() + return new AppOptions() { Parameters = new() { - { "source", _codeListResponse.Source.Name }, - { "version", _codeListResponse.Version }, + { "source", libraryCodeListResponse.Source.Name }, + { "version", libraryCodeListResponse.Version }, },This keeps behavior the same for the current tests but tightens encapsulation and makes the mapping logic more straightforward.
As per coding guidelines.
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
9-26: Constructor wiring looks good; consider null‑guarding the service dependency.The constructor correctly validates
optionId,org, andcodeListId, setsId, and normalizesversionto"latest", which matches the new library code‑list behavior. One small robustness tweak would be to also guardaltinn3LibraryCodeListServiceagainst null (e.g.,ArgumentNullException.ThrowIfNull(...)) so misuse is caught early even outside DI.
33-37: Clarify intentional ignoring ofkeyValuePairsinGetAppOptionsAsync.
GetAppOptionsAsyncdoesn’t usekeyValuePairsat all, which is probably fine if library code lists don’t support query‑based filtering. It might be worth a short XML doc comment or inline comment either here or on the interface to make it explicit that this provider ignoreskeyValuePairs, so future readers don’t assume it’s an oversight.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs(2 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs(2 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(3 hunks)test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs(2 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs(1 hunks)test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs
🧰 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
🧠 Learnings (18)
📓 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.
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.
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
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsonsrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/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.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs
📚 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/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.txttest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
Func(9-20)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
PlatformSettings(7-74)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-65)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(18-23)AppOptions(31-31)src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
Task(30-44)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListItem(51-83)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
IAppOptionsProvider(30-51)src/Altinn.App.Core/Internal/Linq/Extensions.cs (1)
IsNullOrEmpty(21-24)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
DefaultAppOptionsProvider(7-35)DefaultAppOptionsProvider(16-19)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
Task(27-65)Altinn3LibraryCodeListApiClient(9-66)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
Task(17-25)Altinn3LibraryCodeListClientMessageHandlerMock(3-26)Altinn3LibraryCodeListClientMessageHandlerMock(12-15)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Static code analysis
🔇 Additional comments (8)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2)
12-14: LGTM!The field declarations follow C# conventions and coding guidelines correctly.
19-23: LGTM!The constructor correctly follows DI patterns and uses
GetRequiredServicefor fail-fast behavior if dependencies are missing.test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (1)
3-25: Handler mock looks solid and test-focusedThe mock DelegatingHandler is simple, thread-safe (via
Interlocked.Increment), and provides exactly the hooks tests need (CallCount,LastRequestUri) without extra complexity. This is a good fit for exercising the client behavior.test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
1-5119: Skipping snapshot file per repo policy.This is a generated Public API snapshot (*.verified.txt). No code review feedback on snapshots. Based on learnings, ...
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
33-51: Caching and version normalization look solid
GetCachedCodeListResponseAsynccorrectly normalizesversionto"latest", uses a stable cache key, and wires theCancellationTokenthrough to both the cache and underlying client. No changes needed.
54-120: Robust mapping and language fallback
MapAppOptionsandGetValueWithLanguageFallbackhandle nullableDescription/HelpText/Tags, mismatched tag lengths, and language fallbacks cleanly. The fallback order (requested →nb→en→ first key) is implemented as documented and should be resilient to partial localization.test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
18-176: xUnit migration and existing options tests look correctThe conversions from FluentAssertions to xUnit (
Assert.Equal,Assert.Contains,Assert.DoesNotContain) preserve the original intent across the options tests, and the added failure message inGet_ShouldReturnParametersInHeaderWithSpecialCharsgives useful diagnostics if the status code isn’t OK. Header extraction and splitting logic correctly validates URL-encoded parameter values.test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
3220-3325: Check consistency between required path params and textual semantics forcodeListId/version.
codeListIdandversionare modeled as required path parameters, but the descriptions say “required if creator org is provided” and “defaults to latest if not provided”. For client generators and API consumers this can be confusing if the runtime route actually treats them as optional/conditional. Please double‑check that the controller route attributes and OpenAPI annotations match the intended behavior (e.g., separate routes, optional segments, or clear “always required” docs) and re‑generate the snapshot if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
35-50: Make"default"provider check case-insensitive to avoid subtle behavior changesProvider lookup uses
StringComparison.OrdinalIgnoreCase, but the default-provider check uses a case-sensitive!=. For anoptionsIdlike"Default"with no registered provider, this will now be treated as a non-default and fall back to aDefaultAppOptionsProviderwithId = "Default"(which may break on case-sensitive filesystems).Consider aligning with the rest of the factory by comparing case-insensitively:
- if (optionsId != DefaultProviderName) + if (!string.Equals(optionsId, DefaultProviderName, StringComparison.OrdinalIgnoreCase)) { return new DefaultAppOptionsProvider(_serviceProvider) { Id = optionsId }; }This preserves previous behavior and avoids surprising differences between
"default"and"Default".
♻️ Duplicate comments (1)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
65-77: RegisterIOptions<PlatformSettings>in the fixture so the client can be resolvedThe
Altinn3LibraryCodeListApiClientconstructor depends onIOptions<PlatformSettings>forAltinn3LibraryApiEndpoint. The fixture builds a freshServiceCollectionbut never registersPlatformSettings, so resolving the client will fail at runtime.Register a minimal configuration for
PlatformSettingsinFixture.Create(and add the necessary using):-using System.Net; -using Altinn.App.Core.Features.Options.Altinn3LibraryProvider; +using System.Net; +using Altinn.App.Core.Configuration; +using Altinn.App.Core.Features.Options.Altinn3LibraryProvider; @@ { var mockHandler = new Altinn3LibraryCodeListClientMessageHandlerMock(responseMessage); var serviceCollection = new ServiceCollection(); + serviceCollection.Configure<PlatformSettings>(options => + { + options.Altinn3LibraryApiEndpoint = "https://altinn3-library.test/"; + }); serviceCollection .AddHttpClient<IAltinn3LibraryCodeListApiClient, Altinn3LibraryCodeListApiClient>() .ConfigurePrimaryHttpMessageHandler(() => mockHandler); configure?.Invoke(serviceCollection);This satisfies the constructor dependency and keeps the tests self-contained.
🧹 Nitpick comments (2)
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (2)
1697-1700: Caching semantics for code listsIAltinn3LibraryCodeListService exposes GetCachedCodeListResponseAsync(version nullable). Please verify cache key composition (org, codeListId, version/null), TTL/eviction, and invalidation when source changes. Consider background refresh/ETag if available.
82-82: Altinn3LibraryApiEndpoint configurationPlatformSettings.Altinn3LibraryApiEndpoint added. Confirm validation (non-empty, well-formed URI, trailing slash handling), env overrides, and that AddHttpClient uses this with sane timeouts and resiliency (retry/backoff as appropriate).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs(1 hunks)src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs(2 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs(1 hunks)test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(6 hunks)
🧰 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.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (18)
📓 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.
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.
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
📚 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.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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.Core/Features/Options/AppOptionsFactory.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/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.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (4)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
DefaultAppOptionsProvider(7-35)DefaultAppOptionsProvider(16-19)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(18-23)AppOptions(31-31)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-51)AppOptions(54-90)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (6)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (2)
Fixture(413-426)ValueTask(428-428)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (3)
Task(27-64)Altinn3LibraryCodeListApiClient(9-65)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientMessageHandlerMock.cs (3)
Task(17-25)Altinn3LibraryCodeListClientMessageHandlerMock(3-26)Altinn3LibraryCodeListClientMessageHandlerMock(12-15)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListServiceTestData(7-61)Func(9-20)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(18-23)AppOptions(31-31)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-51)AppOptions(54-90)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Static code analysis
🔇 Additional comments (10)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (2)
5-8: Thin, internal sealed provider design looks goodKeeping
Altinn3LibraryOptionsProviderinternal sealedand delegating responsibilities toIAltinn3LibraryCodeListServicematches the feature-folder + DI pattern and keeps this type small and focused. Based on coding guidelines, this is a good direction.
31-37: Delegation toIAltinn3LibraryCodeListServicekeeps provider logic minimalPassing
_versionthrough as nullable and lettingGetCachedCodeListResponseAsyncnormalize it, then mapping viaMapAppOptions, keepsGetAppOptionsAsyncvery small and pushes caching + mapping concerns into the shared service. This is a clean separation and fits well with the new library code-list architecture.test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (5)
1718-1718: Nullability change: GetOptionsAsync may return nullAppOptionsService/IAppOptionsService now return AppOptions? for instance overload. Verify all call sites and the OptionsController map null to the intended HTTP status (404 vs 200 empty), and add release notes for this source-visible change. Based on learnings, maintainers accept source (re)compile requirements but expect documentation.
Also applies to: 1739-1743
1747-1747: Nullable provider path introducedInstanceAppOptionsFactory.GetOptionsProvider returns IInstanceAppOptionsProvider?. Confirm all consumers handle null (no NullInstanceAppOptionsProvider). Add tests for null path through AppOptionsService.
1692-1695: New Altinn3 library API client surfaceIAltinn3LibraryCodeListApiClient added. Confirm HttpClient configuration (base address, default headers, timeouts) and that CancellationToken is threaded through implementations and controller paths.
1670-1670: Tags/TagNames → AppOption.Tags mappingAltinn3LibraryCodeListItem.Tags and Altinn3LibraryCodeListResponse.TagNames are now nullable and AppOption gains Tags: Dictionary<string,string>?. Verify mapping rules when TagNames or item Tags are null/empty, key collisions, and that serialization matches API docs. Ensure language fallback for labels/description remains intact.
Also applies to: 1682-1682, 4050-4052
1704-1706: Sealing AppOptionsFactorySealed class looks fine; confirm no downstream inheritance relied on this type. If any, document in release notes.
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
14-24: Altinn3LibraryCodeListApiClient implementation looks solidHTTP client configuration, URL encoding of path segments, error handling, permissive JSON deserialization, and sanitized logging are all consistent and correct. No changes needed here.
Also applies to: 27-63
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
178-207: New Altinn3 library options test and dummy service are well-aligned with production behaviorThe
Get_ShouldReturnLibraryOptionsDirectlyNotThroughProvidertest andDummyAltinn3LibraryCodeListServicemirror the realAltinn3LibraryCodeListServiceshape (parameterssource/version, tag mapping, and option fields), giving good coverage of the new route without over-complicating the test wiring. This looks good and follows the feature-folder/testing patterns used elsewhere.Also applies to: 211-266
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
21-23: No changes needed. TheIAltinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeListsmethod definesCancellationToken cancellationToken = default, making the parameter optional. Test calls with three arguments compile successfully and use the default cancellation token value.Likely an incorrect or invalid review comment.
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (1)
doc/adr/006-altinn-3-code-list.md (1)
1-127: Complete the ADR before merging.The ADR remains marked as "in progress" with "Not concluded" status and an empty "Decision rationale" section. Based on the PR implementation (new OptionsController endpoint at
{creatorOrg}/{codeListId}), it appears Alternative A5 was chosen, but this decision and rationale must be documented in the ADR before merging.Please update:
- Status (line 3) to "accepted" or "decided"
- Result (line 8) to reflect the chosen alternative (A5)
- Decision rationale section (lines 126+) with reasoning for selecting A5
🧹 Nitpick comments (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
39-43: Consider addingCancellationTokensupport to enable request cancellation.The
GetAppOptionsAsyncmethod performs async operations (caching and HTTP calls) but doesn't accept or propagate aCancellationToken. While theIAppOptionsProviderinterface may not currently define this parameter, adding optionalCancellationTokensupport would allow callers to cancel long-running operations when the client disconnects.If the interface allows adding an optional parameter (per the learning that maintainers accept source-compatible changes), consider:
- public async Task<AppOptions> GetAppOptionsAsync(string? language, Dictionary<string, string> keyValuePairs) + public async Task<AppOptions> GetAppOptionsAsync(string? language, Dictionary<string, string> keyValuePairs, CancellationToken cancellationToken = default) { - var result = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync(_org, _codeListId, _version); + var result = await _altinn3LibraryCodeListService.GetCachedCodeListResponseAsync(_org, _codeListId, _version, cancellationToken); return _altinn3LibraryCodeListService.MapAppOptions(result, language); }Based on learnings, adding optional parameters to existing methods is acceptable provided release notes document the change.
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)
3326-3333: Public docs shouldn’t mention Program.cs.Replace implementation detail with neutral phrasing.
- "description": "The optionsId configured for the provider in Program.cs", + "description": "The optionsId configured for the options provider in the app startup."
3349-3349: Language description nit and consistency.Use “e.g., nb” and align phrasing across all endpoints to a single template (ISO 639‑1).
- "description": "The language selected by the user, ISO 639-1 (eg. nb)", + "description": "The language selected by the user (ISO 639-1, e.g., 'nb')."If desired, I can grep and align all “language” param descriptions repo‑wide.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
242-267: Consider documenting divergence from production implementation or reusing the real service.The
MapAppOptionsimplementation here is a simplified version that differs from the productionAltinn3LibraryCodeListService:
- Only processes the first code item (line 244) vs. iterating all codes
- Hardcodes
"nb"language (lines 257-259) vs. usingGetValueWithLanguageFallback- Simplified tags logic vs. the more robust production implementation
While simplification in test helpers is acceptable, the divergence could mask issues if the production implementation changes.
Consider:
- Adding a comment documenting that this is a simplified test implementation
- Or, injecting and delegating to the real
MapAppOptionslogic to ensure test coverage matches production behavior
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs(1 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(3 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(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs
🧰 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.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.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/OptionsControllerTests.cs
🧠 Learnings (20)
📓 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.
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.
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
📚 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.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtdoc/adr/006-altinn-3-code-list.md
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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/OptionsControllerTests.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: 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Api/Controllers/OptionsController.cstest/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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 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:
test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtdoc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.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 **/*.cs : Use internal accessibility on types by default
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs
📚 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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (2)
Task(18-23)AppOptions(31-31)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-51)AppOptions(54-90)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListItem(51-83)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (2)
Task(34-51)AppOptions(54-90)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)
src/Altinn.App.Api/Controllers/OptionsController.cs (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
Task(18-23)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
Task(30-44)src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
ToUrlEncodedNameValueString(14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...
(DAT)
[uncategorized] ~45-~45: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...st id and version. Formatting creator org, codelist id and version into the opt...
(E_G)
[style] ~77-~77: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...
(ETC_PERIOD)
[misspelling] ~98-~98: This word is normally spelled as one.
Context: ...ntic distinction via source parameter. * Supports B3; no custom parsing of "optionId" ...
(EN_COMPOUNDS_ANTI_PATTERN)
[uncategorized] ~116-~116: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...
(AI_HYDRA_LEO_CPT_IS_ARE)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Static code analysis
🔇 Additional comments (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
1-22: LGTM! Interface follows coding guidelines.The interface is appropriately scoped as
internal, has clear XML documentation, and the method signature properly includes aCancellationTokenwith a default value. This aligns with the coding guideline to use internal accessibility by default.src/Altinn.App.Api/Controllers/OptionsController.cs (1)
20-39: LGTM! Constructor properly wired for dependency injection.The constructor correctly initializes the new dependencies, with
Telemetryappropriately marked as optional. The DI container will ensure required services are non-null.src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
5-7: Good refactoring! Class properly sealed and dependencies simplified.The class is correctly marked
sealedper coding guidelines, and the refactoring to use a singleIAltinn3LibraryCodeListServicedependency instead of multiple services improves maintainability.test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
1-10: Skip review: Public API snapshot fileThis is a .verified.txt snapshot; we don’t review or suggest edits here. Please just confirm the public API changes captured are intentional and documented (e.g., newly nullable return types, new Altinn3 code-list interfaces). As per coding guidelines, treat this as verification-only. Based on learnings, *.verified.txt files are snapshots and should be ignored for review content.
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)
3374-3403: Good addition of 404 with ProblemDetails.Improves client error handling consistency for options.
3220-3316: New library code-list endpoint looks good; tighten param docs.
- creatorOrg/codeListId are required by route; drop conditional phrasing on codeListId.
- Clarify “version” accepted formats (e.g., semver, date, specific label) and keep default “latest”.
- Standardize language description (see separate nit).
Apply wording tweaks:
- "description": "Code list id, required if creator org is provided", + "description": "The code list identifier.", ... - "description": "Code list version, only used in combination with creator org and code list id, defaults to latest if not provided", + "description": "Code list version. Defaults to 'latest' if omitted. Specify exact format accepted (e.g., semver, date, or label)."⛔ Skipped due to 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.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.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
Outdated
Show resolved
Hide resolved
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
Outdated
Show resolved
Hide resolved
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
3318-3404: Good cleanup and error surface; align contract and keep consistent language.
- Wording no longer leaks internal “AppOption” and language description is now consistent. 404 with ProblemDetails added — good.
- Consider adding a 200 content schema (and a shared OptionsItem schema) so the “Tags” note maps to an explicit field; otherwise, rephrase to avoid referring to fields not defined in the spec. You can reuse the same schema across both options endpoints.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
178-209: Remove commented-out test or track in an issue.The commented-out test with the TODO referencing an ADR decision reduces maintainability. Either complete and enable the test if the ADR is resolved, remove the commented code, or create a tracked issue for later implementation.
Would you like me to open a new issue to track this test implementation?
🧹 Nitpick comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
3220-3316: New library code list endpoint: tighten wording and specify 200 schema.
- codeListId description says “required if creator org is provided,” but both are required path params. Simplify.
- version description can drop “only used in combination with …” (already implied by the route).
- Unify language phrasing with the other endpoint (“ISO 639‑1, e.g., 'nb'”).
- 200 response has no schema while the description references a Tags field. Either define a concrete response schema (recommended) or reword to avoid implying fields not present in the contract.
Proposed minimal diff to fix text consistency:
{ "name": "codeListId", "in": "path", - "description": "Code list id, required if creator org is provided", + "description": "The code list identifier.", "required": true, "schema": { "type": "string" } }, { "name": "version", "in": "query", - "description": "Code list version, only used in combination with creator org and code list id, defaults to latest if not provided", + "description": "Code list version; defaults to 'latest' if not provided.", "schema": { "type": "string", "default": "latest" } }, { "name": "language", "in": "query", - "description": "The language selected by the user, ISO 639-1 (eg. nb)", + "description": "The language selected by the user (ISO 639-1, e.g., 'nb').", "schema": { "type": "string" } }Optional (recommended): add a concrete 200 response schema used by both options endpoints, e.g.:
"responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { "$ref": "#/components/schemas/OptionsItem" } + } + } + } },…and define components.schemas.OptionsItem (including an optional “tags” array) so the “Tags” remark is unambiguous.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
262-267: Simplify redundant null-safety operators in test code.Lines 265 use
TagNames?.First()!andTags?.First()!after already verifying both collections haveCount > 0on line 262. The null-conditional operator (?.) and null-forgiving operator (!) are redundant since the pattern-match guard ensures the collections are non-null and non-empty.Apply this diff for cleaner test code:
Tags = libraryCodeListResponse.TagNames is { Count: > 0 } && responseOptionOne.Tags is { Count: > 0 } ? new Dictionary<string, string> { - { libraryCodeListResponse.TagNames?.First()!, responseOptionOne.Tags?.First()! }, + { libraryCodeListResponse.TagNames.First(), responseOptionOne.Tags.First() }, } : null,
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(3 hunks)
🧰 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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/OptionsControllerTests.cs
🧠 Learnings (17)
📓 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.
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.
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
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsondoc/adr/006-altinn-3-code-list.md
📚 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/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsondoc/adr/006-altinn-3-code-list.md
📚 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/OptionsControllerTests.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: 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.csdoc/adr/006-altinn-3-code-list.md
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
ToUrlEncodedNameValueString(14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...
(DAT)
[uncategorized] ~41-~41: The abbreviation “e.g.” (= for example) requires two periods.
Context: ...st id and version. Formatting creator org, codelist id and version into the opt...
(E_G)
[style] ~73-~73: In American English, abbreviations like “etc.” require a period.
Context: ...ains special characters (hyphens, dots, etc), the delimiter choice becomes problema...
(ETC_PERIOD)
[misspelling] ~94-~94: This word is normally spelled as one.
Context: ...ntic distinction via source parameter. * Supports B3; no custom parsing of "optionId" ...
(EN_COMPOUNDS_ANTI_PATTERN)
[uncategorized] ~112-~112: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...
(AI_HYDRA_LEO_CPT_IS_ARE)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Analyze (csharp)
- GitHub Check: Static code analysis
🔇 Additional comments (4)
src/Altinn.App.Api/Controllers/OptionsController.cs (2)
3-5: LGTM! Dependency injection follows established patterns.The new dependencies (IAltinn3LibraryCodeListService and Telemetry) are properly injected and stored. The optional Telemetry parameter with default null is appropriate for graceful degradation.
Also applies to: 20-39
78-107: LGTM! Existing endpoints maintain proper null checks.The refactoring to use
varis appropriate, and the null checks forappOptions?.Optionsare properly maintained.Also applies to: 125-157
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
34-37: LGTM! Test assertions properly migrated to xUnit.The refactoring from FluentAssertions to xUnit assertions follows the coding guidelines and maintains test correctness. The header parsing logic (lines 82-96) with split and individual Contains assertions is appropriate for order-insensitive validation.
Based on coding guidelines, which specify: "Prefer xUnit asserts over FluentAssertions in tests."
Also applies to: 76-97, 117-120, 134-138, 152-152, 171-176
212-272: LGTM! Test service properly implements test interface.The
DummyAltinn3LibraryCodeListServiceprovides appropriate test data and demonstrates correct nullable property handling forDescriptionandHelpText(lines 259-260). The hardcoded response structure supports controller testing without external dependencies.
@olavsorl Fix nitpick comment after ADR decision is made |
There was a problem hiding this 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)
doc/adr/006-altinn-3-code-list.md (1)
3-8: ADR remains incomplete - please finalize before merging.The ADR status is still "in progress" with "Not concluded" result, and the Decision rationale section at line 110 is empty. The implementation in
OptionsController.csuses Alternative A5 (new endpoint/{creatorOrg}/{codeListId}). Please update:
- Status → "accepted"
- Result → "A5: Add a new controller method"
- Decision rationale section with reasoning for choosing A5
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (1)
178-209: Commented-out test should be addressed with ADR completion.This test scaffold is tied to the ADR decision. Once the ADR is finalized (as noted in the first file's review), either enable and complete this test or remove it and track in a separate issue.
🧹 Nitpick comments (1)
doc/adr/006-altinn-3-code-list.md (1)
85-88: Minor grammar fix needed.Static analysis flagged "anti pattern" as a compound word that should be hyphenated.
- * Supports B3; no custom parsing of "optionId" will help maintain a lower anti-pattern complexity. + * Supports B3; no custom parsing of "optionId" will help maintain lower complexity.Note: The phrase "anti-pattern complexity" is unclear - consider rewording to clarify the intended meaning.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(7 hunks)
🧰 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.cs
🧠 Learnings (17)
📓 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.
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.
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
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.
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
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.
📚 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:
doc/adr/006-altinn-3-code-list.mdsrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
doc/adr/006-altinn-3-code-list.mdsrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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: 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.cs
📚 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/Controllers/OptionsControllerTests.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/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (7)
src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
Task(39-43)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/IAltinn3LibraryCodeListService.cs (1)
Task(18-23)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListService.cs (1)
Task(34-51)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Extensions/DictionaryExtensions.cs (1)
ToUrlEncodedNameValueString(14-35)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...* Status: in progress * Deciders: Squad Data * Date: 2025-11-25 ## Result * Not co...
(DAT)
[misspelling] ~81-~81: This word is normally spelled as one.
Context: ...on will be required. ### A3: Modify existing path with new query parameters * Pros * Cle...
(EN_COMPOUNDS_ANTI_PATTERN)
[misspelling] ~85-~85: This word is normally spelled as one.
Context: ...inction via source parameter. * Supports B3; no custom parsing of "optionId" will help mai...
(EN_COMPOUNDS_ANTI_PATTERN)
[uncategorized] ~100-~100: The verb “is” doesn’t seem to fit in this context, “are” is probably more formally correct.
Context: ...structures. * Poor discoverability, API consumers can't tell from the OpenAPI/Sw...
(AI_HYDRA_LEO_CPT_IS_ARE)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Static code analysis
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Analyze (csharp)
🔇 Additional comments (8)
src/Altinn.App.Api/Controllers/OptionsController.cs (4)
20-22: LGTM on new dependency injections.The new fields for
Telemetry?andIAltinn3LibraryCodeListServicefollow established patterns. The optionalTelemetry?parameter with default null is consistent with how telemetry is handled elsewhere in the codebase.
30-39: Constructor properly wired for DI.The constructor correctly initializes all dependencies, with
Telemetry?as an optional parameter following the established pattern in this codebase.
52-80: New library code-list endpoint implementation looks correct.The implementation:
- Uses proper route differentiation (
{creatorOrg}/{codeListId}vs{optionsId})- Passes
HttpContext.RequestAbortedfor cancellation support- Includes null check before accessing
appOptions.Parameters- Follows the established pattern for downstream parameter headers
92-111: Existing endpoint unchanged, correctly preserves behavior.The existing options endpoint at
{optionsId}maintains its current behavior. The use ofvarforappOptionsand the null check pattern are consistent with the new endpoint.test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (4)
34-37: Test assertion correctly updated to xUnit style.The test now uses
Assert.EqualandAssert.Containswith proper header value extraction via.Single(). This aligns with the coding guidelines preferring xUnit asserts over FluentAssertions.
76-97: Header validation logic correctly implemented.The test properly validates URL-encoded header values by splitting and checking each expected value. The approach correctly handles order-independent verification of comma-separated values.
119-120: Language assertion correctly strengthened.The test now properly verifies that
lang=nbis not present in the header value usingDoesNotContainwith case-insensitive comparison, addressing the previous review feedback.
212-271: Test fake implementation follows best practices.The
DummyAltinn3LibraryCodeListService:
- Uses
internal sealedclass per coding guidelines- Properly handles nullable
Description?andHelpText?with null-conditional operators- Guards against empty
TagNames/Tagscollections using pattern matching (is { Count: > 0 })- Returns
Task.FromResultappropriately for synchronous test data
…s for options instance controller method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
♻️ Duplicate comments (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs (1)
9-26: Add null-guard foraltinn3LibraryCodeListService(fail fast).
This avoids a later NRE if constructed manually in tests or miswired DI.public Altinn3LibraryOptionsProvider( string optionId, string org, string codeListId, string? version, IAltinn3LibraryCodeListService altinn3LibraryCodeListService ) { ArgumentException.ThrowIfNullOrWhiteSpace(optionId); ArgumentException.ThrowIfNullOrWhiteSpace(org); ArgumentException.ThrowIfNullOrWhiteSpace(codeListId); + ArgumentNullException.ThrowIfNull(altinn3LibraryCodeListService); Id = optionId; _org = org; _codeListId = codeListId; _version = version; _altinn3LibraryCodeListService = altinn3LibraryCodeListService; }doc/adr/006-altinn-3-code-list.md (1)
3-10: ADR is internally inconsistent (A1 vslib**...format) — align Result + rationale with the actual implemented contract.
Right now A1 is selected, but the “format” described in the rationale doesn’t match A1’s own description (and A5 is listed but not chosen). Please update the ADR so Result, rationale, and examples all describe the same approach.Also applies to: 39-45, 52-53, 111-116
🧹 Nitpick comments (9)
doc/adr/006-altinn-3-code-list.md (1)
16-19: Fix typos/grammar to avoid ambiguity in the final decision doc.
Examples: “endpoints … takes” → “endpoints … take”, “formated” → “formatted”, “doesnt” → “doesn’t”, “optionsId … that consisting” → “that consists”.Also applies to: 64-66, 78-81, 109-116
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
6-21: Consider renamingGetAltinn3LibraryCodeLists→ singular to match returned value.
It returns oneAltinn3LibraryCodeListResponse, so a singular name reads clearer.src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (2)
14-24: ValidateAltinn3LibraryApiEndpoint(fail fast on invalid URI) to avoid late runtime surprises.
Right nownew Uri(platformSettings.Value.Altinn3LibraryApiEndpoint)will throw at runtime if misconfigured; consider a clearer exception message (or a TryCreate + throw with context).
36-52: Consider including (bounded) response body in non-200 errors for debuggability.
Status code alone can be thin when diagnosing blob/CDN errors; if you add body, cap length and sanitize to avoid log/exception injection.src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (1)
8-32: Confirm intended audience: should this interface bepublic(and ImplementableByApps) orinternal?
If apps are not expected to implement it, making itinternalreduces public API surface; if apps are expected to implement it, consider marking it withImplementableByAppsper guidelines.test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
11-58: Tests cover the key behaviors (success + non-200 + logging).
Optional hardening: also assert the outgoingLastRequestUrifromAltinn3LibraryCodeListClientMessageHandlerMockto lock down path/escaping behavior.src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)
92-120:GetValueWithLanguageFallback: returning""for empty dictionaries is a bit odd—consider returningnull(or document why empty-string is desired).
Today, an empty dictionary is treated differently than null, which may leak into API output as empty strings.
16-51: Use consistent cache key delimiter (:instead of-).The cache key should use colons to separate components, following standard caching conventions:
- $"Altinn3Library:{org}-{codeListId}-{version}", + $"Altinn3Library:{org}:{codeListId}:{version}",src/Altinn.App.Api/Controllers/OptionsController.cs (1)
123-154: (Optional) Confirm intended language defaulting behavior when instance endpoint falls back to non-instance/library paths.
The instance endpoint defaultslanguagetonbfor the instance provider call, but in the fallback it passeslanguageas-is (potentiallynull) to non-instance/library resolution. If the intent is “instance route always defaults to nb”, you probably want to consistently uselanguage ?? LanguageConst.Nbin the fallback too.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs(2 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs(3 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs(1 hunks)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs(1 hunks)src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs(2 hunks)test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(8 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(6 hunks)test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs(2 hunks)test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- test/Altinn.App.Core.Tests/Features/Options/JoinedAppOptionsTests.cs
- src/Altinn.App.Core/Features/Options/CommonOptionProviderServiceCollectionExtensions.cs
- test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
- test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
🧰 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.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (20)
📓 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.
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.
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
📚 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.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Api/Controllers/OptionsController.csdoc/adr/006-altinn-3-code-list.mdtest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cssrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-10-22T08:35:24.567Z
Learnt from: bjorntore
Repo: Altinn/app-lib-dotnet PR: 1532
File: test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt:2451-2451
Timestamp: 2025-10-22T08:35:24.567Z
Learning: In Altinn/app-lib-dotnet, IDataClient is generally not implemented by customers; it’s considered internal for DI. As of 2025-10-22, GetBinaryDataStream had not been released yet, so its parameter reordering (adding optional TimeSpan? timeout before CancellationToken) is acceptable without a compatibility shim; recommend documenting the new parameter and using named arguments in samples.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.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 **/*.cs : Register services in DI container properly following existing patterns
Applied to files:
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 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.Core/Extensions/ServiceCollectionExtensions.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.csdoc/adr/006-altinn-3-code-list.mdtest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/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.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/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.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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.Core/Extensions/ServiceCollectionExtensions.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.Core/Extensions/ServiceCollectionExtensions.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cstest/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cstest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListClientTests.cs (1)
IAltinn3LibraryCodeListApiClient(62-63)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (2)
Altinn3LibraryCodeListApiClient(9-65)Altinn3LibraryCodeListApiClient(14-24)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)
Altinn3LibraryCodeListService(11-121)Altinn3LibraryCodeListService(24-31)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (6)
src/Altinn.App.Core/Configuration/PlatformSettings.cs (1)
PlatformSettings(7-74)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
Task(34-51)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)src/Altinn.App.Core/Helpers/JsonSerializerPermissive.cs (1)
JsonSerializerPermissive(10-48)src/Altinn.App.Core/Helpers/LogSanitizer.cs (2)
LogSanitizer(9-45)Sanitize(22-38)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryOptionsProvider.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (2)
Task(34-51)AppOptions(54-90)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (2)
Task(18-23)AppOptions(31-31)src/Altinn.App.Core/Features/Options/Altinn3LibraryProvider/Altinn3LibraryOptionsProvider.cs (1)
Altinn3LibraryOptionsProvider(13-151)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (3)
Altinn3LibraryCodeListResponse(8-34)Altinn3LibraryCodeListItem(51-83)Altinn3LibraryCodeListSource(39-46)
src/Altinn.App.Api/Controllers/OptionsController.cs (7)
src/Altinn.App.Api/Controllers/DataController.cs (9)
Task(213-408)Task(422-452)Task(462-467)Task(895-917)Task(919-923)Task(931-996)Task(998-1060)Task(1062-1145)Task(1163-1218)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Features/Options/AppOptionsFileHandler.cs (1)
Task(30-44)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
AppOptions(54-90)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (1)
AppOptions(31-31)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (8)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (10)
Fact(16-51)Fact(53-81)Fact(83-110)Fact(112-137)Fact(139-175)Fact(177-209)Fact(211-233)Fact(235-263)Fact(265-292)Fact(294-326)test/Altinn.App.Api.Tests/Data/TestData.cs (1)
PrepareInstance(147-174)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
AppOptions(54-90)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)src/Altinn.App.Core/Models/AppOption.cs (1)
AppOption(88-135)src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
IAppOptionsProvider(30-51)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (2)
Altinn3LibraryCodeListResponse(8-34)Altinn3LibraryCodeListItem(51-83)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(22-33)Altinn3LibraryCodeListResponse(35-60)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...
(DAT)
[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~23-~23: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~31-~31: Ensure spelling is correct
Context: ...list as root * B2: Simplify application layout * B3: Keep complexity low for developers *...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~33-~33: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B5: Avoid the need to distinguish betwee...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~34-~34: Ensure spelling is correct
Context: ...guish between "secure": true/false in frontend * B6: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~37-~37: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~89-~89: Ensure spelling is correct
Context: ...odeListId) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~101-~101: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new controlle...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~111-~111: Ensure spelling is correct
Context: ...g we initially didnt want. ## Decision rationale To ease the implementation process for t...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Static code analysis
🔇 Additional comments (8)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
3-34: Good: relaxed JSON shape by makingTagNames/Tagsoptional, but ensure downstream never assumes non-null.
The nullable change is sensible for deserialization tolerance; just keep guarding any TagNames/Tags usage (especially count/indexing).Also applies to: 82-83
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)
13-14: DI wiring for library code lists looks correct and follows existing patterns.
Typed HttpClient + service registration is straightforward and should compose well with the rest of options infrastructure. Based on learnings, follows established feature/DI pattern.Also applies to: 340-343
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
9-20: LGTM: clean test helper for building a 200 JSON response.
22-60: LGTM: sample data covers nb/en and optional tag fields without violating requiredLabel.test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (3)
35-39: Good: assert status code before consuming headers for clearer failures.
77-99: Good: stronger diagnostics for special-char header failures + order-insensitive assertions.
179-266: Good: controller-level library-ref coverage verifies service invocation + downstream parameter header.Also applies to: 537-578
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
1-5125: Skip: verification snapshot fileThis is a
*.verified.txtpublic API snapshot; changes here are expected outputs of API changes elsewhere and shouldn’t be reviewed/suggested on directly. Based on learnings, ignore for code review.
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
Show resolved
Hide resolved
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
doc/adr/006-altinn-3-code-list.md(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 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.
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.
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
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.
📚 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:
doc/adr/006-altinn-3-code-list.md
📚 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:
doc/adr/006-altinn-3-code-list.md
📚 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:
doc/adr/006-altinn-3-code-list.md
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...
(DAT)
[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~32-~32: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B3: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~112-~112: Ensure spelling is correct
Context: ...g we initially didnt want. ## Decision rationale To ease the implementation process for t...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Static code analysis
- GitHub Check: Analyze (csharp)
There was a problem hiding this 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
🧹 Nitpick comments (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (1)
1-186: LGTM - excellent implementation of library code-list integration.The implementation demonstrates strong code quality:
- ✅ Proper error handling with
HttpRequestExceptioncatching andProblemDetailsresponses- ✅ Null safety checks before accessing
appOptions.OptionsandParameters- ✅ Cancellation token propagation via
HttpContext.RequestAborted- ✅ Well-anchored regex pattern with named capture groups
- ✅ Comprehensive XML documentation and
ProducesResponseTypeattributes- ✅ Correct three-tier lookup order for instance endpoint (instance → app → library)
- ✅ Follows C# best practices: async/await, no blocking calls, nullable reference types
All past review concerns have been thoroughly addressed.
Optional documentation clarification:
Lines 44 and 109 mention "(version=latest, if you want the latest version)" — consider clarifying whether "latest" is a literal string value supported by the API or just an example. The current phrasing is slightly ambiguous, though functionally correct since the downstream service handles version resolution.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/DataListsController.cs(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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/DataListsController.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (10)
📓 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.
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.
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
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.
📚 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/DataListsController.cssrc/Altinn.App.Api/Controllers/OptionsController.csdoc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.csdoc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.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: 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/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.cs
📚 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/OptionsController.cs
📚 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:
doc/adr/006-altinn-3-code-list.md
🧬 Code graph analysis (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListService.cs (3)
Task(19-25)Task(35-40)AppOptions(48-48)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
Task(37-48)Task(51-68)AppOptions(71-113)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-11-25 ## Result A1: Use...
(DAT)
[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get code lists thr...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~32-~32: Ensure spelling is correct
Context: ...ptionId" parsed to org, codelist id and version * B3: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~112-~112: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Analyze (csharp)
- GitHub Check: Static code analysis
- GitHub Check: Run dotnet build and test (ubuntu-latest)
🔇 Additional comments (2)
doc/adr/006-altinn-3-code-list.md (1)
1-117: ADR is complete and well-documented.The ADR has been properly updated with "Accepted" status, clearly specifies the chosen alternative (A1), and includes a complete decision rationale. The format specification is consistent throughout the document, and the pros/cons analysis provides good context for the architectural decision.
src/Altinn.App.Api/Controllers/DataListsController.cs (1)
30-30: LGTM - documentation correction.The typo fix improves the XML documentation quality.
There was a problem hiding this 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
🧹 Nitpick comments (1)
doc/adr/006-altinn-3-code-list.md (1)
112-117: Strengthen the decision rationale with explicit tradeoff justification.The decision rationale now states that A1 was chosen to ease implementation, but it doesn't explain why A1 was preferred over the simpler alternatives A2 and A5—both of which claim to support all three decision drivers (B1, B2, B3).
Given A1's documented cons (lines 59–64: increased complexity, string parsing difficulty, format conflicts, lack of framework validation), the rationale should clarify:
- Why A1's implementation burden on the backend was justified
- How the documented parsing and format-conflict risks will be mitigated (e.g., via documentation, regex validation, or future enhancements)
- Why A2 (cleaner path structure) or A5 (dedicated endpoint) were not selected despite their support for all drivers
Suggested revision:
## Decision rationale -To ease the implementation process for the consumers/clients, we have chosen A1. +We chose A1 to reuse the existing options endpoint and avoid introducing a new API surface, +supporting B1 (keep complexity low for developers). Although A1 requires string parsing +and careful format handling, the constraint to library references only (detected via regex +prefix "lib") minimizes collision risk with existing optionIds. A2 and A5 offer cleaner +semantics but would require more migration effort and endpoint management. We mitigate A1's +parsing complexity through documented format rules and regex-based validation. The format for Altinn 3 library code list optionIds is: `lib**{creatorOrg}**{codeListId}**{version}`
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
doc/adr/006-altinn-3-code-list.md(1 hunks)test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt(2 hunks)test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt(2 hunks)
🧰 Additional context used
🧠 Learnings (10)
📓 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.
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.
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
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.
📚 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.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.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.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txtdoc/adr/006-altinn-3-code-list.mdtest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 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:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txtdoc/adr/006-altinn-3-code-list.mdtest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-09-18T10:23:05.995Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json:7263-0
Timestamp: 2025-09-18T10:23:05.995Z
Learning: In PR #1357, ApplicationMetadata.apiScopes (now ApiScopesConfiguration) is currently unused at runtime; the schema change is acceptable without a transition mechanism for now.
Applied to files:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.
Applied to files:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txttest/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.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:
doc/adr/006-altinn-3-code-list.md
📚 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:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.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:
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-12-09 ## Result A1: Use...
(DAT)
[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get Altinn 3 libra...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~32-~32: Ensure spelling is correct
Context: ...tionId" parsed to org, code list id and version * B3: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~100-~100: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~112-~112: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🔇 Additional comments (2)
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Custom_0_Metadata.verified.txt (1)
276-276: Snapshot verification file — skipping substantive review.This is a *.verified.txt snapshot file capturing endpoint metadata. Per established learnings, verification snapshots are auto-managed test artifacts and are not subject to code review suggestions. The parameter name changes align with the PR's library-code-list feature. Build/test will validate snapshot consistency.
Also applies to: 565-565
test/Altinn.App.Integration.Tests/CustomScopes/_snapshots/CustomScopesTests.Metadata_Standard_0_Metadata.verified.txt (1)
251-251: Snapshot verification file — skipping substantive review.This is a *.verified.txt snapshot file capturing endpoint metadata. Per established learnings, verification snapshots are auto-managed test artifacts and are not subject to code review suggestions. The parameter name changes align with the PR's library-code-list feature. Build/test will validate snapshot consistency.
Also applies to: 485-485
…s://github.com/Altinn/app-lib-dotnet into feature/new-way-of-fetching-library-code-lists
There was a problem hiding this 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
🧹 Nitpick comments (2)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)
3220-3425: Options endpoints: contract updates and AppOption usage look solid (minor wording nit only)The two options endpoints now:
- Use
optionsIdOrLibraryRefwith a clear library ref format description.- Return
AppOption[]for all 200 content types.- Consistently describe
languageas “ISO 639‑1, e.g., 'nb'”.- Expose structured ProblemDetails payloads for 400/404/500/502, in line with other endpoints.
This addresses the earlier contract concerns around response schemas and error handling.
Very minor, optional nit: the
queryParamsdescription string differs slightly between the two options endpoints ("Query parameters supplied."vs"Query parameters supplied"). If you care about strict text consistency in the spec, consider aligning the wording/punctuation.Also applies to: 3427-3653
7340-7372: AppOption schema aligns with options responses; consider adding a brief descriptionThe new
AppOptionschema (value/label/description/helpText/tags,additionalProperties: false) matches the options endpoints’ payload and the documented tags behavior, and avoids the earlier issue of referring to an undefined type in descriptions.Optionally, you could add a short schema-level
"description"(e.g., “Represents a selectable option item returned by options endpoints”) to make the published contract slightly clearer for consumers.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(10 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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/OptionsController.cs
🧠 Learnings (11)
📓 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.
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.
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
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.
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 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:
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsonsrc/Altinn.App.Api/Controllers/OptionsController.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: 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/OptionsController.cs
📚 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/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.cs
📚 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/OptionsController.cs
🔇 Additional comments (5)
src/Altinn.App.Api/Controllers/OptionsController.cs (4)
18-35: LGTM: Clean class structure and dependency injection.The addition of
partialmodifier for GeneratedRegex and the newIAltinn3LibraryCodeListServicedependency follow established patterns. Constructor properly injects and stores the service.
37-96: LGTM: First endpoint handles both app options and library code lists correctly.The implementation properly:
- Detects library references using the anchored regex
- Routes to the appropriate service based on the reference type
- Handles
HttpRequestExceptionwith detailedProblem()responses- Passes
HttpContext.RequestAbortedfor proper cancellation support- Validates
appOptionsis not null before accessing propertiesAll concerns from previous reviews have been addressed.
98-182: LGTM: Instance endpoint with well-designed fallback logic.The implementation correctly prioritizes:
- Instance-specific options via provider
- Falls back to app options or library code lists if instance options not found
The language default to
Nb(line 132) for instance-specific requests appears intentional. Error handling and null checks are consistent with the first endpoint.
184-185: LGTM: Regex pattern is properly anchored and validated.The
GeneratedRegexprovides compile-time optimization. The pattern correctly enforces:
- Anchored format to prevent substring matches
- Appropriate character sets for each component
The
orgpattern[a-zA-Z0-9]+is more restrictive than initially suggested in review but represents a deliberate choice for the intended use case.test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
1687-1696: DatalistqueryParamsdescription change looks fineThe updated
"Query parameters supplied"description is clear and consistent with similar datalist endpoints; no further changes needed here.
There was a problem hiding this 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
🧹 Nitpick comments (3)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)
3220-3423: Options endpoint now has clear contract with AppOption[] and ProblemDetailsThe
/api/options/{optionsIdOrLibraryRef}GET now:
- Documents the library-ref pattern in the path parameter.
- Returns a concrete
AppOption[]payload for 200 across content types.- Adds structured
ProblemDetailsbodies for 400/404/500/502.This aligns well with the earlier request for a shared options item schema and explicit 200 response.
If you want to tighten wording later, you could change “on the format” to “in the format” in the
optionsIdOrLibraryRefdescription, but it’s purely editorial.
7340-7372: AppOption schema is a solid addition; consider nullability of required fieldsDefining
AppOptionwithvalue,label,description,helpText, andtags(dictionary) is a clear improvement and makes the options contract explicit.If the API logically requires
valueandlabelto be non-null, you might later consider tightening the schema (droppingnullable: truefor those two) to help client codegen and validation; ifnullis actually allowed, the current definition is fine.src/Altinn.App.Api/Controllers/OptionsController.cs (1)
55-74: Apply consistent language default across both Get methods.The first
Getmethod (line 55) passes nullablelanguagedirectly to services without a default, while the secondGetmethod (line 122) applieslanguage ??= LanguageConst.Nbbefore calling services. For consistency and clarity, apply the same default-setting pattern to the first method, or document why the difference is intentional.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json(12 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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/OptionsController.cs
🧠 Learnings (11)
📓 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.
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.
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
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.
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 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:
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsonsrc/Altinn.App.Api/Controllers/OptionsController.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:
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsonsrc/Altinn.App.Api/Controllers/OptionsController.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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.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: 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/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.cs
📚 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/OptionsController.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Analyze (csharp)
- GitHub Check: Static code analysis
🔇 Additional comments (5)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (2)
1670-1727: Datalists queryParams description looks goodThe updated description is clear and neutral; no further changes needed here.
3427-3652: Instance options endpoint mirrors the top-level options contract correctly
/instances/{instanceOwnerPartyId}/{instanceGuid}/options/{optionsIdOrLibraryRef}now matches the non-instance options endpoint:
- Same
optionsIdOrLibraryRefsemantics and description.- Same
languageandqueryParamsdescriptions.- 200 response as
AppOption[]plus consistentProblemDetailsfor 400/404/500/502.This symmetry should make clients’ expectations straightforward across both endpoints.
src/Altinn.App.Api/Controllers/OptionsController.cs (3)
18-35: LGTM! Class structure properly supports new library code-list feature.The
partialmodifier enablesGeneratedRegex, and the constructor properly injectsIAltinn3LibraryCodeListServicefollowing established DI patterns.
135-158: LGTM! Fallback logic correctly prioritizes instance-specific options.The try block properly attempts instance-specific options first (line 137), then falls back to general or library-based options (lines 145-157) when none are found. This ordering aligns with the PR objectives' stated lookup priority.
184-185: The regex pattern correctly reflects domain requirements. All organization identifiers in the codebase use alphanumeric characters only (ttd, digdir, nav, skd), making the[a-zA-Z0-9]+restriction fororgappropriate. Additionally, theIAltinn3LibraryCodeListServiceproperly handles the "latest" version: when the version parameter is empty or null, line 52 defaults it to "latest" before passing to the API client.Likely an incorrect or invalid review comment.
There was a problem hiding this 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
🧹 Nitpick comments (1)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (1)
21-21: Consider usingMockBehavior.Strictfor consistency.The mock registration doesn't specify
MockBehavior.Strict, while other tests in the codebase (e.g.,PaymentServiceTests.cs) use strict mocks. AlthoughIAppOptionsFileHandlermethods aren't called in these tests, using strict behavior would catch regressions if the implementation changes and improve consistency with the codebase pattern.Apply this diff:
- services.AddSingleton(new Mock<IAppOptionsFileHandler>().Object); + services.AddSingleton(new Mock<IAppOptionsFileHandler>(MockBehavior.Strict).Object);
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
doc/adr/006-altinn-3-code-list.md(1 hunks)src/Altinn.App.Api/Controllers/OptionsController.cs(4 hunks)src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs(2 hunks)src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs(4 hunks)test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt(7 hunks)
🧰 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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cssrc/Altinn.App.Api/Controllers/OptionsController.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.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
🧠 Learnings (15)
📓 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.
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.
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
📚 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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.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:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cssrc/Altinn.App.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtdoc/adr/006-altinn-3-code-list.md
📚 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.Core.Tests/Features/Options/AppOptionsFactoryTests.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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: Follow the AppFixture pattern for integration tests: Central orchestrator managing test lifecycle with feature-specific operations
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs
📚 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.Core/Features/Options/AppOptionsFactory.cssrc/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cssrc/Altinn.App.Api/Controllers/OptionsController.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtdoc/adr/006-altinn-3-code-list.md
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtdoc/adr/006-altinn-3-code-list.md
📚 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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧬 Code graph analysis (3)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (2)
test/Altinn.App.Core.Tests/Features/Payment/PaymentServiceTests.cs (2)
Mock(26-27)Fixture(29-44)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1)
Fixture(517-530)
src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (1)
src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
DefaultAppOptionsProvider(7-42)DefaultAppOptionsProvider(21-25)
src/Altinn.App.Api/Controllers/OptionsController.cs (6)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
Task(37-48)Task(51-68)AppOptions(71-113)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/IAppOptionsService.cs (2)
Task(17-17)Task(29-34)src/Altinn.App.Core/Models/AppOptions.cs (1)
AppOptions(6-24)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
🪛 LanguageTool
doc/adr/006-altinn-3-code-list.md
[style] ~4-~4: Did you mean “that” or “date”?
Context: ...s * Status: Accepted * Deciders: Squad Data * Date: 2025-12-09 ## Result A1: Use...
(DAT)
[grammar] ~11-~11: Ensure spelling is correct
Context: ...g path without modifying it ## Problem context We want to be able to get Altinn 3 libra...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~24-~24: Ensure spelling is correct
Context: ...ct, not list as root for added metadata support * Avoid the need to distinguish between `"...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~32-~32: Ensure spelling is correct
Context: ...tionId" parsed to org, code list id and version * B3: Performance, consider parsing overhe...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~35-~35: Ensure spelling is correct
Context: ...f different approaches ## Alternatives considered * **A1: Use already existing path without m...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~78-~78: Ensure spelling is correct
Context: ...ger complains about required parameters missing * Route ambiguity, /options/something coul...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~88-~88: Ensure spelling is correct
Context: ...e list id) should be in path, not query string ### A4: Modify existing path so that option...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~98-~98: Ensure spelling is correct
Context: ...om the OpenAPI/Swagger docs what format optionsId should be. ### A5: Add a new endpoint ...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
[grammar] ~110-~110: Ensure spelling is correct
Context: ... we initially didn't want. ## Decision rationale To ease the implementation process for t...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Static code analysis
- GitHub Check: Analyze (csharp)
🔇 Additional comments (10)
test/Altinn.App.Core.Tests/Features/Options/AppOptionsFactoryTests.cs (2)
34-34: Test setup correctly reflects new factory behavior.The removal of explicit
DefaultAppOptionsProviderregistration aligns with the factory's new behavior of dynamically creating default providers when no custom provider matches. The tests correctly validate that the factory returnsDefaultAppOptionsProviderinstances with the requested IDs.Also applies to: 46-46
114-115: LGTM! Modern C# syntax.The use of target-typed
new()is idiomatic modern C# and improves readability by reducing redundancy.src/Altinn.App.Core/Features/Options/DefaultAppOptionsProvider.cs (2)
21-25: LGTM! Constructor refactoring improves clarity.The explicit
idparameter makes provider instantiation clearer and eliminates the need for cloning logic. The immediate resolution ofAppImplementationFactoryis appropriate since it's required for all operations.
31-31: Property access correctly restricted.Changing from
internal settoprivate setproperly enforces thatIdis immutable after construction, which aligns with the refactored constructor pattern.doc/adr/006-altinn-3-code-list.md (1)
110-115: ADR is complete and consistent with implementation.The decision rationale clearly explains the choice of A1, and the specified format
lib**{creatorOrg}**{codeListId}**{version}matches the regex implementation in OptionsController.cs. The ADR properly documents the design decision.src/Altinn.App.Core/Features/Options/AppOptionsFactory.cs (2)
12-12: ServiceProvider field properly supports the new provider instantiation pattern.Storing
IServiceProviderenables on-demand creation ofDefaultAppOptionsProviderinstances with the correctid, which aligns with the refactored constructor signature inDefaultAppOptionsProvider.Also applies to: 19-19
41-41: Simplified fallback logic improves flexibility.The new approach creates a
DefaultAppOptionsProviderfor any unmatchedoptionsId, removing the need for special "default" handling and cloning. This works correctly sinceDefaultAppOptionsProvidernow accepts anyidand resolves the corresponding file.src/Altinn.App.Api/Controllers/OptionsController.cs (2)
61-73: Library reference handling implemented consistently.Both endpoints properly detect library references using the regex pattern and route to the appropriate service. The try-catch blocks handle HTTP errors gracefully, and null checks prevent NullReferenceException. The ternary operator usage is clean and the cancellation token is correctly propagated.
Also applies to: 136-156
182-183: No changes required. The regex correctly restricts org identifiers to alphanumeric characters[a-zA-Z0-9]+, which aligns with Altinn organization code naming conventions. All test cases confirm this pattern:ttd,digdir,nav, andskdare alphanumeric-only org identifiers.Likely an incorrect or invalid review comment.
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
1658-1697: Snapshot file – no code-level feedback hereThis file is the generated public API snapshot (
PublicApi_ShouldNotChange_Unintentionally.verified.txt). Per project guidance, changes here should mirror the real code and are not reviewed for behavior or design. Please just confirm that these snapshot updates (Altinn3 library code-list APIs, AppOptions/AppOption surface, etc.) match the intentional code changes insrc/*and associated tests.Also applies to: 1712-1716, 1726-1731, 1736-1745, 4036-4055
There was a problem hiding this 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
🧹 Nitpick comments (3)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (3)
727-739: Make test helper classinternal sealedper coding guidelines.
DummyInstanceProvidershould follow the same accessibility pattern asDummyAltinn3LibraryCodeListServiceto align with the project's coding guidelines.🔎 Apply this diff:
-public class DummyInstanceProvider : IInstanceAppOptionsProvider +internal sealed class DummyInstanceProvider : IInstanceAppOptionsProviderAs per coding guidelines, use internal accessibility on types by default and sealed for classes unless inheritance is considered valid.
741-749: Make test helper classinternal sealedper coding guidelines.
DummyProvidershould be markedinternal sealedfor consistency with other test helpers and project coding guidelines.🔎 Apply this diff:
-public class DummyProvider : IAppOptionsProvider +internal sealed class DummyProvider : IAppOptionsProviderAs per coding guidelines, use internal accessibility on types by default and sealed for classes unless inheritance is considered valid.
751-785: Make test helper classinternalper coding guidelines.
TestDataOptionsControllershould use internal accessibility to align with the project's coding guidelines for test helper classes.🔎 Apply this diff:
-public static class TestDataOptionsController +internal static class TestDataOptionsControllerAs per coding guidelines, use internal accessibility on types by default.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs(8 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs(1 hunks)test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs
🧰 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
🧠 Learnings (16)
📓 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.
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.
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
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.
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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: Include integration tests for platform service interactions
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-22T13:35:09.565Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1446
File: test/Altinn.App.Integration.Tests/Basic/_snapshots/BasicAppTests.Authentication_auth=OldUser.verified.txt:16-38
Timestamp: 2025-08-22T13:35:09.565Z
Learning: Test data in Altinn App Integration Tests snapshots (like SSNs, addresses, phone numbers in BasicAppTests.Authentication snapshots) are synthetic/fake values created for testing purposes, not real PII that needs to be scrubbed from version control.
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs
📚 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.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 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:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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 : Mock external dependencies with Moq in tests
Applied to files:
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cstest/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.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/OptionsControllerTests.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 **/*.cs : Use Nullable Reference Types in C#
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Static code analysis
🔇 Additional comments (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTests.cs (1)
1-534: LGTM! Comprehensive test coverage for Altinn3LibraryCodeListService.The test suite is well-structured and covers all critical scenarios:
- ✅ Caching behavior: Verifies HybridCache works correctly across DI scopes with different and identical cache keys
- ✅ Language fallback logic: Tests all scenarios (empty, null, nb default, en fallback, alphabetical fallback)
- ✅ Tag mapping: Thoroughly tests tag dictionary construction under various conditions (missing, mismatched counts, proper mapping)
- ✅ Test infrastructure: Proper DI setup with mocked HTTP client, sealed Fixture record with async disposal
- ✅ Code quality: Follows coding guidelines (xUnit asserts, no blocking async calls, efficient patterns)
The Fixture helper correctly relies on PlatformSettings default property values (as confirmed in past review discussions), eliminating the need for explicit configuration registration.
test/Altinn.App.Api.Tests/Controllers/OptionsControllerTests.cs (2)
19-647: Comprehensive test coverage for OptionsController endpoints.The test suite thoroughly covers both instance and non-instance endpoints across multiple scenarios: parameter handling, special characters, language defaults, file sources, 404 responses, serialization, and library reference regex validation. The tests follow xUnit patterns, use appropriate assertions, and properly clean up test data.
650-725: LGTM! Well-structured test service implementation.The
DummyAltinn3LibraryCodeListServicecorrectly follows coding guidelines (internal sealed), provides controlled test data, includes proper null-safety guards for collections (lines 702-707), and uses a CallCounter pattern for verification.
There was a problem hiding this 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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/Altinn.App.Api/Controllers/OptionsController.cs (1)
55-95: Address language parameter handling inconsistency between endpoints.Line 131 in the instance-specific endpoint applies
language ??= LanguageConst.Nbto default the language, but the non-instance endpoint (lines 55-95) passes the nullable language parameter directly to services without defaulting. Both endpoints call the same service methods that acceptstring? language. This inconsistency should either be justified (if the difference is intentional) or standardized by applying the same defaulting pattern to both endpoints.
🧹 Nitpick comments (2)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
37-69: Clarify version handling: "latest" vs null/empty produce different cache keys.The version normalization logic is inconsistent:
- When
GetAppOptionsAsyncreceives"latest"(line 46),GetLatestVersiontransforms it to"_latest"- When it receives
null/empty,GetLatestVersionleaves it unchanged, thenGetCachedCodeListResponseAsync(line 59) defaults it to"latest"This means semantically identical requests (both intending "latest version") produce different cache keys (
"_latest"vs"latest"), leading to cache duplication and potentially stale data.Consider normalizing earlier or using a consistent default so both paths result in the same cache key.
🔎 Suggested fix: normalize version consistently
public async Task<AppOptions> GetAppOptionsAsync( string org, string codeListId, string version, string? language, CancellationToken cancellationToken ) { using var telemetry = _telemetry?.StartGetOptionsActivity(); - version = GetLatestVersion(version); + version = string.IsNullOrEmpty(version) ? "latest" : version; var response = await GetCachedCodeListResponseAsync(org, codeListId, version, cancellationToken); return MapAppOptions(response, language); }And update
GetCachedCodeListResponseAsyncto useGetLatestVersion:public async Task<Altinn3LibraryCodeListResponse> GetCachedCodeListResponseAsync( string org, string codeListId, string? version, CancellationToken cancellationToken = default ) { - version = !string.IsNullOrEmpty(version) ? version : "latest"; + version = GetLatestVersion(!string.IsNullOrEmpty(version) ? version : "latest"); var result = await _hybridCache.GetOrCreateAsync( $"Altinn3Library:{org}:{codeListId}:{version}", async cancel => await _altinn3LibraryCodeListApiClient.GetAltinn3LibraryCodeList(org, codeListId, version, cancel), options: _defaultCacheExpiration, cancellationToken: cancellationToken ); return result; }src/Altinn.App.Api/Controllers/OptionsController.cs (1)
134-165: Consider extracting common library reference handling logic.The library reference matching and service invocation pattern (lines 146-155) is duplicated from the first endpoint (lines 61-73). Consider extracting a private helper method to reduce duplication:
🔎 Suggested refactor: extract common logic
+private async Task<AppOptions> GetLibraryOrStandardOptionsAsync( + string optionsIdOrLibraryRef, + string? language, + Dictionary<string, string> queryParams, + CancellationToken cancellationToken) +{ + var libRefMatch = LibraryRefRegex().Match(optionsIdOrLibraryRef); + return libRefMatch.Success + ? await _altinn3LibraryCodeListService.GetAppOptionsAsync( + libRefMatch.Groups["org"].Value, + libRefMatch.Groups["codeListId"].Value, + libRefMatch.Groups["version"].Value, + language, + cancellationToken + ) + : await _appOptionsService.GetOptionsAsync(optionsIdOrLibraryRef, language, queryParams); +}Then use it in both endpoints:
-var libRefMatch = LibraryRefRegex().Match(optionsIdOrLibraryRef); -appOptions = libRefMatch.Success is false - ? await _appOptionsService.GetOptionsAsync(optionsIdOrLibraryRef, language, queryParams) - : await _altinn3LibraryCodeListService.GetAppOptionsAsync( - libRefMatch.Groups["org"].Value, - libRefMatch.Groups["codeListId"].Value, - libRefMatch.Groups["version"].Value, - language, - HttpContext.RequestAborted - ); +appOptions = await GetLibraryOrStandardOptionsAsync( + optionsIdOrLibraryRef, + language, + queryParams, + HttpContext.RequestAborted +);
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/Altinn.App.Api/Controllers/OptionsController.cssrc/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
🧠 Learnings (9)
📓 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.
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.
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
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.
📚 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cssrc/Altinn.App.Api/Controllers/OptionsController.cs
📚 Learning: 2025-09-18T10:12:21.841Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1357
File: src/Altinn.App.Api/Infrastructure/Middleware/ScopeAuthorizationMiddleware.cs:289-293
Timestamp: 2025-09-18T10:12:21.841Z
Learning: In Altinn App security middleware like ScopeAuthorizationMiddleware, prefer explicit failures (throwing exceptions) over silently skipping unexpected endpoint types during discovery to prevent potential authorization gaps and ensure all endpoints are properly handled according to security configuration.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.cs
📚 Learning: 2025-08-29T05:32:47.222Z
Learnt from: martinothamar
Repo: Altinn/app-lib-dotnet PR: 1456
File: test/Altinn.App.Integration.Tests/_fixture/AppFixture.cs:958-958
Timestamp: 2025-08-29T05:32:47.222Z
Learning: In Altinn.App.Integration.Tests, the maintainer prefers fail-fast behavior (Environment.FailFast) when critical test infrastructure components like log reading fail, rather than graceful error handling, because diagnostics are essential for debugging test failures.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.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: 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/OptionsController.cs
📚 Learning: 2025-08-27T06:58:28.126Z
Learnt from: cammiida
Repo: Altinn/app-lib-dotnet PR: 1451
File: src/Altinn.App.Api/Controllers/DataTagsController.cs:0-0
Timestamp: 2025-08-27T06:58:28.126Z
Learning: In the Altinn app-lib-dotnet codebase, validation endpoints follow a pattern where validation only runs when the ignoredValidators query parameter is provided (not null). This is a conscious design choice for consistency across validation endpoints.
Applied to files:
src/Altinn.App.Api/Controllers/OptionsController.cs
📚 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/OptionsController.cs
📚 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/OptionsController.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Static code analysis
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Analyze (csharp)
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
1-35: LGTM! Proper service structure and dependency injection.The service correctly follows the coding guidelines: internal accessibility, sealed class, proper DI constructor pattern, and clear separation of concerns with HybridCache for caching and the API client for external calls.
72-114: LGTM! Proper tag mapping with duplicate protection.The tag dictionary construction correctly handles potential duplicate tag names (lines 83-90) and only maps tags when counts match. The language-aware mapping for label, description, and help text follows the established fallback pattern.
116-144: LGTM! Language fallback logic is clear and correct.The fallback order (requested language → Nb → En → first alphabetically) is well-documented and correctly implemented. The
NotNullIfNotNullattribute properly documents the null-safety contract.src/Altinn.App.Api/Controllers/OptionsController.cs (2)
1-35: LGTM! Clean dependency injection and controller setup.The addition of the library code list service dependency follows established patterns, and making the controller
partialis appropriate for theGeneratedRegexhelper method.
182-183: The regex pattern is correct as-is; the inconsistency is intentional.The test suite explicitly validates that organization identifiers must be alphanumeric only (
[a-zA-Z0-9]+), while code list IDs and versions allow underscores and hyphens. This is confirmed by test case at line 221 ofOptionsControllerTests.cs:[InlineData("lib**ttd-org**CodeListId**1.0")] // Dash in org (invalid - only alphanumeric allowed)The positive test cases show org identifiers can contain uppercase letters and numbers (e.g.,
lib**TTD**andlib**Org123**), but dashes are explicitly rejected. The pattern is working as designed.
There was a problem hiding this 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/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs:
- Around line 145-148: The GetLatestVersion method currently has a single long
return line that violates CSharpier length limits; refactor the method body to
avoid the long inline ternary by splitting the logic across multiple lines
(e.g., use an if/else or assign intermediate boolean/variable) so the return
expression is wrapped and shorter—update the GetLatestVersion(string? version)
method accordingly to return "_latest" when version is null/empty or equals
"latest" (case-insensitive), otherwise return version.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧠 Learnings (3)
📓 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.
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.
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
📚 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.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: 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (4)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/IAltinn3LibraryCodeListApiClient.cs (1)
Task(16-21)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListApiClient.cs (1)
Task(27-64)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
🪛 GitHub Actions: Verify dotnet format
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
[error] 147-147: CSharpier formatting check failed. The code around line 147 is not formatted as expected. Run 'dotnet csharpier check .' to fix.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Static code analysis
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (5)
11-20: LGTM!Good adherence to coding guidelines:
internal sealedclass, nullable telemetry for optional dependency, and static cache options to avoid per-instance allocation.
36-48: LGTM!Clean async method without
Asyncsuffix (per guidelines), proper telemetry activity scoping withusing, and clear separation between fetching and mapping.
59-65: Cache key delimiter consideration.The cache key uses colons as delimiters. If
org,codeListId, orversioncould contain colons, this might cause key collisions. If these values are validated upstream (e.g., from URL path segments), this is acceptable.
70-113: LGTM!The tag mapping correctly uses "first wins" strategy for duplicate tag names. Graceful degradation when tag counts don't match (tagDict remains null) is reasonable.
115-143: LGTM!Good use of
NotNullIfNotNullattribute. The language fallback priority (requested → Nb → En → alphabetically first) is well-documented and correctly implemented.
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
Show resolved
Hide resolved
There was a problem hiding this 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
🧹 Nitpick comments (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (1)
115-143: Language fallback logic is correct.The fallback priority (requested → Nb → En → alphabetically first) is well-implemented with short-circuit evaluation for efficiency. The
NotNullIfNotNullattribute correctly documents null behavior.💡 Optional: Consider using MinBy for slightly better performance
Line 142 could use
MinByinstead ofOrderBy().First()to avoid allocating an ordered enumerable:- return languageCollection.OrderBy(x => x.Key).First().Value; + return languageCollection.MinBy(x => x.Key).Value;This is a minor optimization but more semantically direct.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧠 Learnings (4)
📓 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.
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.
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
📚 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
📚 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.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: 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.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs
🧬 Code graph analysis (1)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (3)
test/Altinn.App.Core.Tests/Features/Options/Altinn3LibraryProvider/Altinn3LibraryCodeListServiceTestData.cs (2)
Altinn3LibraryCodeListResponse(33-48)Altinn3LibraryCodeListResponse(50-79)src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListResponse.cs (1)
Altinn3LibraryCodeListResponse(8-34)src/Altinn.App.Core/Internal/Language/LanguageConst.cs (1)
LanguageConst(3-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Static code analysis
- GitHub Check: Analyze (csharp)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Run dotnet build and test (ubuntu-latest)
🔇 Additional comments (5)
src/Altinn.App.Core/Features/Options/Altinn3LibraryCodeList/Altinn3LibraryCodeListService.cs (5)
1-34: LGTM! Well-structured service implementation.The class declaration, dependencies, and constructor follow coding guidelines correctly. The
internal sealedclass with dependency injection and optional telemetry is appropriate. The 15-minute cache expiration is reasonable for library code lists.
36-48: LGTM! Proper telemetry and async handling.The telemetry activity is correctly disposed using
using var, and the async flow properly propagates the cancellation token through to the caching and mapping layers.
50-68: LGTM! Proper caching implementation.The cache key structure is well-formed, version normalization happens before caching (ensuring consistent keys), and the cancellation token is properly propagated to both the cache and API client layers.
70-113: LGTM! Tag mapping correctly handles edge cases.The duplicate tag name protection (lines 85-88) properly addresses the past review comment. The count check (line 79) prevents index-out-of-range errors, and the first-wins strategy for duplicate tag names is sensible. Setting
IsCacheable = trueand including version/source metadata in Parameters aligns well with the library code list use case.
145-150: LGTM! Version normalization correctly implemented.The formatting issue from the past review has been properly resolved by splitting the ternary across multiple lines. The case-insensitive handling of "latest" and normalization to "_latest" is appropriate.
There was a problem hiding this 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
🧹 Nitpick comments (1)
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (1)
7364-7396: AppOption schema definition looks good; consider a short description ontags.The
AppOptionschema (value/label/description/helpText +tagsas a string map) is well‑formed and matches the new options responses.If you want to make the tags semantics clearer, you could add a brief description to the
tagsproperty (e.g., “Additional metadata tags for the option, keyed by tag name”) in the C# model so it flows into the generated spec, but this is purely optional.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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.Core/Extensions/ServiceCollectionExtensions.cs
🧠 Learnings (12)
📓 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.
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.
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
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txttest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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:
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.jsontest/Altinn.App.Api.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:
test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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:
test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txtsrc/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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 **/*.cs : Register services in DI container properly following existing patterns
Applied to files:
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs
📚 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.Core/Extensions/ServiceCollectionExtensions.cstest/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.Core/Extensions/ServiceCollectionExtensions.cstest/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
📚 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.Core/Extensions/ServiceCollectionExtensions.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.Core/Extensions/ServiceCollectionExtensions.cs
📚 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:
test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Static code analysis
- GitHub Check: Run dotnet build and test (ubuntu-latest)
- GitHub Check: Run dotnet build and test (macos-latest)
- GitHub Check: Run dotnet build and test (windows-latest)
- GitHub Check: Analyze (csharp)
🔇 Additional comments (6)
src/Altinn.App.Core/Extensions/ServiceCollectionExtensions.cs (1)
13-13: LGTM! DI registrations follow established patterns.The new service registrations correctly follow the established patterns in the codebase:
- The HttpClient registration matches the pattern used for other platform clients (lines 102-119)
TryAddTransientfor the service layer allows app-level overrides while providing a sensible default- Transient lifetime is appropriate for stateless services
- Placement within
AddAppOptionsis correct for options-related functionality- The comment clearly documents the purpose
Based on learnings, these registrations properly follow existing DI patterns.
Also applies to: 339-342
test/Altinn.App.Api.Tests/OpenApi/OpenApiSpecChangeDetection.SaveJsonSwagger.verified.json (3)
1670-1697: LGTM: datalistqueryParamsdescription is clear and consistent.The updated
"Query parameters supplied"phrasing matches similar endpoints and keeps thedeepObjectsemantics understandable.
3220-3425: Options endpoint now has explicit typed 200 responses and error contracts.The
/{org}/{app}/api/options/{optionsIdOrLibraryRef}definition looks solid:
- 200 returns an array of
AppOptionfor all three content types.- 400/404/500/502 consistently use
ProblemDetailsacross media types.optionsIdOrLibraryRefdescription clearly explains the library-ref format and “latest” behavior.- Language parameter description matches the ISO 639‑1 guidance from the review thread.
No further changes needed here from an OpenAPI perspective.
3427-3653: Instance‑scoped options endpoint is aligned with the plain options endpoint.
/{org}/{app}/instances/{instanceOwnerPartyId}/{instanceGuid}/options/{optionsIdOrLibraryRef}:
- Mirrors the non‑instance options endpoint (array of
AppOptionfor 200;ProblemDetailsfor 400/404/500/502).- Adds clear descriptions for instance path parameters and language.
- Keeps
queryParamsshape and wording consistent with other deepObject query patterns.This nicely fulfils the earlier request to support all app option kinds and exposes them cleanly in the spec.
test/Altinn.App.Api.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
373-390: Snapshot file — no review necessary.Per established practice in this repository,
.verified.txtfiles are automatically maintained snapshots that guard the public API surface. The changes here reflect intentional public API modifications from this PR (parameter renaming, dependency injection, response type documentation). These updates are expected and will be validated by the public API breaking change detection test.test/Altinn.App.Core.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt (1)
1658-1685: Public API snapshot changes acknowledged (no review of generated content).This
.verified.txtfile is a generated public‑API snapshot used by the PublicApiTests. I’m not reviewing or suggesting changes based on its contents; the important thing is that it accurately reflects the real code after your Altinn 3 library code‑list andAppOption.Tagschanges. As long as this snapshot was regenerated from the updated source and tests pass, it looks fine.Also applies to: 1692-1697, 1715-1716, 1728-1745, 4066-4068
|



Description
Extracted service logic from provider to service and client for reusability. Added regex pattern to match pattern decided in ADR for fetching Altinn 3 library code lists directly. Changed the options endpoint to support fetching Altinn 3 library code lists directly.
Also includes:
Related Issue(s)
Verification
Documentation
Summary by CodeRabbit
New Features
Documentation
Public API
Tests
✏️ Tip: You can customize this high-level summary in your review settings.