Skip to main content

shodh_memory/handlers/
users.rs

1//! User Management Handlers
2//!
3//! Handlers for user-related operations including stats, deletion (GDPR), and listing.
4
5use axum::{
6    extract::{Path, Query, State},
7    response::Json,
8};
9use serde::{Deserialize, Serialize};
10
11use super::state::MultiUserMemoryManager;
12use crate::errors::{AppError, ValidationErrorExt};
13use crate::memory::MemoryStats;
14use crate::validation;
15use std::sync::Arc;
16
17type AppState = Arc<MultiUserMemoryManager>;
18
19/// GET /api/users/{user_id}/stats - Get user statistics
20pub async fn get_user_stats(
21    State(state): State<AppState>,
22    Path(user_id): Path<String>,
23) -> Result<Json<MemoryStats>, AppError> {
24    validation::validate_user_id(&user_id).map_validation_err("user_id")?;
25    let stats = state.get_stats(&user_id).map_err(AppError::Internal)?;
26    Ok(Json(stats))
27}
28
29/// Query parameters for stats endpoint
30#[derive(Debug, Deserialize)]
31pub struct StatsQuery {
32    pub user_id: String,
33}
34
35/// GET /api/stats - OpenAPI spec compatible stats endpoint
36pub async fn get_stats_query(
37    State(state): State<AppState>,
38    Query(query): Query<StatsQuery>,
39) -> Result<Json<MemoryStats>, AppError> {
40    let stats = state
41        .get_stats(&query.user_id)
42        .map_err(AppError::Internal)?;
43    Ok(Json(stats))
44}
45
46/// Response for user deletion
47#[derive(Debug, Serialize)]
48pub struct DeleteUserResponse {
49    pub success: bool,
50    pub user_id: String,
51    pub message: String,
52}
53
54/// DELETE /api/users/{user_id} - Delete user data (GDPR compliance)
55pub async fn delete_user(
56    State(state): State<AppState>,
57    Path(user_id): Path<String>,
58) -> Result<Json<DeleteUserResponse>, AppError> {
59    validation::validate_user_id(&user_id).map_validation_err("user_id")?;
60    state.forget_user(&user_id).map_err(AppError::Internal)?;
61
62    Ok(Json(DeleteUserResponse {
63        success: true,
64        user_id,
65        message: "User data deleted successfully".to_string(),
66    }))
67}
68
69/// GET /api/users - List all users
70pub async fn list_users(State(state): State<AppState>) -> Json<Vec<String>> {
71    Json(state.list_users())
72}