use axum::extract::State; use axum::Json; use serde_json::json; use crate::auth::AuthUser; use crate::config::AppState; use crate::errors::AppError; use crate::models::{PushPreferencesRequest, PushPreferencesResponse, PushSubscribeRequest}; /// GET /api/push/vapid-key pub async fn vapid_key(State(state): State) -> Json { Json(json!({ "vapid_public_key": state.vapid_public_key })) } /// POST /api/push/subscribe pub async fn subscribe( AuthUser(user_id): AuthUser, State(state): State, Json(req): Json, ) -> Result, AppError> { let id = uuid::Uuid::new_v4().to_string(); sqlx::query( "INSERT INTO push_subscriptions (id, user_id, endpoint, p256dh, auth) VALUES (?, ?, ?, ?, ?) ON CONFLICT(endpoint) DO UPDATE SET p256dh = excluded.p256dh, auth = excluded.auth, user_id = excluded.user_id", ) .bind(&id) .bind(&user_id) .bind(&req.endpoint) .bind(&req.p256dh) .bind(&req.auth) .execute(&state.db) .await?; Ok(Json(json!({ "ok": true }))) } /// DELETE /api/push/subscribe pub async fn unsubscribe( AuthUser(user_id): AuthUser, State(state): State, ) -> Result, AppError> { sqlx::query("DELETE FROM push_subscriptions WHERE user_id = ?") .bind(&user_id) .execute(&state.db) .await?; Ok(Json(json!({ "ok": true }))) } /// GET /api/push/preferences pub async fn get_preferences( AuthUser(user_id): AuthUser, State(state): State, ) -> Result, AppError> { let row = sqlx::query_as::<_, (i32, String)>( "SELECT COALESCE(reminder_enabled, 0), COALESCE(reminder_time, '20:00') FROM user_stats WHERE user_id = ?", ) .bind(&user_id) .fetch_optional(&state.db) .await?; match row { Some((enabled, time)) => Ok(Json(PushPreferencesResponse { reminder_enabled: enabled != 0, reminder_time: time, })), None => Ok(Json(PushPreferencesResponse { reminder_enabled: false, reminder_time: "20:00".to_string(), })), } } /// PUT /api/push/preferences pub async fn update_preferences( AuthUser(user_id): AuthUser, State(state): State, Json(req): Json, ) -> Result, AppError> { let enabled = i32::from(req.reminder_enabled); sqlx::query("UPDATE user_stats SET reminder_enabled = ?, reminder_time = ? WHERE user_id = ?") .bind(enabled) .bind(&req.reminder_time) .bind(&user_id) .execute(&state.db) .await?; Ok(Json(json!({ "ok": true }))) }