Skip to content

VPR-143 fix(cms): split file lookup by identifier, index oldURL#160

Merged
rlorenzo merged 3 commits into
mainfrom
VPR-143-oldURL-fix
Apr 23, 2026
Merged

VPR-143 fix(cms): split file lookup by identifier, index oldURL#160
rlorenzo merged 3 commits into
mainfrom
VPR-143-oldURL-fix

Conversation

@rlorenzo
Copy link
Copy Markdown
Contributor

Fixes the #1 Query Store resource consumer. The catch-all LINQ "(@p IS NULL OR col = @p)" shape forced a full scan of all ~31K rows on every /CMS/Files?oldURL=... hit, with nvarchar(max) CONVERT_IMPLICIT on files.oldURL.

  • Split CMS.GetFiles(...) into per-identifier methods (GetFileByGuid, GetFileByOldUrl, GetFileByFriendlyName, GetFileByFolderAndName), each TagWith-stamped. GetFile is now a dispatcher; callers unchanged.
  • HasMaxLength(256) + IsUnicode(false) on OldUrl/FilePath makes EF emit varchar(256) params, eliminating the CONVERT_IMPLICIT.
  • Added IX_files_oldURL covering index to the File entity config.
  • [CMS-FILE-404] NLog warning on ProvideFile misses (sanitized id/friendlyName/oldURL/UA/referer/IP) for evidence-based blocks.

Schema change is applied manually per environment - see JIRA VPR-143 for the ALTER COLUMN and CREATE INDEX script.

Fixes the #1 Query Store resource consumer. The catch-all LINQ
"(@p IS NULL OR col = @p)" shape forced a full scan of all ~31K
rows on every /CMS/Files?oldURL=... hit, with nvarchar(max)
CONVERT_IMPLICIT on files.oldURL.

- Split CMS.GetFiles(...) into per-identifier methods
  (GetFileByGuid, GetFileByOldUrl, GetFileByFriendlyName,
  GetFileByFolderAndName), each TagWith-stamped. GetFile is now a
  dispatcher; callers unchanged.
- HasMaxLength(256) + IsUnicode(false) on OldUrl/FilePath makes EF
  emit varchar(256) params, eliminating the CONVERT_IMPLICIT.
- Added IX_files_oldURL covering index to the File entity config.
- [CMS-FILE-404] NLog warning on ProvideFile misses (sanitized
  id/friendlyName/oldURL/UA/referer/IP) for evidence-based blocks.

Schema change is applied manually per environment - see JIRA
VPR-143 for the ALTER COLUMN and CREATE INDEX script.
Copilot AI review requested due to automatic review settings April 22, 2026 23:57
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Apr 22, 2026

Codecov Report

❌ Patch coverage is 18.75000% with 78 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.25%. Comparing base (72fb86b) to head (ed25087).

Files with missing lines Patch % Lines
web/Areas/CMS/Data/CMS.cs 0.00% 75 Missing ⚠️
web/Areas/CMS/Controllers/CMSController.cs 0.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #160      +/-   ##
==========================================
- Coverage   43.27%   43.25%   -0.03%     
==========================================
  Files         862      862              
  Lines       50319    50386      +67     
  Branches     4696     4703       +7     
==========================================
+ Hits        21777    21795      +18     
- Misses      28019    28068      +49     
  Partials      523      523              
Flag Coverage Δ
backend 43.33% <18.75%> (-0.03%) ⬇️
frontend 41.69% <ø> (ø)

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.

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 targets a performance hotspot in CMS file lookups (notably /CMS/Files?oldURL=...) by changing EF query shapes and schema mapping so SQL Server can use an index efficiently and avoid scan-heavy “optional parameter” predicates.

Changes:

  • Split CMS.GetFile(...) into per-identifier lookup methods (GetFileByGuid, GetFileByOldUrl, GetFileByFriendlyName, GetFileByFolderAndName) with TagWith(...) for easier Query Store analysis and better plan caching.
  • Updated EF model configuration for files.oldURL and files.filePath (max length + non-unicode) and added a covering index on oldURL.
  • Added warning logging for file misses in ProvideFile including request metadata (UA/referer/IP) with log sanitization.

Reviewed changes

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

File Description
web/Classes/SQLContext/VIPERContext.cs Adds IX_files_oldURL covering index and adjusts OldUrl/FilePath mapping to varchar(256) via EF configuration.
web/Areas/CMS/Data/CMS.cs Refactors file lookup into per-identifier queries and adds [CMS-FILE-404] warning logging on ProvideFile misses.

Comment thread web/Areas/CMS/Data/CMS.cs
Comment thread web/Areas/CMS/Data/CMS.cs Outdated
Comment thread web/Areas/CMS/Data/CMS.cs Outdated
Addresses Copilot review on PR #160.

- Remove OrderBy(FilePath) from GetFileByOldUrl. It was carried over
  from the old GetFiles catch-all (which returned a list) but the new
  method returns FirstOrDefault, so the sort adds plan work without
  affecting correctness. FilePath isn't an IX_files_oldURL key column.
- Wrap RemoteIpAddress through LogSanitizer.SanitizeString in
  [CMS-FILE-404]. Defense in depth: when ForwardedHeaders parses XFF
  from the F5, a spoofed header could theoretically land in the log.
  Matches the sanitization pattern used on every other field.
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

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

Comment thread web/Areas/CMS/Data/CMS.cs
Comment thread web/Areas/CMS/Data/CMS.cs
Addresses Copilot review on PR #160. Without this, _logger on Data.CMS
was always null for /CMS/Files traffic (the ctor arg defaulted to null
and CMSController didn't pass one), so the not-found warnings were
silently dropped — defeating the whole observability point of the log.
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

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

@codecov-commenter
Copy link
Copy Markdown

Bundle Report

Bundle size has no change ✅

@rlorenzo
Copy link
Copy Markdown
Contributor Author

@bsedwards I deployed the query improvements and index last night at around 6:30pm and on SSMS it appears that fixed the query's performance:
Screenshot 2026-04-23 at 9 02 37 AM

@rlorenzo rlorenzo requested review from bsedwards April 23, 2026 16:14
@rlorenzo rlorenzo merged commit 3d7cc5f into main Apr 23, 2026
11 checks passed
@rlorenzo rlorenzo deleted the VPR-143-oldURL-fix branch April 23, 2026 17:26
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