Add REST endpoint for slot

This commit is contained in:
Simon Goller 2024-05-02 23:25:04 +02:00
parent 82e89baeeb
commit 8f378472ea
28 changed files with 1925 additions and 28 deletions

View file

@ -6,6 +6,8 @@ edition = "2021"
[dependencies]
async-trait = "0.1.80"
mockall = "0.12.1"
time = "0.3.36"
uuid = "1.8.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

8
service/src/clock.rs Normal file
View file

@ -0,0 +1,8 @@
use mockall::automock;
#[automock]
pub trait ClockService {
fn time_now(&self) -> time::Time;
fn date_now(&self) -> time::Date;
fn date_time_now(&self) -> time::PrimitiveDateTime;
}

View file

@ -2,8 +2,14 @@ use async_trait::async_trait;
use mockall::automock;
use std::{future::Future, sync::Arc};
use thiserror::Error;
use time::Date;
use time::Time;
use uuid::Uuid;
pub mod clock;
pub mod permission;
pub mod slot;
pub mod uuid_service;
pub use permission::MockPermissionService;
pub use permission::PermissionService;
@ -11,6 +17,11 @@ pub use permission::Privilege;
pub use permission::Role;
pub use permission::User;
#[derive(Debug, PartialEq, Eq)]
pub enum ValidationFailureItem {
ModificationNotAllowed(Arc<str>),
}
#[derive(Debug, Error)]
pub enum ServiceError {
#[error("Database query error: {0}")]
@ -18,6 +29,33 @@ pub enum ServiceError {
#[error("Forbidden")]
Forbidden,
#[error("Entity {0} aready exists")]
EntityAlreadyExists(Uuid),
#[error("Entity {0} not found")]
EntityNotFound(Uuid),
#[error("Entity {0} conflicts, expected version {1} but got {2}")]
EntityConflicts(Uuid, Uuid, Uuid),
#[error("Validation error: {0:?}")]
ValidationError(Arc<[ValidationFailureItem]>),
#[error("ID cannot be set on create")]
IdSetOnCreate,
#[error("Version cannot be set on create")]
VersionSetOnCreate,
#[error("Overlapping time range")]
OverlappingTimeRange,
#[error("Time order wrong. {0} must is not smaller or equal to {1}")]
TimeOrderWrong(Time, Time),
#[error("Date order wrong. {0} must is not smaller or equal to {1}")]
DateOrderWrong(Date, Date),
}
#[automock]

93
service/src/slot.rs Normal file
View file

@ -0,0 +1,93 @@
use async_trait::async_trait;
use mockall::automock;
use std::sync::Arc;
use uuid::Uuid;
use crate::ServiceError;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum DayOfWeek {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}
impl From<dao::slot::DayOfWeek> for DayOfWeek {
fn from(day_of_week: dao::slot::DayOfWeek) -> Self {
match day_of_week {
dao::slot::DayOfWeek::Monday => Self::Monday,
dao::slot::DayOfWeek::Tuesday => Self::Tuesday,
dao::slot::DayOfWeek::Wednesday => Self::Wednesday,
dao::slot::DayOfWeek::Thursday => Self::Thursday,
dao::slot::DayOfWeek::Friday => Self::Friday,
dao::slot::DayOfWeek::Saturday => Self::Saturday,
dao::slot::DayOfWeek::Sunday => Self::Sunday,
}
}
}
impl From<DayOfWeek> for dao::slot::DayOfWeek {
fn from(day_of_week: DayOfWeek) -> Self {
match day_of_week {
DayOfWeek::Monday => Self::Monday,
DayOfWeek::Tuesday => Self::Tuesday,
DayOfWeek::Wednesday => Self::Wednesday,
DayOfWeek::Thursday => Self::Thursday,
DayOfWeek::Friday => Self::Friday,
DayOfWeek::Saturday => Self::Saturday,
DayOfWeek::Sunday => Self::Sunday,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Slot {
pub id: Uuid,
pub day_of_week: DayOfWeek,
pub from: time::Time,
pub to: time::Time,
pub valid_from: time::Date,
pub valid_to: Option<time::Date>,
pub deleted: Option<time::PrimitiveDateTime>,
pub version: Uuid,
}
impl From<&dao::slot::SlotEntity> for Slot {
fn from(slot: &dao::slot::SlotEntity) -> Self {
Self {
id: slot.id,
day_of_week: slot.day_of_week.into(),
from: slot.from,
to: slot.to,
valid_from: slot.valid_from,
valid_to: slot.valid_to,
deleted: slot.deleted,
version: slot.version,
}
}
}
impl From<&Slot> for dao::slot::SlotEntity {
fn from(slot: &Slot) -> Self {
Self {
id: slot.id,
day_of_week: slot.day_of_week.into(),
from: slot.from,
to: slot.to,
valid_from: slot.valid_from,
valid_to: slot.valid_to,
deleted: slot.deleted,
version: slot.version,
}
}
}
#[automock]
#[async_trait]
pub trait SlotService {
async fn get_slots(&self) -> Result<Arc<[Slot]>, ServiceError>;
async fn get_slot(&self, id: &Uuid) -> Result<Slot, ServiceError>;
async fn create_slot(&self, slot: &Slot) -> Result<Slot, ServiceError>;
async fn delete_slot(&self, id: &Uuid) -> Result<(), ServiceError>;
async fn update_slot(&self, slot: &Slot) -> Result<(), ServiceError>;
}

View file

@ -0,0 +1,7 @@
use mockall::automock;
use uuid::Uuid;
#[automock]
pub trait UuidService {
fn new_uuid(&self, usage: &str) -> Uuid;
}