//! Endpoints scoped to the *current user*. Kept separate from `auth::handlers` because //! these aren't about acquiring / refreshing a session — they're about reading my own //! state once I'm already signed in. //! //! Current routes: //! - `GET /api/v1/me/context` — bundled profile + feature flags + privacy note. The //! account page loads this once on mount instead of issuing several round trips. //! - `GET /api/v1/me/quota` — live per-user storage quota estimate. use axum::extract::State; use axum::Json; use serde::Serialize; use crate::auth::middleware::AuthUser; use crate::error::AppError; use crate::handlers::upload::compute_storage_quota; use crate::models::user::User; use crate::services::config; use crate::state::AppState; #[derive(Serialize)] pub struct QuotaDto { pub enabled: bool, pub used_bytes: i64, pub limit_bytes: Option, pub active_uploaders: i64, pub free_disk_bytes: i64, } pub async fn get_quota( State(state): State, auth: AuthUser, ) -> Result, AppError> { let user = User::find_by_id(&state.pool, auth.user_id) .await? .ok_or_else(|| AppError::NotFound("Benutzer nicht gefunden.".into()))?; let estimate = compute_storage_quota(&state).await; Ok(Json(QuotaDto { enabled: estimate.limit_bytes.is_some(), used_bytes: user.total_upload_bytes, limit_bytes: estimate.limit_bytes, active_uploaders: estimate.active_uploaders, free_disk_bytes: estimate.free_disk_bytes, })) } #[derive(Serialize)] pub struct MeContextDto { pub user_id: uuid::Uuid, pub display_name: String, pub role: String, /// Plain-text Datenschutzhinweis set by the admin. Empty string when not configured. pub privacy_note: String, pub quota_enabled: bool, pub storage_quota_enabled: bool, } pub async fn get_context( State(state): State, auth: AuthUser, ) -> Result, AppError> { let user = User::find_by_id(&state.pool, auth.user_id) .await? .ok_or_else(|| AppError::NotFound("Benutzer nicht gefunden.".into()))?; let privacy_note = config::get_str(&state.pool, "privacy_note", "").await; let quota_enabled = config::get_bool(&state.pool, "quota_enabled", true).await; let storage_quota_enabled = config::get_bool(&state.pool, "storage_quota_enabled", true).await; Ok(Json(MeContextDto { user_id: user.id, display_name: user.display_name, role: user.role.as_str().to_string(), privacy_note, quota_enabled, storage_quota_enabled, })) }