# User Profile Endpoints Documentation This document describes the user profile API endpoints implemented for the Beach Litter Mapping Platform. ## Overview The user profile endpoints provide functionality for: - Retrieving user profiles with statistics - Updating user profile information - Managing notification preferences - Fetching user's reports and events - Calculating impact scores ## Authentication Most endpoints require authentication via Clerk session token: ``` Authorization: Bearer ``` ## Endpoints ### 1. Get User Profile **Endpoint:** `GET /api/users/:id` **Description:** Retrieve a user's profile including statistics about their contributions. **Authentication:** Not required (public profiles) **Parameters:** - `id` (path) - User database ID **Response:** ```json { "id": "uuid", "clerkId": "user_xxx", "email": "user@example.com", "username": "johndoe", "firstName": "John", "lastName": "Doe", "avatarUrl": "https://...", "impactScore": 150, "notificationEmail": true, "notificationInApp": true, "areasOfInterest": [ { "lat": 53.3498, "lng": -6.2603, "radius": 10 } ], "createdAt": "2024-01-01T00:00:00.000Z", "updatedAt": "2024-01-01T00:00:00.000Z", "stats": { "reportsSubmitted": 5, "eventsAttended": 3, "eventsOrganized": 1 } } ``` **Error Responses:** - `404` - User not found - `500` - Internal server error --- ### 2. Update User Profile **Endpoint:** `PATCH /api/users/:id` **Description:** Update user profile information (first name, last name, username). **Authentication:** Required (users can only update their own profile) **Parameters:** - `id` (path) - User database ID **Request Body:** ```json { "firstName": "John", "lastName": "Doe", "username": "johndoe123" } ``` All fields are optional. Only provided fields will be updated. **Response:** ```json { "id": "uuid", "clerkId": "user_xxx", "email": "user@example.com", "username": "johndoe123", "firstName": "John", "lastName": "Doe", "avatarUrl": "https://...", "impactScore": 150, "createdAt": "2024-01-01T00:00:00.000Z", "updatedAt": "2024-01-01T00:00:00.000Z" } ``` **Error Responses:** - `400` - Username already taken - `401` - Not authenticated - `403` - Cannot update another user's profile - `404` - User not found - `500` - Internal server error --- ### 3. Get User Reports **Endpoint:** `GET /api/users/:id/reports` **Description:** Retrieve all reports submitted by a user. **Authentication:** Not required **Parameters:** - `id` (path) - User database ID **Response:** ```json [ { "id": "uuid", "userId": "uuid", "latitude": 53.3498, "longitude": -6.2603, "locationSource": "gps", "photoUrls": ["/uploads/photo1.jpg"], "photoTimestamp": "2024-01-01T12:00:00.000Z", "litterType": "plastic", "quantity": "moderate", "description": "Plastic bottles on beach", "verificationStatus": "verified", "createdAt": "2024-01-01T12:00:00.000Z", "environmentalConcerns": [], "verifications": [] } ] ``` **Error Responses:** - `500` - Internal server error --- ### 4. Get User Events **Endpoint:** `GET /api/users/:id/events` **Description:** Retrieve events the user has registered for and organized. **Authentication:** Not required **Parameters:** - `id` (path) - User database ID **Response:** ```json { "registered": [ { "id": "uuid", "title": "Beach Cleanup", "description": "Community cleanup event", "latitude": 53.3498, "longitude": -6.2603, "locationName": "Sandymount Beach", "scheduledDate": "2024-02-01T10:00:00.000Z", "duration": 120, "status": "upcoming", "participantCount": 15, "organizer": { "id": "uuid", "username": "organizer", "avatarUrl": "https://..." }, "registeredAt": "2024-01-15T10:00:00.000Z", "attended": false } ], "organized": [ { "id": "uuid", "title": "My Beach Cleanup", "description": "Event I organized", "latitude": 53.3498, "longitude": -6.2603, "locationName": "Dollymount Beach", "scheduledDate": "2024-03-01T10:00:00.000Z", "duration": 180, "status": "upcoming", "participantCount": 20, "organizer": { "id": "uuid", "username": "johndoe", "avatarUrl": "https://..." }, "registrations": [] } ] } ``` **Error Responses:** - `500` - Internal server error --- ### 5. Update Notification Preferences **Endpoint:** `PATCH /api/users/:id/preferences` **Description:** Update user's notification preferences and areas of interest. **Authentication:** Required (users can only update their own preferences) **Parameters:** - `id` (path) - User database ID **Request Body:** ```json { "notificationEmail": true, "notificationInApp": true, "areasOfInterest": [ { "lat": 53.3498, "lng": -6.2603, "radius": 10 }, { "lat": 51.8985, "lng": -8.4756, "radius": 25 } ] } ``` **Field Validation:** - `radius` must be between 1 and 50 kilometers - Each area must have `lat`, `lng`, and `radius` **Response:** ```json { "id": "uuid", "notificationEmail": true, "notificationInApp": true, "areasOfInterest": [ { "lat": 53.3498, "lng": -6.2603, "radius": 10 } ] } ``` **Error Responses:** - `400` - Validation error (invalid radius, missing fields, etc.) - `401` - Not authenticated - `403` - Cannot update another user's preferences - `404` - User not found - `500` - Internal server error --- ### 6. Calculate Impact Score **Endpoint:** `POST /api/users/:id/calculate-impact` **Description:** Calculate and update the user's impact score based on their contributions. **Authentication:** Not required **Parameters:** - `id` (path) - User database ID **Impact Score Formula:** ``` Impact Score = (reports × 10) + (events attended × 20) + (events organized × 50) ``` **Response:** ```json { "impactScore": 150 } ``` **Error Responses:** - `404` - User not found - `500` - Internal server error --- ## Usage Examples ### Get User Profile ```bash curl http://localhost:3005/api/users/abc-123 ``` ### Update Profile ```bash curl -X PATCH http://localhost:3005/api/users/abc-123 \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "firstName": "John", "lastName": "Doe", "username": "johndoe" }' ``` ### Update Notification Preferences ```bash curl -X PATCH http://localhost:3005/api/users/abc-123/preferences \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{ "notificationEmail": true, "notificationInApp": true, "areasOfInterest": [ { "lat": 53.3498, "lng": -6.2603, "radius": 10 } ] }' ``` ### Calculate Impact Score ```bash curl -X POST http://localhost:3005/api/users/abc-123/calculate-impact ``` ## Frontend Integration The frontend service (`src/services/userService.ts`) provides TypeScript methods for all endpoints: ```typescript import { userService } from '@/services/userService'; // Get profile const profile = await userService.getProfile(userId); // Update profile const updated = await userService.updateProfile(userId, { firstName: 'John', lastName: 'Doe', username: 'johndoe' }); // Get user's reports const reports = await userService.getUserReports(userId); // Get user's events const events = await userService.getUserEvents(userId); // Update notification preferences const preferences = await userService.updateNotificationPreferences(userId, { notificationEmail: true, notificationInApp: true, areasOfInterest: [ { lat: 53.3498, lng: -6.2603, radius: 10 } ] }); // Calculate impact score const { impactScore } = await userService.calculateImpactScore(userId); ``` ## Requirements Satisfied This implementation satisfies the following requirements from the specification: - **Requirement 6.3**: User profile display showing submitted reports and events attended - **Requirement 6.4**: Impact score calculation based on contributions - **Requirement 6.5**: User profile showing map of submitted report locations (data provided via reports endpoint) - **Requirement 10.4**: Notification preferences with area of interest configuration (1-50km radius) ## Notes - User authentication is handled by Clerk - Users are automatically created in the database when they first interact with the API - The `areasOfInterest` field is stored as JSON in the database - Impact scores are calculated on-demand but can be cached for performance - All endpoints follow RESTful conventions - Error responses follow a consistent format with error codes and timestamps