Skip to content

feat: narrow Wealth Management app and Symphony host integration#44

Closed
mistryvinay wants to merge 2 commits intomasterfrom
wealth-management-v2
Closed

feat: narrow Wealth Management app and Symphony host integration#44
mistryvinay wants to merge 2 commits intomasterfrom
wealth-management-v2

Conversation

@mistryvinay
Copy link
Copy Markdown
Collaborator

@mistryvinay mistryvinay commented Mar 23, 2026

Summary

  • narrow the Wealth Management feature by moving its data, models, and reusable UI primitives under the WealthManagement folder instead of leaving them shared at the app root
  • keep only the Symphony integration required for that feature surface: the shared chat shell, embedded client chat host, theme bridge handoff, unread notification wiring, and scoped host bootstrap and error handling
  • remove workspace-specific VS Code settings and unused dependency surface, while folding in the follow-up fixes for centralized debug logging, stream unread cleanup, stronger segment typing, and accessible Wealth-specific menu and sheet behavior

Validation

  • npm test -- --runInBand --watch=false
  • npm run build

- add the Wealth Management dashboard, contacts, and client detail flows with supporting data models, assets, and route updates
- embed the Symphony client chat host with shared shell controls, theme bridging, unread notifications, and bootstrap improvements
- add UI primitives, Tailwind/PostCSS setup, and test coverage for Wealth Management, chat integration, and theming
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clever-deal Error Error Mar 23, 2026 4:30pm

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

Adds a new Wealth Management mini-app experience inside CleverDeal.React, including a client dashboard/contacts/client detail flow, plus an embedded Symphony chat integration with shared theming/notifications and supporting UI primitives + Tailwind/PostCSS setup.

Changes:

  • Introduces the Wealth Management routes/pages and supporting data models + shell data.
  • Adds Symphony chat embedding (shared chat + client chat host), notification tracking, and a theme ownership bridge.
  • Adds Tailwind/PostCSS configuration and a small set of reusable UI primitives with accompanying tests.

Reviewed changes

Copilot reviewed 59 out of 68 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
AppExamples/CleverDeal.React/tsconfig.json Updates TS include/exclude patterns for the React app.
AppExamples/CleverDeal.React/tailwind.config.js Adds Tailwind config (content paths, theme extensions, preflight disabled).
AppExamples/CleverDeal.React/src/index.tsx Adds lazy-loaded Wealth Management route + dev error filtering for ResizeObserver loop.
AppExamples/CleverDeal.React/src/Theme/symphonyThemeBridge.ts Adds theme bridge to coordinate global vs route-owned Symphony themes.
AppExamples/CleverDeal.React/src/Theme/symphonyThemeBridge.test.ts Unit tests for the Symphony theme bridge ownership behavior.
AppExamples/CleverDeal.React/src/Theme/ThemeProvider.tsx Routes Symphony theme updates through the shared theme bridge.
AppExamples/CleverDeal.React/src/Theme/ThemeProvider.test.tsx Tests ThemeProvider calls the theme bridge correctly.
AppExamples/CleverDeal.React/src/Models/WealthManagementData.ts Adds Wealth Management data model types and constants.
AppExamples/CleverDeal.React/src/Data/wealthManagementShell.ts Adds lightweight shell data for room/contact stream IDs + avatars.
AppExamples/CleverDeal.React/src/Data/wealthManagement.ts Adds demo Wealth Management dataset (dashboard, clients, PDFs, etc.).
AppExamples/CleverDeal.React/src/Data/routes.ts Adds “Wealth Management” entry for landing page tiles.
AppExamples/CleverDeal.React/src/Components/ui/utils.ts Adds cn helper for className composition.
AppExamples/CleverDeal.React/src/Components/ui/tabs.tsx Adds a Tabs UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/table.tsx Adds Table UI primitives.
AppExamples/CleverDeal.React/src/Components/ui/sheet.tsx Adds Sheet (drawer/modal-like) UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/separator.tsx Adds Separator UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/scroll-area.tsx Adds ScrollArea UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/resizable.tsx Adds basic resizable panel group primitive.
AppExamples/CleverDeal.React/src/Components/ui/menubar.tsx Adds Menubar UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/input.tsx Adds Input UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/dropdown-menu.tsx Adds DropdownMenu UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/card.tsx Adds Card UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/calendar.tsx Adds Calendar UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/button.tsx Adds Button UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/badge.tsx Adds Badge UI primitive.
AppExamples/CleverDeal.React/src/Components/ui/avatar.tsx Adds Avatar UI primitive with image/fallback handling.
AppExamples/CleverDeal.React/src/Components/ui/avatar.test.tsx Tests Avatar fallback vs loaded state behavior.
AppExamples/CleverDeal.React/src/Components/WealthManagement/styles/wealthManagement.css Adds Tailwind entry CSS for Wealth Management-only styling.
AppExamples/CleverDeal.React/src/Components/WealthManagement/pages/ModulePlaceholderPage.tsx Adds placeholder page for future Wealth modules.
AppExamples/CleverDeal.React/src/Components/WealthManagement/pages/ContactsPage.tsx Adds client list (table + filters) and chat-launch integration.
AppExamples/CleverDeal.React/src/Components/WealthManagement/pages/ClientDetailPage.tsx Adds client profile page with embedded client chat + document share flow.
AppExamples/CleverDeal.React/src/Components/WealthManagement/pages/ClientDetailPage.test.tsx Tests client document share sequencing + error handling.
AppExamples/CleverDeal.React/src/Components/WealthManagement/index.ts Exports WealthManagement module entrypoints.
AppExamples/CleverDeal.React/src/Components/WealthManagement/components/SymphonyMark.tsx Adds Symphony logo mark component.
AppExamples/CleverDeal.React/src/Components/WealthManagement/components/SymphonyChatShell.tsx Adds shared shell wrapper around embedded Symphony chat experiences.
AppExamples/CleverDeal.React/src/Components/WealthManagement/components/ChatLoadingOverlay.tsx Adds loading overlay used during chat bootstrapping/masking.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/wealthSymphonyTheme.ts Defines Wealth Symphony theme + ownership helpers + settle/reapply logic.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/wealthSymphonyTheme.test.ts Tests Wealth theme payload/serialization + refresh behavior.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useSharedWealthChatController.ts Adds shared chat bootstrap + stream switching controller with retries.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useSharedWealthChatController.test.tsx Tests shared chat controller bootstrap/switch + retry behavior.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useSharedChatPresentationTransition.ts Adds masking/refresh behavior when shared chat layout changes.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useSharedChatPresentationTransition.test.tsx Tests masking/refresh behavior across mode/visibility transitions.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useEmbeddedClientChatHost.ts Adds client chat host iframe URL + readiness/error message handling.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useEmbeddedClientChatHost.test.tsx Tests host URL building + ready/error message filtering.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/useEcpSlot.ts Adds hook to manage/cleanup a Symphony ECP slot container.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/symphonySdk.ts Adds SDK service for script loading, rendering, stream switching, error recovery.
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/symphonySdk.test.ts Tests SDK service behaviors (init/render/openStream/error/reset).
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/symphonyNotifications.ts Adds notification listener service (global + per-stream unread + debug).
AppExamples/CleverDeal.React/src/Components/WealthManagement/chat/symphonyNotifications.test.ts Tests notification baselines/fallback behavior + per-stream tracking.
AppExamples/CleverDeal.React/src/Components/WealthManagement/WealthManagement.test.tsx Integration-style tests for Wealth Management flows and chat UI.
AppExamples/CleverDeal.React/src/Components/LandingPage/LandingPage.tsx Adds enabled support for tiles and “Coming Soon” rendering logic.
AppExamples/CleverDeal.React/src/Components/CleverResearch/CleverResearch.scss Scopes research modal styles under .research-modal.
AppExamples/CleverDeal.React/public/wealth-client-chat-host.html Adds standalone host page that embeds Symphony and proxies share actions.
AppExamples/CleverDeal.React/public/index.html Adds early “Script error” suppression for Symphony SDK iframe noise.
AppExamples/CleverDeal.React/postcss.config.js Adds PostCSS plugins for Tailwind + autoprefixer.
AppExamples/CleverDeal.React/package.json Adds dependencies/devDependencies for Wealth UI + Tailwind.
.vscode/settings.json Adds Snyk VS Code configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +11 to +13
const WEALTH_DEBUG_STORAGE_KEY = 'wealthDebugTheme';

function isWealthThemeDebugEnabled() {
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isWealthThemeDebugEnabled and the storage key are duplicated here and in Theme/symphonyThemeBridge.ts. Consider centralizing this debug-flag logic in a shared helper to avoid drift between implementations.

Suggested change
const WEALTH_DEBUG_STORAGE_KEY = 'wealthDebugTheme';
function isWealthThemeDebugEnabled() {
export const WEALTH_DEBUG_STORAGE_KEY = 'wealthDebugTheme';
export function isWealthThemeDebugEnabled() {

Copilot uses AI. Check for mistakes.
Comment on lines +79 to +82
const contacts = useMemo(() => wealthManagementData.contacts ?? [], []);

useEffect(() => symphonyNotifications.onStreamUnreadChange(setStreamUnreadCounts), []);
const filteredContacts = useMemo(
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onStreamUnreadChange returns an unsubscribe function, but this effect doesn't return it, so the stream unread listener will stay registered after the page unmounts (leak + duplicate updates on remount). Return the cleanup function from useEffect.

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +33
function debugDocumentShare(message: string, context?: Record<string, unknown>) {
if (context) {
console.debug(`[WealthClientShare] ${message}`, context);
return;
}

console.debug(`[WealthClientShare] ${message}`);
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debugDocumentShare logs to console.debug unconditionally. If this runs in production it will add noisy logs for every host message / share action. Consider gating this behind the existing wealth debug flag (query/localStorage) or NODE_ENV !== 'production' like other debug helpers in this PR.

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +51
export type ContactSegment = 'UHNW' | 'HNW' | 'Retail';

export const SEGMENT_STYLES: Record<string, string> = {
UHNW: 'bg-rose-600 text-white',
HNW: 'bg-violet-600 text-white',
Retail: 'bg-slate-600 text-white',
};
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SEGMENT_STYLES is typed as Record<string, string>, which loses type-safety and allows invalid segment keys at compile time. Since ContactSegment is declared just above, use Record<ContactSegment, string> (and optionally export it as such) so additions/removals are type-checked.

Copilot uses AI. Check for mistakes.
Comment on lines +6 to +9
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-menubar": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These Radix UI packages are added as dependencies but there are no imports/usages in src/ (at least in this PR). If they're not needed yet, remove them to avoid extra install/bundle surface; otherwise add the intended usage so the dependency is justified.

Suggested change
"@radix-ui/react-dialog": "^1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-menubar": "^1.1.15",
"@radix-ui/react-scroll-area": "^1.2.10",

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +3
"snyk.advanced.organization": "c9d28c43-bb57-4687-8398-f2cd3e94ab31",
"snyk.advanced.autoSelectOrganization": true
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committing workspace-specific .vscode/settings.json with a fixed Snyk organization ID makes the repo configuration developer/tooling-specific and may unintentionally expose internal identifiers. Consider removing this file from the PR and using documented setup steps (or .vscode/settings.json via local-only tooling) instead.

Suggested change
"snyk.advanced.organization": "c9d28c43-bb57-4687-8398-f2cd3e94ab31",
"snyk.advanced.autoSelectOrganization": true

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +39
window.addEventListener('error', function(e) {
if (e.message === 'Script error.' || e.message === 'Script error') {
e.stopImmediatePropagation();
e.preventDefault();
}
}, true);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This global capture listener suppresses all cross-origin "Script error" events for the entire app. That can mask real production issues from other third-party scripts and makes debugging harder. Consider scoping this suppression more narrowly (e.g., only when the Symphony embed is present, checking e.filename/e.target/known iframe, or gating behind a URL flag) rather than blanket suppression.

Suggested change
window.addEventListener('error', function(e) {
if (e.message === 'Script error.' || e.message === 'Script error') {
e.stopImmediatePropagation();
e.preventDefault();
}
}, true);
(function () {
// Only register this handler when the Symphony container is present,
// and only suppress generic cross-origin-style "Script error" events.
if (!document.getElementById('symphony-ecm')) {
return;
}
window.addEventListener(
'error',
function (e) {
// Cross-origin "Script error" typically has an empty filename.
if (
(e.message === 'Script error.' || e.message === 'Script error') &&
e.filename === ''
) {
e.stopImmediatePropagation();
e.preventDefault();
}
},
true
);
})();

Copilot uses AI. Check for mistakes.
Comment on lines +61 to +67
}: {
title: string;
headerContent?: React.ReactNode;
bodyClassName?: string;
className?: string;
children: React.ReactNode;
}) {
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file references React.ReactNode in prop types, but React is not imported (only named hooks are imported from react). This will fail TypeScript compilation. Import type ReactNode (or type React) from react and use that instead.

Copilot uses AI. Check for mistakes.
Comment on lines +89 to +97
return (
<>
<div className="fixed inset-0 z-50 bg-slate-950/50" onClick={() => setOpen(false)} />
<div
className={cn(
'fixed top-0 z-50 h-full w-[320px] border-slate-200 bg-white shadow-2xl',
side === 'left' ? 'left-0 border-r' : 'right-0 border-l',
className,
)}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SheetContent renders a modal-like surface but doesn't expose dialog semantics or keyboard handling (e.g., role="dialog", aria-modal, labelling, Escape-to-close) and doesn't manage focus when opened/closed. This will be difficult for keyboard/screen-reader users. Consider adding the appropriate ARIA attributes + focus management (or using an accessible dialog primitive).

Copilot uses AI. Check for mistakes.
Comment on lines +33 to +58
export function DropdownMenu({ children }: { children: ReactNode }) {
const [open, setOpen] = useState(false);
const ref = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!open) return;

const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
setOpen(false);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => document.removeEventListener('mousedown', handleClickOutside);
}, [open]);

const value = useMemo(() => ({ open, setOpen }), [open]);

return (
<MenuContext.Provider value={value}>
<div ref={ref} className="relative inline-flex">
{children}
</div>
</MenuContext.Provider>
);
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dropdown implementation is click-only: it doesn't apply menu ARIA roles, keyboard navigation (Arrow keys/Enter/Escape), or focus management when opening/closing. If this is meant as a shared UI primitive, consider adding those behaviors/attributes or using an accessible menu component.

Copilot uses AI. Check for mistakes.
@mistryvinay
Copy link
Copy Markdown
Collaborator Author

DO NOT MERGE.

@mistryvinay mistryvinay changed the title feat: add Wealth Management experience and Symphony chat integration feat: narrow Wealth Management app and Symphony host integration Mar 23, 2026
@mistryvinay
Copy link
Copy Markdown
Collaborator Author

Superseded by #45, which carries the same feature work on a fresh one-commit branch without the leaked workspace settings history.

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.

2 participants