From 6d6d4d9a5b4c3a71151631157fd5682647c41458 Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 22 Oct 2026 14:50:47 -0700 Subject: [PATCH] case 4690 - retarget net10.0; framework-matched Microsoft.* 10.0.13, Npgsql EF 10.0.3 Co-Authored-By: Claude Opus 5.5 --- .vscode/launch.json | 4 ++-- devdocs/modernization/NET10-PORT.md | 7 +++++-- server/AyaNova/AyaNova.csproj | 14 +++++++------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 18397ed0..8b080b58 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,7 +24,7 @@ "preLaunchTask": "build debug", // If you have changed target frameworks, make sure to update the program path. //#### THIS MEANS YOU JOHNNY! If the debugger fails this is the issue - "program": "${workspaceFolder}/server/AyaNova/bin/Debug/net8.0/AyaNova.dll", + "program": "${workspaceFolder}/server/AyaNova/bin/Debug/net10.0/AyaNova.dll", "args": [], "cwd": "${workspaceFolder}/server/AyaNova", "stopAtEntry": false, @@ -94,7 +94,7 @@ "preLaunchTask": "build debug subscription", // If you have changed target frameworks, make sure to update the program path. //#### THIS MEANS YOU JOHNNY! If the debugger fails this is the issue - "program": "${workspaceFolder}/server/AyaNova/bin/Debug/net8.0/AyaNova.dll", + "program": "${workspaceFolder}/server/AyaNova/bin/Debug/net10.0/AyaNova.dll", "args": [], "cwd": "${workspaceFolder}/server/AyaNova", "stopAtEntry": false, diff --git a/devdocs/modernization/NET10-PORT.md b/devdocs/modernization/NET10-PORT.md index 98370fff..5e74137a 100644 --- a/devdocs/modernization/NET10-PORT.md +++ b/devdocs/modernization/NET10-PORT.md @@ -74,7 +74,8 @@ them. Items touching those three areas carry more weight here than they did in S ## 1. Framework and packages -- [ ] `net8.0` → `net10.0`, with every framework-matched `Microsoft.*` package to 10.x in the same step (`AyaNova.csproj:3`; `raven-launcher.csproj:5`) +- [x] `net8.0` → `net10.0`, with every framework-matched `Microsoft.*` package to 10.x in the same step (`AyaNova.csproj:3`). Done for the server: JwtBearer, Mvc.NewtonsoftJson, EntityFrameworkCore, ApiDescription.Server, HealthChecks.EntityFrameworkCore → 10.0.13; Npgsql.EntityFrameworkCore.PostgreSQL → 10.0.3 (required by EF 10); `.vscode/launch.json` program paths → `net10.0`. Builds with no new code changes. `raven-launcher.csproj:5` still to do +- [ ] `raven-launcher`: `net8.0` → `net10.0` (no package references) - [x] **Hosting model.** n/a: `Program.cs:330-351` already uses `Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(...)` with `UseStartup`. Only a commented-out `BuildWebHost` line remains (`:308`) - [ ] **Asp.Versioning.** Already done: `Asp.Versioning.Mvc` and `.ApiExplorer` 8.1.0 (`AyaNova.csproj:36-37`), wired at `Startup.cs:200-217` as `AddApiVersioning(...).AddApiExplorer(...)`. Remaining: bump to 10.x and confirm `AddApiExplorer` still registers MVC versioning without an explicit `.AddMvc()`. Leave AV0014 warnings: **do not add `[ApiController]`** - [ ] **Npgsql / EF Core 10.** @@ -93,7 +94,7 @@ them. Items touching those three areas carry more weight here than they did in S - The default download is Chrome for Testing, into `Chrome/` and `ChromeHeadlessShell/` beside the app. AyaNova 8.2.0 already moved from Chromium to Chrome to follow Puppeteer's default, so the browser choice is settled - [ ] Launch arguments must be separate array elements. **Both paths are wrong today:** the defaults are one element `"--headless --no-sandbox "` (`ReportBiz.cs:812`, `:829`), and `AYANOVA_REPORT_RENDER_BROWSER_PARAMS` is passed whole as one element (`:819-822`) - AppArmor restricts unprivileged user namespaces on Ubuntu 24.04+, which affects the Chrome sandbox -- [ ] Remaining packages to current releases. MailKit 4.5.0 carries a moderate advisory (NU1902). After the upgrade, check what still pulls in `System.Text.Json` 5.0.2 +- [ ] Remaining packages to current releases. MailKit 4.5.0 carries a moderate advisory (NU1902); on `net10.0` the audit also reports high-severity NU1903 for `MimeKit` 4.5.0 and transitive `System.Security.Cryptography.Pkcs` 8.0.0. After the upgrade, check what still pulls in `System.Text.Json` 5.0.2 - [ ] Warnings: CA2022 → `ReadExactly` at `FileUtil.cs:875` (**licence build-date path**: covered by the licence gate); ASP0019 → header indexer instead of `Headers.Append` at `Startup.cs:514` - [ ] **MiniProfiler. Present, not absent.** `MiniProfiler.AspNetCore.Mvc` and `.EntityFrameworkCore` 4.3.8 (`AyaNova.csproj:48-49`); `AddMiniProfiler(...).AddEntityFramework()` (`Startup.cs:62-74`); auth workaround for `/profiler/results` (`Startup.cs:393-441`); `UseMiniProfiler()` (`Startup.cs:530`); `using StackExchange.Profiling.Internal` (`ReportBiz.cs:14`). Nothing in `raven-client`. Keep and upgrade, or remove: see Open questions - [x] **BinaryFormatter.** n/a: not used anywhere in `server/AyaNova` @@ -179,6 +180,7 @@ Found during the port, out of scope. One line each. - `License.DoFetchAsync` (`License.cs:629-661`) rethrows at `x == 3`, so the fifth server (Sockeye) is never tried, and it can return `null` to a caller that dereferences it - Stray `raven-client\ayanova\cypress.json`: the Cypress suite lives in `raven-test\e2e` +- **Race, affects production after every restart:** `FormFieldReference.FormFieldReferenceList` (`biz/FormFieldReference.cs:57-59`) builds a static dictionary lazily with no lock, assigning it before filling it. A concurrent first request sees it half-built and throws `FormFieldReferenceList: is not valid`. Seen once (`VendorCrud.CRUD`) on the first .NET 10 suite run after boot. Fix: build the dictionary fully before publishing it (`Lazy` or a static initialiser). Pre-existing, not a port change. John's decision: its own case, fixed with the other cases going into this release, not under the port ## Log @@ -188,3 +190,4 @@ Found during the port, out of scope. One line each. | 2026-10-22 | Integration baseline, `eb607d34` (unmodified, .NET 8.0.24, fresh test database) | 103 tests: 96 passed, 2 failed (the two known server bugs), 5 skipped | | 2026-10-22 | Case 4676 data-list SQL injection fix (.NET 8) | Integration suite same as baseline. API probe: valid Integer, Decimal and Roles filters return rows; `0 OR 1=1`, `0); select pg_sleep(3); --`, `1)=1 OR (1` and similar are rejected with `ArgumentException` before any SQL runs | | 2026-10-22 | `AdminConnectionString` via `NpgsqlConnectionStringBuilder` (.NET 8) | Boot database check passes; integration suite same as baseline. Old vs new on sample strings: old turned role `AyaNova` and password `AyaNova@1 x` into `postgres`, and host `ayanova.example.com` into `postgres.example.com`; new changes only `Database`. The section 4 role test still applies | +| 2026-10-22 | Retarget `net10.0` + framework-matched `Microsoft.*` 10.0.13 + Npgsql EF 10.0.3 | Builds, 0 errors (warnings: CA2022 `FileUtil.cs:875`; NU1902/NU1903 MailKit/MimeKit/Pkcs). Boots on .NET 10.0.3, licence accepted. Suite, first run after boot: 95 passed, 3 failed: the two known plus `VendorCrud.CRUD`, caused by the existing `FormFieldReference` start-up race (see Deferred); `VendorCrud` passes alone. Full rerun: 96 passed, 2 failed (known), 5 skipped = baseline. No EF warning-as-error thrown. Licence, report and E2E gates to run next on this build | diff --git a/server/AyaNova/AyaNova.csproj b/server/AyaNova/AyaNova.csproj index 73e97f67..0264c872 100644 --- a/server/AyaNova/AyaNova.csproj +++ b/server/AyaNova/AyaNova.csproj @@ -1,6 +1,6 @@ - net8.0 + net10.0 true @@ -29,27 +29,27 @@ - - + + - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + - +