Open
Conversation
Task 1: Centralize state with Redux Toolkit (4 slices, typed hooks, selectors) Task 2: Centralized HTTP client with interceptors (httpClient singleton) Task 3: Extract 18 reusable components from monolithic files Task 4: Wrap all components with React.memo + displayName, useCallback throughout Task 5: Extract business logic into 7 custom hooks (useChatOrchestrator, etc.) - App.tsx reduced from ~787 to ~85 lines - Zero raw fetch calls (except /.auth/me) - All console.log downgraded to console.debug - Build: 0 TypeScript errors
New utility modules in utils/: - messageUtils.ts: createMessage() factory, formatContentForClipboard() - contentParsing.ts: parseTextContent(), resolveImageUrl(), buildGeneratedContent() - sseParser.ts: parseSSEStream() — eliminates duplicated SSE decode loop - generationStages.ts: getGenerationStage() — pure progress-stage mapper - briefFields.ts: BRIEF_FIELD_LABELS, BRIEF_DISPLAY_ORDER, BRIEF_FIELD_KEYS - stringUtils.ts: escapeRegex(), createNameSwapper(), matchesAnyKeyword() - apiUtils.ts: retryRequest (exponential backoff), RequestCache, throttle - index.ts: barrel export for all utils Deduplicated code: - msg() helper was identical in 2 hooks → createMessage() in messageUtils - SSE stream parser was identical in 2 API functions → parseSSEStream() - GeneratedContent parsing was near-identical in 3 hooks → buildGeneratedContent() - Brief field constants duplicated in 2 components → shared briefFields - Keyword matching pattern repeated 3x → matchesAnyKeyword() Internal helpers marked non-exported: - rewriteBlobUrl() in contentParsing.ts - defaultShouldRetry(), sleep() in apiUtils.ts - plainDownload() in downloadImage.ts (already was) Build: 0 TypeScript errors
…hten utility exports
…ts and memoization
…lidation, hooks barrel
…ontent, resolveImageUrl)
- Route fetch('/.auth/me') through platformClient (HttpClient with empty baseUrl)
- Un-export parseTextContent/resolveImageUrl (module-internal only)
- DRY userId || 'anonymous' x6 into normalizeUserId() helper
- Remove redundant duplicate prompt field from WelcomeCard suggestions
Contributor
There was a problem hiding this comment.
Pull request overview
This pull request refactors the frontend to introduce Redux-based state management and extracts duplicated UI / utility logic into reusable modules, alongside dependency updates to support Redux Toolkit and React-Redux.
Changes:
- Add Redux Toolkit store, slices, selectors, and typed hooks; wire the store into
main.tsx. - Extract duplicated utilities/hooks/components (SSE parsing, message factory, brief field metadata, image download, compliance UI, etc.) into shared modules.
- Update frontend dependencies (
@reduxjs/toolkit,react-redux) and regeneratepackage-lock.json.
Reviewed changes
Copilot reviewed 72 out of 75 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/app/frontend/package.json | Adds Redux dependencies needed for new store architecture. |
| src/app/frontend/package-lock.json | Locks Redux ecosystem dependencies and peer metadata updates. |
| src/app/frontend/src/store/* | Introduces Redux store setup, slices, selectors, and typed hooks. |
| src/app/frontend/src/main.tsx | Wraps the app in react-redux Provider. |
| src/app/frontend/src/api/httpClient.ts | Adds a centralized HTTP client with interceptors/timeouts. |
| src/app/frontend/src/api/index.ts | Refactors API surface to multiple endpoints + SSE helpers. |
| src/app/frontend/src/hooks/* | New hooks for orchestration, generation, clipboard, resize, scroll. |
| src/app/frontend/src/utils/* | New shared utilities for parsing, errors, stages, SSE, etc. |
| src/app/frontend/src/components/* | Refactors UI into smaller memoized components and shared sections. |
| src/app/frontend/src/types/index.ts | Removes unused interfaces (Conversation, BrandGuidelines). |
| content-gen/src/app/frontend/src/** | Duplicates of the same frontend changes under content-gen/. |
Files not reviewed (1)
- src/app/frontend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
- httpClient: replace require() with ESM dynamic import() for store access - useConversationActions: pass explicit undefined to resetChat() - parseBrief: route to /chat endpoint (no /brief/parse backend route) - streamChat: use httpClient.post + yield instead of SSE (backend returns JSON) - selectProducts: route to /chat endpoint (no /products/select backend route) - streamRegenerateImage: use /chat + polling instead of non-existent /regenerate SSE - remove unused readSSEResponse helper and parseSSEStream import
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request updates the frontend dependencies for the project, primarily to introduce Redux state management capabilities. The most important changes are the addition of Redux-related libraries and their dependencies, as well as updates to package metadata to improve compatibility and peer dependency handling.
Redux integration
@reduxjs/toolkitandreact-reduxto the main dependencies inpackage.jsonandpackage-lock.json, enabling Redux-based state management in the frontend. [1] [2]redux,redux-thunk, andreselect, as well asimmerfor immutable state updates. [1] [2] [3] [4]Type and utility dependencies
@types/use-sync-external-storeand@standard-schema/spec/@standard-schema/utilsas dependencies required by the Redux ecosystem. [1] [2]Peer dependency and metadata updates
"peer": trueflags to multiple dependencies inpackage-lock.json, improving compatibility and signaling proper peer dependency relationships for packages like React, React DOM, and others. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16]These changes collectively prepare the frontend for Redux-based state management and improve dependency handling for future development.## Purpose
Does this introduce a breaking change?
Golden Path Validation
Deployment Validation
What to Check
Verify that the following are valid
Other Information