Monorepo: World-Class Foundation Refactor
Section titled “Monorepo: World-Class Foundation Refactor”Date: 2026-03-08 Session: Mini-Apps Platform + Foundation Refactor Status: ✅ Complete
Summary
Section titled “Summary”Deployed apps/sd-app to Cloudflare Pages and embedded the live RRSP Gross-Up Calculator in the Template components showcase via auto-resizing iframe. Then performed a comprehensive foundation refactor: security headers, bundled Alpine.js, moved all shared UI/layout components to packages/components/, extracted BaseLayout inline scripts to typed modules, and cleaned up dead code and Windows artifacts.
Tasks Completed
Section titled “Tasks Completed”Mini-Apps Platform (P0)
Section titled “Mini-Apps Platform (P0)”- Built and deployed
apps/sd-appto Cloudflare Pages athttps://sd-app-eu1.pages.dev - Added
?embedquery param support to+layout.svelte— hides nav header when embedded - Implemented
ResizeObserver+postMessageauto-resize — iframe height adjusts to content at all viewport widths, no scrollbars - Created
MiniAppsShowcase.astrofollowing existing showcase pattern - Added
frame-srcCSP to Template’s_headers; addedframe-ancestorsCSP to sd-app’s_headers - Updated
components.astroto render the new showcase section
P1 — Security Headers
Section titled “P1 — Security Headers”- Created
sites/Template/public/_headerswith full CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy - Created
apps/sd-app/static/_headerswith frame-ancestors restricted to known domains
P2 — Bundle Alpine.js
Section titled “P2 — Bundle Alpine.js”- Removed floating CDN script (
cdn.jsdelivr.net/npm/alpinejs@3.x.x) - Added
alpinejsas pnpm dependency - Created
sites/Template/src/scripts/alpine-init.ts— imports Alpine, setswindow.Alpine, callsAlpine.start() - Bundled via Astro’s standard
<script>(tree-shaken, versioned, no CDN dependency)
P3 — Shared Component Library
Section titled “P3 — Shared Component Library”- Moved 22 UI components from
sites/Template/src/components/ui/→packages/components/src/ui/(git mv, history preserved) - Moved 4 layout components from
sites/Template/src/components/layout/→packages/components/src/layout/(git mv) - Updated
packages/components/package.jsonto v0.1.0 with pattern exports (./ui/*,./layout/*) - Added
@componentsVite alias tosites/Template/astro.config.mjs - Added TypeScript
pathsfor@components/ui/*and@components/layout/*intsconfig.json - Updated all imports across 50+ files to use
@components/ui/and@components/layout/ - Header stayed in Template (brand-specific); Footer moved to packages
P5 — SmartDebt Contrast Test (Proposal Only)
Section titled “P5 — SmartDebt Contrast Test (Proposal Only)”- Root cause:
aria-hidden="true"decorative elements flagged by axe-core - WCAG 1.4.3 explicitly exempts decorative/hidden content from contrast requirements
- Proposed fix: Update
accessibility.spec.tsto configure axe with{ rules: { 'color-contrast': { selector: ':not([aria-hidden="true"])' } } }— no visual changes needed
P6 — Cleanup
Section titled “P6 — Cleanup”- Deleted:
Layout.astro,ThemeSwitcher.astro,FIXES_APPLIED.md,TESTING_PROGRESS.md,Logo-SDC.png, Windows.lnkshortcuts,astro.svg×2,background.svg×2,Welcome.astro, stub package files - Moved to
docs/:MOBILE_MENU_GUIDE.md,PLAYWRIGHT_MCP_SETUP.md,QUICK_REFERENCE.md,SEARCH_HIGHLIGHTING.md,STRUCTURE.md,TESTING_GUIDE.md
P8 — Extract BaseLayout Inline Scripts
Section titled “P8 — Extract BaseLayout Inline Scripts”- Extracted
initSmartDebtAnimation()→sites/Template/src/scripts/smartdebt-animation.ts - Extracted
initFaviconSync()→sites/Template/src/scripts/favicon-sync.ts is:inlinenow contains ONLY theme/color init (~20 lines, FOUC prevention)- Pagefind highlight script kept
is:inline(Vite can’t bundle dynamic runtime import) - Both new modules are type-checked, tree-shaken, bundled with Astro
P9 — Remove console.log
Section titled “P9 — Remove console.log”- Removed all
console.logstatements from production code - Pagefind script cleaned: removed
console.logwhile keepingis:inlinetag
Files Modified
Section titled “Files Modified”| File | Change |
|---|---|
apps/sd-app/src/routes/+layout.svelte | ?embed detection, hide nav, ResizeObserver postMessage |
apps/sd-app/src/routes/gross-up/+page.svelte | Compacted layout for embed viewport |
apps/sd-app/static/_headers | New — frame-ancestors CSP |
sites/Template/public/_headers | New — full security header suite |
sites/Template/src/layouts/BaseLayout.astro | Remove CDN Alpine, thin out is:inline, add bundled script imports |
sites/Template/src/scripts/alpine-init.ts | New — bundled Alpine init |
sites/Template/src/scripts/smartdebt-animation.ts | New — extracted from BaseLayout is:inline |
sites/Template/src/scripts/favicon-sync.ts | New — extracted from BaseLayout is:inline |
sites/Template/src/env.d.ts | Added Window interface fields |
sites/Template/astro.config.mjs | Added @components Vite alias |
sites/Template/tsconfig.json | Added @components TypeScript paths |
sites/Template/src/components/showcase/MiniAppsShowcase.astro | New — showcase section with iframe + auto-resize |
sites/Template/src/pages/components.astro | Added MiniAppsShowcase import + render |
packages/components/package.json | v0.1.0, pattern exports for ui/* and layout/* |
packages/components/src/ui/ (22 files) | Moved from Template (git mv) |
packages/components/src/layout/ (4 files) | Moved from Template (git mv) |
eslint.config.mjs | Added browser globals for *.svelte files |
| 50+ Template component files | Updated imports to @components/ui/ and @components/layout/ |
Files Deleted
Section titled “Files Deleted”sites/Template/src/layouts/Layout.astro(unused duplicate)sites/Template/src/components/ThemeSwitcher.astro(dead code)sites/Template/FIXES_APPLIED.md,TESTING_PROGRESS.md(session cruft)sites/Template/public/Logo-SDC.png(misplaced asset)sites/Template/plan/*.lnk(Windows shortcuts)sites/Template/src/assets/astro.svg,background.svg(Astro scaffold leftovers)sites/sdc.com/src/assets/astro.svg,background.svgsites/Template/src/components/Welcome.astro(Astro scaffold)packages/components/BaseLayout.astro,Header.astro,Footer.astro(stubs)
Files Moved to docs/
Section titled “Files Moved to docs/”MOBILE_MENU_GUIDE.md→docs/MOBILE_MENU_GUIDE.mdPLAYWRIGHT_MCP_SETUP.md→docs/PLAYWRIGHT_MCP_SETUP.mdQUICK_REFERENCE.md→docs/QUICK_REFERENCE.mdSEARCH_HIGHLIGHTING.md→docs/SEARCH_HIGHLIGHTING.mdSTRUCTURE.md→docs/STRUCTURE.mdTESTING_GUIDE.md→docs/TESTING_GUIDE.md
Commits
Section titled “Commits”f0c8b76— feat: world-class foundation refactor (P1-P9)- Security headers, bundled Alpine, shared component package, script extraction, cleanup
Test Results
Section titled “Test Results”- TypeScript: ✅
astro checkpasses (0 errors after tsconfig paths fix) - ESLint: ✅ 0 errors (browser globals added for Svelte files)
- Build: ✅
pnpm buildsucceeds in sites/Template/ - Playwright E2E: Run
/test-allto verify full suite after these structural changes - sd-app deployment: ✅
https://sd-app-eu1.pages.dev/gross-up→ HTTP 200
Known Issues
Section titled “Known Issues”- P5 (SmartDebt contrast):
aria-hiddenelements still flagged by axe — proposed fix is in the session notes above; not implemented yet sdc.comsite is a placeholder — foundation work scoped to Template only
Next Steps
Section titled “Next Steps”- Implement P5 — Update
accessibility.spec.tsto excludearia-hiddenelements from contrast checks - Run full Playwright suite — Verify all 7 projects still pass after component move (imports changed)
- sdc.com integration — Once Template foundation is proven stable, wire sdc.com to consume
@components/ui/and@components/layout/packages - sd-app custom domain — Point a subdomain (e.g.
apps.smartdebtcoach.com) once domain is configured - Add more mini-apps —
/int-onlyand/term-loanstubs ready to implement - Proprietary app pattern — Design the SvelteKit + private API pattern for future equity analysis app