Bug: EventChatPage referenced formatHeat() function in header's heat display
(line 365) but the function was removed during Phase 3 refactoring when
creating the HeatBadges component.
Solution:
1. Enhanced HeatBadges component with badgeClassName prop to support
custom styling (needed for dark header background)
2. Replaced manual heat rendering in EventChatPage header with
HeatBadges component
3. Passed custom badge styling to match the dark primary-700 header
Changes:
- HeatBadges.jsx: Added badgeClassName prop for style customization
- EventChatPage.jsx: Replaced manual heat map with HeatBadges component
Fixes: "Uncaught ReferenceError: formatHeat is not defined" error
Separate concerns - move Socket.IO and form logic from components to reusable hooks
New Hooks:
- useForm: Generic form state management with handleChange/handleSubmit/reset
- useEventChat: Extract Socket.IO logic from EventChatPage (156 lines)
* Manages messages, active users, connection state
* Handles send message, load older messages with scroll preservation
* Real-time updates via Socket.IO event listeners
- useMatchChat: Extract Socket.IO logic from MatchChatPage (115 lines)
* Manages 1:1 chat messages and connection
* Loads message history from API
* Real-time message sync via Socket.IO
Pages Refactored:
- EventChatPage: 661 → 564 lines (-97 lines, -15%)
- MatchChatPage: 517 → 446 lines (-71 lines, -14%)
Benefits:
- Cleaner component code - UI separated from business logic
- Reusable hooks can be used in other components
- Easier to test - hooks can be unit tested independently
- Better code organization - single responsibility principle
- 168 lines eliminated from pages, moved to 271 lines of reusable hooks
Phase 2 Total: -168 lines
Grand Total (Phase 1+2): -389 lines (-12%)
- Add Alert component with 4 variants (success/error/warning/info)
- Add LoadingSpinner and LoadingButton components
- Add FormInput and FormSelect components with icon support
- Add Modal and ConfirmationModal components
- Add ChatMessage, ChatMessageList, and ChatInput components
- Add EventCard component
These components will eliminate ~450 lines of duplicated code across pages.
Part of Phase 1 (Quick Wins) frontend refactoring.
CONTEXT.md updates:
- Changed 'Planned' to 'Implemented' for backend, db, and WebRTC
- Updated Docker Compose components - all services now implemented
- Updated database models section with actual schema
- Updated tech stack - removed 'Planned' labels
- Added test coverage stats (223/223 tests passing)
- Updated Last Updated date to 2025-11-20
- Added MVP complete status
ARCHITECTURE.md updates:
- Updated architecture diagram - marked backend and db as ✅ IMPL
- Changed 'Planned Services' to 'Implemented Services'
- Added production Dockerfile info
- Added test coverage (223/223 passing, 71%)
- Added Prisma ORM details
- Updated Last Updated date to 2025-11-20
- Added production-ready status
Both files now accurately reflect the completed MVP state.
- All 223/223 backend tests now passing (100%)
- Code coverage improved to 71% (from ~43%)
- Updated progress to ~95% (from ~90%)
- Removed 'improved test coverage' from What's Missing
- Added test isolation achievement to Phase 3 status
- Replace deleteMany({}) with selective deletion by username/email/slug in:
- events.test.js (target specific test users/events only)
- matches.test.js (target specific test users/events only)
- csrf.test.js (target csrftest user only)
- Replace delete() with deleteMany() for resilient cleanup:
- matches.test.js (2 inline cleanups)
- socket-webrtc.test.js (1 inline cleanup)
- Update TODO.md with test status and future UX/UI improvements
Test improvement: 189/223 passing (84.8%), up from 145/223 (65%)
- Replace delete() with deleteMany() in all afterAll hooks (more resilient)
- Add checks for testUser existence before creating EventParticipant
- Add .catch() handlers to ignore duplicate or foreign key errors
- Add conditional checks with ?. before cleanup operations
Changes improve test isolation and prevent foreign key constraint
violations when tests run together. All socket tests now pass
individually (12/12 socket.test.js, 7/7 socket-webrtc.test.js).
- Fixed CORS test in app.test.js to use allowed origin
- Updated auth-phase1.5.test.js to match actual error messages
- Fixed socket.test.js to use slug parameter instead of eventId
- Added EventParticipant records for socket event room tests
- Updated security config to allow both frontend origins in dev
All socket tests now passing (12/12). Test changes ensure proper
cleanup and prevent database conflicts by using selective deletion
instead of wiping entire tables.
Replace deleteMany({}) with selective cleanup targeting only test data:
- events.test.js: Delete only test users (john_dancer, sarah_swings, mike_blues)
and test events (test-dance-festival-2025) before creating new ones
- matches.test.js: Clean up john_dancer, sarah_swings, mike_moves and
test-dance-festival slug specifically
- users.test.js: Remove only john_dancer and sarah_swings test users
in both beforeAll and afterAll hooks
- auth.test.js: Target specific test usernames/emails (testuser, newuser,
lockouttest, etc.) instead of all users
- auth-phase1.5.test.js: Clean up 12 specific test users by username/email
- socket.test.js: Add beforeAll cleanup for sockettest user to prevent
conflicts from previous test runs
- socket-webrtc.test.js: Clean up webrtc_user1 and webrtc_user2 before
creating them
Fix CORS configuration for tests:
- security.js: Add http://localhost:3000 to allowed origins in development
mode to fix app.test.js CORS test (was failing with 500 error)
Results: Improved from 125/223 passing to 137/223 passing (12 more tests fixed)
All test data cleanup now uses WHERE clauses with specific usernames/emails/slugs
instead of wiping entire tables with deleteMany({})
- Update auth.test.js to match current API error messages
- Registration success message includes email verification notice
- Duplicate credentials use generic message to prevent user enumeration
- Add test commands to Makefile
- make test: run all backend tests
- make test-watch: run tests in watch mode
- make test-coverage: run tests with coverage report
All auth tests now pass (19/19 ✓)
- Add reusable Avatar with fallback, status dot, ring
- Replace <img> uses in Navbar, Profile, PublicProfile
- Use Avatar in MatchChatPage and EventChatPage messages and sidebars
- Fix own-message detection for snake_case payloads
- Add openrelay.metered.ca TURN servers for testing
- Support connections through symmetric NAT (mobile networks)
- Add TCP transport fallback for strict firewalls
- Enables P2P file transfer across different networks
- Create nginx.conf with try_files directive for React Router
- Update Dockerfile.prod to copy nginx configuration
- Fixes 404 errors on direct navigation to /login, /register, etc.
- Add gzip compression and static asset caching
- Change API_URL from hardcoded 'http://localhost:8080/api' to '/api'
- Change SOCKET_URL from hardcoded to window.location.origin
- Fixes production build connecting to wrong port
- Now works correctly in both dev (localhost:8080) and prod (localhost)
- Rename .env.example to .env.development.example
- Update docker-compose.yml to use env_file for dev backend
- Update .gitignore to ignore .env.development and .env.production
- Remove generic .env and .env.example in favor of:
* .env.development (dev) + .env.development.example (template)
* .env.production (prod) + .env.production.example (template)
- Add production Dockerfiles for frontend and backend
* Frontend: multi-stage build with nginx serving static files
* Backend: multi-stage build with Prisma generation
- Create production nginx configuration (nginx/conf.d.prod/)
* Routes to frontend-prod:80 and backend-prod:3000
* Supports WebSocket connections for Socket.IO
- Update docker-compose.yml to use production config
* Add env_file support for backend-prod
* Mount production nginx config directory
- Add .env.production.example template for deployment
Update README.md:
- Add landing page to features
- Update test coverage section (43% backend, 116 tests passing)
- Add WebRTC tests information (7 tests passing)
- Update project structure (HomePage, hooks, utils, tests)
- Add STUN servers to WebRTC features
- Remove STUN/TURN and server upload fallback from Next Up
- Update roadmap to Phase 3 in progress
- Update test flow with landing page
- Update progress to ~80%
Update SESSION_CONTEXT.md:
- Current phase: Phase 3 (MVP Finalization) in progress
- Add landing page and WebRTC tests to What Works Now
- Update What's Missing (remove STUN, add coverage improvement)
- Add HomePage to routes and key files
- Add useWebRTC, webrtcDetection, test files to key files
- Update socket.js description with WebRTC signaling
- Update final status with all completed phases
- Update progress and date
Create new HomePage component with:
- Hero section with CTAs for registration and login
- Features showcase highlighting WebRTC, matching, chat, security
- How it works section with 3-step process
- CTA section and footer with links
- Responsive design with gradient backgrounds
Update routing to show HomePage at / instead of redirecting to /events
Changed WebRTC config from localhost-only to STUN servers:
- Removed rtcConfigLocalhost (no longer needed)
- Using rtcConfig with Google STUN servers
- Enables NAT traversal for users on different networks
- Removed unnecessary iceCandidatePoolSize config
- Link sharing remains as fallback for blocked users
Updated documentation to reflect Phase 2.5 completion:
- Moved WebRTC from 'Next Up' to 'Implemented' features
- Added WebRTC to tech stack
- Updated test flow with real WebRTC details
- Marked Phase 2.5 as COMPLETED in roadmap
- Updated progress to ~78% overall
- Updated SESSION_CONTEXT.md current status and missing features
Implemented complete WebRTC peer-to-peer file transfer system for match chat:
**Core WebRTC Implementation:**
- Created useWebRTC hook with RTCPeerConnection and RTCDataChannel
- P2P file transfer with 16KB chunking for large files (tested up to 700MB)
- Real-time progress monitoring for sender and receiver
- Automatic file download on receiver side
- End-to-end encryption via DTLS (native WebRTC)
- ICE candidate exchange via Socket.IO signaling
- Support for host candidates (localhost testing)
**WebRTC Detection & User Experience:**
- Automatic WebRTC capability detection on page load
- Detects if ICE candidates can be generated (fails in Opera, privacy-focused browsers, VPNs)
- User-friendly warning component with fix suggestions
- Graceful degradation: disables WebRTC button when blocked
- Suggests alternative methods (video links via Google Drive/Dropbox)
**Socket.IO Improvements:**
- Fixed multiple socket instance creation issue
- Implemented socket instance reuse pattern
- Disabled React.StrictMode to prevent reconnection loops in development
**Technical Details:**
- RTCPeerConnection with configurable STUN servers (currently using localhost config)
- RTCDataChannel with ordered delivery
- Comprehensive logging for debugging (ICE gathering, connection states, signaling)
- Match room-based signaling relay via Socket.IO
- Authorization checks for all WebRTC signaling events
**Files Changed:**
- frontend/src/hooks/useWebRTC.js - Complete WebRTC implementation
- frontend/src/utils/webrtcDetection.js - WebRTC capability detection
- frontend/src/components/WebRTCWarning.jsx - User warning component
- frontend/src/pages/MatchChatPage.jsx - WebRTC integration
- frontend/src/services/socket.js - Socket instance reuse
- frontend/src/main.jsx - Disabled StrictMode for Socket.IO stability
**Testing:**
- ✅ Verified working in Chrome (ICE candidates generated)
- ✅ Tested with 700MB file transfer
- ✅ Detection working in Opera (shows warning when WebRTC blocked)
- ✅ P2P connection establishment and DataChannel opening
- ✅ File chunking and progress monitoring
**TODO:**
- Add STUN server configuration for production (NAT traversal)
- Consider server-based upload fallback for blocked users
Add complete WebRTC peer-to-peer file transfer functionality:
Backend changes:
- Add WebRTC signaling events to Socket.IO (offer, answer, ICE candidates)
- Implement authorization checks for match participants
- Add signaling relay between matched users
Frontend changes:
- Create useWebRTC hook for RTCPeerConnection management
- Implement RTCDataChannel with 16KB chunking for large files
- Add real-time progress monitoring for sender and receiver
- Implement automatic file download on receiver side
- Add connection state tracking and error handling
- Integrate WebRTC with MatchChatPage (replace mockup)
Configuration:
- Add Vite allowed hosts configuration via VITE_ALLOWED_HOSTS env var
- Support comma-separated host list or 'all' for development
- Add .env.example with configuration examples
- Update docker-compose.yml with default allowed hosts
Documentation:
- Add comprehensive WebRTC testing guide with troubleshooting
- Add quick test checklist for manual testing
- Document WebRTC flow, requirements, and success criteria
Features:
- End-to-end encrypted P2P transfer (DTLS)
- 16KB chunk size optimized for DataChannel
- Buffer management to prevent overflow
- Automatic connection establishment with 30s timeout
- Support for files of any size
- Real-time progress tracking
- Clean connection lifecycle management