more multi-tenancy

This commit is contained in:
2025-10-23 16:06:56 +02:00
parent e175d28c2c
commit 0ad79c9bc1
35 changed files with 1229 additions and 534 deletions
+21 -12
View File
@@ -1,6 +1,6 @@
use std::collections::{BTreeMap, HashMap};
use axum::{extract::Path, http::StatusCode, response::IntoResponse, Json};
use axum::{extract::Path, http::StatusCode, Json};
use chrono::Utc;
use diesel::{dsl::count_star, prelude::*, result::DatabaseErrorKind, PgConnection};
use serde::{Deserialize, Serialize};
@@ -12,10 +12,12 @@ use crate::{
error::{AppError, AppResult},
models::{Correspondent, NewCorrespondent},
schema::{correspondents, document_correspondents},
utils::{
db::{no_content, EnsureEntity, IntoJsonResponse},
time::to_iso,
},
};
use super::documents::to_iso;
#[derive(Serialize)]
pub struct CorrespondentUsage {
pub total: i64,
@@ -92,7 +94,7 @@ pub async fn list_correspondents(
response.push(build_summary(correspondent, role_counts));
}
Ok(Json(response))
response.into_json()
}
pub async fn create_correspondent(
@@ -128,8 +130,13 @@ pub async fn create_correspondent(
Err(err) => return Err(AppError::from(err)),
}
let correspondent: Correspondent = correspondents::table.find(new_id).first(&mut conn)?;
Ok(Json(build_summary(correspondent, BTreeMap::new())))
let correspondent: Correspondent = correspondents::table
.find(new_id)
.filter(correspondents::tenant_id.eq(tenant_id))
.first(&mut conn)
.one()?;
build_summary(correspondent, BTreeMap::new()).into_json()
}
pub async fn update_correspondent(
@@ -144,7 +151,8 @@ pub async fn update_correspondent(
let existing: Correspondent = correspondents::table
.find(correspondent_id)
.filter(correspondents::tenant_id.eq(tenant_id))
.first(&mut conn)?;
.first(&mut conn)
.one()?;
let mut new_name: Option<String> = None;
if let Some(ref candidate) = payload.name {
@@ -176,7 +184,7 @@ pub async fn update_correspondent(
if new_name.is_none() && new_metadata.is_none() {
let usage = load_usage_for_correspondent(&mut conn, tenant_id, correspondent_id)?;
return Ok(Json(build_summary(existing.clone(), usage)));
return build_summary(existing.clone(), usage).into_json();
}
let mut changeset = CorrespondentChangeset::default();
@@ -199,9 +207,10 @@ pub async fn update_correspondent(
let updated: Correspondent = correspondents::table
.find(correspondent_id)
.filter(correspondents::tenant_id.eq(tenant_id))
.first(&mut conn)?;
.first(&mut conn)
.one()?;
let usage = load_usage_for_correspondent(&mut conn, tenant_id, correspondent_id)?;
Ok(Json(build_summary(updated, usage)))
build_summary(updated, usage).into_json()
}
pub async fn delete_correspondent(
@@ -211,7 +220,7 @@ pub async fn delete_correspondent(
tenant_id,
..
}: TenantScopedConn,
) -> AppResult<impl IntoResponse> {
) -> AppResult<StatusCode> {
let usage: i64 = document_correspondents::table
.filter(document_correspondents::tenant_id.eq(tenant_id))
.filter(document_correspondents::correspondent_id.eq(correspondent_id))
@@ -233,7 +242,7 @@ pub async fn delete_correspondent(
if deleted == 0 {
return Err(AppError::not_found());
}
Ok(StatusCode::NO_CONTENT)
no_content()
}
fn build_summary(