diff --git a/crates/back/src/api/course.rs b/crates/back/src/api/course.rs index cf07e39f89433a9f66395623afd0268e0c8cb0d7..64df61dcc47e77de61edafc6d352bf2403ee3e80 100644 --- a/crates/back/src/api/course.rs +++ b/crates/back/src/api/course.rs @@ -58,6 +58,25 @@ pub struct Course { pub points_max: u32, } +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NewCourse { + /// Uuid for this course + #[schema(example = "c52de49c-5dba-4820-bf64-0da20f9f339f")] + pub id: Uuid, + + /// Name of the course + #[schema(example = "Project IV")] + pub name: String, + + /// Description for the course + #[schema(example = "Project IV description")] + pub description: Option<String>, + + /// Max points for the course + #[schema(example = 40)] + pub points_max: u32, +} + // #[cfg(test)] diff --git a/crates/back/src/api/courses.rs b/crates/back/src/api/courses.rs index b85fbf70ea478884cf363cb59ac5e61c568cef5a..1ad10ecbfcb06219cd02f6247455c6da65181f27 100644 --- a/crates/back/src/api/courses.rs +++ b/crates/back/src/api/courses.rs @@ -1,10 +1,12 @@ use crate::db::Database; use actix_web::{ dev::HttpServiceFactory, - web::{self, Data}, + web::{self, Data, Json}, HttpResponse, }; +use super::course::NewCourse; + // pub fn api() -> impl HttpServiceFactory { @@ -31,7 +33,14 @@ async fn get(db: Data<Database>) -> HttpResponse { } } -async fn post() -> HttpResponse { +/// Add a new course +#[utoipa::path( + post, + path = "/api/courses", + responses((status = CREATED, description = "Add a new course", body = Uuid)), +)] +async fn post(Json(course): Json<NewCourse>) -> HttpResponse { + course; HttpResponse::Ok().json("aaa") } diff --git a/crates/back/src/db/any.rs b/crates/back/src/db/any.rs index 7c0528f61e181b900301c4ee206bcd79b6c4fbc4..c731813eb2c71a58ca76670961f568190c2a7ef3 100644 --- a/crates/back/src/db/any.rs +++ b/crates/back/src/db/any.rs @@ -3,7 +3,7 @@ use std::mem::transmute; use super::{embedded, postgres, DbCreateUser, DbError, DbResult, DbUser}; use crate::{ api::{ - course::Course, + course::{Course, NewCourse}, exercise::{Exercise, ExerciseDetail, ExerciseVerifyData}, lesson::Lesson, }, @@ -147,6 +147,10 @@ impl AnyDatabase { gen_match!(self, get_courses()) } + pub async fn add_course(&self, course: NewCourse) -> DbResult<()> { + gen_match!(self, add_course(course)) + } + pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> { gen_match!(self, get_lessons(course)) } diff --git a/crates/back/src/db/mod.rs b/crates/back/src/db/mod.rs index 1d9bb92670a59723255a1da8f3455460d91a24e0..eb61bb1909df97b9626a9623b5f4d454493d0c5c 100644 --- a/crates/back/src/db/mod.rs +++ b/crates/back/src/db/mod.rs @@ -1,7 +1,7 @@ use self::any::AnyDatabase; use crate::{ api::{ - course::Course, + course::{Course, NewCourse}, exercise::{Exercise, ExerciseDetail, ExerciseVerifyData}, lesson::Lesson, }, @@ -82,6 +82,10 @@ impl Database { self.db().await.get_courses().await } + pub async fn add_course(&self, course: NewCourse) -> DbResult<()> { + self.db().await.add_course(course).await + } + pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> { self.db().await.get_lessons(course).await } diff --git a/crates/back/src/db/postgres.rs b/crates/back/src/db/postgres.rs index a00d642ac091b1312d53007b5ec5b0e0fbc11fc2..57a2f63568167415c278ccbf492e559331469bc0 100644 --- a/crates/back/src/db/postgres.rs +++ b/crates/back/src/db/postgres.rs @@ -1,6 +1,6 @@ use super::{DbCreateUser, DbError, DbResult, DbUser}; use crate::api::{ - course::Course, + course::{Course, NewCourse}, exercise::{Exercise, ExerciseDetail, ExerciseVerifyData}, lesson::Lesson, }; @@ -53,6 +53,20 @@ impl Database { .collect()) } + pub async fn add_course(&self, course: NewCourse) -> DbResult<Uuid> { + Ok(sqlx::query_as::<_, (Uuid,)>( + r#"INSERT INTO + courses (name, description, points_max) + VALUES + ($1, $2, $3) + RETURNING + id"#, + ) + .fetch_one(&self.pool) + .await? + .0) + } + pub async fn get_lessons(&self, course: Uuid) -> DbResult<Vec<Lesson>> { Ok(sqlx::query_as( r#"SELECT @@ -165,7 +179,7 @@ impl Database { r#"INSERT INTO users (username, password) VALUES - ($2, $3); + ($2, $3) ON CONFLICT DO NOTHING RETURNING