Merge pull request 'start replacing activitybuilder' (#1015) from acitvities-adaption into main

Reviewed-on: Ruderverein-Donau-Linz/rowt#1015
This commit is contained in:
philipp 2025-05-12 23:09:46 +02:00
commit edcdc74c1c
3 changed files with 56 additions and 37 deletions

View File

@ -1,6 +1,9 @@
use std::ops::DerefMut; use std::ops::DerefMut;
use super::{role::Role, user::User}; use super::{
role::Role,
user::{ManageUserUser, User},
};
use chrono::{DateTime, Duration, Local, NaiveDateTime, TimeZone, Utc}; use chrono::{DateTime, Duration, Local, NaiveDateTime, TimeZone, Utc};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
@ -14,6 +17,29 @@ pub struct Activity {
pub keep_until: Option<NaiveDateTime>, pub keep_until: Option<NaiveDateTime>,
} }
pub enum Reason<'a> {
// `User` tried to login with `String` as UserAgent
SuccLogin(&'a User, String),
// `User` changed the data of `User`, explanation in `String`
UserDataChange(&'a ManageUserUser, &'a User, String),
}
impl From<Reason<'_>> for ActivityBuilder {
fn from(value: Reason<'_>) -> Self {
match value {
Reason::SuccLogin(user, agent) => {
Self::new(&format!("{user} hat sich eingeloggt (User-Agent: {agent})"))
.relevant_for_user(user)
.keep_until_days(7)
}
Reason::UserDataChange(changed_by, changed_user, explanation) => Self::new(&format!(
"{changed_by} hat die Daten von {changed_user} aktualisiert: {explanation}"
))
.relevant_for_user(changed_user),
}
}
}
pub struct ActivityBuilder { pub struct ActivityBuilder {
text: String, text: String,
relevant_for: String, relevant_for: String,
@ -21,6 +47,7 @@ pub struct ActivityBuilder {
} }
impl ActivityBuilder { impl ActivityBuilder {
/// TODO: maybe make this private, and only allow specific acitivites defined in `Reason`
#[must_use] #[must_use]
pub fn new(text: &str) -> Self { pub fn new(text: &str) -> Self {
Self { Self {

View File

@ -2,7 +2,10 @@
use super::{AllowedToEditPaymentStatusUser, ManageUserUser, User}; use super::{AllowedToEditPaymentStatusUser, ManageUserUser, User};
use crate::model::{ use crate::model::{
activity::ActivityBuilder, family::Family, mail::valid_mails, notification::Notification, activity::{self, ActivityBuilder},
family::Family,
mail::valid_mails,
notification::Notification,
role::Role, role::Role,
}; };
use chrono::NaiveDate; use chrono::NaiveDate;
@ -19,8 +22,11 @@ impl User {
) -> Result<(), String> { ) -> Result<(), String> {
let note = note.trim(); let note = note.trim();
ActivityBuilder::new(&format!("({updated_by}) {note}")) ActivityBuilder::from(activity::Reason::UserDataChange(
.relevant_for_user(user) updated_by,
self,
format!("Neue Notizen: {note}"),
))
.save(db) .save(db)
.await; .await;
@ -47,18 +53,11 @@ impl User {
.unwrap(); //Okay, because we can only create a User of a valid id .unwrap(); //Okay, because we can only create a User of a valid id
let msg = match &self.mail { let msg = match &self.mail {
Some(old_mail) => { Some(old_mail) => format!("Mail-Adresse von {old_mail} auf {new_mail} geändert."),
format!( None => format!("Neue Mail-Adresse für: {new_mail}"),
"{updated_by} hat die Mail-Adresse von {self} von {old_mail} auf {new_mail} geändert."
)
}
None => {
format!("{updated_by} eine neue Mail-Adresse für {self} hinzugefügt: {new_mail}")
}
}; };
ActivityBuilder::new(&msg) ActivityBuilder::from(activity::Reason::UserDataChange(updated_by, self, msg))
.relevant_for_user(self)
.save(db) .save(db)
.await; .await;
@ -89,19 +88,16 @@ impl User {
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
let msg = match &self.phone { let msg = match &self.phone {
Some(old_phone) if new_phone.is_empty() => format!( Some(old_phone) if new_phone.is_empty() => {
"{updated_by} hat die Telefonnummer von {self} entfernt (alte Nummer: {old_phone})" format!("Telefonnummer wurde entfernt (alte Nummer: {old_phone})")
), }
Some(old_phone) => format!( Some(old_phone) => {
"{updated_by} hat die Telefonnummer von {self} von {old_phone} auf {new_phone} geändert." format!("Telefonnummer wurde von {old_phone} auf {new_phone} geändert.")
), }
None => format!( None => format!("Neue Telefonnummer hinzugefügt: {new_phone}"),
"{updated_by} hat eine neue Telefonnummer für {self} hinzugefügt: {new_phone}"
),
}; };
ActivityBuilder::new(&msg) ActivityBuilder::from(activity::Reason::UserDataChange(updated_by, self, msg))
.relevant_for_user(self)
.save(db) .save(db)
.await; .await;
} }

View File

@ -1,5 +1,4 @@
use rocket::{ use rocket::{
FromForm, Request, Route, State,
form::Form, form::Form,
get, get,
http::{Cookie, CookieJar}, http::{Cookie, CookieJar},
@ -9,12 +8,13 @@ use rocket::{
response::{Flash, Redirect}, response::{Flash, Redirect},
routes, routes,
time::{Duration, OffsetDateTime}, time::{Duration, OffsetDateTime},
FromForm, Request, Route, State,
}; };
use rocket_dyn_templates::{Template, context, tera}; use rocket_dyn_templates::{context, tera, Template};
use sqlx::SqlitePool; use sqlx::SqlitePool;
use crate::model::{ use crate::model::{
activity::ActivityBuilder, activity::{self, ActivityBuilder},
log::Log, log::Log,
user::{LoginError, User}, user::{LoginError, User},
}; };
@ -83,11 +83,7 @@ async fn login(
cookies.add_private(Cookie::new("loggedin_user", format!("{}", user.id))); cookies.add_private(Cookie::new("loggedin_user", format!("{}", user.id)));
ActivityBuilder::new(&format!( ActivityBuilder::from(activity::Reason::SuccLogin(&user, agent.0))
"{user} hat sich eingeloggt (User-Agent: {})",
agent.0
))
.relevant_for_user(&user)
.save(db) .save(db)
.await; .await;