CodeQL 3: fix: close CodeQL correctness alerts#191
Conversation
📝 WalkthroughWalkthroughPR hardens null-safety by consolidating nullable-conditional patterns into explicit non-null assertions where control flow guarantees non-nullability. Also seals model classes, removes EF virtual modifiers, adopts factory-method pattern for RoleTemplateSimplified, changes CompetencyController duplicate-detection behavior to include the current competency, and improves validation logic in services and utilities. ChangesNull-safety assertions and code quality improvements
🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 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 |
Bundle ReportBundle size has no change ✅ |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #191 +/- ##
==========================================
+ Coverage 42.96% 43.02% +0.05%
==========================================
Files 877 877
Lines 51468 51471 +3
Branches 4802 4798 -4
==========================================
+ Hits 22113 22143 +30
+ Misses 28831 28803 -28
- Partials 524 525 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Three rule families consolidated into one PR because each fix needs per-site judgment rather than mechanical replacement. cs/virtual-call-in-constructor (5): seal CMSFile, StudentClassYear, RoleTemplateSimplified — none are inherited from in C# and none are mocked; project has no UseLazyLoadingProxies so EF doesn't need them non-sealed. Drops `virtual` on properties newly declared inside the now-sealed classes. cs/unsafe-year-construction (4): in PercentRolloverService, bound the HTTP-derived year parameter with ArgumentOutOfRangeException and use .AddYears(1) instead of `new DateTime(year+1, ...)` for the target end date. In AcademicYearHelper.GetAcademicYearStart, build the July date first then .AddYears(-1) instead of subtracting from .Year before constructing. cs/constant-condition (21): remove redundant null-propagation that the analyzer can already prove dead — `?.` chains after `!= null` guards, an unreachable CompetencyId range check after the FindAsync record-existence check, and a duplicated `RegionEndpoint` element lookup in SetAwsCredentials. RAPSController null-flow was restructured to lift the path null check up.
b0b03a6 to
7b95293
Compare
These were flagged by the ReSharper PR-scoped gate as new warnings on
lines my CodeQL 3 fix touched:
- CMSFile.cs: drop redundant 'partial' modifier (PartialTypeWithSinglePart)
- RAPSController.cs: 'is int idx' on int? -> 'is { } idx'
(ConvertTypeCheckPatternToNullCheck)
- RoleTemplatesController.cs: drop '??' fallbacks; both properties are
declared non-null (NullCoalescingConditionIsAlwaysNotNullAccordingToAPIContract)
- Program.cs: drop redundant 'Amazon.' qualifier on RegionEndpoint
(RedundantNameQualifier)
- RoleTemplateSimplified.cs: convert Roles setter to 'init' so the
getter has a clear owner (UnusedAutoPropertyAccessor.Global)
7b95293 to
53b6eef
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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 `@web/Areas/RAPS/Controllers/RoleTemplatesController.cs`:
- Around line 45-49: Replace the explicit loop and mutable list plumbing by
projecting dbRoleTemplates into the simplified DTO: use a LINQ Select that calls
RoleTemplateSimplified.FromRoleTemplate for each rt on dbRoleTemplates and
materialize to a List (assign to roleTemplates) instead of creating
roleTemplates and using foreach + Add.
In `@web/Areas/RAPS/Models/RoleTemplateSimplified.cs`:
- Around line 22-31: Replace the manual mapping inside
RoleTemplateSimplified.FromRoleTemplate by delegating to a Mapperly-generated
mapper: change the implementation to call
RoleTemplateSimplifiedMapper.ToSimplified(rt), and add a new static partial
mapper type named RoleTemplateSimplifiedMapper decorated with
[Mapper(RequiredMappingStrategy = RequiredMappingStrategy.None)] that declares a
partial method ToSimplified(RoleTemplate source) returning
RoleTemplateSimplified so Mapperly can generate the mapping.
In `@web/Program.cs`:
- Around line 558-565: The lookup can return null for unknown names; replace the
reflection-based lookup with RegionEndpoint.GetBySystemName(regionValue) (or try
both regionValue and a PascalCase variant) and if that returns null either set
profile.Region = RegionEndpoint.USWest1 as a safe default or throw a
FormatException; update the code around regionValue/profile.Region to use
RegionEndpoint.GetBySystemName(regionValue) and handle a null result explicitly
(throwing FormatException or assigning the default).
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 501d2df3-d7b5-44d5-a105-53874a3f7b1b
📒 Files selected for processing (15)
test/CTS/AssessmentControllerTest.csweb/Areas/CMS/Models/CMSFile.csweb/Areas/CTS/Controllers/AssessmentController.csweb/Areas/CTS/Controllers/CompetencyController.csweb/Areas/CTS/Models/AuditRow.csweb/Areas/Effort/Services/PercentRolloverService.csweb/Areas/Effort/Services/PercentageService.csweb/Areas/RAPS/Controllers/RAPSController.csweb/Areas/RAPS/Controllers/RoleTemplatesController.csweb/Areas/RAPS/Models/RoleTemplateSimplified.csweb/Areas/RAPS/Services/RAPSAuditService.csweb/Classes/Utilities/AcademicYearHelper.csweb/Controllers/HomeController.csweb/Models/Students/StudentClassYear.csweb/Program.cs
💤 Files with no reviewable changes (1)
- web/Areas/CTS/Controllers/CompetencyController.cs
c92bfb2 to
46c06c2
Compare
- RoleTemplatesController.GetRoleTemplates: replace foreach + Add with .Select(...).ToList() to match the project's LINQ conventions. - Program.cs SetAwsCredentials: trim the RegionEndpoint value, look it up with BindingFlags.IgnoreCase, and fall back to USWest1 when the name is non-empty but does not match any known region (previously left profile.Region as null).
Two unit tests for the static factory introduced by codeql/3: - FromRoleTemplate_MapsScalarsAndFlattensRoles: verifies the scalar properties and the nested RoleTemplateRoles -> Roles flattening via Role.RoleId / Role.FriendlyName. - FromRoleTemplate_EmptyRoles_ReturnsEmptyCollection: ensures the Roles initializer does not depend on a non-empty source collection. Gives the constructor-to-factory conversion a regression net.
46c06c2 to
57e3771
Compare
Summary
Closes ~30 CodeQL alerts across three correctness rule families. Each fix needs per-site judgment, so they're consolidated here rather than split - the reviewer mental model is the same throughout.
cs/virtual-call-in-constructor (5)
Sealed three DTO/model classes whose copy-constructors trip the rule by assigning to virtual properties:
CMSFile(web/Areas/CMS/Models/CMSFile.cs) -partial→sealed partialStudentClassYear(web/Models/Students/StudentClassYear.cs) - also dropsvirtualon properties declared on the now-sealed classRoleTemplateSimplified(web/Areas/RAPS/Models/RoleTemplateSimplified.cs) - sameSafety check: none of the three are inherited from in C#, none are
Substitute.For<...>in tests, and there is noUseLazyLoadingProxies()call anywhere in the project so EF doesn't need them non-sealed.cs/unsafe-year-construction (4)
web/Areas/Effort/Services/PercentRolloverService.cs- addedArgumentOutOfRangeException.ThrowIfLessThan(year, 1)/ThrowIfGreaterThan(year, 9998)at the top ofGetRolloverPreviewAsync(year comes from HTTP). Replacednew DateTime(year + 1, 6, 30, …)withjune30Start.AddYears(1).web/Classes/Utilities/AcademicYearHelper.cs::GetAcademicYearStart- construct July ofdate.Yearfirst, then.AddYears(-1)if needed, instead ofnew DateTime(date.Year - 1, …).cs/constant-condition (21)
Removed redundant null-propagation that the analyzer can already prove dead:
PercentageService.cs:309- droppedtype != null &&after the IsValid guard already eliminated the null case.Program.csSetAwsCredentials - hoistedAccessKeyId/SecretAccessKey/RegionEndpointelement lookups into locals (one each) so the duplicated?.chains and the redundant secondRegionEndpointlookup go away.HomeController.cs:150,322- replacedprotector?.Protect(...)andsuccessNode?.Element(...)with the non-null form inside their guarded blocks.CompetencyController.cs:139- removed the unreachableCompetencyId == null || <= 0check that runs afterFindAsyncalready confirmed the record exists and aftercompetencyId != competency.CompetencyIdwas rejected.AssessmentController.cs:300-student?.StudentInfo→student.StudentInfoinside thestudent == null ||short-circuit.test/CTS/AssessmentControllerTest.cs:261-result?.StatusCode→result.StatusCodeinsideif (result != null).RAPSAuditService.cs:148-auditLog?.→auditLog.(foreach variable cannot be null).RoleTemplatesController.cs:189-190- dropuser?.after theif (user == null) return null;guard.RAPSController.cs:51,56- restructured the twoif (rapsIdx != null && rapsIdx > -1 && path?.Count > …)blocks into a single outer null-and-bounds check that lifts the path null check up.AuditRow.cs:27-28-dbAudit?.Encounter?./dbAudit.Encounter?.Student?.chains collapsed inside the surrounding non-null guard.Context
Third in the
CodeQL N:cleanup series (after #189, #190).Test plan
npm run test- 1946 backend + 749 frontend passingnpm run verify:build- clean (0 errors)npm run lint- passing on changed files