No blocking findings
I found no actionable regression in the reviewed diff.
The migration removes a large dependency from three lazy entries without changing their component logic. SharedModule remains in 3 of 45 lazy application entries, down from 6. The measured JavaScript reductions support the change.
There is one deliberate behavior change. Dashboard stops inheriting portfolio routes through PortfolioModule. The supported dashboard portfolio URLs remain in its own route configuration. The removed aliases deserve a release note, but I would not block this PR on routes that the author explicitly retires and that have no direct callers in the checked source.
This verdict covers source, compilation and bundle checks. I did not independently run logged-in workflows, hydration or server-rendered URL comparisons for this PR.
What changes
Link-in-bio
The fan preview and its feed, carousel and welcome-video components replace SharedModule with explicit template imports. The imports include the existing media player, formatting pipes, fundraising view, polls and mobile directives.
Profile
The app lazy-loads PROFILE_ROUTES for both /:id and /wls/:id. ProfileContainerComponent and DynamicSeoProfileComponent become standalone. The route still renders DynamicSeoProfileComponent at its empty child path.
Portfolio
The 18 former module declarations become standalone. Monetize lazy-loads PORTFOLIO_ROUTES. Dashboard imports PortfolioBannerViewComponent directly, so rendering that view no longer imports the portfolio editor's route table.
What I checked in the code
Component logic is unchanged
An AST comparison found 26 changed files that differ only in imports, standalone metadata or comments. The remaining 12 files contain module and route wiring, module removal, or the four HTML binding removals described below. No component method body changes.
Template dependencies remain available
Angular emits 650 components at the PR head, compared with 653 at the comparison base. Of the 650 common components, 649 retain exactly the same matched directives and pipes after resolving import aliases.
PortfolioComponent loses only NativeElementInjectorDirective from ngx-intl-tel-input. Its template has no phone input. The three missing compiled components are SelectInterestsAccordionComponent, SeoLandingComponent and SeoLandingCreatorCardComponent. Their files remain, but the removed module imports and declarations were their only connection to the active compilation graph.
Routes and providers stay in place
The profile route array and all 26 portfolio route objects are byte-identical after excluding their renamed declarations and NgModule wrappers. Paths, ordering, component references, permission guards and route data remain intact. The app and monetize parents change only their lazy import targets.
SharedModule's providers and exports are unchanged. AppModule already calls provideSharedRootProviders, which includes the circle-progress root configuration and shared services. Removing PortfolioModule's duplicate NgCircleProgressModule.forRoot call does not remove that root configuration.
The four removed bindings were not component inputs
Four portfolio templates remove [infoIconSize]="18" from app-info-icon. InfoIconComponent has height and width inputs, but no infoIconSize input. The removed modules allowed custom elements, which hid this invalid binding. Removing it does not change the component's declared dimensions.
The dashboard route change is intentional
Before this PR, DashboardModule imported PortfolioModule to render its banner view. That import also registered the portfolio routes under dashboard. Importing the standalone banner component removes that accidental registration.
The PR author reports that /dashboard/add-edit-portfolio now behaves like an unknown dashboard path and /dashboard/banner-view/:id becomes a 404. I confirmed the import change and found no direct source links to those two aliases. I did not rerun those HTTP requests.
The real dashboard route /dashboard/portfolio/:userId/banner-view/:id remains. Profile navigation, unlock flows and the portfolio navigation helper use that form. Dashboard's music, podcast, video and collection routes remain too.
If old bookmarks or external integrations rely on the accidental aliases, they will need redirects. The repository search cannot establish whether such external callers exist.
Independent bundle measurements
| Lazy entry | Base MB | PR MB | Reduction |
|---|---|---|---|
| Link-in-bio | 3.816 | 1.204 | 68.5% |
| Profile | 3.345 | 1.863 | 44.3% |
| Portfolio | 5.099 | 2.068 | 59.4% |
| Dashboard | 6.457 | 5.657 | 12.4% |
The initial JavaScript grows by 1,127 bytes, from 7,139,809 to 7,140,936 bytes. Dashboard, edit-preference and the white-label cover page are the three remaining lazy entries that load SharedModule.
I calculated these totals from the build graph by following static JavaScript imports and subtracting the initial main, polyfill and scripts chunks. They are bundle measurements, not compressed transfer sizes or page-load timings. The 45 entries include dynamically loaded components as well as route entries.
Checks run for this review
| Check | Result |
|---|---|
| TopFans QA build | Pass. Fresh client and server build from an isolated checkout of the PR head. The 42 warning groups match the base build's count. |
| Angular compiler | Pass. Fresh compilation at head; emitted template dependencies compared against the saved base output. |
| Generated ajwhite QA project | Pass. Generated ajwhite from QA API data in the isolated checkout, then compiled its client and server bundles. |
| Route comparison | Pass. Profile and portfolio route arrays match the base exactly. |
| Source and whitespace checks | Pass. Component logic comparison, provider inspection, caller searches and git diff --check. |
The comparison uses merge base b0114afffd, which is the prior PR's reviewed head. I reused its existing QA build and compiler artifacts, and ran the head checks afresh. The target branch tip reported by GitHub was 5891824685; this review does not claim to test the result of merging onto that tip.
Build command and scope
node --max_old_space_size=10048 node_modules/@angular/cli/bin/ng.js \
build TopFans --configuration qa --prerender=false --stats-json \
--output-path=/tmp/pr10838-astra-qa
The white-label check uses the same 10 GB Node heap limit with the generated ajwhite project. Prerendering is disabled. This review does not include a fresh development or production build, the full prerender list, or an interactive application test.
What still needs browser evidence
The author reports logged-in white-label comparisons across 20 portfolio URLs, profile hydration checks, media playback, groups selection, form validation and server-rendered comparisons. Those are author-reported results, not checks I reran.
Before release, retain coverage for opening a creator profile on the main and white-label sites, playing a link-in-bio media preview, editing a portfolio through its steps, opening pricing and image dialogs, and following a dashboard portfolio link.
The author also reports a portfolio_shape error on the add-edit-portfolio page and says it occurs on base. I did not reproduce it. It is outside this review's verified findings.