diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2025-02-01 22:52:56 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2025-02-01 22:52:56 +0100 |
| commit | 85e6c3ae1f4315138bbd68feb5bb7cebc24f6ae2 (patch) | |
| tree | bcaf27055e35c4335f99e68e70e2eb46ede9745e | |
| parent | d780391408b9e6d443e5e4f907748cae484b79fb (diff) | |
Include branch in project/reviews response
But also add /review endpoint that takes an id. So you can get
review data with either the reviewid or the branchname.
| -rw-r--r-- | server/.sqlx/query-0d7020607f7137538a3526e9e4cee127079adc31aa21ab57ff8038b20fac5785.json (renamed from server/.sqlx/query-956140cf5bb8421762ee55e7ab7ce179eac7fb43ee9fb4a0c35ef3792a2df831.json) | 19 | ||||
| -rw-r--r-- | server/.sqlx/query-5566324138b5b05c369f70857d3d92603401f76dd5962159892a720537c96136.json | 113 | ||||
| -rw-r--r-- | server/.sqlx/query-666dec12f7177008c84cc15417e21be7ca6f63741e45928fba9f58915e6975e8.json (renamed from server/.sqlx/query-3864a730b1bcee1f511748360f92af157f36f3d92a667c0adc06c100cc495c67.json) | 21 | ||||
| -rw-r--r-- | server/src/api_model.rs | 2 | ||||
| -rw-r--r-- | server/src/main.rs | 124 |
5 files changed, 229 insertions, 50 deletions
diff --git a/server/.sqlx/query-956140cf5bb8421762ee55e7ab7ce179eac7fb43ee9fb4a0c35ef3792a2df831.json b/server/.sqlx/query-0d7020607f7137538a3526e9e4cee127079adc31aa21ab57ff8038b20fac5785.json index 22a6d40..8f0fda3 100644 --- a/server/.sqlx/query-956140cf5bb8421762ee55e7ab7ce179eac7fb43ee9fb4a0c35ef3792a2df831.json +++ b/server/.sqlx/query-0d7020607f7137538a3526e9e4cee127079adc31aa21ab57ff8038b20fac5785.json @@ -1,6 +1,6 @@ { "db_name": "MySQL", - "query": "SELECT reviews.id AS id,title,state,progress,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? ORDER BY id DESC LIMIT ? OFFSET ?", + "query": "SELECT reviews.id AS id,title,state,progress,branch,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? ORDER BY id DESC LIMIT ? OFFSET ?", "describe": { "columns": [ { @@ -45,6 +45,16 @@ }, { "ordinal": 4, + "name": "branch", + "type_info": { + "type": "VarString", + "flags": "NOT_NULL | NO_DEFAULT_VALUE", + "char_set": 224, + "max_size": 4096 + } + }, + { + "ordinal": 5, "name": "user_id", "type_info": { "type": "VarString", @@ -54,7 +64,7 @@ } }, { - "ordinal": 5, + "ordinal": 6, "name": "name", "type_info": { "type": "VarString", @@ -64,7 +74,7 @@ } }, { - "ordinal": 6, + "ordinal": 7, "name": "user_dn", "type_info": { "type": "VarString", @@ -84,8 +94,9 @@ false, false, false, + false, true ] }, - "hash": "956140cf5bb8421762ee55e7ab7ce179eac7fb43ee9fb4a0c35ef3792a2df831" + "hash": "0d7020607f7137538a3526e9e4cee127079adc31aa21ab57ff8038b20fac5785" } diff --git a/server/.sqlx/query-5566324138b5b05c369f70857d3d92603401f76dd5962159892a720537c96136.json b/server/.sqlx/query-5566324138b5b05c369f70857d3d92603401f76dd5962159892a720537c96136.json new file mode 100644 index 0000000..df62083 --- /dev/null +++ b/server/.sqlx/query-5566324138b5b05c369f70857d3d92603401f76dd5962159892a720537c96136.json @@ -0,0 +1,113 @@ +{ + "db_name": "MySQL", + "query": "SELECT title,description,state,progress,branch,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND reviews.id=?", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "title", + "type_info": { + "type": "VarString", + "flags": "NOT_NULL | NO_DEFAULT_VALUE", + "char_set": 224, + "max_size": 4096 + } + }, + { + "ordinal": 1, + "name": "description", + "type_info": { + "type": "Blob", + "flags": "NOT_NULL | BLOB", + "char_set": 224, + "max_size": 67108860 + } + }, + { + "ordinal": 2, + "name": "state", + "type_info": { + "type": "Tiny", + "flags": "NOT_NULL | UNSIGNED", + "char_set": 63, + "max_size": 3 + } + }, + { + "ordinal": 3, + "name": "progress", + "type_info": { + "type": "Float", + "flags": "NOT_NULL", + "char_set": 63, + "max_size": 12 + } + }, + { + "ordinal": 4, + "name": "branch", + "type_info": { + "type": "VarString", + "flags": "NOT_NULL | NO_DEFAULT_VALUE", + "char_set": 224, + "max_size": 4096 + } + }, + { + "ordinal": 5, + "name": "archived", + "type_info": { + "type": "Tiny", + "flags": "NOT_NULL", + "char_set": 63, + "max_size": 1 + } + }, + { + "ordinal": 6, + "name": "user_id", + "type_info": { + "type": "VarString", + "flags": "NOT_NULL | PRIMARY_KEY | NO_DEFAULT_VALUE", + "char_set": 224, + "max_size": 512 + } + }, + { + "ordinal": 7, + "name": "name", + "type_info": { + "type": "VarString", + "flags": "NOT_NULL", + "char_set": 224, + "max_size": 4096 + } + }, + { + "ordinal": 8, + "name": "user_dn", + "type_info": { + "type": "VarString", + "flags": "", + "char_set": 224, + "max_size": 1024 + } + } + ], + "parameters": { + "Right": 2 + }, + "nullable": [ + false, + false, + false, + false, + false, + false, + false, + false, + true + ] + }, + "hash": "5566324138b5b05c369f70857d3d92603401f76dd5962159892a720537c96136" +} diff --git a/server/.sqlx/query-3864a730b1bcee1f511748360f92af157f36f3d92a667c0adc06c100cc495c67.json b/server/.sqlx/query-666dec12f7177008c84cc15417e21be7ca6f63741e45928fba9f58915e6975e8.json index e277262..2ebdede 100644 --- a/server/.sqlx/query-3864a730b1bcee1f511748360f92af157f36f3d92a667c0adc06c100cc495c67.json +++ b/server/.sqlx/query-666dec12f7177008c84cc15417e21be7ca6f63741e45928fba9f58915e6975e8.json @@ -1,6 +1,6 @@ { "db_name": "MySQL", - "query": "SELECT reviews.id AS id,title,description,state,progress,branch,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND branch=?", + "query": "SELECT reviews.id AS id,title,description,state,progress,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND branch=?", "describe": { "columns": [ { @@ -55,16 +55,6 @@ }, { "ordinal": 5, - "name": "branch", - "type_info": { - "type": "VarString", - "flags": "NOT_NULL | NO_DEFAULT_VALUE", - "char_set": 224, - "max_size": 4096 - } - }, - { - "ordinal": 6, "name": "archived", "type_info": { "type": "Tiny", @@ -74,7 +64,7 @@ } }, { - "ordinal": 7, + "ordinal": 6, "name": "user_id", "type_info": { "type": "VarString", @@ -84,7 +74,7 @@ } }, { - "ordinal": 8, + "ordinal": 7, "name": "name", "type_info": { "type": "VarString", @@ -94,7 +84,7 @@ } }, { - "ordinal": 9, + "ordinal": 8, "name": "user_dn", "type_info": { "type": "VarString", @@ -116,9 +106,8 @@ false, false, false, - false, true ] }, - "hash": "3864a730b1bcee1f511748360f92af157f36f3d92a667c0adc06c100cc495c67" + "hash": "666dec12f7177008c84cc15417e21be7ca6f63741e45928fba9f58915e6975e8" } diff --git a/server/src/api_model.rs b/server/src/api_model.rs index f062935..dbb42d8 100644 --- a/server/src/api_model.rs +++ b/server/src/api_model.rs @@ -111,6 +111,8 @@ pub struct ReviewEntry { pub state: ReviewState, #[schema(example = 37.5)] pub progress: f32, + #[schema(example = "r/user/TASK-123456")] + pub branch: String, } #[derive(Deserialize, Serialize, ToSchema)] diff --git a/server/src/main.rs b/server/src/main.rs index b2974ac..019f28f 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -45,6 +45,7 @@ struct Db(sqlx::MySqlPool); project_user_del, reviews, review, + review_id, users, user_key_add, user_key_get, @@ -460,7 +461,7 @@ async fn reviews( let uw_offset = offset.unwrap_or(0); let uw_limit = limit.unwrap_or(10); let entries = sqlx::query!( - "SELECT reviews.id AS id,title,state,progress,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? ORDER BY id DESC LIMIT ? OFFSET ?", + "SELECT reviews.id AS id,title,state,progress,branch,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? ORDER BY id DESC LIMIT ? OFFSET ?", projectid, uw_limit, uw_offset) .fetch(&mut **db) .map_ok(|r| api_model::ReviewEntry { @@ -473,6 +474,7 @@ async fn reviews( }, state: api_model::ReviewState::try_from(r.state).unwrap(), progress: r.progress, + branch: r.branch, }) .try_collect::<Vec<_>>() .await @@ -512,35 +514,11 @@ async fn reviews( })) } -async fn get_review_from_branch( +async fn get_review_users( mut db: Connection<Db>, projectid: &str, - branch: &str, -) -> Result<Json<api_model::Review>, NotFound<&'static str>> { - let mut review = sqlx::query!( - "SELECT reviews.id AS id,title,description,state,progress,branch,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND branch=?", - projectid, branch) - .fetch_one(&mut **db) - .map_ok(|r| { - api_model::Review { - id: r.id, - title: r.title, - description: r.description, - owner: api_model::User { - id: r.user_id, - name: r.name, - active: r.user_dn.is_some(), - }, - users: Vec::new(), - state: api_model::ReviewState::try_from(r.state).unwrap(), - progress: r.progress, - branch: r.branch, - archived: r.archived != 0, - } - }) - .map_err(|_| NotFound("No such review")) - .await?; - + reviewid: u64, +) -> Vec<api_model::ReviewUserEntry> { let mut users = sqlx::query!( "SELECT id,name,dn,project_users.default_role AS role FROM users JOIN project_users ON project_users.user=id WHERE project_users.project=? ORDER BY role,id", projectid) @@ -559,7 +537,7 @@ async fn get_review_from_branch( let override_users = sqlx::query!( "SELECT id,name,dn,review_users.role AS role FROM users JOIN review_users ON review_users.user=id WHERE review_users.review=? ORDER BY role,id", - review.id) + reviewid) .fetch(&mut **db) .map_ok(|r| api_model::ReviewUserEntry { user: api_model::User { @@ -584,7 +562,73 @@ async fn get_review_from_branch( } } - review.users = users; + users +} + +async fn get_review_from_branch( + mut db: Connection<Db>, + projectid: &str, + branch: &str, +) -> Result<Json<api_model::Review>, NotFound<&'static str>> { + let mut review = sqlx::query!( + "SELECT reviews.id AS id,title,description,state,progress,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND branch=?", + projectid, branch) + .fetch_one(&mut **db) + .map_ok(|r| { + api_model::Review { + id: r.id, + title: r.title, + description: r.description, + owner: api_model::User { + id: r.user_id, + name: r.name, + active: r.user_dn.is_some(), + }, + users: Vec::new(), + state: api_model::ReviewState::try_from(r.state).unwrap(), + progress: r.progress, + branch: branch.to_string(), + archived: r.archived != 0, + } + }) + .map_err(|_| NotFound("No such review")) + .await?; + + review.users = get_review_users(db, projectid, review.id).await; + + Ok(Json(review)) +} + +async fn get_review_from_id( + mut db: Connection<Db>, + projectid: &str, + reviewid: u64, +) -> Result<Json<api_model::Review>, NotFound<&'static str>> { + let mut review = sqlx::query!( + "SELECT title,description,state,progress,branch,archived,users.id AS user_id,users.name AS name,users.dn AS user_dn FROM reviews JOIN users ON users.id=owner WHERE project=? AND reviews.id=?", + projectid, reviewid) + .fetch_one(&mut **db) + .map_ok(|r| { + api_model::Review { + id: reviewid, + title: r.title, + description: r.description, + owner: api_model::User { + id: r.user_id, + name: r.name, + active: r.user_dn.is_some(), + }, + users: Vec::new(), + state: api_model::ReviewState::try_from(r.state).unwrap(), + progress: r.progress, + branch: r.branch, + archived: r.archived != 0, + } + }) + .map_err(|_| NotFound("No such review")) + .await?; + + review.users = get_review_users(db, projectid, reviewid).await; Ok(Json(review)) } @@ -621,6 +665,25 @@ async fn review_encoded_path( #[utoipa::path( responses( + (status = 200, description = "Get review", body = api_model::Review), + (status = 404, description = "No such review"), + ), + security( + ("session" = []), + ), +)] +#[get("/review/<projectid>?<reviewid>")] +async fn review_id( + db: Connection<Db>, + _session: auth::Session, + projectid: &str, + reviewid: u64, +) -> Result<Json<api_model::Review>, NotFound<&'static str>> { + get_review_from_id(db, projectid, reviewid).await +} + +#[utoipa::path( + responses( (status = 200, description = "Get all users", body = api_model::Users), ), security( @@ -879,6 +942,7 @@ fn rocket_from_config(figment: Figment) -> Rocket<Build> { reviews, review, review_encoded_path, + review_id, users, user_key_add, user_key_get, |
