Migration Review -- Master Summary¶
Last Updated: 2026-02-28
Project: Progress Credit Union -- Umbraco v8 to v17 Migration
V8 Source: psCreditUnion/Progress.Web/ + SQL Server progresscu.ie
V17 Target: dbl.Progress/src/www/ + Umbraco 17 at psv17.double.pt
Migration Tool: double-migration-tool/
Shared codebase note: This codebase is shared across multiple credit union client databases. Items with zero content in
progresscu.iemay be actively used in other client databases. All datatypes and element types are migrated. Cleanup is performed per-destination-DB only after cross-validating all clients.
Current Status¶
| Area | Status |
|---|---|
| Page Templates | DONE -- 45 of 48 migrated; 3 confirmed obsolete |
| Component Views | DONE -- 146 total (121 blockgrid + 7 blocklist + 18 SiteLayout) |
| Bootstrap 5 Upgrade | DONE -- 1,142 CSS replacements across 159 files |
| Migration Tool Fixes | DONE -- duplication eliminated (commits 09935d2, 164069f, 76a17cf) |
| Calculator Localization | DONE -- 6 partials with IDictionaryService |
| Color Picker / Double-Hash | DONE -- fixed across 20+ files |
| MediaPicker3 Single-Pick | DONE -- fixed across 20+ files |
| DropDown.Flexible JSON | DONE -- migration tool root cause fixed (commit 4168abe), wrapped across 20+ views |
| RTE TipTap Config | DONE -- toolbar, extensions, HTML preservation |
| Obsolete API Calls | DONE -- .Children/.Parent properties converted to methods |
| API Keys Externalized | DONE -- moved to appsettings.json |
| Orphan Element Views | DONE -- 4 removed (commit 81d4ca6) |
Overall migration completeness: ~98% (frontend code + runtime fixes). All W10 tasks DONE — see Week Plan W10. Only migration re-run and post-launch cleanup items remain.
Active Issues (Week W10)¶
Investigation on 2026-02-28 identified remaining runtime issues across 3 categories. Comprehensive findings in Report 32.
P0 — Critical (blocks page rendering)¶
| # | Issue | Status | Owner |
|---|---|---|---|
| 1 | DropDown.Flexible migration -- GridValueTypeConverter.ConvertDropdownValue() returned JArray instead of string |
FIXED (commit 4168abe) |
Marco |
| ~~2~~ | ~~IPublishedContent → MediaWithCrops — 87 occurrences in 41 files converted~~ | FIXED c6dd388 — Value<MediaWithCrops> + .MediaUrl(). 15 content pickers preserved. |
~~João~~ |
| ~~3~~ | ~~jQuery UI slider async/defer race — sliders call $.slider() before jQuery UI loaded~~ |
FIXED 5babe78 — ScriptHelper default changed to async: false. |
~~Rodrigo~~ |
| ~~4~~ | ~~Contact-us area placement~~ | STALE — not a bug, v8 data confirmed correct | ~~Marco~~ |
| ~~5~~ | ~~Cache busting missing~~ | FIXED 5383a48 — asp-append-version="true" on all local tags in 10 views. ScriptHelper/CssHelper updated with IFileVersionProvider. |
~~Rodrigo~~ |
| ~~6~~ | ~~masterLogin missing RenderScripts/RenderCss — no JS/CSS on login page~~ | FIXED 1c727d4 — Added @Html.RenderScripts() and @Html.RenderCss() to MasterLogin.cshtml. |
~~João~~ |
P1 — High (functional bugs)¶
| # | Issue | Status | Owner |
|---|---|---|---|
| ~~7~~ | ~~Calculator dictionary keys~~ | FIXED 2ac8a4f — all 169 v8 items already migrated. V17 views corrected to use original key names. |
~~Marco + João~~ |
| ~~8~~ | ~~18+ unprotected DropDown.Flexible reads — bare Value<string>() throws JsonException~~ |
FIXED a0f588a — 10 dropdown reads across 8 files converted to SafeDropdownValue(). |
~~João~~ |
| ~~9~~ | ~~Hardcoded media URLs in 4 JS files~~ | FIXED 5babe78 — replaced with window.location.origin + "/media/" |
~~Rodrigo~~ |
| ~~10~~ | ~~e.preventDefault missing parentheses~~ |
FIXED 5babe78 — 9 call sites across 7 files |
~~Rodrigo~~ |
| ~~11~~ | ~~JS selectors mismatch v17 HTML~~ | FIXED 5babe78 — #loans → #loansInput in calculatorLarge.js |
~~Rodrigo~~ |
| ~~12~~ | ~~Calculator frequency comparison~~ | FIXED deccc8c — "Weekly" → "W" + default fallbacks |
~~João~~ |
| ~~13~~ | ~~Menu JS broken for menu2/3/4 — ScriptHelper registers identical slick JS for all menu variants~~ | FIXED a0f588a — Fixed menu2/3/4 JS in master.cshtml and MasterThirdParty.cshtml. |
~~Rodrigo~~ |
| ~~14~~ | ~~ScriptHelper default async:true~~ | FIXED 5babe78 — default changed to async: false |
~~Rodrigo~~ |
| ~~15~~ | ~~Case sensitivity — 14 path fixes across 4 files~~ | FIXED dbab2c7 — Home/ → home/, GlobalAddress paths corrected. Linux/Docker compatible. |
~~João~~ |
| ~~16~~ | ~~popUpForms.cshtml — entire form rendering commented out with TODO~~ | FIXED 73a6640 — Restored @await Component.InvokeAsync("RenderForm") with PascalCase params. Layout fixed to masterNoHeaderNof. |
~~João~~ |
| ~~17~~ | ~~CommonBondRange table — ~2,500 postcodes in custom v8 table, not migrated to v17~~ | NOT AN ISSUE — v8 table has 0 rows for this client. V17 auto-creates table via migration plan. | ~~Marco~~ |
| ~~18~~ | ~~UserServiceComposer~~ | FIXED PR #1422 — UserGroupSave/DeleteProtectionHandler implemented | ~~Marco~~ |
| ~~19~~ | ~~GalleryService — 5 gallery items in v8 DB, service not migrated to v17~~ | FIXED b39ad7c — IGalleryService interface, GalleryService impl, GalleryResultSet view model. Registered scoped in Program.cs. |
~~João~~ |
P2 — Quality¶
| # | Issue | Status | Owner |
|---|---|---|---|
| ~~20~~ | ~~External CDN refs (AOS) — 18 refs to unpkg.com in 9 files~~ | FIXED 9d2c1cf — AOS 2.3.1 vendored to wwwroot/vendor/aos/. 18 CDN refs replaced with local paths. asp-append-version="true" added. |
~~Rodrigo~~ |
| ~~21~~ | ~~Hardcoded EUR/en-IE — UK clients see euro briefly~~ | FIXED f18c57d — hardcoded EUR/en-IE removed from 4 calculator JS files |
~~Rodrigo~~ |
| ~~22~~ | ~~SEO Open Graph image — uses IPublishedContent~~ |
FIXED c6dd388 — fixed as part of J1 (SEO.cshtml converted to MediaWithCrops). |
~~João~~ |
| ~~23~~ | ~~Calculator CSS gap — 1,728 lines across 3 v8 CSS files may not be in v17 wwwroot~~ | VERIFIED — CSS files present in v17 wwwroot | ~~Rodrigo~~ |
| ~~24~~ | ~~CalculatorSmall no dictionary~~ | FIXED 2ac8a4f — all views now use IDictionaryService |
~~João~~ |
| ~~25~~ | ~~Email templates — 25 Razor templates need manual per-client recreation~~ | DEFERRED — per-client task, not a migration blocker | ~~Marco~~ |
| ~~26~~ | ~~Section name mismatch — some partials register scripts with non-matching section names~~ | FIXED — ScriptHelper/CssHelper pattern eliminates section name dependency | ~~Rodrigo~~ |
See Report 30, Report 32, and Week Plan W10 for full details.
Completed Phases¶
| Phase | Scope | Status |
|---|---|---|
| Phase 1 -- P0 Fixes | Data protection files, camelCase duplicates, DT 1055 | DONE |
| Phase 2 -- MkDocs | Documentation site setup | DONE |
| Phase 3 -- P1 Fixes | Page templates, component views, calculator localization, video slides, orphan audit | DONE |
| Phase 4 -- Bootstrap 5 | Bootstrap 4.4.1 to 5.3.3 upgrade (package, templates, layouts, components, partials, JS, CSS) | DONE |
| Phase 5 -- P2/P3 | LoanBoxes, API keys, obsolete API calls | DONE |
Key Decisions Made¶
-
Per-datatype element types retained. Report 11 confirmed zero identical layouts across datatypes. Layout/area wrapper deduplication is impossible without breaking editor permissions. This architecture is correct by design.
-
Settings deduplication deferred. 29 potential savings, but GUID remapping risk across all client databases outweighs the benefit. No functional impact from keeping them separate.
-
4-level BlockGrid hierarchy retained. Row Config, Layout, Area Wrapper, Content. Area Wrappers preserve v8 cell-level styles. Mitigated via Content Templates and Quick Add backoffice extension (documented in Report 13).
-
Bootstrap 5.3.3 chosen. Latest stable release. All
data-*attributes converted todata-bs-*, class renames applied across all views and JS files. -
3 page templates declared obsolete:
TrustpilotWidget,LoanBoxContactControl,NewsCategoryItems. These were v8-specific widgets with no content in any client database. -
Flat directory structure retained for
blockgrid/Components/. Subdirectory organization (Report 08 Option A) was deferred -- the prefix-based naming convention (grid_element_*,grid_builtin_*, etc.) provides sufficient organization.
Remaining Work¶
Active (Week W10 -- blocks go-live) -- ALL DONE¶
| # | Item | Detail | Owner |
|---|---|---|---|
| ~~1~~ | ~~IPublishedContent → MediaWithCrops~~ | FIXED c6dd388 — 87 occurrences in 41 files converted. 15 content pickers preserved. |
~~João~~ |
| ~~2~~ | ~~Cache busting~~ | FIXED 5383a48 — asp-append-version="true" on all local tags. ScriptHelper/CssHelper updated. |
~~Rodrigo~~ |
| ~~3~~ | ~~Calculator dictionary keys~~ | FIXED 2ac8a4f — views corrected to use v8 key names. |
~~Marco~~ |
| ~~4~~ | ~~CommonBondRange table~~ | NOT AN ISSUE — v8 table has 0 rows. V17 auto-creates table via migration plan. Per-client data population. | ~~Marco~~ |
| ~~5~~ | ~~UserServiceComposer~~ | FIXED PR #1422. | ~~Marco~~ |
| ~~6~~ | ~~Case sensitivity~~ | FIXED dbab2c7 — 14 path fixes across 4 files. |
~~João~~ |
| ~~7~~ | ~~GalleryService~~ | FIXED b39ad7c — IGalleryService + GalleryService + GalleryResultSet. Scoped DI in Program.cs. |
~~João~~ |
| ~~8~~ | ~~Calculator config in SiteSettingsService~~ | FIXED f18c57d — calculatorsConfiguration moved to SiteSettingsService. |
~~Marco~~ |
| ~~9~~ | ~~Hardcoded EUR/en-IE~~ | FIXED f18c57d — removed from 4 calculator JS files. |
~~Rodrigo~~ |
| ~~10~~ | ~~bootstrap-datepicker version~~ | FIXED 85873c2 — aligned to local v1.9.0 vendor. |
~~Rodrigo~~ |
| ~~11~~ | ~~CalculatorSmall @ prefix~~ | FIXED 24dea20 + d6299da — missing @ prefix fixed. |
~~João~~ |
| ~~12~~ | ~~Null-safe patterns audit~~ | FIXED 7273808 — 4 null-safe fixes applied. |
~~João~~ |
P2 -- Medium (non-blocking for go-live)¶
| # | Item | Detail |
|---|---|---|
| 8 | Calculator slider UI | Number inputs instead of jQuery UI sliders. Hidden fields and data attributes are in place. |
| 9 | Calculator form validation | Basic HTML5 only. Needs jQuery validation with localization support. |
| 10 | Calculator CSS verification | 1,728 lines across 3 CSS files -- verify copied to v17 wwwroot. |
| 11 | Email templates | 25 Razor email templates need manual per-client recreation. |
| ~~12~~ | ~~External CDN refs (AOS)~~ | FIXED 9d2c1cf — AOS 2.3.1 vendored locally. 18 refs replaced. |
P3 -- Low (post-launch cleanup)¶
| # | Item | Detail |
|---|---|---|
| 13 | Test DataType 2236 cleanup | Not checked across client databases. Candidate for removal if unused everywhere. |
| 14 | Content usage audit | Detailed content-per-element-type breakdown (Report 04 Section 7). |
| 15 | Settings element type deduplication | 29 savings. Deferred due to GUID remapping risk. |
| ~~16~~ | ~~CalculatorSmall localization~~ | FIXED 2ac8a4f — all views use IDictionaryService now. |
Component Readiness¶
| Component | Status | Notes |
|---|---|---|
| News | 100% | All display modes, culture/visibility filters, property casing verified. |
| Grid Layouts | 100% | Property whitelist confirmed complete. 11 v8 files consolidated to 3. |
| Testimonials | 100% | Slider layout, image suppression, read-more link, default mode all fixed. |
| LoanBoxes | 100% | All 4 modes (Tabs, Boxes, FlipCards, Accordion). P2 performance item deferred. |
| Calculators | 95% | Dictionary keys fixed (2ac8a4f), frequency comparison fixed (deccc8c), config in SiteSettingsService (f18c57d), EUR/en-IE removed (f18c57d). Remaining: slider UI + form validation (runtime testing). |
| Data Protection | 100% | All 5 components working. Duplicate camelCase views removed. |
| Video Slides | 100% | YouTube, Vimeo, and internal video slides created. |
| Announcement/Spotlight | 100% | Scroll and spotlight grid verified working. |
Key Numbers¶
| Metric | Value |
|---|---|
| V8 views (total) | 257 |
| V17 views (migrated) | ~246 (~96%) |
| Page templates | 45 of 48 (3 obsolete) |
| Component views | 146 (121 blockgrid + 7 blocklist + 18 SiteLayout) |
| V8 grid datatypes | 14 |
| V17 BlockGrid datatypes | 13 (one v8 DT had no doc type) |
| V17 element types (after fresh migration) | ~430 (~25 duplicates eliminated) |
| Element types in-use (in content) | 164 |
| Element types configured (no content) | 217 |
| Element types orphaned | 74 (30 infrastructure + 44 content) |
| Migration tool fix commits | 4 (09935d2, 164069f, 76a17cf, 4168abe dropdown fix) |
| Bootstrap 5 commits | 5 (643174b, 4cfa267, 7cd8ee8, f7f697c, 08e9a5d) |
| Bootstrap CSS replacements | 1,142 across 159 files |
| Content nodes in v17 | 115 |
| Nodes with BlockGrid data | 76 |
| Duplicate view pairs | 0 (all resolved) |
| Case sensitivity issues | 0 (all 14 fixed — commit dbab2c7) |
| P0 issues | 0 open (all fixed) |
| P1 issues | 0 open (all fixed) |
| P2 items remaining | 0 (email templates deferred to per-client) |
4-Level BlockGrid Hierarchy¶
The v17 BlockGrid uses a strict 4-level nesting hierarchy:
Row Config -> Layout -> Area Wrapper -> Content
- Layout AllowAtRoot is set to
false, enforcing that editors must start with a Row Config. - Frontend rendering (
BootstrapGrid.cshtml) handles all 4 levels. No changes needed. - Content migration (
GridLayoutToBlockGridMigrator.cs) creates proper 4-level nesting. Existing migrated content is correct.
Why 4 Levels Are Necessary¶
Area Wrappers preserve v8 cell-level styles (background color, padding, margins, etc.) that have no other home in the BlockGrid model. The Row Config level provides page-level section configuration (full-width breakout, container behavior). Both are required for feature parity with v8.
Backoffice UX Mitigations¶
The 4-level hierarchy approximately doubles editor clicks. Three mitigations are documented:
- Content Templates (lowest effort) -- pre-populated page blueprints that eliminate hierarchy setup.
- Quick Add backoffice extension -- toolbar button offering presets like "Add Full Width Row" in one click.
- Auto-insert single-choice levels -- skip the catalogue modal when only one option exists (5 of 14 datatypes).
Report Index¶
| Report | File | Topic |
|---|---|---|
| 00 | 00-SUMMARY.md |
This summary |
| 01 | 01-views-migration-audit.md |
V8 to v17 views comparison |
| 02 | 02-duplicate-views-analysis.md |
Duplicate view resolution (ARCHIVED) |
| 03 | 03-v8-grid-baseline.md |
Immutable v8 reference |
| 04 | 04-v17-element-type-audit.md |
455 element types audit |
| 05 | 05-grid-deduplication-analysis.md |
Deduplication analysis and decisions (ARCHIVED) |
| 06 | 06-view-element-crossref.md |
View/element type cross-reference |
| 07 | 07-deep-dive-analysis.md |
Component deep-dive analysis |
| 08 | 08-fix-plan-frontend.md |
Frontend naming fix plan (ARCHIVED) |
| 09 | 09-fix-plan-doctypes.md |
DocType/DataType fix plan (ARCHIVED) |
| 10 | 10-fix-plan-logic.md |
Component logic fix plan (ARCHIVED) |
| 11 | 11-grid-dedup-deep-investigation.md |
Grid dedup investigation (zero identical layouts confirmed) |
| 12 | 12-grid-architecture-explained.md |
Grid architecture documentation |
| 13 | 13-grid-migration-visual-plan.md |
Content migration and UX mitigations |
| 15 | 15-bootstrap5-upgrade.md |
Bootstrap 5 upgrade (DONE) |
| 19 | 19-full-migration-validation.md |
Full v8→v17 file-by-file validation |
| 20-29 | 20-*.md through 29-*.md |
Side-by-side comparison reports |
| 30 | 30-v17-rendering-issues-scan.md |
V17 rendering issues scan (87 IPublishedContent + 18 dropdown) |
| 31 | 31-dropdown-migration-analysis.md |
DropDown.Flexible root cause and fix (DONE) |
| 32 | 32-comprehensive-investigation-findings.md |
Consolidated investigation findings (Feb 28) |
Supporting Data Files¶
| File | Purpose |
|---|---|
_v17-api-results.json |
Full API results (element types, doc types, tree) |
_blockgrid-configs.json |
All 13 BlockGrid data type configurations |
_content-usage.json |
Content node analysis -- element type usage counts |
_element-type-status.json |
Classified: in-use / configured / orphaned |