//! Per-user reader preferences. Rows are lazily inserted on the first //! upsert — a user that has never customised their settings has no row, //! and reads fall back to the in-memory defaults in `UserPreferences::defaults_for`. use sqlx::PgPool; use uuid::Uuid; use crate::domain::UserPreferences; use crate::error::AppResult; pub async fn find(pool: &PgPool, user_id: Uuid) -> AppResult> { let row = sqlx::query_as::<_, UserPreferences>( r#" SELECT user_id, reader_mode, reader_page_gap, updated_at FROM user_preferences WHERE user_id = $1 "#, ) .bind(user_id) .fetch_optional(pool) .await?; Ok(row) } pub async fn upsert( pool: &PgPool, user_id: Uuid, reader_mode: &str, reader_page_gap: &str, ) -> AppResult { let row = sqlx::query_as::<_, UserPreferences>( r#" INSERT INTO user_preferences (user_id, reader_mode, reader_page_gap) VALUES ($1, $2, $3) ON CONFLICT (user_id) DO UPDATE SET reader_mode = EXCLUDED.reader_mode, reader_page_gap = EXCLUDED.reader_page_gap, updated_at = now() RETURNING user_id, reader_mode, reader_page_gap, updated_at "#, ) .bind(user_id) .bind(reader_mode) .bind(reader_page_gap) .fetch_one(pool) .await?; Ok(row) }