Skip to content

Upgrade to LTS versions of .NET 10 and NodeJS 24#120

Open
rlorenzo wants to merge 37 commits intomainfrom
upgrade/lts-dotnet10-node24
Open

Upgrade to LTS versions of .NET 10 and NodeJS 24#120
rlorenzo wants to merge 37 commits intomainfrom
upgrade/lts-dotnet10-node24

Conversation

@rlorenzo
Copy link
Copy Markdown
Contributor

@rlorenzo rlorenzo commented Mar 20, 2026

Summary

LTS upgrade bringing VIPER2 to .NET 10 + Node.js 24, with support through late 2028. Beyond the runtime bump, this branch replaces several libraries that had licensing, security, or governance concerns — and modernizes DX patterns across the stack.

  • .NET 8 → 10, EF Core 8 → 10, Node.js 20 → 24, Vite 7 → 8 (Rolldown). Current versions EOL: .NET 8 on Nov 10, 2026, Node.js 20 on Apr 30, 2026.
  • AutoMapper → Mapperly — compile-time source-generated mapping, resolves NU1903 vulnerability and avoids new commercial license
  • Moq → NSubstitute — actively maintained replacement, addresses SponsorLink governance risk
  • Scrutor convention-based DI — auto-discovers services, eliminates manual registration boilerplate
  • DbContext DI pattern — 6 contexts migrated from OnConfiguring() to proper DI
  • Vue Composition API — all 8 SPAs migrated to <script setup lang="ts">
  • oxfmt + oxlint — faster formatting/linting, 210 warnings resolved
  • 20+ NuGet and 9 npm major version bumps across the full dependency tree
  • 1,099 backend + 575 frontend tests passing

DX Improvements

Scrutor Auto-Registration

Replaced 18+ manual AddScoped<IService, Service>() lines in Program.cs with convention-based auto-discovery. New services matching the *Service / *Validator naming pattern are registered automatically — no manual wiring needed.

AutoMapper → Mapperly

Replaced AutoMapper (which had a high-severity DoS vulnerability and moved to a commercial license) with Mapperly, a compile-time source-generator mapper. Benefits:

  • Zero runtime reflection — mapping code is generated at build time
  • Strongly typed — mapping errors caught at compile time, not runtime
  • No DI registration — removed IMapper injection from ~15 service constructors
  • Apache 2.0 licensed — no license keys or restrictions
  • Migrated 24 mapping definitions and ~85 call sites across CTS and Effort areas

Moq → NSubstitute

Replaced Moq (abandoned since the SponsorLink incident) with NSubstitute across all 64 test files. NSubstitute is actively maintained by multiple contributors. Cleaner API — no mock.Object unwrapping, no .Setup() ceremony.

Libman Build Optimization

Moved libman restore from running on every build to a one-time pre-dev restore. Eliminates race conditions during concurrent builds and speeds up the inner dev loop.

DbContext DI Pattern

Migrated 6 DbContext classes from OnConfiguring() connection string hardcoding to proper AddDbContext<T>() dependency injection in Program.cs. The OnConfiguring() pattern is deprecated in EF Core 10 in favor of constructor-injected options — aligning with ASP.NET Core's DI-first design.

Vue Composition API

Migrated all 8 SPA entry points and layouts from Options API to <script setup lang="ts">. Removed legacy v-cloak directives, this.$route/this.$router, and ref() inside data() anti-patterns.

Build Warnings Cleanup

Reduced .NET build warnings from 125 → 25 (80% reduction). Fixed 21 critical nullability warnings (CS8603/CS8618/CS8604), 40 mechanical LINQ/style warnings, 22 low-risk warnings, 4 throw new Exception → specific types, and 10 design/naming issues. Test project warnings dropped from 64 to 2.

Linting & Formatting

  • Replaced Prettier with oxfmt (faster, deterministic formatting)
  • Added oxlint and resolved 210 frontend warnings (151 wwwroot + 59 Vue)
  • Added reactivity linting rules for Vue/Pinia patterns
  • Extracted bootstrapSpa() helper to DRY multi-SPA entry points

Performance

Vitest ~20% faster

Frontend test suite averages 16.1s (down from 20.2s). Environment setup ~27% faster.

Vite 8 with Rolldown

Build pipeline upgraded to Vite 8, powered by Rolldown (Rust-based bundler).

EF Core 10 JIT Improvements

Free server-side performance gains from better inlining and devirtualization in .NET 10.

EndsWith(char) SQL Translation

EF Core 10 now translates EndsWith('R') char overloads to SQL — removed #pragma warning disable S6610 suppressions from 4 Effort service files.

Security

  • Resolved NU1903 high-severity DoS vulnerability (GHSA-rvv3-g6hj-g44x) by removing AutoMapper
  • Removed Moq (governance risk — SponsorLink data collection incident)
  • Removed dead EntityFrameworkCore.Testing.Moq dependency
  • Removed System.Linq.Async — .NET 10 has built-in System.Linq.AsyncEnumerable
  • Node.js 24.13.0+ includes fixes for CVE-2025-59465, CVE-2025-55132, CVE-2025-55130, CVE-2026-21637

Backend Tests

1,099 backend tests passing. 575 frontend tests passing.

rlorenzo added 28 commits March 18, 2026 10:37
…tion

- Upgrade from .NET 8 to .NET 10 across all projects and packages
- Centralize DbContext connection strings in Program.cs with fail-fast
  null validation, removing scattered OnConfiguring methods
- Add Scrutor for convention-based service registration, replacing 30+
  manual service registrations with namespace-based auto-discovery
- Convert LibMan from global tool to local dotnet tool for consistent
  versioning across dev environments
- Update Jenkins pipeline for net10.0 output paths and libman restore
- Modernize routing from UseEndpoints to minimal API MapControllerRoute
- Upgrade Node.js from 20.19.4 to 24.13.0 LTS with security patches
- Migrate 11 Vue files from Options API to Composition API with script setup
- Replace this.$route/this.$router with useRoute()/useRouter() composables
- Remove deprecated v-cloak directives across layout files
- Update @tsconfig/node24 and @types/node to v24 compatible versions
- Remove unused using statements across C# codebase
- Normalize TypeScript/Vue code style (quotes, trailing commas)
- Make ApiController helper methods static
- Update TypeScript target to ES2023
- Improve oxlint config and generic null checks
- Replace EndsWith(string) with EndsWith(char) and remove
  S6610 pragma suppressions across four Effort services
- Convert App.vue to script setup, remove v-cloak directive
- Replace AutoMapper.Extensions.Microsoft.DependencyInjection with AutoMapper 14.0.0 (last MIT-licensed; DI extension folded into core)
- Upgrade NLog 5.3→6.1 and add NLog.MailKit for mail target (now a separate package)
- Major bumps: QuestPDF 2025.12.4, Scrutor 7.0, Razor.Templating.Core 3.0, Joonasw.SecurityHeaders 6.0
- Test infra: xunit 2.9.3, coverlet 6.0.4, SonarAnalyzer 10.19
- Microsoft.NET.Test.Sdk 18.0.1, xunit runner 3.1.5,
  JunitXml.TestLogger 8.0.0
- Remove System.Linq.Async (built into .NET 10),
  EntityFrameworkCore.Testing.Moq (unused),
  System.Security.Claims (built into .NET 10)
- Add AutoMapper to test project for mapping tests
- Replace vuedraggable with vue-draggable-plus (unmaintained → active)
- Replace manual event/keyboard/timer code with useKeyModifier, useEventListener, useTimeoutFn
- Bump vue-router 5, vueuse 14, vitest 4, stylelint 17, glob 13, chokidar 5, cross-env 10
- @eslint/js now required as explicit dep (unbundled in v10)
- eslint-plugin-security ^3→^4, eslint-plugin-html ^8.1.4
  (minimum for ESLint 10 context.sourceCode API)
- typescript-eslint ^8.56, eslint-plugin-vue ^10.8,
  vuejs-accessibility ^2.5 for ESLint 10 peer deps
- Remove unused eslint-plugin-quasar (v0.17→v1 migration rules)
- oxfmt 0.35 replaces Prettier; lint-any.js
simplified (no double-pass)
- oxlint 1.29→1.50, tsgolint 0.8→0.14.1; config
migrated to ignorePatterns
- VS Code default formatter switched to oxc extension
- Make PermissionService/PhotoGalleryService stateless methods static
  (class-methods-use-this errors)
- Reduce complexity in ViperFetch and lint-staged-dotnet by extracting
  helpers (complexity errors)
- Add vitest/globals tsconfig to eliminate 40 redundant test imports
- Apply auto-fixes: capitalized comments, prefer-const, !!x→Boolean(x),
  matcher improvements, no-loop-func suppressions
- Remove tsconfig noCheck to enforce type safety in tests
- Fix EffortDbContext to use VIPER connection string (same DB)
- Delete obsolete shims-vue.d.ts and remove auto-imported Vue macros
…arnings

- Align @vitest/coverage-v8 with vitest 4 peer dependency
- Fix Effort router import to match named export
- Eliminate DEP0190 warnings in build scripts by passing
  command+args as single string to spawn with shell: true
- Change downloadFile from static to instance method call after
  ClosedXML replaced OpenXml on main
- Update photo-gallery-store test mock to match instance method
- Add non-null assertions to VPR-48 test files for strict TS
- Fix self-referential type annotations in effort column tests
…injection

- Remove parameterless constructors in CMS, LeftNavMenu, and
  SessionTimeoutService that resolved DbContexts via HttpHelper
- Inject AAUDContext into DirectoryController and extract
  IndividualSearchResult.LookupEmailHost() to avoid inline context creation
- Thread VIPERContext through AreaController, ApiSessionUpdateFilter,
  HomeController, and LayoutController for session timeout calls
- Vite ^7.1.11 → ^8.0.0 (4.2x faster production builds)
- Enable experimental bundledDev mode for 8x faster dev page loads
- Rename rollupOptions → rolldownOptions per migration guide
- Remove rollup-plugin-visualizer and vite-plugin-vue-inspector
  (visualizer redundant with Codecov; inspector pending bundledDev
  compatibility fix upstream)
- Remove hash-based proxy skip in ViteProxyHelpers.cs so bundledDev
  memory-served assets are forwarded to Vite in dev mode
- Add @quasar/vite-plugin override for Vite 8 peer dep
- Enable server.forwardConsole for browser→terminal log forwarding
- Fix CTS router guard: check permissions !== undefined to prevent
  crash exposed by Rolldown's module initialization order
- Fix 8 VueApp errors: extract downloadFile from class, remove
  unused imports, suppress config default-export rules
- Fix 33 wwwroot errors in site.js/qtable.js: var→let/const,
  void→undefined, isNaN→Number.isNaN, remove BOMs, unused
  params, optional catch binding, forEach→for...of
- Fix remaining 18 wwwroot errors: extract wrapCsvValue from
  class, add .catch() to promise chain, fix param reassignment,
  suppress import/unambiguous for script files
- Bump MailKit 4.15.0→4.15.1 to match MimeKit
…ethods

- Make RoleBelongsToInstance, RoleTemplateBelongsToInstance, and
  PermissionBelongsToInstance static since they use no instance state
- Replace foreach+if nesting with .Where()/.Select() across RAPS,
  CMS, CTS, Students, and shared components
- Fix ViteProxy to correctly proxy /2/vue/assets/ paths
- Add VueTableDefault unit tests and pre-filter skipColumns
- Use async APIs: RenderSectionAsync in layouts, ToListAsync/BeginTransactionAsync in services
- Fix CS8604 nullability in ApiController sort helpers (null-forgiving after existing guard)
- Fix CS8602 in LeftNav by removing unnecessary null-conditional operator
- Specify DateTimeKind.Local for DateTime constructors in Offering and test setup
- Suppress S3251 partial methods for EF scaffold files via scoped .editorconfig glob
- Remove unused AssetHashRegex and dead constants from ViteProxyHelpers
- Replace throw new Exception with specific types (S112, 4 files)
- Make GradYearClassLevel static with ImmutableArray (S1118/S3887/S2386)
- Rename VwException → VwAaudExemption to avoid S2166
- Remove overlapping method signatures (S3427, 3 files)
- Fix IndexOf > 0 → Contains, add [HttpGet], auto-properties
- Merge duplicate test methods in ViteProxyHelpersTest (S4144)
- Modernize JS: strict equality, template literals, globalThis,
  named constants, destructuring, Object.hasOwn() guard
- Extract populateErrorTarget helper to reduce nesting depth
- Rename vueSetup.js → vue-setup.js for kebab-case compliance
- Add oxlint-disable with reasons for intentional skips
  (max-params, prefer-await-to-then, new-cap, no-magic-numbers)
- Add process.exit(1) when oxfmt check fails in lint-any.js
- Apply oxfmt formatting to 13 files that slipped through
- All 8 SPA entry files reduced to a single bootstrapSpa() call
- bootstrapSpa guards against mounting on wrong path via VITE_VIPER_HOME
- Jenkins pipeline updated to Node.js 24.14.0
- Updated README.md to reflect new versions
- Replace Moq/MockQueryable.Moq with NSubstitute/MockQueryable.NSubstitute
  across all 66 test files
- Fix lint warnings: add missing await on async mock verifications, specify
  DateTimeKind.Local, remove unused variables
- Use --artifacts-path in test runner for isolation from dev server
- Fix EmailService.GetRequestContext to handle missing route data gracefully
- Sort package.json scripts alphabetically and add clear-cache command
…appers

 - Eliminates runtime reflection and NU1903 vulnerability (GHSA-rvv3-g6hj-g44x)
 - Apache 2.0 licensed, no commercial license key required
…patterns

- Add eslint-plugin-harlanzw with 10 Vue reactivity rules as warnings
- Enable ESLint caching (--cache --cache-strategy content) for faster lint runs
- Extract async onMounted callbacks into named functions across 15 components
- Convert defineProps/defineEmits to type-based syntax and Pinia stores to setup API
Copilot AI review requested due to automatic review settings March 20, 2026 07:04
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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of files (300). Try reducing the number of changed files and requesting a review from Copilot again.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 20, 2026

Codecov Report

❌ Patch coverage is 40.78947% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.66%. Comparing base (f7542a9) to head (98e2b48).

Files with missing lines Patch % Lines
VueApp/src/composables/ViperFetch.ts 0.00% 12 Missing ⚠️
VueApp/src/store/ErrorStore.ts 9.09% 10 Missing ⚠️
...c/ClinicalScheduler/services/permission-service.ts 66.66% 4 Missing ⚠️
VueApp/src/store/UserStore.ts 69.23% 4 Missing ⚠️
...rc/ClinicalScheduler/stores/permissions-actions.ts 25.00% 3 Missing ⚠️
...ueApp/src/Students/stores/photo-gallery-helpers.ts 0.00% 3 Missing ⚠️
VueApp/src/Effort/services/report-service.ts 33.33% 2 Missing ⚠️
...App/src/Students/services/photo-gallery-service.ts 0.00% 2 Missing ⚠️
...ueApp/src/Students/stores/photo-gallery-actions.ts 50.00% 2 Missing ⚠️
VueApp/src/composables/ErrorHandler.ts 33.33% 2 Missing ⚠️
... and 1 more
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #120       +/-   ##
===========================================
+ Coverage   26.31%   42.66%   +16.34%     
===========================================
  Files        1027      802      -225     
  Lines       82761    48441    -34320     
  Branches     4560     4445      -115     
===========================================
- Hits        21778    20665     -1113     
+ Misses      60528    27285    -33243     
- Partials      455      491       +36     
Flag Coverage Δ
backend 42.58% <ø> (+0.31%) ⬆️
frontend 44.74% <40.78%> (+39.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

…latest

- Update EF Core 10.0.2→10.0.5, QuestPDF 2026.2.4, NLog, SonarAnalyzer, coverlet 8.0.1
- Update Vue 3.5.30, Quasar 2.18.7, @quasar/app-vite 2.5.2; drop vite override for @quasar/vite-plugin
- Align CI workflow with Node.js 24 and .NET 10
- Refactor Mailpit script to auto-detect latest GitHub release and replace fkill with native process kill
- Fix minor lint issues in site.js and CtsHome.vue
- Move HTTPS cert generation and proxy config behind command === "serve"
  so vite build skips unnecessary I/O and cert checks
- Sanitize route values in EmailService logging to prevent log injection
…ver config

- Cert generation warns instead of throwing, so builds succeed without dotnet CLI
- Proxy routes declared unconditionally; HTTPS applied only when certs exist
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 20, 2026

Bundle Report

Changes will decrease total bundle size by 204.71kB (-8.13%) ⬇️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
viper-frontend-esm 2.31MB -204.71kB (-8.13%) ⬇️

Affected Assets, Files, and Routes:

view changes for bundle: viper-frontend-esm

Assets Changed:

Asset Name Size Change Total Size Change (%)
assets/quasar.client-*.js (New) 480.13kB 480.13kB 100.0% 🚀
assets/vendor-*.js -59.27kB 270.18kB -17.99%
assets/GenericError-*.css (New) 203.31kB 203.31kB 100.0% 🚀
assets/TermManagement-*.js -706 bytes 55.08kB -1.27%
assets/ManageLinkCollections-*.js -137.65kB 52.21kB -72.5%
assets/RecentSelections-*.js (New) 51.08kB 51.08kB 100.0% 🚀
assets/CourseDetail-*.js -613 bytes 40.51kB -1.49%
assets/PhotoGallery-*.js -526 bytes 35.94kB -1.44%
assets/InstructorEdit-*.js -469 bytes 32.11kB -1.44%
assets/InstructorList-*.js -331 bytes 25.93kB -1.26%
assets/StaffDashboard-*.js -248 bytes 25.24kB -0.97%
assets/vue-*.js (New) 24.99kB 24.99kB 100.0% 🚀
assets/CrossListedCoursesSection-*.js -314 bytes 23.63kB -1.31%
assets/effort-*.js -21 bytes 988 bytes -2.08%
assets/effort-*.js -149 bytes 23.26kB -0.64%
assets/ClinicianScheduleView-*.js -237 bytes 20.17kB -1.16%
assets/MultiYearReport-*.js -406 bytes 18.99kB -2.09%
assets/GenericError-*.js (New) 18.96kB 18.96kB 100.0% 🚀
assets/AuditList-*.js -138 bytes 17.3kB -0.79%
assets/AuditList-*.js -88 bytes 5.2kB -1.66%
assets/RotationScheduleView-*.js -144 bytes 16.75kB -0.85%
assets/CourseList-*.js -274 bytes 15.85kB -1.7%
assets/EffortTypeList-*.js -92 bytes 14.95kB -0.61%
assets/runtime-*.esm-bundler--djReR3o.js (New) 12.29kB 12.29kB 100.0% 🚀
assets/ViperFetch-*.js (New) 11.09kB 11.09kB 100.0% 🚀
assets/permission-*.js -131 bytes 10.67kB -1.21%
assets/CourseImportDialog-*.js (New) 10.53kB 10.53kB 100.0% 🚀
assets/cts-*.js -105 bytes 9.71kB -1.07%
assets/CourseLinkDialog-*.js (New) 9.05kB 9.05kB 100.0% 🚀
assets/MyEffort-*.js -90 bytes 8.53kB -1.04%
assets/ReportFilterForm-*.js (New) 8.51kB 8.51kB 100.0% 🚀
assets/ManageBundleCompetencies-*.js -32 bytes 8.23kB -0.39%
assets/StudentClassYear-*.js -49 bytes 8.03kB -0.61%
assets/inflection-*.js -3.06kB 6.99kB -30.47%
assets/AssessmentList-*.js -120 bytes 6.81kB -1.73%
assets/ManageSessionCompetencies-*.js -80 bytes 6.54kB -1.21%
assets/TermSelection-*.js -102 bytes 6.47kB -1.55%
assets/UnitList-*.js -39 bytes 6.26kB -0.62%
assets/RecentSelections-*.css (New) 6.25kB 6.25kB 100.0% 🚀
assets/CompetenciesBundleReport-*.js -46 bytes 5.98kB -0.76%
assets/ManageCompetencies-*.js -98 bytes 5.87kB -1.64%
assets/ClinicalEffort-*.js -70 bytes 5.71kB -1.21%
assets/AssessmentEpa-*.js -56 bytes 5.69kB -0.98%
assets/MyAssessments-*.js -169 bytes 5.59kB -2.93%
assets/EffortRecordEditDialog-*.js (New) 5.56kB 5.56kB 100.0% 🚀
assets/InstructorDetail-*.js -133 bytes 5.52kB -2.35%
assets/WebReports-*.js -92 bytes 5.38kB -1.68%
assets/use-*.js -155 bytes 5.36kB -2.81%
assets/use-*.js 5 bytes 664 bytes 0.76%
assets/StudentSelect-*.js (New) 5.31kB 5.31kB 100.0% 🚀
assets/dist-*.js (New) 5.3kB 5.3kB 100.0% 🚀
assets/PhotoGallery-*.css -35 bytes 5.16kB -0.67%
assets/ManageEpas-*.js -134 bytes 5.01kB -2.61%
assets/SchoolSummary-*.js -180 bytes 4.9kB -3.55%
assets/ManageBundles-*.js -80 bytes 4.72kB -1.67%
assets/TeachingActivityGrouped-*.js -206 bytes 4.58kB -4.31%
assets/MeritAverage-*.js -188 bytes 4.53kB -3.99%
assets/TeachingActivityIndividual-*.js -138 bytes 4.26kB -3.14%
assets/course-*.js -59 bytes 4.25kB -1.37%
assets/MeritDetail-*.js -231 bytes 4.24kB -5.16%
assets/ManageLevels-*.js -38 bytes 4.08kB -0.92%
assets/DeptSummary-*.js -227 bytes 4.08kB -5.27%
assets/EvalDetail-*.js -180 bytes 3.88kB -4.43%
assets/AssessmentEpaEdit-*.js 86 bytes 3.85kB 2.28%
assets/MeritSummary-*.js -217 bytes 3.73kB -5.5%
assets/StudentClassYearImport-*.js 34 bytes 3.63kB 0.94%
assets/BiorenderStudents-*.js -45 bytes 3.6kB -1.24%
assets/ClinicalSchedulerHome-*.js 44 bytes 3.59kB 1.24%
assets/ManageCourseCompetencies-*.js -3.3kB 3.57kB -48.0%
assets/ManageMilestones-*.js -21 bytes 3.5kB -0.6%
assets/ScheduledCliWeeks-*.js -159 bytes 3.26kB -4.66%
assets/EvalSummary-*.js -155 bytes 3.01kB -4.89%
assets/AssessmentCompetency-*.js 43 bytes 2.99kB 1.46%
assets/ManageDomains-*.js -74 bytes 2.92kB -2.47%
assets/ManageLinkCollections-*.css -12 bytes 2.84kB -0.42%
assets/PercentAssignTypeList-*.js -2 bytes 2.74kB -0.07%
assets/LevelSelect-*.js 76 bytes 2.6kB 3.01%
assets/MultiYearReport-*.css -2 bytes 2.59kB -0.08%
assets/PercentAssignTypeInstructors-*.js 7 bytes 2.45kB 0.29%
assets/CourseStudents-*.js -111 bytes 2.31kB -4.59%
assets/CtsHome-*.js -8 bytes 2.29kB -0.35%
assets/instructor-*.js -39 bytes 2.25kB -1.71%
assets/main-*.css -125 bytes 2.23kB -5.3%
assets/InstructorList-*.css -9 bytes 2.11kB -0.42%
assets/cahfs-*.js -36 bytes 1.85kB -1.91%
assets/clinicalscheduler-*.js -52 bytes 1.77kB -2.85%
assets/ManageRoles-*.js -21 bytes 1.73kB -1.2%
assets/RotationScheduleView-*.css -12 bytes 1.68kB -0.71%
assets/cms-*.js -36 bytes 1.58kB -2.23%
assets/record-*.js -29 bytes 1.52kB -1.87%
assets/StaffDashboard-*.css -6 bytes 1.52kB -0.39%
assets/students-*.js -43 bytes 1.5kB -2.78%
assets/ClinicianScheduleView-*.css -14 bytes 1.46kB -0.95%
assets/verification-*.js -16 bytes 1.43kB -1.11%
assets/EffortHome-*.js -8 bytes 1.42kB -0.56%
assets/computing-*.js -25 bytes 1.18kB -2.07%
assets/TestPage-*.js -55 bytes 1.09kB -4.78%
assets/ReportDeptTabs-*.js (New) 1.08kB 1.08kB 100.0% 🚀
assets/unit-*.js -23 bytes 975 bytes -2.3%
assets/validation-*.css -19 bytes 892 bytes -2.09%
assets/main-*.js 67 bytes 849 bytes 8.57% ⚠️
assets/DateFunctions-*.js 7 bytes 700 bytes 1.01%
assets/modulepreload-*.js (New) 698 bytes 698 bytes 100.0% 🚀
assets/validation-*.js 2 bytes 662 bytes 0.3%
assets/CAHFSAuth-*.js -56 bytes 661 bytes -7.81%
assets/ReportLayout-*.js -5 bytes 568 bytes -0.87%
assets/Home-*.js -64 bytes 563 bytes -10.21%
assets/CAHFSSection-*.js -34 bytes 540 bytes -5.92%
assets/AssessmentChart-*.js -12 bytes 531 bytes -2.21%
assets/ReportLayout-*.css -14 bytes 530 bytes -2.57%
assets/percent-*.js -12 bytes 501 bytes -2.34%
assets/ContentBlock-*.js (New) 481 bytes 481 bytes 100.0% 🚀
assets/ClinicalSchedulerHome-*.css -6 bytes 384 bytes -1.54%
assets/MyEffort-*.css -5 bytes 355 bytes -1.39%
assets/Error404-*.js -54 bytes 353 bytes -13.27%
assets/CourseList-*.css -2 bytes 277 bytes -0.72%
assets/LevelSelect-*.css -8 bytes 264 bytes -2.94%
assets/CAHFSHome-*.js -74 bytes 263 bytes -21.96%
assets/StudentsHome-*.js -5 bytes 227 bytes -2.16%
assets/ManageLegacyCompetencyMapping-*.js 58 bytes 207 bytes 38.93% ⚠️
assets/format-*.js -3 bytes 157 bytes -1.88%
assets/CheckPagePermission-*.js -7 bytes 150 bytes -4.46%
assets/CmsHome-*.js -7 bytes 149 bytes -4.49%
assets/EffortTypeList-*.css -13 bytes 137 bytes -8.67%
assets/_plugin-*.js -717 bytes 84 bytes -89.51%
assets/rolldown-*.js (New) 77 bytes 77 bytes 100.0% 🚀
assets/dept-*.js -1 bytes 0 bytes -100.0%
assets/index-*.js (Deleted) -1.75kB 0 bytes -100.0% 🗑️
assets/index-*.js (Deleted) -540.44kB 0 bytes -100.0% 🗑️
assets/index-*.css (Deleted) -204.57kB 0 bytes -100.0% 🗑️
assets/ScheduleView-*.js (Deleted) -52.01kB 0 bytes -100.0% 🗑️
assets/CourseImportDialog.vue_vue_type_script_setup_true_lang-*.js (Deleted) -10.6kB 0 bytes -100.0% 🗑️
assets/CourseLinkDialog.vue_vue_type_script_setup_true_lang-*.js (Deleted) -9.15kB 0 bytes -100.0% 🗑️
assets/ReportFilterForm.vue_vue_type_script_setup_true_lang-*.js (Deleted) -8.63kB 0 bytes -100.0% 🗑️
assets/ScheduleView-*.css (Deleted) -6.34kB 0 bytes -100.0% 🗑️
assets/EffortRecordEditDialog.vue_vue_type_script_setup_true_lang-*.js (Deleted) -5.57kB 0 bytes -100.0% 🗑️
assets/StudentSelect.vue_vue_type_script_setup_true_lang-*.js (Deleted) -5.4kB 0 bytes -100.0% 🗑️
assets/ReportDeptTabs.vue_vue_type_script_setup_true_lang-*.js (Deleted) -1.09kB 0 bytes -100.0% 🗑️
assets/ContentBlock.vue_vue_type_style_index_0_lang-*.js (Deleted) -507 bytes 0 bytes -100.0% 🗑️

Files in assets/WebReports-*.js:

  • ./src/CMS/components/Link.vue → Total Size: 191 bytes

Files in assets/cahfs-*.js:

  • ./src/CAHFS/cahfs.ts → Total Size: 152 bytes

  • ./src/CAHFS/App.vue → Total Size: 108 bytes

  • ./src/CAHFS/router/index.ts → Total Size: 508 bytes

  • ./src/CAHFS/router/routes.ts → Total Size: 1.17kB

Files in assets/cms-*.js:

  • ./src/CMS/App.vue → Total Size: 106 bytes

  • ./src/CMS/cms.ts → Total Size: 146 bytes

Files in assets/main-*.js:

  • ./src/App.vue → Total Size: 911 bytes

Files in assets/CAHFSAuth-*.js:

  • ./src/CAHFS/pages/CAHFSAuth.vue → Total Size: 132 bytes

Files in assets/CAHFSSection-*.js:

  • ./src/CAHFS/pages/CAHFSSection.vue → Total Size: 141 bytes

Files in assets/ContentBlock-*.js:

  • ./src/CMS/components/ContentBlock.vue → Total Size: 144 bytes

Files in assets/CAHFSHome-*.js:

  • ./src/CAHFS/pages/CAHFSHome.vue → Total Size: 132 bytes

- Wrap large .Contains() calls with EF.Parameter() for OPENJSON translation
- Replace N+1 loops with batched queries (EPA checks, competency counts, photo URLs)
- Replace correlated .Any() subqueries with .Join() or pre-loaded ID sets
- Add .AsNoTracking() to read-only queries missing it
- Remove unnecessary .ToLower() in string comparisons (CI collation)
- Set SQL Server compat level 130 so EF Core 10 generates optimal SQL
- Enable ReadyToRun publishing for faster cold-start
- Disable AppendRuntimeIdentifierToOutputPath so R2R publish outputs
  to net10.0/publish/ matching Jenkins robocopy expectations
- Run dotnet linter in parallel with frontend linters via async spawn
- Enable compiler server and skip restore in dotnet format calls
- Guard RAPS AuditLog against unexpected audit criteria parameters
@rlorenzo rlorenzo requested a review from bsedwards March 21, 2026 18:21
@rlorenzo
Copy link
Copy Markdown
Contributor Author

@bsedwards I benchmarked the deployment on TEST and found some performance regressions due to the new parameterized collection changes: https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-10.0/whatsnew#improved-translation-for-parameterized-collection

I fixed a bunch of queries and found some other EF improvements. Overall, the site should be faster than before.

Need help testing the other areas of the VIPER2 system that I have not yet worked on and am not fully familiar with.

image

…ipts, and backend

- Bump GitHub Actions to latest majors (checkout@v6, codeql@v4, codecov@v5)
- Add --files-from support in lint scripts to avoid Windows ENAMETOOLONG
- Replace string concatenation with StringBuilder in VMACSExport and IamApi
- Remove redundant vitest imports (globals enabled) and fix test assertions
- Enable capitalized-comments rule and disable numeric-separators-style in oxlintrc
bsedwards
bsedwards previously approved these changes Mar 25, 2026
Copy link
Copy Markdown
Collaborator

@bsedwards bsedwards left a comment

Choose a reason for hiding this comment

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

I reviewed most of the backend changes. Next time I'd suggest breaking up changes this extensive into multiple PRs, e.g.

  • .Net 10
  • NodeJS 24
  • Replacing Moq/Mapper
  • Fixing warnings and implementing suggestions
  • Linting

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants