Skip to content

feat(fiks-arkiv): configurable case file classifications and document format codes#1765

Open
danielskovli wants to merge 3 commits into
mainfrom
fiks-classifications
Open

feat(fiks-arkiv): configurable case file classifications and document format codes#1765
danielskovli wants to merge 3 commits into
mainfrom
fiks-classifications

Conversation

@danielskovli
Copy link
Copy Markdown
Contributor

@danielskovli danielskovli commented May 22, 2026

Description

Fixes and extends the archive document generator to comply with requirements from IKTA:

  • Adds optional CaseFileClassifications on FiksArkivMetadataSettings.
  • Adds Optional FormatCode override per document (e.g. PDF/A).
  • Variantformat changed from Produksjonsformat (P) to Arkivformat (A).
  • Breaking: IFiksArkivConfigResolver.GetInstanceOwnerClassification replaced with GetCaseFileClassifications.

Related

Summary by CodeRabbit

  • New Features
    • Added support for configuring multiple case file classifications instead of a single owner classification.
    • Added optional format code override for document archival settings.
    • Updated document format variant handling to use archive format codes.

Review Change Stack

… format codes

- Optional CaseFileClassifications on FiksArkivMetadataSettings.
- Optional FormatCode override per document (e.g. PDF/A).
- Variantformat changed from Produksjonsformat (P) to Arkivformat (A).
- IFiksArkivConfigResolver: GetInstanceOwnerClassification replaced
  with GetCaseFileClassifications (breaking).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

📝 Walkthrough

Walkthrough

This PR extends Fiks Arkiv support to handle multiple case-file classifications and configurable document format codes. A new FiksArkivClassification model allows specifying classifications in settings, which are combined with the instance-owner classification and applied to outgoing arkivmelding payloads. Document format codes can now be overridden per datatype, with MessagePayloadWrapper resolving the final format via explicit code, file extension, or filename.

Changes

Classification and Format Code Configuration

Layer / File(s) Summary
Classification schema and conversion extension
src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs, src/Altinn.App.Clients.Fiks/Extensions/FiksArkivClassificationExtensions.cs
Introduces FiksArkivClassification record with required SystemId, ClassificationId, Title and optional IsRestricted, adds CaseFileClassifications property to FiksArkivMetadataSettings with validation, and provides ToKlassifikasjon extension method for model-to-domain conversion.
FormatCode override and MessagePayloadWrapper resolution
src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs, src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs
FiksArkivDataTypeSettings gains optional FormatCode property with validation; MessagePayloadWrapper carries FileFormatCode parameter and exposes GetFileFormat() method that resolves format from code, file extension, or filename.

Configuration Resolver and Payload Generation

Layer / File(s) Summary
Configuration resolver contract and implementation
src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs, src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs
Replaces GetInstanceOwnerClassification with GetCaseFileClassifications that returns instance-owner plus configured classifications; refactors helper to private static for internal reuse.
Payload generation with classifications and format codes
src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs
Retrieves classifications via new resolver method and iterates over list to populate caseFile.Klassifikasjon; passes explicit FormatCode through document settings into GetPayload and MessagePayloadWrapper; updates GetDocumentDescription to use payloadWrapper.GetFileFormat() for format and archive variant constants.

Test Coverage and Verification

Layer / File(s) Summary
Configuration resolver and settings validation tests
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs, test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs
Replaces GetInstanceOwnerClassification tests with GetCaseFileClassifications coverage including known/unknown authentication, configured classification appending, and owner-only scenarios; adds validation tests for FiksArkivClassification required fields and FormatCode non-empty constraints.
Payload generator test refactoring
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs
Refactors to use per-test NewDefaultInstance() helper avoiding state leakage; extends TestCase and fixture signatures with additionalClassifications parameter; adds test case 5 with additional classifications and PDF/A format code; updates config resolver mock to return GetCaseFileClassifications list.
MessagePayloadWrapper and infrastructure tests
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/MessagePayloadWrapperTest.cs, test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs, test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs
Introduces MessagePayloadWrapperTest covering format code override, fallback to extension, and filename-based resolution; updates test helper calls to explicitly pass FileFormatCode parameter.
Verified snapshots and public API contract
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/*, test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt
Updates five payload snapshots changing dokumentobjekt variantformat from production (P/Produksjonsformat) to archive (A/Arkivformat); adds new test case 5 snapshot with full arkivmelding payload; updates public API contract to reflect method and property signature changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

other

Suggested reviewers

  • ivarne
  • bjorntore
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.81% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding configurable case file classifications and document format codes to the Fiks Arkiv implementation.
Linked Issues check ✅ Passed All code changes directly address issue #18783 requirements: classifiable message structure is now supported via configurable CaseFileClassifications, format codes are configurable, and implementation allows app-level customization.
Out of Scope Changes check ✅ Passed All changes are within scope: classification and format configuration additions, payload generation updates, resolver refactoring, and comprehensive test coverage align with the PR objectives.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fiks-classifications

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@danielskovli danielskovli added feature Label Pull requests with new features. Used when generation releasenotes backport-ignore This PR is a new feature and should not be cherry-picked onto release branches labels May 22, 2026
@danielskovli danielskovli marked this pull request as ready for review May 22, 2026 12:48
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs (1)

417-417: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove blocking GetAwaiter().GetResult() in test code. Line 417 in test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs uses Authenticated.User user => KlassifikasjonFactory.CreateUser(user).GetAwaiter().GetResult(),, which violates the guideline “Don't use .GetAwaiter().GetResult(), .Result(), .Wait() or other blocking APIs on Task”. Refactor the helper/fixture to be async and await the factory result instead.

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

In
`@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs`
at line 417, The test uses a blocking call in the expression Authenticated.User
user => KlassifikasjonFactory.CreateUser(user).GetAwaiter().GetResult(); remove
the blocking .GetAwaiter().GetResult() by making the test helper/fixture async:
change the provider to return a Task<User> (or make the factory call inside an
async setup method) and await KlassifikasjonFactory.CreateUser(user) instead;
update callers in FiksArkivDefaultPayloadGeneratorTest (and any usages of
Authenticated.User) to await the Task or run within an async test/setup method
so no synchronous blocking APIs (.Result/.Wait/GetAwaiter().GetResult) are used.
🧹 Nitpick comments (2)
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs (1)

539-547: ⚡ Quick win

Assert the owner classification explicitly at index 0.

Line 539-547 verifies appended configured classifications, but it doesn’t directly assert that the owner classification remains first. A direct assertion on result[0] would harden this contract.

Proposed assertion addition
         Assert.Equal(3, result.Count);
+        Assert.NotNull(result[0].KlassifikasjonssystemID);
+        Assert.NotNull(result[0].KlasseID);
         Assert.Equal("configured-system-1", result[1].KlassifikasjonssystemID);
         Assert.Equal("configured-class-1", result[1].KlasseID);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs`
around lines 539 - 547, Add an explicit assertion that the owner classification
remains at index 0 in the test FiksArkivConfigResolverTest by asserting
properties on result[0] (e.g., KlassifikasjonssystemID, KlasseID, Tittel and
ErSkjermet) before the existing assertions that check configured entries; this
ensures the owner classification is still first and hardens the test contract.
test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs (1)

14-17: ⚡ Quick win

Add whitespace validation cases for ClassificationId and Title.

Line 14-17 already checks required-field behavior, but ClassificationId and Title only test empty-string inputs, not whitespace-only values. Adding whitespace cases closes an easy regression gap.

Proposed test additions
     [InlineData("sys", "", "title", null, "ClassificationId configuration is required")]
+    [InlineData("sys", "   ", "title", null, "ClassificationId configuration is required")]
     [InlineData("sys", "cls", "", null, "Title configuration is required")]
+    [InlineData("sys", "cls", "   ", null, "Title configuration is required")]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs`
around lines 14 - 17, The tests in FiksArkivSettingsTest currently validate
whitespace-only SystemId but not ClassificationId or Title; add InlineData cases
for whitespace-only values for those fields so the test method (the
InlineData-decorated test) asserts the same "required" errors for
ClassificationId and Title when they are strings of whitespace. Specifically,
add entries analogous to [InlineData("   ", "cls", "title", null, "SystemId
configuration is required")] but targeting ClassificationId (e.g.,
[InlineData("sys", "   ", "title", null, "ClassificationId configuration is
required")]) and Title (e.g., [InlineData("sys", "cls", "   ", null, "Title
configuration is required")]) so FiksArkivSettingsTest covers whitespace-only
validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs`:
- Around line 9-15: The GetFileFormat method writes FileFormatCode directly into
Format.KodeProperty which can include surrounding whitespace; trim
FileFormatCode before assigning it. Update the logic in GetFileFormat (the
method that returns Format with KodeProperty) to use FileFormatCode.Trim() (or
check trimmed value for IsNullOrWhiteSpace) and fall back to
Payload.GetDotlessFileExtension() when the trimmed value is empty, so
KodeProperty never contains leading/trailing spaces.

---

Outside diff comments:
In
`@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs`:
- Line 417: The test uses a blocking call in the expression Authenticated.User
user => KlassifikasjonFactory.CreateUser(user).GetAwaiter().GetResult(); remove
the blocking .GetAwaiter().GetResult() by making the test helper/fixture async:
change the provider to return a Task<User> (or make the factory call inside an
async setup method) and await KlassifikasjonFactory.CreateUser(user) instead;
update callers in FiksArkivDefaultPayloadGeneratorTest (and any usages of
Authenticated.User) to await the Task or run within an async test/setup method
so no synchronous blocking APIs (.Result/.Wait/GetAwaiter().GetResult) are used.

---

Nitpick comments:
In `@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs`:
- Around line 539-547: Add an explicit assertion that the owner classification
remains at index 0 in the test FiksArkivConfigResolverTest by asserting
properties on result[0] (e.g., KlassifikasjonssystemID, KlasseID, Tittel and
ErSkjermet) before the existing assertions that check configured entries; this
ensures the owner classification is still first and hardens the test contract.

In
`@test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs`:
- Around line 14-17: The tests in FiksArkivSettingsTest currently validate
whitespace-only SystemId but not ClassificationId or Title; add InlineData cases
for whitespace-only values for those fields so the test method (the
InlineData-decorated test) asserts the same "required" errors for
ClassificationId and Title when they are strings of whitespace. Specifically,
add entries analogous to [InlineData("   ", "cls", "title", null, "SystemId
configuration is required")] but targeting ClassificationId (e.g.,
[InlineData("sys", "   ", "title", null, "ClassificationId configuration is
required")]) and Title (e.g., [InlineData("sys", "cls", "   ", null, "Title
configuration is required")]) so FiksArkivSettingsTest covers whitespace-only
validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 65047a5d-114f-48ad-b00c-823dc7b2eb5c

📥 Commits

Reviewing files that changed from the base of the PR and between d18d3f6 and b0fcbda.

📒 Files selected for processing (22)
  • src/Altinn.App.Clients.Fiks/Extensions/FiksArkivClassificationExtensions.cs
  • src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivConfigResolver.cs
  • src/Altinn.App.Clients.Fiks/FiksArkiv/FiksArkivDefaultPayloadGenerator.cs
  • src/Altinn.App.Clients.Fiks/FiksArkiv/IFiksArkivConfigResolver.cs
  • src/Altinn.App.Clients.Fiks/FiksArkiv/Models/FiksArkivSettings.cs
  • src/Altinn.App.Clients.Fiks/FiksArkiv/Models/MessagePayloadWrapper.cs
  • test/Altinn.App.Clients.Fiks.Tests/Extensions/ListExtensionsTests.cs
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.Org.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.ServiceOwner.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.SystemUser.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivConfigResolverTest.GetCaseFileClassifications_ReturnsOwnerClassification_ForKnownAuthenticationTypes.User.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.1.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.2.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.3.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.4.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/.Verify/FiksArkivDefaultPayloadGeneratorTest.GeneratePayload_GeneratesCorrectPayload.5.verified.txt
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivConfigResolverTest.cs
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/FiksArkivDefaultPayloadGeneratorTest.cs
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivDocumentsTest.cs
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/FiksArkivSettingsTest.cs
  • test/Altinn.App.Clients.Fiks.Tests/FiksArkiv/Models/MessagePayloadWrapperTest.cs
  • test/Altinn.App.Clients.Fiks.Tests/PublicApiTests.PublicApi_ShouldNotChange_Unintentionally.verified.txt

Copy link
Copy Markdown
Contributor

@martinothamar martinothamar left a comment

Choose a reason for hiding this comment

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

generally LGTM, though not sure it is safe to do PDF/A by default?

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

Labels

backport-ignore This PR is a new feature and should not be cherry-picked onto release branches feature Label Pull requests with new features. Used when generation releasenotes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Klassifikasjon av meldinger sendt via Fiks Arkiv/Sjenkebevilling

2 participants