- Backend: /generate-discussion-guide now returns task_id immediately (202)
and runs generation as a background asyncio task, delivering the guide
via WebSocket task_completed event (bypasses GCP LB 30s timeout)
- Frontend: useDiscussionGuideGeneration awaits ws:task_completed event
to resolve the guide Promise instead of waiting on the HTTP response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extract business logic and UI into reusable pieces:
Custom Hooks:
- useFocusGroupAutoSave: debounced auto-save with retry logic
- useFolderManagement: folder CRUD operations
- usePersonaFiltering: filter state and persona filtering
- useDiscussionGuideGeneration: guide generation and progress
UI Components:
- SaveStatusIndicator: auto-save status display
- FolderSidebar: folder list and management
- PersonaFilterDialog: persona filter modal
- CopyGuideDialog: copy guide from other focus groups
Tab Components:
- SetupTab: form and asset uploader
- ReviewTab: discussion guide viewer
- ParticipantsTab: persona selection grid
Reduces FocusGroupModerator from 2,396 to ~600 lines (75% reduction).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>