# Frontend Migration Guide ## Backend API Overview The backend provides two API versions with smart timezone handling and proper URL generation: ### API Versions - **V1 API** (`/api/*`): Legacy compatibility, returns EST timezone, existing URL formats - **V2 API** (`/api/v2/*`): Modern API, returns UTC timestamps, client handles timezone conversion ## Authentication ### Login ```http POST /api/auth/login Content-Type: application/json { "username": "admin", "password": "password" } ``` **Response:** ```json { "success": true, "data": { "token": "jwt_token_here", "user": { "id": "uuid", "username": "admin" } } } ``` ### Protected Routes - Add header: `Authorization: Bearer {token}` - Admin routes are under `/api/admin/*` --- ## Bulletins API ### List Bulletins ```http GET /api/bulletins?page=1&per_page=20&active_only=true GET /api/v2/bulletins?page=1&per_page=20 ``` ### Get Current Bulletin (≤ today's date) ```http GET /api/bulletins/current GET /api/v2/bulletins/current ``` ### Get Next Bulletin (> today's date) - NEW! ```http GET /api/bulletins/next GET /api/v2/bulletins/next ``` ### Get Bulletin by ID ```http GET /api/bulletins/{id} GET /api/v2/bulletins/{id} ``` ### Create Bulletin (Admin) ```http POST /api/admin/bulletins Authorization: Bearer {token} Content-Type: application/json { "title": "Weekly Bulletin", "date": "2025-08-02", "url": "https://example.com", "cover_image": null, "sabbath_school": "Elder Smith", "divine_worship": "Pastor Johnson", "scripture_reading": "John 3:16", "sunset": "7:45 PM", "is_active": true } ``` ### Update Bulletin (Admin) ```http PUT /api/admin/bulletins/{id} Authorization: Bearer {token} Content-Type: application/json {...same fields as create...} ``` ### Delete Bulletin (Admin) ```http DELETE /api/admin/bulletins/{id} Authorization: Bearer {token} ``` --- ## Events API ### List Events ```http GET /api/events?page=1&per_page=20 GET /api/v2/events?page=1&per_page=20 ``` ### Get Upcoming Events ```http GET /api/events/upcoming?limit=10 GET /api/v2/events/upcoming?limit=10 ``` ### Get Featured Events ```http GET /api/events/featured?limit=5 GET /api/v2/events/featured?limit=5 ``` ### Get Event by ID ```http GET /api/events/{id} GET /api/v2/events/{id} ``` ### Submit Event (Public) ```http POST /api/events/submit Content-Type: application/json { "title": "Prayer Meeting", "description": "Weekly prayer meeting", "start_time": "2025-08-02T19:00:00", "end_time": "2025-08-02T20:00:00", "location": "Fellowship Hall", "location_url": "https://maps.google.com/...", "category": "worship", "is_featured": false, "recurring_type": "weekly", "bulletin_week": "2025-08-02", "submitter_email": "user@example.com" } ``` ### Admin Event Management ```http POST /api/admin/events # Create event PUT /api/admin/events/{id} # Update event DELETE /api/admin/events/{id} # Delete event GET /api/admin/events/pending # List pending submissions POST /api/admin/events/pending/{id}/approve # Approve pending POST /api/admin/events/pending/{id}/reject # Reject pending DELETE /api/admin/events/pending/{id} # Delete pending ``` ### Admin User Management ```http GET /api/admin/users # List all users ``` --- ## File Uploads (Admin) ### Upload Bulletin PDF ```http POST /api/upload/bulletins/{id}/pdf Authorization: Bearer {token} Content-Type: multipart/form-data file: bulletin.pdf ``` ### Upload Bulletin Cover Image ```http POST /api/upload/bulletins/{id}/cover Authorization: Bearer {token} Content-Type: multipart/form-data file: cover.jpg ``` ### Upload Event Image ```http POST /api/upload/events/{id}/image Authorization: Bearer {token} Content-Type: multipart/form-data file: event.jpg ``` **Upload Response:** ```json { "success": true, "file_path": "uploads/bulletins/uuid.pdf", "pdf_path": "https://api.rockvilletollandsda.church/uploads/bulletins/uuid.pdf", "message": "File uploaded successfully" } ``` **Note:** Files are served at `/uploads/*` path (handled by Caddy, not API) --- ## Scripture Processing The API now automatically processes scripture references in bulletin fields: ### Automatic Scripture Lookup - **Input:** Short reference like `"John 3:16 KJV"` - **Output:** Enhanced with full verse text: `"For God so loved the world... - John 3:16 KJV"` - **Fallback:** If no match found, returns original text unchanged - **Smart Detection:** Already long texts (>50 chars) are left unchanged ### How It Works 1. When creating/updating bulletins, `scripture_reading` field is processed 2. Uses existing Bible verse database with fuzzy search 3. Matches on both reference and partial text content 4. Returns best match from database ### Example API Response ```json { "success": true, "data": { "id": "...", "title": "Weekly Bulletin", "scripture_reading": "For God so loved the world, that he gave his only begotten Son, that whosoever believeth in him should not perish, but have everlasting life. - John 3:16 KJV", ... } } ``` --- ## Other APIs ### Bible Verses ```http GET /api/bible_verses/random GET /api/bible_verses?page=1&per_page=20 GET /api/bible_verses/search?q=love&limit=10 GET /api/v2/bible_verses/random GET /api/v2/bible_verses?page=1&per_page=20 GET /api/v2/bible_verses/search?q=love&limit=10 ``` ### Contact Form ```http POST /api/contact POST /api/v2/contact Content-Type: application/json { "name": "John Doe", "email": "john@example.com", "subject": "Question", "message": "Hello..." } ``` ### Schedule ```http GET /api/schedule?date=2025-08-02 GET /api/conference-data GET /api/v2/schedule?date=2025-08-02 GET /api/v2/conference-data ``` ### Admin Schedule Management ```http POST /api/admin/schedule # Create schedule PUT /api/admin/schedule/{date} # Update schedule by date DELETE /api/admin/schedule/{date} # Delete schedule by date GET /api/admin/schedule # List all schedules ``` ### Sermons & Livestreams ```http GET /api/sermons GET /api/livestreams ``` ### Configuration ```http GET /api/config # Public config GET /api/admin/config # Admin config (protected) ``` ### Legacy Android App Support ```http GET /api/collections/rtsda_android/records # Legacy Android app update check ``` ### Debug Endpoints ```http GET /api/debug/jellyfin # Debug Jellyfin connectivity (development only) ``` --- ## Response Format All responses follow this format: ```json { "success": true, "data": {...}, "message": "Optional message" } ``` **Paginated responses:** ```json { "success": true, "data": { "items": [...], "total": 150, "page": 1, "per_page": 20, "total_pages": 8 } } ``` **Error responses:** ```json { "success": false, "message": "Error description" } ``` --- ## Timezone Handling ### V1 API (Legacy) - **Input:** Accepts times in any format - **Output:** Converts all timestamps to EST timezone - **Use case:** Existing clients that expect EST times ### V2 API (Modern) - **Input:** Expects UTC timestamps with timezone info when needed - **Output:** Returns UTC timestamps - **Client responsibility:** Convert to local timezone for display **V2 Timezone Example:** ```json { "start_time": "2025-08-02T23:00:00Z", "timezone_info": { "utc": "2025-08-02T23:00:00Z", "local_display": "2025-08-02T19:00:00-04:00" } } ``` --- ## Frontend Migration Strategy ### Phase 1: Update Shared Rust Crate 1. **Add V2 API models** with UTC timestamp handling 2. **Keep V1 models** for backward compatibility 3. **Add timezone conversion utilities** 4. **Update HTTP client** to handle both API versions ### Phase 2: Client-by-Client Migration 1. **Web Admin Panel:** Migrate to V2 API first 2. **Mobile App:** Update to use new bulletin endpoints (`/next`) 3. **Website:** Gradually migrate public endpoints 4. **Keep V1 for old clients** until all are updated ### Phase 3: New Features 1. **Use V2 API only** for new features 2. **Proper UTC handling** from day one 3. **Client-side timezone conversion** --- ## Breaking Changes to Watch For ### URL Structure - **Old:** Some inconsistent URL patterns - **New:** Consistent `/api/v2/*` structure - **Files:** Always served at `/uploads/*` (via Caddy) ### Timestamp Format - **V1:** Mixed timezone handling, EST output - **V2:** Consistent UTC timestamps - **Migration:** Update date parsing/formatting code ### Response Fields - **V2 may have additional fields** for timezone info - **V1 fields remain unchanged** for compatibility - **New endpoints** (like `/next`) available in both versions ### Authentication - **Same JWT tokens** work for both API versions - **Admin routes** use same authorization header - **No changes needed** to auth flow --- ## Implementation Notes ### Error Handling ```rust // Example error handling in shared crate match api_client.get_current_bulletin().await { Ok(response) if response.success => { // Handle response.data }, Ok(response) => { // Handle API error: response.message }, Err(e) => { // Handle network/parsing error } } ``` ### Timezone Conversion (V2) ```rust // Example timezone handling fn convert_utc_to_local(utc_time: &str, timezone: &str) -> Result { let utc = DateTime::parse_from_rfc3339(utc_time)?; let local_tz: Tz = timezone.parse()?; Ok(utc.with_timezone(&local_tz).to_string()) } ``` ### File Upload ```rust // Example multipart upload let form = multipart::Form::new() .file("file", path_to_file)?; let response = client .post(&format!("{}/api/upload/bulletins/{}/pdf", base_url, bulletin_id)) .bearer_auth(&token) .multipart(form) .send() .await?; ``` --- ## Testing Endpoints ### Development - **API Base:** `http://localhost:3002` - **Files:** `http://localhost:3002/uploads/*` ### Production - **API Base:** `https://api.rockvilletollandsda.church` - **Files:** `https://api.rockvilletollandsda.church/uploads/*` ### Health Check ```http GET /api/config ``` Should return basic configuration without authentication.