
Complete church management system with bulletin management, media processing, live streaming integration, and web interface. Includes authentication, email notifications, database migrations, and comprehensive test suite.
475 lines
10 KiB
Markdown
475 lines
10 KiB
Markdown
# 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<String> {
|
|
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. |