Skip to content

Adopt ANcpLua.NET.Sdk 3.4.27 across .NET projects and refactor JS SDK usage#17

Closed
ANcpLua wants to merge 2 commits into
mainfrom
feat/ancplua-net-sdk-adoption
Closed

Adopt ANcpLua.NET.Sdk 3.4.27 across .NET projects and refactor JS SDK usage#17
ANcpLua wants to merge 2 commits into
mainfrom
feat/ancplua-net-sdk-adoption

Conversation

@ANcpLua
Copy link
Copy Markdown
Owner

@ANcpLua ANcpLua commented May 15, 2026

This pull request introduces several infrastructure and codebase updates to modernize the build system, improve dependency management, and enhance code quality and consistency. The most significant changes involve switching project SDKs to custom ANcpLua.NET SDKs, centralizing dependency and analyzer management, addressing security vulnerabilities in transitive dependencies, and improving code clarity and testability.

Build and Dependency Management Modernization:

  • Switched all project files (.csproj) from standard Microsoft SDKs to custom ANcpLua.NET.Sdk and ANcpLua.NET.Sdk.Web/Test SDKs, enabling centralized test stack injection, improved analyzer management, and streamlined test configuration. [1] [2] [3] [4]
  • Enabled central package version management for transitive dependencies and added explicit security overrides for vulnerable packages (NuGet.Packaging, System.Security.Cryptography.Xml) to address known GitHub security advisories. [1] [2]
  • Removed direct references to AwesomeAssertions and its analyzers from test projects, as these are now injected by the custom SDK. [1] [2] [3]

Build Process and Analyzer Configuration:

  • Updated .nuke/build.schema.json to add a Verify step to the build pipeline.
  • Configured Directory.Build.props to treat most warnings as errors, but carved out specific analyzer rule IDs for deferred cleanup, improving code quality while allowing incremental adoption.

Code Quality and Consistency Improvements:

  • Standardized static field naming to use s_ prefix for private static fields in ReportProcessor and SearchIndexService. [1] [2]
  • Simplified error handling and result conversion in TypedErrorOrAsyncExtensions by removing unnecessary static fields and using TypedResults directly. [1] [2] [3]
  • Minor code cleanups, such as returning null instead of null! where appropriate and removing redundant code in build scripts.

Test Improvements and Reliability:

  • Updated test code to consistently pass CancellationToken to Task.Delay and service methods, improving test reliability and cancellation support. [1] [2] [3] [4] [5] [6] [7]

Other Notable Changes:

  • Added documentation and comments to clarify the purpose of new properties and SDK behaviors. [1] [2] [3]

These changes collectively modernize the build and dependency management, improve security, and enhance codebase maintainability.

ANcpLua and others added 2 commits May 12, 2026 15:06
Wire each .NET project to the appropriate ANcpLua.NET.Sdk flavor (3.4.27)
through global.json's msbuild-sdks block, mirroring qyl's setup:

- Paperless.Contracts → ANcpLua.NET.Sdk (library)
- PaperlessREST, PaperlessUI.Blazor → ANcpLua.NET.Sdk.Web
- PaperlessServices → ANcpLua.NET.Sdk (worker; UseMicrosoftTestingPlatform=false,
  explicit OutputType=Exe + M.E.X usings replace Microsoft.NET.Sdk.Worker's
  implicit defaults)
- PaperlessREST.Tests → ANcpLua.NET.Sdk.Web + IsTestProject=true
  (WebApplicationFactory needs Web SDK; IsTestProject opts in Tests.targets)
- PaperlessServices.Tests → ANcpLua.NET.Sdk.Test
- Pipeline/Build.csproj stays on Microsoft.NET.Sdk by design (NUKE bootstrap
  self-contained, opts out of root CPVM)

What the SDK brings (Common.props):
  AnalysisLevel=latest-all, EnforceCodeStyleInBuild, Features=strict,
  Deterministic, embedded source link, CentralPackageTransitivePinningEnabled,
  NuGetAudit=all+low, TreatWarningsAsErrors in CI/Release, and 9 auto-injected
  editorconfigs (Global, CodingStyle, Compiler, GeneratedFiles, NamingConvention,
  per-analyzer for NetAnalyzers/BannedApiAnalyzers/xunit/AwesomeAssertions/ANcpLua).
Test projects also auto-receive AwesomeAssertions + xunit.v3.mtp-v2.

JS frontends opt into the Debug solution config via <Build Solution="Debug|*"/>
in Paperless.slnx and bump Microsoft.VisualStudio.JavaScript.Sdk to 1.0.5483906
(latest on nuget.org); <ShouldRunNpmInstall>false</ShouldRunNpmInstall> keeps
dotnet build inert for them so pnpm-lock.yaml is preserved (CI builds them via
their own pnpm jobs per CLAUDE.md).

Security: pin NuGet.Packaging 7.3.1 and System.Security.Cryptography.Xml 10.0.7
directly on Pipeline/Build.csproj (closes GHSA-g4vj-cjjj-v7hg,
GHSA-37gx-xxp4-5rgx, GHSA-w3x6-4m5h-cxqf transitive through Nuke.Common); the
same pins live in Directory.Packages.props so Paperless projects under CPVM
get them via transitive pinning.

Genuine bugs surfaced by latest-all are fixed in-tree:
  - xUnit1051: cancellation tokens threaded through Task.Delay calls in
    DocumentRepositoryIntegrationTests + ErrorOr<>.UploadDocumentAsync calls
    in DocumentServiceErrorMappingTests
  - CS1573: Document.CreateFromUpload XML doc gains <param name="timeProvider">
  - IDE0052 + IDE1006: unused TypedResults.NotFound()/NoContent() statics in
    TypedErrorOrAsyncExtensions inlined at use sites
  - IDE1006: ReportProcessor.Serializer renamed to s_serializer; SInitLock /
    SInitializedIndices renamed to s_initLock / s_initializedIndices in
    SearchIndexService
  - IDE0370: unneeded null-forgiving operators dropped on DocumentService
    TryMapStorageException return and ServiceCollectionExtensions.AddPostgres
    connection string

Style/migration warnings (AL0025/AL0026/AL0039/RS0030 BannedSymbols, CA2000,
CA1034, etc. — 371 sites mostly in test code) are surfaced as warnings but
carved out of TreatWarningsAsErrors at Directory.Build.props via
WarningsNotAsErrors, scheduled for follow-up cleanup PRs per qyl's pattern.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace both PaperlessUI.{Angular,React}.esproj projects with the qyl
hand-rolled MSBuild pattern (qyl/services/qyl.dashboard/qyl.dashboard.esproj),
adapted for pnpm. No more <Project Sdk=...>; custom Restore/Build/Test/Clean
targets shell to pnpm only when RunFrontendOnBuild=true, defaulting to no-op
so CI's dedicated frontend jobs remain the single source of truth.

Removes the entire shim stack that existed only to neutralize the JS SDK:
  - <Project Sdk="Microsoft.VisualStudio.JavaScript.Sdk/1.0.5483906">
  - <ShouldRunBuildScript>false</ShouldRunBuildScript>
  - <ShouldRunNpmInstall>false</ShouldRunNpmInstall>
  - <JavaScriptTestRoot>src\</JavaScriptTestRoot>           (VS-Windows only)
  - <JavaScriptTestFramework>Jasmine|Vitest</...>           (VS-Windows only)
  - <BuildOutputFolder>$(MSBuildProjectDirectory)\dist\...> (backslashes leaked
    literal 'obj\Debug' folders on macOS/Linux every time dotnet build ran)
  - <Build Solution="Debug|*"/> opt-in in Paperless.slnx (only needed because
    the JS SDK ignored projects that weren't explicitly selected per config)

The bootstrap commit (02ce2b3, today 01:34 UTC+2) hand-typed SDK version
1.0.1641815, which is a Visual Studio Windows internal build number from the
IDE's private NuGet feed and never published to nuget.org — that's why
dotnet build outside VS-Windows failed to resolve it. Dropping the SDK
entirely removes the version-pinning fragility for good.

Both projects still surface their source trees to Rider's solution explorer
via <None Include="src/**/*"/> etc., and 'dotnet build Paperless.slnx'
remains green (0 errors). Real frontend builds keep happening in the pnpm CI
jobs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 15, 2026 14:23
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8c8d3320-fb53-44ef-97ce-160153f09648

📥 Commits

Reviewing files that changed from the base of the PR and between dd6f947 and 98959af.

⛔ Files ignored due to path filters (19)
  • .nuke/build.schema.json is excluded by none and included by none
  • Paperless.Contracts/Paperless.Contracts.csproj is excluded by none and included by none
  • PaperlessREST.Tests/Integration/DocumentRepositoryIntegrationTests.cs is excluded by none and included by none
  • PaperlessREST.Tests/PaperlessREST.Tests.csproj is excluded by none and included by none
  • PaperlessREST.Tests/Unit/DocumentServiceErrorMappingTests.cs is excluded by none and included by none
  • PaperlessREST/Features/BatchProcessing/Application/ReportProcessor.cs is excluded by none and included by none
  • PaperlessREST/Features/DocumentManagement/Application/Document.cs is excluded by none and included by none
  • PaperlessREST/Features/DocumentManagement/Application/DocumentService.cs is excluded by none and included by none
  • PaperlessREST/Host/Extensions/ServiceCollectionExtensions.cs is excluded by none and included by none
  • PaperlessREST/Host/Extensions/TypedErrorOrAsyncExtensions.cs is excluded by none and included by none
  • PaperlessREST/PaperlessREST.csproj is excluded by none and included by none
  • PaperlessServices.Tests/PaperlessServices.Tests.csproj is excluded by none and included by none
  • PaperlessServices/Features/OcrProcessing/Infrastructure/Search/SearchIndexService.cs is excluded by none and included by none
  • PaperlessServices/PaperlessServices.csproj is excluded by none and included by none
  • PaperlessUI.Angular/PaperlessUI.Angular.esproj is excluded by none and included by none
  • PaperlessUI.Blazor/PaperlessUI.Blazor.csproj is excluded by none and included by none
  • PaperlessUI.React/PaperlessUI.React.esproj is excluded by none and included by none
  • Pipeline/Build.csproj is excluded by none and included by none
  • global.json is excluded by none and included by none
📒 Files selected for processing (2)
  • Directory.Build.props
  • Directory.Packages.props
📜 Recent review details
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: copilot-pull-request-reviewer
  • GitHub Check: Codacy Static Code Analysis
🧰 Additional context used
📓 Path-based instructions (1)
**/*.props

⚙️ CodeRabbit configuration file

MSBuild property files (Directory.Build.props, Directory.Packages.props, Version.props). Review for: Central Package Management correctness, version consistency, and that new packages are added with explicit version pins. Flag transitive dependency promotions that aren't justified. Verify TFM targeting is correct (.NET 10).

Files:

  • Directory.Build.props
  • Directory.Packages.props
🔇 Additional comments (2)
Directory.Build.props (1)

3-15: LGTM!

Directory.Packages.props (1)

7-10: LGTM!

Also applies to: 42-42, 78-83


Summary by CodeRabbit

Chores

  • Optimierte Build- und Compiler-Konfiguration für verbesserte Projekteinstellungen und Warning-Handling
  • Aktivierte zentrale Paket-Verwaltung mit strikteren Versionskontrolle
  • Sicherheits-Updates für kritische Paketabhängigkeiten durchgeführt und transitive Versionen stabilisiert

Walkthrough

Die Änderung aktualisiert zentrale MSBuild-Eigenschaften: TestingPlatformDotnetTestSupport wird durch WarningsNotAsErrors mit definierten Regel-Ausnahmen ersetzt; parallel wird transitive Paket-Pinning aktiviert, Test-Paket-Versionen entfernt und Sicherheitsübersteuerungen für NuGet.Packaging und System.Security.Cryptography.Xml hinzugefügt.

Changes

Zentrale Build-Konfiguration

Layer / File(s) Summary
Warnungsbehandlung und Analyzer-Ausnahmen
Directory.Build.props
TestingPlatformDotnetTestSupport wird entfernt; WarningsNotAsErrors definiert explizite Regel-IDs (AL0025 bis IDE1006), die trotz aktivierter TreatWarningsAsErrors nicht als Fehler behandelt werden.
Transitive Paket-Pinning und Sicherheitsübersteuerungen
Directory.Packages.props
CentralPackageTransitivePinningEnabled wird aktiviert, um Pinning transitiv zu propagieren; AwesomeAssertions-Versionen werden entfernt (jetzt über ANcpLua.NET.Sdk.Test verwaltet); NuGet.Packaging (7.3.1) und System.Security.Cryptography.Xml (10.0.7) werden als Sicherheits-Pins explizit festgenagelt.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • ANcpLua/Paperless#10: Identische Änderungen an beiden MSBuild-Konfigurationsdateien (Entfernung von TestingPlatformDotnetTestSupport, Hinzufügung von WarningsNotAsErrors, Aktivierung von CentralPackageTransitivePinningEnabled, Entfernung von AwesomeAssertions-Versionen und Pinning von Sicherheitspaketen).
  • ANcpLua/Paperless#15: Modifiziert die WarningsNotAsErrors-Konfiguration in Directory.Build.props direkt (PR #15 entfernt sie, während diese PR sie reintroduziert).
  • ANcpLua/Paperless#16: Ändert die gleiche MSBuild-Property WarningsNotAsErrors (diese PR erweitert sie, PR #16 entfernt sie), beeinflussend welche Analyzer-Regel-IDs von TreatWarningsAsErrors ausgenommen sind.

Suggested labels

area:infra


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Title check ❌ Error Der Titel ist 75 Zeichen lang und überschreitet damit die 72-Zeichen-Grenze; zudem verwendet er kein konventionelles Commit-Format mit Präfix (feat|fix|refactor|chore) und Scope. Verwenden Sie ein konventionelles Commit-Format wie 'chore(infra): adopt ANcpLua.NET.Sdk 3.4.27' und halten Sie es unter 72 Zeichen.
Cancellationtoken Threading ⚠️ Warning Public async method ExtractTextAsync lacks CancellationToken parameter. Cannot forward token from caller OcrProcessor. Add CancellationToken to IPdfExtractor.ExtractTextAsync and CreatePdfExtractor implementation. Forward token in OcrProcessor line 29 call.
✅ Passed checks (6 passed)
Check name Status Explanation
Description check ✅ Passed Die Beschreibung ist detailliert und bezieht sich vollständig auf die Änderungen im Changeset—SDK-Migration, Abhängigkeitsverwaltung, Sicherheitsübersteuerungen und Code-Qualitätsverbesserungen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Otel Instrumentation Required ✅ Passed Diese PR fügt keine neuen injectable Services hinzu. Sie enthält hauptsächlich SDK-Upgrades und Package-Management-Änderungen. Alle bestehenden Services wurden nicht neu hinzugefügt.
No Unbounded Mcp Responses ✅ Passed No MCP tool definitions (src/qyl.mcp/) exist in this .NET project. This PR modifies only build configuration files (Directory.Build.props, Directory.Packages.props) with no MCP-related changes.
Duckdb Backpressure On Write Paths ✅ Passed PR enthält keine neuen DuckDB-Code-Pfade. Check ist nicht anwendbar; ändert hauptsächlich Build-Infrastruktur und SDK-Versionen ohne Datenbanklogik-Änderungen.
✨ Finishing Touches
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/ancplua-net-sdk-adoption

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

@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 101 complexity · 15 duplication

Metric Results
Complexity 101
Duplication 15

View in Codacy

AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR modernizes the repo’s .NET build/dependency setup by adopting ANcpLua.NET.Sdk v3.4.27 across projects, centralizing package/analyzer management, and decoupling the frontend .esproj files from the fragile Microsoft.VisualStudio.JavaScript.Sdk packaging.

Changes:

  • Adopt ANcpLua.NET.Sdk/.Web/.Test (3.4.27) across .NET projects and adjust project properties accordingly.
  • Enable central transitive package pinning and add explicit security override versions for NuGet.Packaging and System.Security.Cryptography.Xml.
  • Replace VS JavaScript SDK-based .esproj files with hand-rolled MSBuild projects that are CI-friendly and keep dotnet build working.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
Pipeline/Build.csproj Adds explicit package overrides to address vulnerable transitive dependencies in the NUKE toolchain.
PaperlessUI.React/PaperlessUI.React.esproj Replaces VS JavaScript SDK usage with a minimal MSBuild project shell (no-op by default).
PaperlessUI.Blazor/PaperlessUI.Blazor.csproj Switches to ANcpLua.NET.Sdk.Web and updates packaging settings.
PaperlessUI.Angular/PaperlessUI.Angular.esproj Replaces VS JavaScript SDK usage with a minimal MSBuild project shell (no-op by default).
PaperlessServices/PaperlessServices.csproj Migrates worker project to ANcpLua.NET.Sdk and compensates for lost Worker-SDK implicit usings.
PaperlessServices/Features/OcrProcessing/Infrastructure/Search/SearchIndexService.cs Renames private static fields to s_ prefix for consistency.
PaperlessServices.Tests/PaperlessServices.Tests.csproj Migrates test project to ANcpLua.NET.Sdk.Test and relies on SDK-injected test stack.
PaperlessREST/PaperlessREST.csproj Migrates REST API project to ANcpLua.NET.Sdk.Web and adjusts packaging settings.
PaperlessREST/Host/Extensions/TypedErrorOrAsyncExtensions.cs Simplifies result conversion by using TypedResults directly instead of cached static results.
PaperlessREST/Host/Extensions/ServiceCollectionExtensions.cs Tweaks Postgres configuration wiring (notably connection string retrieval).
PaperlessREST/Features/DocumentManagement/Application/DocumentService.cs Minor cleanup in exception-to-domain-error mapping (null!null).
PaperlessREST/Features/DocumentManagement/Application/Document.cs Documentation update to clarify injected TimeProvider usage for testability.
PaperlessREST/Features/BatchProcessing/Application/ReportProcessor.cs Renames serializer static field to match s_ convention.
PaperlessREST.Tests/Unit/DocumentServiceErrorMappingTests.cs Updates tests to pass CancellationToken through service calls.
PaperlessREST.Tests/PaperlessREST.Tests.csproj Migrates test project SDK usage and relies on SDK-injected AwesomeAssertions/analyzers via IsTestProject.
PaperlessREST.Tests/Integration/DocumentRepositoryIntegrationTests.cs Passes CancellationToken to Task.Delay calls for better cancellation behavior.
Paperless.Contracts/Paperless.Contracts.csproj Migrates contracts project to ANcpLua.NET.Sdk.
global.json Pins ANcpLua.NET.* MSBuild SDK versions to 3.4.27.
Directory.Packages.props Enables transitive pinning and centralizes security override versions; removes direct AwesomeAssertions version management.
Directory.Build.props Adds WarningsNotAsErrors carve-outs for incremental analyzer cleanup.
.nuke/build.schema.json Adds a Verify target to the NUKE schema.

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

private IServiceCollection AddPostgres(IConfiguration config)
{
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(config.GetConnectionString("PaperlessDb")!)
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(config.GetConnectionString("PaperlessDb"))
Comment on lines +24 to +28
<Target Name="Build" DependsOnTargets="Restore">
<Message Text="[PaperlessUI.React] Build is a no-op; pnpm run build runs in the CI frontend job." Importance="low"/>
<Exec Command="$(PnpmExe) install --frozen-lockfile=false" WorkingDirectory="$(FrontendRoot)" Condition=" '$(RunFrontendOnBuild)' == 'true' "/>
<Exec Command="$(PnpmExe) run build" WorkingDirectory="$(FrontendRoot)" Condition=" '$(RunFrontendOnBuild)' == 'true' "/>
</Target>

<Target Name="Build" DependsOnTargets="Restore">
<Message Text="[PaperlessUI.Angular] Build is a no-op; pnpm run build runs in the CI frontend job." Importance="low"/>
<Exec Command="$(PnpmExe) install --frozen-lockfile=false" WorkingDirectory="$(FrontendRoot)" Condition=" '$(RunFrontendOnBuild)' == 'true' "/>
Copy link
Copy Markdown

@codacy-production codacy-production Bot left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces several infrastructure improvements, but contains critical errors that will prevent a successful build. Specifically, the package versions specified in Directory.Packages.props (7.3.1 and 10.0.7) are invalid and do not exist on the public NuGet gallery.

Furthermore, there is a major misalignment between the PR metadata and the code changes: the title and description mention 'refactoring JS SDK usage' and switching project-level SDKs in .csproj files, but no such changes appear in the diff. Beyond these blockers, there are logic issues regarding potential ArgumentNullException in the database setup and several quality findings related to high method complexity and incomplete assertions in integration tests.

About this PR

  • The description claims project files (.csproj) were switched from standard Microsoft SDKs to custom ones, but the diff only shows SDK version updates in global.json. If project-level changes were intended, they appear to be missing from this commit.
  • The PR title and description mention refactoring 'JS SDK usage', but no JavaScript files, npm packages, or JS-related logic are included in the code changes. Please ensure the PR description accurately reflects the scope of the changes.
3 comments outside of the diff
PaperlessREST.Tests/Integration/DocumentRepositoryIntegrationTests.cs

line 325-38111 🟡 MEDIUM RISK
The local variables 'hasMore' and 'hasMoreSecond' are unused. Add assertions to verify these flags or use a discard if the values are intentionally ignored.

PaperlessREST/Features/BatchProcessing/Application/ReportProcessor.cs

line 65 🟡 MEDIUM RISK
This method has high cyclomatic complexity and length. Consider extracting the XML schema validation and the deserialization logic into dedicated private methods to improve testability and readability.

PaperlessREST/Host/Extensions/ServiceCollectionExtensions.cs

line 123 🟡 MEDIUM RISK
Suggestion: This dependency injection registration method is too large (168 lines). It is recommended to break this down into logical feature-based extension methods such as 'AddDatabaseServices', 'AddMessaging', or 'AddDocumentFeature'.

Test suggestions

  • Verify CentralPackageTransitivePinningEnabled is set to true to ensure security overrides propagate.
  • Verify that Task.Delay calls in DocumentRepositoryIntegrationTests receive the CancellationToken from TestContext.
  • Verify that private static fields in ReportProcessor and SearchIndexService follow the 's_' naming convention.
  • Verify the 'Verify' target is present in the NUKE build schema.
  • Verify that DocumentService.UploadDocumentAsync calls in tests propagate the CancellationToken.
  • Assert the value of 'hasMore' in DocumentRepositoryIntegrationTests.cs to verify pagination completeness.
  • Assert the value of 'hasMoreSecond' in DocumentRepositoryIntegrationTests.cs to verify multi-page pagination.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Assert the value of 'hasMore' in DocumentRepositoryIntegrationTests.cs to verify pagination completeness.
2. Assert the value of 'hasMoreSecond' in DocumentRepositoryIntegrationTests.cs to verify multi-page pagination.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

Comment thread Directory.Packages.props
Comment on lines +82 to +83
<PackageVersion Include="NuGet.Packaging" Version="7.3.1" />
<PackageVersion Include="System.Security.Cryptography.Xml" Version="10.0.7" />
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 HIGH RISK

Update the package versions to match the stable releases mentioned in the comment to ensure a successful build. The versions 7.3.1 and 10.0.7 do not exist for these packages.

Suggested change
<PackageVersion Include="NuGet.Packaging" Version="7.3.1" />
<PackageVersion Include="System.Security.Cryptography.Xml" Version="10.0.7" />
<PackageVersion Include="NuGet.Packaging" Version="6.12.1" />
<PackageVersion Include="System.Security.Cryptography.Xml" Version="9.0.1" />

private IServiceCollection AddPostgres(IConfiguration config)
{
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(config.GetConnectionString("PaperlessDb")!)
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(config.GetConnectionString("PaperlessDb"))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM RISK

Add a guard clause to handle missing connection strings explicitly, which improves error clarity and satisfies the compiler when NRT is enabled.

Suggested change
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(config.GetConnectionString("PaperlessDb"))
string connectionString = config.GetConnectionString("PaperlessDb") ?? throw new InvalidOperationException("Connection string 'PaperlessDb' not found.");
NpgsqlDataSource dataSource = new NpgsqlDataSourceBuilder(connectionString)

private static readonly NotFound NotFound = TypedResults.NotFound();
private static readonly NoContent NoContent = TypedResults.NoContent();

private static ValidationProblem CreateValidationProblem(IReadOnlyList<Error> errors) =>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ LOW RISK

Nitpick: Re-introduce the cached static instances for NotFound and NoContent results to maintain performance and reduce allocations in high-traffic scenarios.

Copy link
Copy Markdown

@codacy-production codacy-production Bot left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR successfully adopts ANcpLua.NET.Sdk 3.4.27 and implements central package pinning to address transitive security vulnerabilities. While the codebase is generally up to standards according to Codacy, there are critical discrepancies and logic gaps that must be addressed before merging.

Most importantly, there is a temporal inconsistency in the Document entity where TimeProvider is ignored during GUID v7 generation, which will lead to non-deterministic behavior in tests. Additionally, the PR title and description mention refactors (JS SDK and Directory.Build.props) that are completely absent from the file diff, suggesting a partial commit or misleading metadata. Finally, thread-safety concerns in ReportProcessor and excessive complexity in XML parsing should be resolved to ensure system stability.

About this PR

  • The PR title references 'refactor JS SDK usage' and the description mentions 'Directory.Build.props' configuration, but neither of these changes are present in the submitted files. Please verify if some files were missed in the commit.
4 comments outside of the diff
PaperlessREST.Tests/Integration/DocumentRepositoryIntegrationTests.cs

line 325 🟡 MEDIUM RISK
The local variable 'hasMore' is declared but never used. Replacing it with a discard improves code clarity: (List<Document> results, _) = await _repository.

line 381 🟡 MEDIUM RISK
The local variable 'hasMoreSecond' is not used in this test. Consider using a discard to simplify the assignment: (List<Document> secondPage, _) = await _repository.

PaperlessREST/Features/BatchProcessing/Application/ReportProcessor.cs

line 65 🟡 MEDIUM RISK
This method is doing too much and is difficult to test in isolation. Consider extracting the XmlReaderSettings configuration and the AccessReportDto validation logic into separate private methods. Specifically, extract GetXmlReaderSettings and a ValidateReportDto method to reduce cyclomatic complexity and improve readability.

PaperlessREST/Features/DocumentManagement/Application/Document.cs

line 104 🟡 MEDIUM RISK
The timeProvider is ignored when generating the Version 7 GUID. In tests, this leads to a mismatch between the document's CreatedAt timestamp (mocked) and the timestamp embedded in the Id (real system clock). Since .NET's Guid.CreateVersion7() does not currently support a custom timestamp override, this creates a temporal inconsistency in the domain entity metadata.

Test suggestions

  • Verify that Document.CreateFromUpload correctly uses the injected TimeProvider for CreatedAt and StoragePath generation.
  • Verify that SearchIndexService correctly handles concurrent initialization using the renamed s_initLock.
  • Verify that ReportProcessor correctly deserializes reports using the renamed s_serializer.
  • Verify that DocumentRepositoryIntegrationTests successfully cancel operations when a CancellationToken is triggered during Task.Delay.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Verify that Document.CreateFromUpload correctly uses the injected TimeProvider for CreatedAt and StoragePath generation.
2. Verify that SearchIndexService correctly handles concurrent initialization using the renamed s_initLock.
3. Verify that ReportProcessor correctly deserializes reports using the renamed s_serializer.
Low confidence findings
  • While central package pinning is enabled in Directory.Packages.props, there is no verification that the build process correctly resolves to these pinned versions. Consider adding a build-time check or confirming via logs.

TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback

private static readonly XmlSerializer Serializer = new(typeof(AccessReportDto));
private static readonly XmlSerializer s_serializer = new(typeof(AccessReportDto));

private XmlSchemaSet Schemas => field ??= LoadSchemas();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ LOW RISK

Suggestion: Lazy initialization with field ??= is not thread-safe. Concurrent requests may cause LoadSchemas() to run multiple times. Consider using LazyInitializer.EnsureInitialized or a Lazy<XmlSchemaSet> field to ensure the schema set is built only once in a thread-safe manner.

@ANcpLua
Copy link
Copy Markdown
Owner Author

ANcpLua commented May 15, 2026

Superseded — the substantive changes here landed via PR #10 (18d606f adopt ANcpLua.NET.Sdk 3.4.27) and PR #11 (9565e43 drop JavaScript SDK shims). The SDK pin has since been bumped past 3.4.27 to 3.4.29 via PR #15. Closing as obsolete; nothing of value to merge.

Branch feat/ancplua-net-sdk-adoption may be deleted at convenience.

@ANcpLua ANcpLua closed this May 15, 2026
@ANcpLua ANcpLua deleted the feat/ancplua-net-sdk-adoption branch May 16, 2026 02:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants