refactor Ulid und Dataloader

This commit is contained in:
2026-06-06 11:59:20 +02:00
parent 581c8bee88
commit b5182b7f19
54 changed files with 364 additions and 301 deletions

View File

@@ -3,14 +3,14 @@ use async_graphql::{ComplexObject, Context, FieldResult, SimpleObject};
use crate::{
dataloader::LoaderContext,
domain::{gruppe::model::Gruppe, rolle::model::Rolle},
scalar::Id,
scalar::Ulid,
};
#[derive(sqlx::FromRow, SimpleObject)]
#[graphql(complex)]
pub struct Benutzer {
/// Die UUID eines Benutzers
pub id: Id,
/// Die ULid eines Benutzers
pub id: Ulid,
/// Die Kennung des Benutzers
pub kennung: String,

View File

@@ -1,12 +1,13 @@
use crate::scalar::Id;
use async_graphql::InputObject;
use crate::scalar::Ulid;
#[derive(InputObject)]
pub struct BenutzerCreateInput {
// #[graphql(validator(min_length = 6, max_length = 8))]
pub kennung: String,
pub vorname: String,
pub nachname: String,
pub rollen: Option<Vec<Id>>,
pub gruppen: Option<Vec<Id>>,
pub rollen: Option<Vec<Ulid>>,
pub gruppen: Option<Vec<Ulid>>,
}

View File

@@ -1,7 +1,7 @@
use async_graphql::{ComplexObject, Enum, SimpleObject};
use sqlx::Type;
use crate::scalar::{Id, Time};
use crate::scalar::{Time, Ulid};
/// Aus welcher Quelle die Gruppe stammt.
#[derive(Enum, Clone, Debug, Eq, Copy, PartialEq, Type)]
@@ -21,7 +21,7 @@ pub enum Herkunft {
#[graphql(complex)]
pub struct GruppeAnsicht {
/// Die UUID einer Gruppe
pub id: Id,
pub id: Ulid,
/// Der Gruppenname
pub gruppenname: String,

View File

@@ -5,17 +5,17 @@ use std::sync::Arc;
use crate::domain::gruppe::model::Gruppe;
use crate::domain::gruppe::service::Service;
use crate::scalar::Id;
use crate::scalar::Ulid;
pub struct GruppenLoader {
pub pool: sqlx::PgPool,
}
impl Loader<Id> for GruppenLoader {
impl Loader<Ulid> for GruppenLoader {
type Value = Vec<Gruppe>;
type Error = Arc<sqlx::Error>;
async fn load(&self, keys: &[Id]) -> Result<HashMap<Id, Self::Value>, Self::Error> {
async fn load(&self, keys: &[Ulid]) -> Result<HashMap<Ulid, Self::Value>, Self::Error> {
let rows = Service::new(self.pool.clone())
.gruppe_dataloader(keys)
.await?;

View File

@@ -1,2 +1,6 @@
pub mod gruppe;
pub use gruppe::Gruppe;
pub use gruppe::GruppeDataloader;
pub use gruppe::GruppeErstellen;
pub use gruppe::GruppeLoeschen;
pub use gruppe::GruppeUpdate;

View File

@@ -1,8 +1,30 @@
use crate::scalar::{Id, Time};
use sqlx::FromRow;
pub struct Gruppe {
pub id: Id,
use crate::scalar::{Id, Time, Ulid};
pub struct GruppeErstellen {
pub gruppe_id: Id,
pub id: Ulid,
pub gruppenname: String,
pub erstellt_am: Option<Time>,
pub geaendert_am: Option<Time>,
pub erstellt_am: Time,
pub geaendert_am: Time,
}
pub struct GruppeLoeschen {
pub id: Ulid,
}
pub struct GruppeUpdate {
pub id: Ulid,
pub gruppenname: String,
pub geaendert_am: Time,
}
#[derive(Debug, FromRow)]
pub struct GruppeDataloader {
pub r_ulid: Ulid,
pub g_ulid: Ulid,
pub gruppenname: String,
pub erstellt_am: Time,
pub geaendert_am: Time,
}

View File

@@ -1,12 +1,12 @@
use async_graphql::{ComplexObject, SimpleObject};
use crate::scalar::{Id, Time};
use crate::scalar::{Time, Ulid};
#[derive(sqlx::FromRow, SimpleObject, Clone, Debug)]
#[graphql(complex)]
pub struct Gruppe {
/// Die UUID einer Gruppe
pub id: Id,
pub id: Ulid,
/// Der Gruppenname
pub gruppenname: String,

View File

@@ -1,9 +1,9 @@
use async_graphql::InputObject;
use crate::scalar::Id;
use crate::scalar::Ulid;
#[derive(InputObject)]
pub struct GruppeLoeschenInput {
/// Die ID einer Gruppe
pub id: Id,
/// Die ULID einer Gruppe
pub id: Ulid,
}

View File

@@ -1,10 +1,10 @@
use crate::scalar::Id;
use crate::scalar::Ulid;
use async_graphql::InputObject;
#[derive(InputObject)]
pub struct GruppeUpdateInput {
/// Die ID einer Gruppe
pub id: Id,
/// Die Ulid einer Gruppe
pub id: Ulid,
/// Der Name einer Gruppe
pub gruppenname: String,

View File

@@ -1,48 +1,53 @@
use itertools::Itertools;
use std::collections::HashMap;
use std::sync::Arc;
use itertools::Itertools;
use super::Repository;
use crate::database::Queryer;
use crate::domain::gruppe::entity::GruppeDataloader;
use crate::domain::gruppe::model::Gruppe;
use crate::scalar::Id;
use crate::scalar::Ulid;
impl Repository {
pub async fn gruppe_dataloader<'c, C: Queryer<'c>>(
&self,
db: C,
keys: &[Id],
) -> Result<HashMap<Id, Vec<Gruppe>>, Arc<sqlx::Error>> {
let rows = sqlx::query!(
r#"
SELECT
rg.rolle_id,
g.id,
g.gruppenname,
g.erstellt_am,
g.geaendert_am
FROM gruppen AS g
LEFT JOIN rollen_gruppen AS rg ON g.id = rg.gruppe_id
WHERE rg.rolle_id = ANY($1);
"#,
keys
)
.fetch_all(db)
.await?
.into_iter()
.map(|row| {
(
row.rolle_id,
Gruppe {
id: row.id,
gruppenname: row.gruppenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
keys: &[Ulid],
) -> Result<HashMap<Ulid, Vec<Gruppe>>, Arc<sqlx::Error>> {
const QUERY: &str = r#"
SELECT
rg.rolle_id as r_ulid,
g.id as g_ulid,
g.gruppenname,
g.erstellt_am,
g.geaendert_am
FROM gruppen AS g
LEFT JOIN rollen_gruppen AS rg ON g.gruppe_id = rg.gruppe_id
WHERE rg.rolle_id IN (
SELECT benutzer_id
FROM benutzer
WHERE id = ANY($1)
);
"#;
let rows = sqlx::query_as::<_, GruppeDataloader>(QUERY)
.bind(keys)
.fetch_all(db)
.await?
.into_iter()
.map(|row| {
(
row.r_ulid,
Gruppe {
id: row.g_ulid,
gruppenname: row.gruppenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
Ok(rows)
}

View File

@@ -8,19 +8,20 @@ impl Repository {
pub async fn gruppe_erstellen<'c, C: Queryer<'c>>(
&self,
db: C,
gruppe: &entity::Gruppe,
gruppe: &entity::GruppeErstellen,
) -> Result<model::Gruppe, Error> {
const QUERY: &str = r#"
INSERT INTO gruppen (id, erstellt_am, geaendert_am, gruppenname) VALUES (
$1, $2, $3, $4
) RETURNING id, erstellt_am, geaendert_am, gruppenname;
INSERT INTO gruppen (gruppe_id, id, gruppenname, erstellt_am, geaendert_am) VALUES (
$1, $2, $3, $4, $5
) RETURNING id, gruppenname, erstellt_am, geaendert_am;
"#;
let gruppe = sqlx::query_as::<_, model::Gruppe>(QUERY)
.bind(gruppe.gruppe_id)
.bind(gruppe.id)
.bind(&gruppe.gruppenname)
.bind(gruppe.erstellt_am)
.bind(gruppe.geaendert_am)
.bind(&gruppe.gruppenname)
.fetch_one(db)
.await?;

View File

@@ -8,7 +8,7 @@ impl Repository {
pub async fn gruppe_loeschen<'c, C: Queryer<'c>>(
&self,
db: C,
gruppe: &entity::Gruppe,
gruppe: &entity::GruppeLoeschen,
) -> Result<model::Gruppe, Error> {
const QUERY: &str = r#"
DELETE FROM gruppen WHERE id=$1 RETURNING id, gruppenname, erstellt_am, geaendert_am;

View File

@@ -8,12 +8,12 @@ impl Repository {
pub async fn gruppe_update<'c, C: Queryer<'c>>(
&self,
db: C,
gruppe: &entity::Gruppe,
gruppe: &entity::GruppeUpdate,
) -> Result<model::Gruppe, Error> {
const QUERY: &str = r#"
UPDATE gruppen
SET geaendert_am = $2, ruppenname = $3 WHERE gruppeid = $1
RETURNING id, geaendert_am, erstellt_am, gruppenname;
RETURNING id, gruppenname, geaendert_am, erstellt_am;
"#;
let gruppe = sqlx::query_as::<_, model::Gruppe>(QUERY)

View File

@@ -1,14 +1,14 @@
use std::{collections::HashMap, sync::Arc};
use crate::{domain::gruppe::model::Gruppe, scalar::Id};
use crate::{domain::gruppe::model::Gruppe, scalar::Ulid};
use super::Service;
impl Service {
pub async fn gruppe_dataloader(
&self,
keys: &[Id],
) -> Result<HashMap<Id, Vec<Gruppe>>, Arc<sqlx::Error>> {
keys: &[Ulid],
) -> Result<HashMap<Ulid, Vec<Gruppe>>, Arc<sqlx::Error>> {
let gruppen_dataloader = self.repo.gruppe_dataloader(&self.db, keys).await?;
Ok(gruppen_dataloader)
}

View File

@@ -1,23 +1,25 @@
use super::Service;
use crate::{
domain::gruppe::{
entity,
model::{self, GruppeErstelleInput},
},
scalar::Ulid,
};
use anyhow::Error;
use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::gruppe::{
entity,
model::{self, GruppeErstelleInput},
};
impl Service {
pub async fn gruppe_erstellen(
&self,
input: GruppeErstelleInput,
) -> Result<model::Gruppe, Error> {
let gruppe_input = entity::Gruppe {
id: Ulid::new().into(),
let gruppe_input = entity::GruppeErstellen {
gruppe_id: ulid::Ulid::new().into(),
id: Ulid(ulid::Ulid::new().into()),
gruppenname: input.gruppenname,
erstellt_am: Some(Utc::now()),
geaendert_am: Some(Utc::now()),
erstellt_am: Utc::now(),
geaendert_am: Utc::now(),
};
let gruppe = self.repo.gruppe_erstellen(&self.db, &gruppe_input).await?;

View File

@@ -1,5 +1,4 @@
use anyhow::Error;
use chrono::Utc;
use super::Service;
use crate::domain::gruppe::{
@@ -12,12 +11,7 @@ impl Service {
&self,
input: GruppeLoeschenInput,
) -> Result<model::Gruppe, Error> {
let gruppe_input = entity::Gruppe {
id: input.id,
gruppenname: String::new(),
erstellt_am: None,
geaendert_am: Some(Utc::now()),
};
let gruppe_input = entity::GruppeLoeschen { id: input.id };
let gruppe = self.repo.gruppe_loeschen(&self.db, &gruppe_input).await?;
Ok(gruppe)

View File

@@ -1,6 +1,5 @@
use anyhow::Error;
use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::gruppe::{
@@ -10,11 +9,10 @@ use crate::domain::gruppe::{
impl Service {
pub async fn gruppe_update(&self, input: GruppeUpdateInput) -> Result<model::Gruppe, Error> {
let gruppe_input = entity::Gruppe {
id: Ulid::new().into(),
let gruppe_input = entity::GruppeUpdate {
id: input.id,
gruppenname: input.gruppenname,
erstellt_am: None,
geaendert_am: Some(Utc::now()),
geaendert_am: Utc::now(),
};
let gruppe = self.repo.gruppe_update(&self.db, &gruppe_input).await?;

View File

@@ -1,51 +1,23 @@
use async_graphql::dataloader::*;
use async_graphql::*;
use itertools::Itertools;
use async_graphql::dataloader::Loader;
use std::collections::HashMap;
use std::sync::Arc;
use crate::domain::rolle::model::Rolle;
use crate::scalar::Id;
use crate::domain::rolle::service::Service;
use crate::scalar::Ulid;
pub struct RollenLoader {
pub pool: sqlx::PgPool,
}
impl Loader<Id> for RollenLoader {
impl Loader<Ulid> for RollenLoader {
type Value = Vec<Rolle>;
type Error = Arc<sqlx::Error>;
async fn load(&self, keys: &[Id]) -> Result<HashMap<Id, Self::Value>, Self::Error> {
let rows = sqlx::query!(
r#"
SELECT
br.benutzer_id,
r.id,
r.rollenname,
r.erstellt_am,
r.geaendert_am
FROM rollen AS r
LEFT JOIN benutzer_rollen AS br ON r.id = br.rolle_id
WHERE br.benutzer_id = ANY($1);
"#,
keys
)
.fetch_all(&self.pool)
.await?
.into_iter()
.map(|row| {
(
row.benutzer_id,
Rolle {
id: row.id,
rollenname: row.rollenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
async fn load(&self, keys: &[Ulid]) -> Result<HashMap<Ulid, Self::Value>, Self::Error> {
let rows = Service::new(self.pool.clone())
.rolle_dataloader(keys)
.await?;
Ok(rows)
}
}

View File

@@ -1,2 +1,6 @@
pub mod rolle;
pub use rolle::Rolle;
pub use rolle::RolleErstellen;
pub use rolle::RolleLoeschen;
pub use rolle::RolleRow;
pub use rolle::RolleUpdate;

View File

@@ -1,8 +1,30 @@
use crate::scalar::{Id, Time};
use sqlx::FromRow;
pub struct Rolle {
pub id: Id,
use crate::scalar::{Id, Time, Ulid};
pub struct RolleErstellen {
pub rolle_id: Id,
pub id: Ulid,
pub rollenname: String,
pub erstellt_am: Option<Time>,
pub geaendert_am: Option<Time>,
pub erstellt_am: Time,
pub geaendert_am: Time,
}
pub struct RolleLoeschen {
pub id: Ulid,
}
pub struct RolleUpdate {
pub id: Ulid,
pub rollenname: String,
pub geaendert_am: Time,
}
#[derive(Debug, FromRow)]
pub struct RolleRow {
pub b_ulid: Ulid,
pub r_ulid: Ulid,
pub rollenname: String,
pub erstellt_am: Time,
pub geaendert_am: Time,
}

View File

@@ -3,15 +3,15 @@ use async_graphql::{ComplexObject, Context, FieldResult, SimpleObject};
use crate::{
dataloader::LoaderContext,
domain::gruppe::model::Gruppe,
scalar::{Id, Time},
scalar::{Time, Ulid},
};
/// Um die Administration zu erleichtern werden Gruppen in die Rollen hinzugefuegt
#[derive(sqlx::FromRow, SimpleObject, Debug, Clone)]
#[graphql(complex)]
pub struct Rolle {
/// Die uuid einer Rolle
pub id: Id,
/// Die ULID einer Rolle
pub id: Ulid,
/// Der Rollenname
pub rollenname: String,

View File

@@ -1,9 +1,9 @@
use async_graphql::InputObject;
use crate::scalar::Id;
use crate::scalar::Ulid;
#[derive(InputObject)]
pub struct RolleLoeschenInput {
/// Die ID einer Rolle
pub id: Id,
/// Die Ulid einer Rolle
pub id: Ulid,
}

View File

@@ -1,10 +1,10 @@
use crate::scalar::Id;
use crate::scalar::Ulid;
use async_graphql::InputObject;
#[derive(InputObject)]
pub struct RolleUpdateInput {
/// Die ID einer Rolle
pub id: Id,
/// Die Ulid einer Rolle
pub id: Ulid,
/// Der Name einer Rolle
pub rollenname: String,

View File

@@ -1,7 +1,7 @@
use async_graphql::{Context, FieldResult, Object};
use sqlx::postgres::PgPool;
use crate::domain::rolle::model::Rolle;
use crate::domain::rolle::{model::Rolle, service::Service};
#[derive(Default)]
pub struct RolleQuery {}
@@ -15,11 +15,8 @@ impl RolleQuery {
// }
async fn rollen(&self, ctx: &Context<'_>) -> FieldResult<Vec<Rolle>> {
let pool = ctx.data::<PgPool>()?;
let rollen = sqlx::query_as!(Rolle, "SELECT * FROM rollen")
.fetch_all(pool)
.await?;
let pool = ctx.data::<PgPool>()?.clone();
let rollen = Service::new(pool).rolle_alle().await?;
Ok(rollen)
}

View File

@@ -1,9 +1,10 @@
mod find_all_rolle;
mod find_rolle_by_id;
mod rolle_alle;
mod rolle_dataloader;
mod rolle_erstellen;
mod rolle_loeschen;
mod rolle_update;
mod rollen_dataloader;
#[derive(Debug, Clone)]
pub struct Repository {}
@@ -13,6 +14,7 @@ impl Repository {
Repository {}
}
}
impl Default for Repository {
fn default() -> Self {
Self::new()

View File

@@ -0,0 +1,17 @@
use anyhow::Error;
use super::Repository;
use crate::{database::Queryer, domain::rolle::model};
impl Repository {
pub async fn rolle_alle<'c, C: Queryer<'c>>(&self, db: C) -> Result<Vec<model::Rolle>, Error> {
const QUERY: &str = r#"
SELECT id, rollenname, erstellt_am, geaendert_am FROM rollen
"#;
let rollen = sqlx::query_as::<_, model::Rolle>(QUERY)
.fetch_all(db)
.await?;
Ok(rollen)
}
}

View File

@@ -0,0 +1,55 @@
use itertools::Itertools;
use std::collections::HashMap;
use std::sync::Arc;
use super::Repository;
use crate::database::Queryer;
use crate::domain::rolle::entity::RolleRow;
use crate::domain::rolle::model;
use crate::scalar::Ulid;
impl Repository {
pub async fn rolle_dataloader<'c, C: Queryer<'c>>(
&self,
db: C,
keys: &[Ulid],
) -> Result<HashMap<Ulid, Vec<model::Rolle>>, Arc<sqlx::Error>> {
const QUERY: &str = r#"
SELECT
b.id as b_ulid,
r.id as r_ulid,
r.rollenname,
r.erstellt_am,
r.geaendert_am
FROM rollen AS r
LEFT JOIN benutzer_rollen AS br ON r.rolle_id = br.rolle_id
LEFT JOIN benutzer AS b ON br.benutzer_id = b.benutzer_id
WHERE br.benutzer_id IN (
SELECT benutzer_id
FROM benutzer
WHERE id = ANY($1)
)
"#;
let rows = sqlx::query_as::<_, RolleRow>(QUERY)
.bind(keys)
.fetch_all(db)
.await?
.into_iter()
.map(|row| {
(
row.b_ulid,
model::Rolle {
id: row.r_ulid,
rollenname: row.rollenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
Ok(rows)
}
}

View File

@@ -8,19 +8,20 @@ impl Repository {
pub async fn rolle_erstellen<'c, C: Queryer<'c>>(
&self,
db: C,
rolle: &entity::Rolle,
rolle: &entity::RolleErstellen,
) -> Result<model::Rolle, Error> {
const QUERY: &str = r#"
INSERT INTO rollen (id, erstellt_am, geaendert_am, rollenname) VALUES (
$1, $2, $3, $4
) RETURNING id, erstellt_am, geaendert_am, rollenname
INSERT INTO rollen (rolle_id, id, rollenname, erstellt_am, geaendert_am) VALUES (
$1, $2, $3, $4, $5
) RETURNING id, rollenname, erstellt_am, geaendert_am
"#;
let rolle = sqlx::query_as::<_, model::Rolle>(QUERY)
.bind(rolle.rolle_id)
.bind(rolle.id)
.bind(&rolle.rollenname)
.bind(rolle.erstellt_am)
.bind(rolle.geaendert_am)
.bind(&rolle.rollenname)
.fetch_one(db)
.await?;

View File

@@ -10,7 +10,7 @@ impl Repository {
pub async fn rolle_loeschen<'c, C: Queryer<'c>>(
&self,
db: C,
rolle: &entity::Rolle,
rolle: &entity::RolleLoeschen,
) -> Result<model::Rolle, Error> {
const QUERY: &str = r#"
DELETE FROM rollen WHERE id=$1 RETURNING id, rollenname, erstellt_am, geaendert_am;

View File

@@ -8,7 +8,7 @@ impl Repository {
pub async fn rolle_update<'c, C: Queryer<'c>>(
&self,
db: C,
rolle: &entity::Rolle,
rolle: &entity::RolleUpdate,
) -> Result<model::Rolle, Error> {
const QUERY: &str = r#"
UPDATE rollen

View File

@@ -1,49 +0,0 @@
use std::collections::HashMap;
use std::sync::Arc;
use itertools::Itertools;
use super::Repository;
use crate::database::Queryer;
use crate::domain::rolle::model::Rolle;
use crate::scalar::Id;
impl Repository {
pub async fn rollen_dataloader<'c, C: Queryer<'c>>(
&self,
db: C,
keys: &[Id],
) -> Result<HashMap<Id, Vec<Rolle>>, Arc<sqlx::Error>> {
let rows = sqlx::query!(
r#"
SELECT
br.benutzer_id,
r.id,
r.rollenname,
r.erstellt_am,
r.geaendert_am
FROM rollen AS r
LEFT JOIN benutzer_rollen AS br ON r.id = br.rolle_id
WHERE br.benutzer_id = ANY($1);
"#,
keys
)
.fetch_all(db)
.await?
.into_iter()
.map(|row| {
(
row.benutzer_id,
Rolle {
id: row.id,
rollenname: row.rollenname,
erstellt_am: row.erstellt_am,
geaendert_am: row.geaendert_am,
},
)
})
.into_group_map();
Ok(rows)
}
}

View File

@@ -1,3 +1,5 @@
mod rolle_alle;
mod rolle_dataloader;
mod rolle_erstellen;
mod rolle_loeschen;
mod rolle_update;

View File

@@ -0,0 +1,12 @@
use anyhow::Error;
use crate::domain::rolle::model;
use super::Service;
impl Service {
pub async fn rolle_alle(&self) -> Result<Vec<model::Rolle>, Error> {
let typen = self.repo.rolle_alle(&self.db).await?;
Ok(typen)
}
}

View File

@@ -0,0 +1,15 @@
use std::{collections::HashMap, sync::Arc};
use crate::{domain::rolle::model, scalar::Ulid};
use super::Service;
impl Service {
pub async fn rolle_dataloader(
&self,
keys: &[Ulid],
) -> Result<HashMap<Ulid, Vec<model::Rolle>>, Arc<sqlx::Error>> {
let typen = self.repo.rolle_dataloader(&self.db, keys).await?;
Ok(typen)
}
}

View File

@@ -1,20 +1,23 @@
use anyhow::Error;
use chrono::Utc;
use ulid::Ulid;
use super::Service;
use crate::domain::rolle::{
entity,
model::{self, RolleErstelleInput},
use crate::{
domain::rolle::{
entity,
model::{self, RolleErstelleInput},
},
scalar::Ulid,
};
impl Service {
pub async fn rolle_erstellen(&self, input: RolleErstelleInput) -> Result<model::Rolle, Error> {
let rolle_input = entity::Rolle {
id: Ulid::new().into(),
let rolle_input = entity::RolleErstellen {
rolle_id: ulid::Ulid::new().into(),
id: Ulid(ulid::Ulid::new()),
rollenname: input.rollenname,
erstellt_am: Some(Utc::now()),
geaendert_am: Some(Utc::now()),
erstellt_am: Utc::now(),
geaendert_am: Utc::now(),
};
let rolle = self.repo.rolle_erstellen(&self.db, &rolle_input).await?;

View File

@@ -8,12 +8,7 @@ use crate::domain::rolle::{
impl Service {
pub async fn rolle_loeschen(&self, input: RolleLoeschenInput) -> Result<model::Rolle, Error> {
let rolle_input = entity::Rolle {
id: input.id,
rollenname: String::new(),
erstellt_am: None,
geaendert_am: None,
};
let rolle_input = entity::RolleLoeschen { id: input.id };
let deleted = self.repo.rolle_loeschen(&self.db, &rolle_input).await?;
Ok(deleted)

View File

@@ -9,11 +9,10 @@ use crate::domain::rolle::{
impl Service {
pub async fn rolle_update(&self, input: RolleUpdateInput) -> Result<model::Rolle, Error> {
let rolle_input = entity::Rolle {
let rolle_input = entity::RolleUpdate {
id: input.id,
rollenname: input.rollenname,
erstellt_am: None,
geaendert_am: Some(Utc::now()),
geaendert_am: Utc::now(),
};
let rolle = self.repo.rolle_update(&self.db, &rolle_input).await?;

View File

@@ -1,6 +1,5 @@
pub mod typ;
// pub use typ::Typ;
pub use typ::TypErstellen;
pub use typ::TypLoeschen;
pub use typ::TypUpdate;