create gruppen, rollen, etc...

This commit is contained in:
Peter Schiwy
2024-12-06 14:06:27 +01:00
parent bfce29c8ee
commit 623d28f77b
63 changed files with 735 additions and 185 deletions

View File

View File

@@ -0,0 +1,3 @@
pub mod benutzer;
pub use benutzer::Benutzer;

View File

@@ -0,0 +1,8 @@
use crate::scalar::Id;
pub struct Benutzer {
pub id: Id,
pub kennung: String,
pub nachname: String,
pub vorname: String,
}

View File

@@ -0,0 +1,5 @@
pub mod benutzer;
pub mod benutzer_create_input;
pub use benutzer::Benutzer;
pub use benutzer_create_input::BenutzerCreateInput;

View File

@@ -0,0 +1,48 @@
use async_graphql::{ComplexObject, Context, FieldResult, SimpleObject};
use crate::{
dataloader::LoaderContext,
domain::{gruppe::model::Gruppe, rolle::model::Rolle},
models::gruppe_ansicht::GruppeAnsicht,
scalar::Id,
};
#[derive(sqlx::FromRow, SimpleObject)]
#[graphql(complex)]
pub struct Benutzer {
/// Die UUID eines Benutzers
pub id: Id,
/// Die Kennung des Benutzers
pub kennung: String,
/// Der Vorname des Benutzers
pub vorname: String,
/// Der Nachname des Benutzers
pub nachname: String,
}
#[ComplexObject]
impl Benutzer {
/// Die Rollen des Benutzers
pub async fn rollen<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Option<Vec<Rolle>>> {
let loader = ctx.data::<LoaderContext>()?;
Ok(loader.rollen.load_one(self.id).await?)
}
/// Die Gruppen des Benutzers
pub async fn gruppen<'ctx>(&self, ctx: &Context<'ctx>) -> FieldResult<Option<Vec<Gruppe>>> {
let loader = ctx.data::<LoaderContext>()?;
Ok(loader.gruppen.load_one(self.id).await?)
}
/// Die Gruppen eines Benutzer kumulativ mit den Gruppen aus den Rollen
pub async fn gruppen_kumulativ<'ctx>(
&self,
ctx: &Context<'ctx>,
) -> FieldResult<Option<Vec<GruppeAnsicht>>> {
let loader = ctx.data::<LoaderContext>()?;
Ok(loader.benutzer_gruppen_kumulativ.load_one(self.id).await?)
}
}

View File

@@ -0,0 +1,12 @@
use crate::scalar::Id;
use async_graphql::InputObject;
#[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>>,
}

View File

@@ -0,0 +1,18 @@
mod alle_benutzer;
pub mod create_benutzer;
pub mod find_gruppen;
#[derive(Debug, Clone)]
pub struct Repository {}
impl Repository {
pub fn new() -> Repository {
Repository {}
}
}
impl Default for Repository {
fn default() -> Self {
Self::new()
}
}

View File

@@ -0,0 +1,23 @@
use anyhow::Error;
use super::Repository;
use crate::database::Queryer;
use crate::domain::benutzer::model;
impl Repository {
pub async fn alle_benutzer<'c, C: Queryer<'c>>(
&self,
db: C,
) -> Result<Vec<model::Benutzer>, Error> {
const QUERY: &str = r#"
SELECT *
FROM benutzer
"#;
let benutzer = sqlx::query_as::<_, model::Benutzer>(QUERY)
.fetch_all(db)
.await?;
Ok(benutzer)
}
}

View File

@@ -0,0 +1,31 @@
use anyhow::Error;
use super::Repository;
use crate::database::Queryer;
use crate::domain::benutzer::entity;
use crate::domain::benutzer::model;
use crate::scalar::Id;
impl Repository {
pub async fn create_benutzer<'c, C: Queryer<'c>>(
&self,
db: C,
benutzer: &entity::Benutzer,
) -> Result<model::Benutzer, Error> {
const QUERY: &str = r#"
INSERT INTO benutzer (id, kennung, nachname, vorname)
VALUES ($1, $2, $3, $4)
RETURNING id, kennung, nachname, vorname;
"#;
let benutzer = sqlx::query_as::<_, model::Benutzer>(QUERY)
.bind::<Id>(benutzer.id)
.bind(&benutzer.kennung)
.bind(&benutzer.nachname)
.bind(&benutzer.vorname)
.fetch_one(db)
.await?;
Ok(benutzer)
}
}

View File

@@ -0,0 +1,40 @@
use anyhow::Error;
use async_graphql::Context;
use crate::domain::gruppe::model::Gruppe;
use super::Repository;
impl Repository {
pub async fn find_gruppen<'a>(&self, ctx: &'a Context<'_>) -> Result<Vec<Gruppe>, Error> {
// let rows = sqlx::query!(
// r#"
// SELECT
// bg.benutzer_id,
// g.id,
// g.gruppenname,
// g.erstellt_am
// LEFT JOIN benutzer_gruppen AS bg ON g.id = bg.gruppe_id
// WHERE bg.benutzer_id = ANY($1);
// "#,
// keys
// )
// .fetch_all(&self.pool)
// .await?
// .into_iter()
// .map(|row| {
// (
// row.benutzer_id,
// Gruppe {
// id: row.id,
// gruppenname: row.gruppenname,
// erstellt_am: row.erstellt_am,
// geaendert_am: row.geaendert_am,
// },
// )
// })
// .into_group_map();
// }
todo!()
}
}

View File

@@ -0,0 +1,18 @@
mod alle_benutzer;
pub mod create_benutzer;
use super::repository::Repository;
use crate::database::DB;
#[derive(Debug)]
pub struct Service {
repo: Repository,
pub db: DB,
}
impl Service {
pub fn new(db: DB) -> Self {
let repo = Repository::new();
Self { repo, db }
}
}

View File

@@ -0,0 +1,11 @@
use async_graphql::FieldResult;
use crate::domain::benutzer::model::Benutzer;
use super::Service;
impl Service {
pub async fn alle_benutzer(&self) -> FieldResult<Vec<Benutzer>> {
Ok(self.repo.alle_benutzer(&self.db).await?)
}
}

View File

@@ -0,0 +1,25 @@
use async_graphql::FieldResult;
use ulid::Ulid;
use crate::domain::benutzer::{
entity,
model::{Benutzer, BenutzerCreateInput},
};
use super::Service;
impl Service {
pub async fn create_benutzer(&self, input: BenutzerCreateInput) -> FieldResult<Benutzer> {
let benutzer_entity = entity::Benutzer {
id: Ulid::new().into(),
kennung: input.kennung,
nachname: input.nachname,
vorname: input.vorname,
};
Ok(self
.repo
.create_benutzer(&self.db, &benutzer_entity)
.await?)
}
}