Refactor schedule and user repositories into modular structure
- Moved schedule repository logic into separate modules for SQLite and PostgreSQL implementations. - Created a mapping module for shared data structures and mapping functions in the schedule repository. - Added new mapping module for user repository to handle user data transformations. - Implemented PostgreSQL and SQLite user repository adapters with necessary CRUD operations. - Added tests for user repository functionality, including saving, finding, and deleting users.
This commit is contained in:
55
k-tv-backend/api/src/routes/channels/mod.rs
Normal file
55
k-tv-backend/api/src/routes/channels/mod.rs
Normal file
@@ -0,0 +1,55 @@
|
||||
//! Channel routes
|
||||
//!
|
||||
//! CRUD + schedule generation require authentication (Bearer JWT).
|
||||
//! Viewing endpoints (list, now, epg, stream) are intentionally public so the
|
||||
//! TV page works without login.
|
||||
|
||||
use axum::{Router, routing::{get, post}};
|
||||
use chrono::{DateTime, Utc};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error::ApiError, state::AppState};
|
||||
|
||||
mod broadcast;
|
||||
mod crud;
|
||||
mod schedule;
|
||||
|
||||
pub fn router() -> Router<AppState> {
|
||||
Router::new()
|
||||
.route("/", get(crud::list_channels).post(crud::create_channel))
|
||||
.route(
|
||||
"/{id}",
|
||||
get(crud::get_channel).put(crud::update_channel).delete(crud::delete_channel),
|
||||
)
|
||||
.route(
|
||||
"/{id}/schedule",
|
||||
post(schedule::generate_schedule).get(schedule::get_active_schedule),
|
||||
)
|
||||
.route("/{id}/now", get(broadcast::get_current_broadcast))
|
||||
.route("/{id}/epg", get(broadcast::get_epg))
|
||||
.route("/{id}/stream", get(broadcast::get_stream))
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Shared helpers
|
||||
// ============================================================================
|
||||
|
||||
pub(super) fn require_owner(channel: &domain::Channel, user_id: Uuid) -> Result<(), ApiError> {
|
||||
if channel.owner_id != user_id {
|
||||
Err(ApiError::Forbidden("You don't own this channel".into()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn parse_optional_dt(
|
||||
s: Option<String>,
|
||||
default: DateTime<Utc>,
|
||||
) -> Result<DateTime<Utc>, ApiError> {
|
||||
match s {
|
||||
None => Ok(default),
|
||||
Some(raw) => DateTime::parse_from_rfc3339(&raw)
|
||||
.map(|dt| dt.with_timezone(&Utc))
|
||||
.map_err(|_| ApiError::validation(format!("Invalid datetime '{}' — use RFC3339", raw))),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user