
Some checks are pending
iOS UniFFI Build / build-ios (push) Waiting to run
Add church management API library with cross-platform support for iOS, Android, and WASM. Features include event management, bulletin handling, contact forms, and authentication.
348 lines
9.1 KiB
Markdown
348 lines
9.1 KiB
Markdown
# Church Core
|
|
|
|
A shared Rust crate providing unified API access and data models for church applications across multiple platforms (iOS, Android, Web, Desktop).
|
|
|
|
## Overview
|
|
|
|
Church Core centralizes all church application logic, API communication, and data management into a single, well-tested Rust crate. This enables client applications to become "dumb display devices" while ensuring consistency across platforms.
|
|
|
|
## Features
|
|
|
|
- **Unified API Client**: Single interface for all church APIs
|
|
- **Consistent Data Models**: Shared types for events, bulletins, sermons, etc.
|
|
- **Cross-Platform Support**: Native bindings for iOS, Android, WASM, and FFI
|
|
- **Built-in Caching**: Automatic response caching with TTL
|
|
- **Offline Support**: Graceful offline operation with cached data
|
|
- **Authentication**: PocketBase and Jellyfin integration
|
|
- **Error Handling**: Comprehensive error types with retry logic
|
|
- **Type Safety**: Rust's type system prevents API mismatches
|
|
|
|
## Architecture
|
|
|
|
```
|
|
church-core/
|
|
├── src/
|
|
│ ├── client/ # HTTP client and API modules
|
|
│ │ ├── events.rs # Event operations
|
|
│ │ ├── bulletins.rs # Bulletin operations
|
|
│ │ ├── sermons.rs # Sermon operations
|
|
│ │ ├── contact.rs # Contact form handling
|
|
│ │ └── config.rs # Configuration management
|
|
│ ├── models/ # Data structures
|
|
│ │ ├── event.rs # Event models
|
|
│ │ ├── bulletin.rs # Bulletin models
|
|
│ │ ├── sermon.rs # Sermon models
|
|
│ │ ├── contact.rs # Contact models
|
|
│ │ └── auth.rs # Authentication models
|
|
│ ├── auth/ # Authentication modules
|
|
│ ├── cache/ # Caching system
|
|
│ ├── utils/ # Utility functions
|
|
│ └── error.rs # Error types
|
|
└── README.md
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```rust
|
|
use church_core::{ChurchApiClient, ChurchCoreConfig};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// Create client with default configuration
|
|
let config = ChurchCoreConfig::default();
|
|
let client = ChurchApiClient::new(config)?;
|
|
|
|
// Get upcoming events
|
|
let events = client.get_upcoming_events(Some(10)).await?;
|
|
for event in events {
|
|
println!("{}: {}", event.title, event.start_time);
|
|
}
|
|
|
|
// Get current bulletin
|
|
if let Some(bulletin) = client.get_current_bulletin().await? {
|
|
println!("Current bulletin: {}", bulletin.title);
|
|
}
|
|
|
|
// Submit contact form
|
|
let contact = ContactForm::new(
|
|
"John Doe".to_string(),
|
|
"john@example.com".to_string(),
|
|
"Prayer Request".to_string(),
|
|
"Please pray for my family.".to_string()
|
|
);
|
|
let submission_id = client.submit_contact_form(contact).await?;
|
|
println!("Contact form submitted: {}", submission_id);
|
|
|
|
Ok(())
|
|
}
|
|
```
|
|
|
|
### Custom Configuration
|
|
|
|
```rust
|
|
use church_core::{ChurchApiClient, ChurchCoreConfig};
|
|
use std::time::Duration;
|
|
|
|
let config = ChurchCoreConfig::new()
|
|
.with_base_url("https://api.mychurch.org/api")
|
|
.with_cache_ttl(Duration::from_secs(600))
|
|
.with_timeout(Duration::from_secs(15))
|
|
.with_retry_attempts(5)
|
|
.with_offline_mode(true);
|
|
|
|
let client = ChurchApiClient::new(config)?;
|
|
```
|
|
|
|
## Data Models
|
|
|
|
### Event
|
|
|
|
```rust
|
|
use church_core::{Event, EventCategory, NewEvent};
|
|
use chrono::{DateTime, Utc};
|
|
|
|
// Create a new event
|
|
let new_event = NewEvent {
|
|
title: "Bible Study".to_string(),
|
|
description: "Weekly Bible study group".to_string(),
|
|
start_time: Utc::now(),
|
|
end_time: Utc::now() + chrono::Duration::hours(2),
|
|
location: "Fellowship Hall".to_string(),
|
|
location_url: Some("https://maps.google.com/...".to_string()),
|
|
category: EventCategory::Education,
|
|
is_featured: true,
|
|
// ... other fields
|
|
};
|
|
|
|
let event_id = client.create_event(new_event).await?;
|
|
```
|
|
|
|
### Bulletin
|
|
|
|
```rust
|
|
use church_core::{Bulletin, NewBulletin};
|
|
use chrono::NaiveDate;
|
|
|
|
// Get current bulletin
|
|
if let Some(bulletin) = client.get_current_bulletin().await? {
|
|
println!("Sabbath School: {}", bulletin.sabbath_school);
|
|
println!("Divine Worship: {}", bulletin.divine_worship);
|
|
|
|
// Check for announcements
|
|
for announcement in bulletin.active_announcements() {
|
|
println!("📢 {}: {}", announcement.title, announcement.content);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Contact Form
|
|
|
|
```rust
|
|
use church_core::{ContactForm, ContactCategory, VisitorInfo};
|
|
|
|
let contact = ContactForm::new(
|
|
"Jane Smith".to_string(),
|
|
"jane@example.com".to_string(),
|
|
"New Visitor".to_string(),
|
|
"I'm interested in learning more about your church.".to_string()
|
|
)
|
|
.with_category(ContactCategory::Visitor)
|
|
.with_phone("555-123-4567".to_string())
|
|
.with_visitor_info(VisitorInfo {
|
|
is_first_time: true,
|
|
wants_follow_up: true,
|
|
wants_newsletter: true,
|
|
// ... other fields
|
|
});
|
|
|
|
let submission_id = client.submit_contact_form(contact).await?;
|
|
```
|
|
|
|
## Authentication
|
|
|
|
### PocketBase Authentication
|
|
|
|
```rust
|
|
use church_core::auth::{LoginRequest, AuthToken};
|
|
|
|
// Authenticate with PocketBase
|
|
let login = LoginRequest {
|
|
identity: "admin@church.org".to_string(),
|
|
password: "secure_password".to_string(),
|
|
};
|
|
|
|
// Note: Authentication methods would be implemented in auth module
|
|
// let token = client.authenticate_pocketbase(login).await?;
|
|
// client.set_auth_token(token).await;
|
|
```
|
|
|
|
## Caching
|
|
|
|
The client automatically caches responses with configurable TTL:
|
|
|
|
```rust
|
|
// Cache is automatically used
|
|
let events = client.get_upcoming_events(None).await?; // Fetches from API
|
|
let events = client.get_upcoming_events(None).await?; // Returns from cache
|
|
|
|
// Manual cache management
|
|
client.clear_cache().await;
|
|
let (cache_size, max_size) = client.get_cache_stats().await;
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```rust
|
|
use church_core::{ChurchApiError, Result};
|
|
|
|
match client.get_event("invalid-id").await {
|
|
Ok(Some(event)) => println!("Found event: {}", event.title),
|
|
Ok(None) => println!("Event not found"),
|
|
Err(ChurchApiError::NotFound) => println!("Event does not exist"),
|
|
Err(ChurchApiError::Network(_)) => println!("Network error - check connection"),
|
|
Err(ChurchApiError::Auth(_)) => println!("Authentication required"),
|
|
Err(e) => println!("Other error: {}", e),
|
|
}
|
|
```
|
|
|
|
## Platform Integration
|
|
|
|
### iOS (Swift)
|
|
|
|
```swift
|
|
// FFI bindings would be generated for iOS
|
|
import ChurchCore
|
|
|
|
let client = ChurchApiClient()
|
|
client.getUpcomingEvents(limit: 10) { events in
|
|
// Handle events
|
|
}
|
|
```
|
|
|
|
### Android (Kotlin/Java)
|
|
|
|
```kotlin
|
|
// JNI bindings for Android
|
|
import org.church.ChurchCore
|
|
|
|
val client = ChurchCore()
|
|
val events = client.getUpcomingEvents(10)
|
|
```
|
|
|
|
### Web (WASM)
|
|
|
|
```javascript
|
|
// WASM bindings for web
|
|
import { ChurchApiClient } from 'church-core-wasm';
|
|
|
|
const client = new ChurchApiClient();
|
|
const events = await client.getUpcomingEvents(10);
|
|
```
|
|
|
|
## Testing
|
|
|
|
Run the test binary to verify API connectivity:
|
|
|
|
```bash
|
|
cargo run --bin church-core-test
|
|
```
|
|
|
|
This will test:
|
|
- Health check endpoint
|
|
- Upcoming events retrieval
|
|
- Current bulletin fetching
|
|
- Configuration loading
|
|
- Cache statistics
|
|
|
|
## API Endpoints
|
|
|
|
The client interfaces with these standard endpoints:
|
|
|
|
- `GET /events/upcoming` - Get upcoming events
|
|
- `GET /events/{id}` - Get single event
|
|
- `POST /events` - Create event
|
|
- `GET /bulletins/current` - Get current bulletin
|
|
- `GET /bulletins` - List bulletins
|
|
- `GET /config` - Get church configuration
|
|
- `POST /contact` - Submit contact form
|
|
- `GET /sermons` - List sermons
|
|
- `GET /sermons/search` - Search sermons
|
|
|
|
## Development
|
|
|
|
### Building for iOS (No Python Required!)
|
|
|
|
```bash
|
|
# Quick build using Makefile
|
|
make ios
|
|
|
|
# Or use the build script directly
|
|
./build_ios.sh
|
|
|
|
# Install dependencies first time
|
|
make install-deps
|
|
|
|
# Development build (faster)
|
|
make dev
|
|
|
|
# Clean build artifacts
|
|
make clean
|
|
```
|
|
|
|
### Building Steps Explained
|
|
|
|
1. **Install iOS targets**: Adds Rust toolchains for iOS devices and simulators
|
|
2. **Build static libraries**: Creates `.a` files for each iOS architecture
|
|
3. **Create universal library**: Combines all architectures using `lipo`
|
|
4. **Generate Swift bindings**: Uses `uniffi-bindgen` to create Swift interfaces
|
|
5. **Copy to iOS project**: Moves all files to your Xcode project
|
|
|
|
Generated files:
|
|
- `church_core.swift` - Swift interface to your Rust code
|
|
- `church_coreFFI.h` - C header file
|
|
- `church_coreFFI.modulemap` - Module map for Swift
|
|
- `libchurch_core.a` - Universal static library
|
|
|
|
### Standard Rust Building
|
|
|
|
```bash
|
|
# Standard build
|
|
cargo build
|
|
|
|
# Build with WASM support
|
|
cargo build --features wasm
|
|
|
|
# Build with UniFFI support
|
|
cargo build --features uniffi
|
|
|
|
# Run tests
|
|
cargo test --features uniffi
|
|
```
|
|
|
|
### Features
|
|
|
|
- `default`: Native Rust client
|
|
- `wasm`: WebAssembly bindings
|
|
- `uniffi`: UniFFI bindings for iOS/Android (replaces old `ffi` feature)
|
|
- `native`: Native platform features
|
|
|
|
## License
|
|
|
|
MIT License - see LICENSE file for details.
|
|
|
|
## Contributing
|
|
|
|
1. Fork the repository
|
|
2. Create a feature branch
|
|
3. Add tests for new functionality
|
|
4. Ensure all tests pass
|
|
5. Submit a pull request
|
|
|
|
## Support
|
|
|
|
For issues and questions:
|
|
- Check the API documentation
|
|
- Review existing GitHub issues
|
|
- Create a new issue with detailed information |