- Update getUserProfile, getUserReports, getUserEvents, and getUserActivity to call findOrCreateUser for Clerk IDs
- This ensures users are automatically created in database when accessing their profile for the first time
- Update User type to have email as 'string | null' instead of 'string'
- Fixes 404 errors when new users try to access their profile
This resolves the issue where new users signing up without email would get 404 errors when accessing their profile page.
- Add Prisma import for JsonNull filter
- Fix async/await for calculateDistance function
- Install mysql2 for database operations
- Apply ALTER TABLE migration to make email nullable in database
- Verify all tests pass successfully
Tests confirm:
- Users can be created without email
- Notifications work for users without email
- Email sending gracefully skipped when no email present
- Database queries correctly filter by email presence
- Make email field optional in database schema
- Update user creation to handle null emails
- Enhance notification service to gracefully skip email for users without email addresses
- Add validation in email service for null/empty emails
- Create comprehensive documentation for Clerk configuration
- Add test script for email-optional functionality
- Update all user creation points (userService, eventController, reportController)
Users can now sign up with just username and password. Email notifications
are gracefully skipped for users without email addresses, while in-app
notifications continue to work for all users.
Closes: Email-optional authentication requirement
- Updated app name in all source files, documentation, and configuration
- Changed package names in package.json files
- Updated header, titles, and user-facing text
- Modified email templates and notification text
- Updated steering rules and spec documents
- Add https://litter.psbailey.uk to CORS allowed origins
- Update CORS_ORIGIN in .env to production domain
- Update FRONTEND_URL for email links
- Support both http and https for the domain
Backend needs to be restarted after pulling this change.
- Update all toggle switches to use consistent sizing (h-6 w-11)
- Add proper shadow and border styling
- Improve transition animations
- Remove touch-manipulation styles that were causing layout issues
- Add focus ring states for accessibility
- Make switches look more polished and professional
All toggles now have a clean, modern appearance.
- Change FROM_EMAIL to use verified domain psbailey.uk
- Add payload logging for debugging
- Still getting 'invalid credentials' from AhaSend API
The API v1 key may need activation time or account verification.
All notification system code is complete and ready.
- Switch from API v2 to API v1 key
- Simplify payload format for v1 API
- Update documentation with domain verification requirement
- API Key v1: pxZ2d30PIqTl6Uj7p6g3o0uez2AacMaOstKCTcj9MTIrNEBvhikgvyAARUTvXAcA
Note: Domain beachlitter.ie likely needs verification in AhaSend dashboard
- Add notifications table with migration
- Create NotificationService with area-of-interest matching
- Integrate Mailgun for email delivery
- Add notification API endpoints (get, mark as read, unread count)
- Create scheduled jobs for event reminders and cleanup
- Build NotificationBell component for frontend
- Add notification triggers for reports and events
- Implement comprehensive test script
- Update Header with notification bell
- Add email templates with HTML formatting
Requirements satisfied:
- 10.1: Users can define areas of interest (1-50km radius)
- 10.2: Notifications sent within 10 minutes
- 10.3: Notifications for new reports/events in user area
- 10.4: Configurable notification preferences (email/in-app)
Task 33 completed
- Add hotspot calculation methods to analytics service
- Implement MySQL spatial queries for clustering (5+ reports within 500m)
- Calculate severity scores based on report count and frequency
- Create GET /api/analytics/hotspots endpoint
- Create GET /api/analytics/hotspots/:id endpoint for details
- Create POST /api/analytics/hotspots/calculate for manual trigger
- Implement scheduled job with node-cron (runs every 5 minutes)
- Add comprehensive test scripts for hotspot functionality
- Create detailed implementation documentation
Requirements addressed:
- 3.2: Identify areas with 5+ reports within 500m radius
- 3.3: Rank hotspots by severity score
- 3.4: Update calculations within 5 minutes
- 3.5: Provide data for map visualization with severity indicators
- Created analytics service with summary, trends, comparison, and aggregated data methods
- Implemented 5 analytics endpoints: summary, trends, comparison, aggregated, and CSV export
- Added time series data with day/week/month interval support
- Implemented period-over-period comparison metrics with percentage changes
- Added CSV export functionality using json2csv
- Updated frontend analytics service to unwrap API responses
- Fixed chart components to work with new data structure (reportCount, eventCount, litterCollected)
- Updated TypeScript types to match backend API structure
- All endpoints tested and verified working
Requirements satisfied: 5.1, 5.2, 5.3, 5.4, 5.5
- Add GBIF API integration for marine species observations
- Implement species categorization (birds, fish, mammals, algae, etc.)
- Add Marine Protected Area detection for 7 Irish MPAs
- Determine habitat types from observations
- Add BiodiversityInfo component back to EnvironmentalDataPanel
- Free API, no key required
Note: GBIF API parameters need adjustment - currently returning 400 error
- Add static dataset of 38 Irish beaches with 2024 water quality data
- Implement nearest beach finder (within 20km radius)
- Return real water quality status (excellent/good/sufficient/poor)
- Include E.coli and Enterococci parameters
- Remove unimplemented services from EnvironmentalDataPanel (beach quality, biodiversity)
- Update panel description to reflect available data
Coverage: Dublin, Wicklow, Wexford, Waterford, Cork, Kerry, Clare, Galway, Mayo, Sligo, Donegal, Antrim, Down
- Document EU Bathing Water Quality API (free, no key needed)
- Add EPA Ireland and Marine Institute alternatives
- Provide implementation examples
- Clarify that water quality data is completely free and public
- Fix TideDisplay component crash (use extremes instead of tides)
- Handle 401 weather API errors gracefully (return null data with note)
- Update weather controller to return 200 with null values instead of 503
- Add helpful message about API key activation time
- Fix tide type capitalization (High/Low instead of high/low)
- Prepend API base URL to relative photo paths
- Use process.cwd() for upload directory in server
- Ensures photos display correctly in report detail modal
- Change UPLOAD_DIR from ../uploads to ./uploads in server/.env
- Use absolute path with process.cwd() in upload middleware
- Ensures uploads directory is created in correct location
- Add cleaned_at and cleaned_by_user_id fields to reports table
- Create database migration for cleanup tracking
- Add markAsCleaned backend endpoint and service method
- Add Mark as Cleaned Up button to ReportDetailModal
- Update types to include cleaned fields
- Add frontend handler to mark reports as cleaned
- Add verify/dispute endpoints to backend API
- Create verification service methods with auto-hide logic for 3+ disputes
- Update ReportDetailModal with verification buttons and comment forms
- Add verification audit log display showing history of verifications/disputes
- Implement auto-hide warning for disputed reports
- Update MapPage to handle verification actions and refresh data
- Add verification counts to report responses
- Filter out disputed reports from public view by default
- Add verification test script
Requirements: 7.1, 7.2, 7.3, 7.4, 7.5
- Handle both Clerk ID and database ID in authorization checks
- Compare Clerk IDs when URL parameter is a Clerk ID (user_xxx)
- Convert Clerk ID to database ID for service layer operations
- Apply fix to both updateNotificationPreferences and updateUserProfile endpoints
- Create NotificationSettings component with map-based area selector
- Add radius configuration slider (1-50km range)
- Implement notification type toggles (email, in-app)
- Add notifications tab to user profile page (visible only to profile owner)
- Update backend to parse and return areasOfInterest JSON
- Save and load user notification preferences
- Requirements: 10.1, 10.4
- Update getUserProfile to count only eventRegistrations where attended=true
- This ensures 'Events Attended' shows actual attended events, not just registrations
- Impact score calculation already had this logic and remains unchanged
Now 'Events Attended' will only increment after an event is completed and marked as attended
- Fix NaN error in impact score calculation by handling undefined reportCount/eventCount
- Fix duplicate React keys in activity timeline by using unique composite keys
- Add reportCount and eventCount to backend profile response to match frontend expectations
- Keep stats object for backward compatibility
Fixes:
- 'Received NaN for children attribute' warning
- 'Encountered two children with the same key' errors
- Update user creation logic to strip 'user_' prefix from Clerk ID before generating username
- Change default username pattern from 'user_<clerkId>' to 'user<cleanId>'
- This prevents usernames like 'user_user_35Z...' and creates 'user35Z...' instead
- Apply fix to both userService and reportController
- Add migration script to fix existing duplicate usernames
Example: user_user_35ZFZ... -> user35ZFZ...
- Update getUserProfile to accept both database ID and Clerk ID
- Update getUserReports to handle Clerk IDs
- Update getUserEvents to handle Clerk IDs
- Add getUserActivity endpoint to return timeline of user actions
- Add activity route GET /api/users/:id/activity
- Fix TypeScript errors with const assertions
This fixes 404 errors when frontend uses Clerk IDs to fetch user data
- Add GET /api/users/:id for profile retrieval with stats
- Add PATCH /api/users/:id for profile updates
- Add GET /api/users/:id/reports to fetch user's reports
- Add GET /api/users/:id/events to fetch user's events (registered & organized)
- Add PATCH /api/users/:id/preferences for notification settings
- Add POST /api/users/:id/calculate-impact for impact score calculation
- Create userService with all business logic
- Create userController with request handling
- Create userRoutes and register in main server
- Update frontend userService with new endpoints
- Add comprehensive documentation in USER_PROFILE_ENDPOINTS.md
- Add test script for manual endpoint testing
Requirements satisfied: 6.3, 6.4, 6.5, 10.4
- Add completeEvent endpoint to backend API
- Create EventCompletionForm component with litter quantity input and photo upload
- Update EventDetailModal to show completion form for organizers
- Add isOrganizer check in EventsPage
- Update event service to support completion
- Display completion data (litter collected, photos) for completed events
- Add findOrCreateUser helper function to handle Clerk ID to database ID mapping
- Update all authenticated endpoints to convert Clerk ID to database user ID
- Ensures events can be created and managed by authenticated users
- Matches pattern used in reportController
- Fix Prisma client generation and database schema sync issues
- Implement user auto-creation from Clerk authentication
- Add raw SQL queries to handle MySQL POINT spatial fields
- Make password_hash optional for Clerk-only authentication
- Update MapPage to fetch real reports from API
- Add photo display in map popups with full-size modal view
- Configure CORS and Helmet for cross-origin image loading
- Add cleanup tracking task to implementation plan
Fixes report submission 500 errors and enables end-to-end workflow from submission to map display.
- Change UPLOAD_DIR from ./uploads to ../uploads
- Update static file serving path to ../../uploads
- Files now upload to project root uploads/ folder instead of server/uploads/
- Replace deprecated verifySession() with verifyToken()
- Use JWT-based authentication (networkless verification)
- Update Clerk secret key to correct test key
- Fixes 410 Gone error from deprecated endpoint
This resolves the authentication issues with file uploads.
- Create CLERK_SETUP.md with step-by-step instructions
- Improve error message to indicate Clerk configuration issue
- Remove debug logging from auth middleware
- Update error handling to be more helpful
The 401 error is caused by missing Clerk Secret Key in server/.env