Skip to content

Week Plan — W10 (March 2-6, 2026)

Team

Name Role Focus Area
Marco Teodoro Senior Umbraco Dev & Coordinator Migration tool fixes, data issues, Umbraco config
Rodrigo Pinto Frontend Developer CSS, JS, client-side bugs
Joao Henriques .NET Developer Razor views, MVC logic, C# services

Priority Legend

  • P0 — Blocks page rendering (broken images, crashes)
  • P1 — Functional bugs (wrong behavior, missing data)
  • P2 — Quality issues (hardcoded values, performance)

Marco — Migration & Data (12 tasks)

P0 — Critical

# Task Description Est.
~~M1~~ ~~DropDown.Flexible migration fix~~ DONE (commit 4168abe). One-line fix: return normalizedValues.ToString(Formatting.None) in GridValueTypeConverter.ConvertDropdownValue(). ~~4h~~
~~M2~~ ~~Calculator dictionary items~~ DONE (commit 2ac8a4f). All 169 v8 dictionary items were already migrated correctly. The v17 views were using wrong key names (e.g., Calc.TypeOfLoan instead of calculator.TypeOfLoan). Fixed 95 dictionary key references across 6 calculator views. ~~2h~~
~~M3~~ ~~Contact-us area placement bug~~ STALE — Not a Bug. Investigation confirmed v8 grid JSON has two areas with grid=6 each, both correctly migrated to separate area wrappers. Data is correct. ~~2h~~

P1 — High

# Task Description Est.
~~M4~~ ~~Verify calculatorsConfiguration node exists~~ PASS. Node 2129 exists, published, correct path. All 13 properties via compositions match CalculatorService.cs. ~~1h~~
~~M5~~ ~~NestingContently -> TrueFalse migration~~ PASS. All 11 NestingContently datatypes converted to Umbraco.TrueFalse. Zero legacy refs remain. ~~1h~~
~~M6~~ ~~Legacy MediaPicker -> MediaPicker3~~ PASS. All 71 MediaPicker datatypes migrated. Calculator icon uses single-pick MediaPicker3 with correct MediaWithCrops pattern. ~~1h~~
M7 Re-run migration on test DB After M1-M3 fixes, re-run run-migrations.ps1 on test DB and verify dropdown values are plain strings. 2h
~~M11~~ ~~CommonBondRange table migration~~ NOT AN ISSUE. V8 table exists but has 0 rows — never populated for this client. V17 table auto-created by CreateCommonBondTableMigration. Per-client data population task, not a migration bug. ~~2h~~
~~M12~~ ~~UserServiceComposer -> INotificationHandler~~ DONE (PR #1422). UserGroupSaveProtectionHandler + UserGroupDeleteProtectionHandler implemented. ~~2h~~

P2 — Quality

# Task Description Est.
~~M8~~ ~~Calculator config in SiteSettingsService~~ DONE (commit f18c57d). calculatorsConfiguration lookup moved into SiteSettingsService. ~~2h~~
M9 Coordinate and review Review PRs from Rodrigo and Joao, test integrated fixes, update documentation. 3h
M10 Docs site maintenance Push doc updates, verify Cloudflare Pages deployment, keep week plan updated. 1h

Marco total: ~17h (12/12 tasks done — M1-M8, M11, M12 DONE; M7 re-run migration, M9 review, M10 docs ongoing)


Rodrigo — CSS & JS (11 tasks)

P0 — Critical

# Task Description Files Est.
~~R1~~ ~~jQuery UI slider async/defer race~~ DONE (commit 5babe78). ScriptHelper default changed from async: true to async: false. Prevents race conditions. ~~calculatorLarge.js, calculatorSmall.js, calculatorIcon.js + 6 calculator .cshtml partials~~ ~~2h~~
~~R9~~ ~~Cache busting missing~~ DONE (commit 5383a48). Added asp-append-version="true" to all local <link> and <script> tags across 10 view files. ScriptHelper and CssHelper updated with IFileVersionProvider for cache-busting query strings. CSP nonce support added to ScriptHelper. Build: 0 errors. ~~5 master layouts~~ ~~2h~~

P1 — High

# Task Description Files Est.
~~R2~~ ~~Hardcoded assetsUri media URLs~~ DONE (commit 5babe78). Replaced with window.location.origin + "/media/" in 4 JS files. ~~calculatorInput.js:605, calculatorInputSmall.js:513, calculatorInputVarRate.js:732, calculatorIcon.js:358~~ ~~2h~~
~~R3~~ ~~e.preventDefault missing parentheses~~ DONE (commit 5babe78). Fixed 9 call sites across 7 JS files. ~~calculatorLarge.js:277,295, calculatorInput.js:571~~ ~~0.5h~~
~~R4~~ ~~JS selectors mismatch v17 HTML~~ DONE (commit 5babe78). #loans#loansInput, .selectpicker#loansInput in calculatorLarge.js. ~~calculatorLarge.js:32-33~~ ~~1h~~
~~R5~~ ~~External CDN references (AOS)~~ DONE (commit 9d2c1cf). AOS 2.3.1 CSS/JS vendored to wwwroot/vendor/aos/. All 18 CDN references (unpkg.com) replaced with local paths across 9 .cshtml files. Added asp-append-version="true". ~~9 .cshtml files in Views/~~ ~~2h~~
~~R10~~ ~~Menu JS broken for menu2/3/4~~ DONE (commit a0f588a). Fixed menu2/3/4 JS loading in master.cshtml and MasterThirdParty.cshtml — was loading duplicate slick.min.js instead of each menu's own main.js. MasterLogin already correct. ~~ScriptHelper + menu partials~~ ~~2h~~
~~R11~~ ~~ScriptHelper default async:true -> async:false~~ DONE (commit 5babe78). Default changed to async: false in both AddScript() overloads. ~~ScriptHelper.cs + all callers~~ ~~1h~~

P2 — Quality

# Task Description Files Est.
~~R6~~ ~~Hardcoded EUR/en-IE~~ DONE (commit f18c57d). Hardcoded EUR/en-IE removed from 4 calculator JS files. ~~calculatorInput.js:1-7~~ ~~1h~~
~~R7~~ ~~bootstrap-datepicker version~~ DONE (commit 85873c2). Datepicker aligned to local v1.9.0 vendor. ~~3 master layouts~~ ~~1h~~
~~R8~~ ~~MasterLogin missing RenderScripts~~ DONE (commit 1c727d4). Added @Html.RenderScripts() and @Html.RenderCss() to MasterLogin.cshtml. Login page JS was completely non-functional (bootstrap, slick, navigation, fancybox, lazysizes all silently dropped). ~~MasterLogin.cshtml~~ ~~1h~~

Rodrigo total: ~15.5h (11/11 tasks done — R1-R11 ALL DONE)


Joao — Razor & MVC Logic (15 tasks)

P0 — Critical

# Task Description Files Est.
~~J1~~ ~~IPublishedContent -> MediaWithCrops~~ DONE (commit c6dd388). 87 occurrences in 41 files converted from Value<IPublishedContent> to Value<MediaWithCrops> + .MediaUrl(). 15 content picker properties correctly preserved. Build: 0 errors. ~~53 .cshtml files~~ ~~8h~~
~~J2~~ ~~CalculatorSmall missing @ prefix~~ DONE (commits 24dea20 + d6299da). CalculatorSmall @ prefix fixed. ~~CalculatorSmall.cshtml:223~~ ~~0.5h~~

P1 — High

# Task Description Files Est.
~~J3~~ ~~SafeDropdownValue for remaining views~~ DONE (commit a0f588a). 10 dropdown reads across 8 files converted from bare Value<string>() to SafeDropdownValue(). Properties: display, gradient, buttonStyle, flip, imageLocation, styling, buttonClass. ~~announcementControls, ctaCurves, flipCardControls, cardGridControls, loanboxescompletegrideditor, services_list_image, iconListOptContactInfoControl, standardPageWithImageText~~ ~~2h~~
~~J4~~ ~~Calculator literal fallback strings~~ DONE (commit deccc8c). Replaced @amountToBorrowLabel literals with proper English fallbacks. ~~calculatorInput.cshtml:21, calculatorInputSmall.cshtml:21, calculatorInputVarRate.cshtml:19-21~~ ~~0.5h~~
~~J5~~ ~~Calculator hardcoded hidden fields~~ DONE (commit deccc8c). Changed value="months" to value="@monthsLabel" in all files. ~~calculatorInputSmall.cshtml:90-93, calculatorInputVarRate.cshtml:130-134~~ ~~0.5h~~
~~J6~~ ~~Calculator frequency logic mismatch~~ DONE (commit deccc8c). Changed "Weekly" to "W" comparison + fixed default fallbacks. ~~calculatorInputSmall.cshtml:59,67-71~~ ~~0.5h~~
~~J7~~ ~~iconWidth DropDown read as int~~ DONE (commit deccc8c). Added GetDropdownValueFromElement() helper, reads as string then int.TryParse. ~~CalculatorService.cs:176~~ ~~0.5h~~
~~J8~~ ~~loanPurposeId always empty~~ DONE (commit deccc8c). Changed to value="@selectedLoan.LoanPurposeId" in all 5 views. ~~All calculator partials~~ ~~1h~~
~~J13~~ ~~Case sensitivity — Home/ vs home/~~ DONE (commit dbab2c7). 14 path fixes across 4 files: Home/home/ (7 refs), Grid/Editors/GlobalAddress/blockgrid/Components/GlobalAddress/ (7 refs). All paths now match actual directory casing for Linux/Docker compatibility. ~~Views referencing ~/Views/Home/ and ~/Views/GlobalAddress/~~ ~~1h~~
~~J14~~ ~~popUpForms.cshtml form commented out~~ DONE (commit 73a6640). Restored @await Component.InvokeAsync("RenderForm") with PascalCase params. Umbraco.Forms v17.0.3 already installed. Fixed Layout from masterNoHeaderNoFooter to masterNoHeaderNof matching uSync config. ~~popUpForms.cshtml~~ ~~2h~~
~~J15~~ ~~GalleryService migration~~ DONE (commit b39ad7c). Created IGalleryService interface, GalleryService implementation, GalleryResultSet view model. Registered as scoped in Program.cs. Updated LatestGalleries.cshtml to use service with pagination. ~~GalleryService.cs + DI registration~~ ~~2h~~

P2 — Quality

# Task Description Files Est.
~~J9~~ ~~SEO Open Graph image~~ DONE (commit c6dd388). Fixed as part of J1 — SEO.cshtml was one of the 41 files converted to MediaWithCrops. ~~SEO.cshtml~~ ~~0.5h~~
~~J10~~ ~~Null-safe patterns audit~~ DONE (commit 7273808). Null-safe patterns audit complete, 4 fixes applied. ~~Multiple files~~ ~~2h~~
~~J11~~ ~~Header image on 11 page templates~~ DONE (commit c6dd388). Fixed as part of J1 — 13 page templates converted to MediaWithCrops. ~~11 page templates~~ ~~(included in J1)~~
~~J12~~ ~~Calculator dictionary key alignment~~ DONE (commit 2ac8a4f). All 169 v8 dictionary items were already migrated. Views corrected to use v8 key names. No coordination needed. ~~6 calculator partials~~ ~~2h~~

Joao total: ~23h (15/15 tasks done — J1-J15 ALL DONE)


Week Schedule

Day Marco Rodrigo Joao
Mon ~~M1 (DONE)~~, M2 (dictionary items) R1 (slider async/defer), R11 (async default) J1 (IPublishedContent->MediaWithCrops — start)
Tue M11 (CommonBondRange table), M12 (UserServiceComposer) R9 (cache busting), R3 (preventDefault) J1 (continue — 53 files), J2 (CalculatorSmall @)
Wed M4-M6 (verify config/migration) R2 (hardcoded URLs), R4 (JS selectors) J3 (SafeDropdownValue), J4-J6 (calc fixes), J13 (case sensitivity)
Thu M7 (re-run migration) R5 (CDN refs), R10 (menu JS) J7-J8 (calc service), J14 (popUpForms), J15 (GalleryService)
Fri M9-M10 (review, docs, testing) Bug fixes from review J9, J12 (dictionary alignment), bug fixes

All P2 overflow tasks completed: ~~M8~~ (DONE f18c57d), ~~R6~~ (DONE f18c57d), ~~R7~~ (DONE 85873c2), ~~J10~~ (DONE 7273808)


Additional Tasks (Added Mar 1)

# Owner Task Description Priority
R12 Rodrigo Compare ListViews v8 vs v17 V8 had custom AngularJS ListViews (App_Plugins/ListViewNews/, App_Plugins/ListViewTestimonals/). V17 uses native Collection View via uSync config (NewsListView.config, ListViewTestimonials.config). Compare v8 custom list views (card layout with images, author, category) with v17 native table/grid list views. Document visual differences and determine if v17 native is acceptable or if a custom Lit-based backoffice extension is needed. P2
M13 Marco ~~Email templates migration~~ DONE (commits 782d347, a70bb0c). All 25 v8 Umbraco Forms email templates converted to v17 — @inherits updated, HttpContext.Current replaced with Context.Request, nullable warning fixed. Path: Views/Partials/Forms/Emails/. Clients can override by placing files in the same path. DONE
M14 Marco Manual test matrix Create comprehensive test matrix for runtime verification — calculators, login, news, gallery, forms, images, menus, cache busting. P1

Definition of Done

  • All calculator pages render with correct labels, sliders work, apply/enquire buttons function
  • All images render across the site (no more silent null from IPublishedContent)
  • Dropdown properties don't crash on migrated JSON array data
  • Migration tool produces correct dropdown values (M1 DONE)
  • Login page has working JavaScript
  • SEO Open Graph images render
  • Cache busting active on all script/style tags
  • CommonBondRange table populated in v17
  • UserServiceComposer protection active in v17
  • All case-sensitive paths normalized
  • Menu2/3/4 have correct JS loaded
  • All changes committed with conventional commits, docs updated

Risks & Dependencies

Risk Impact Mitigation
~~M1 (dropdown fix) may need fresh migration run~~ ~~Blocks testing of J3~~ Resolved — M1 is DONE (commit 4168abe)
J1 (87 IPublishedContent fixes) is large May spill into next week Prioritize page templates first (11 files), then components
Dictionary key decision (M2/J12) needs coordination Blocks calculator localization Decide Monday morning: option (a) or (b)
Some IPublishedContent reads are content pickers, not media Wrong fix could break content pickers Joao must check datatype before changing each one
Cache busting (R9) is a quick win that prevents all post-deployment issues Stale assets after any deployment Schedule early in the week (Tuesday) — low effort, high impact
CommonBondRange (M11) blocks calculator postcode lookups Calculator postcode search returns no results Must complete before calculator integration testing on Thursday
Case sensitivity (J13) only matters for Linux deployment — Windows works fine Broken paths on Linux/Docker production Low urgency for dev, but must fix before Docker deployment

Post-Migration Verification Checklist

  • Issue: v8 stores dropdown values as plain strings (e.g., "ScrollLeft"), v17 expects JSON arrays (["ScrollLeft"]). Umbraco's FlexibleDropdownPropertyValueConverter throws JsonException on plain strings.
  • Current workaround: SafeDropdownValue() in BlockGridExtensions.cs reads raw source value via GetProperty().GetSourceValue(), bypassing the converter. No performance impact (actually faster than converter pipeline).
  • Structured logging: All plain-string values are logged as warnings with SourceContext = 'Progress.Migration.DropdownFix'
  • How to query: In Umbraco backoffice Log Viewer, filter by @SourceContext = 'Progress.Migration.DropdownFix'. Each log entry includes PropertyAlias, ContentType, RawValue, and ElementKey.
  • Migration tool fix needed: SqlMigrationService should wrap dropdown values in JSON arrays for top-level document properties (grid content was already fixed in commit 4168abe). After re-running migration with this fix, SafeDropdownValue() can be simplified back to Value<string>().
  • Properties affected: gradient, buttonStyle, imageLocation, layout, layoutStyle, flip, display, iconWidth, buttonClass, styling, and others

Error Handling

  • Added: ErrorHandlingComposer.cs in Infrastructure/ErrorHandling/ -- registers error middleware via UmbracoPipelineFilter.PrePipeline
  • Production: 500 errors -> wwwroot/500.html, 404s -> wwwroot/404.html (static pages from v8 with animated gears)
  • Development: UseDeveloperExceptionPage() for full stack traces
  • NuGet RCL ready: Uses Umbraco composer pattern, not Program.cs -- will move cleanly into baseline package

CSP Nonce Support

  • Added: ScriptHelper.SetNonce()/GetNonce() on HttpContext -- ready for Content-Security-Policy when inline scripts are cleaned up
  • Not active yet: No middleware sets nonce currently. Enable when ready to enforce CSP.

Cache Busting

  • Static tags: asp-append-version="true" on all local <link> and <script> tags across 10 master layouts
  • ScriptHelper/CssHelper: IFileVersionProvider appends ?v=hash to all dynamically rendered scripts and CSS
  • Verify after deployment: Check browser Network tab -- all local assets should have ?v= query strings
Migration documentation by Double for Progress Credit Union