-
Notifications
You must be signed in to change notification settings - Fork 15
[FEATURE] Feedback system #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 2 commits
8b3b0ef
d3a8b4a
2bf8d11
4f5d50e
f6955bd
bbfa273
6484a9f
40f7295
7bd426c
35943d2
4f46629
84a6534
a7643a5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,10 +8,11 @@ CREATE TABLE mod_feedback | |
| id SERIAL PRIMARY KEY NOT NULL, | ||
| mod_version_id INTEGER NOT NULL, | ||
| reviewer_id INTEGER NOT NULL, | ||
| feedback TEXT COLLATE pg_catalog."default" NOT NULL DEFAULT 'No feedback provided.'::text, | ||
| feedback TEXT COLLATE pg_catalog."default" NOT NULL, | ||
| decision BOOLEAN NOT NULL DEFAULT false, | ||
| type feedback_type NOT NULL, | ||
| CONSTRAINT mod_feedback_mod_id_reviewer_id_key UNIQUE (mod_version_id, reviewer_id), | ||
| dev bool NOT NULL DEFAULT false, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could get a little confusing, considering that "this person is a developer of this mod" is not constant. i'd rather this check be done during the sql query (like the admin field) instead of stored in the table
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah alr |
||
| created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| CONSTRAINT mod_feedback_mod_version_id_fkey FOREIGN KEY (mod_version_id) | ||
| REFERENCES public.mod_versions (id) | ||
| ON DELETE CASCADE, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,7 +14,6 @@ use crate::{ | |
| }; | ||
| use crate::types::models::mod_version::ModVersion; | ||
| use crate::types::models::mod_feedback::{ModFeedback,FeedbackTypeEnum}; | ||
| use crate::types::models::mod_version_status::ModVersionStatusEnum; | ||
|
|
||
| #[derive(Deserialize)] | ||
| pub struct GetModFeedbackPath { | ||
|
|
@@ -28,6 +27,11 @@ pub struct PostModFeedbackPayload { | |
| feedback: String, | ||
| } | ||
|
|
||
| #[derive(Deserialize)] | ||
| pub struct DeleteModFeedbackPayload { | ||
| id: i32 | ||
| } | ||
|
|
||
| #[get("/v1/mods/{id}/versions/{version}/feedback")] | ||
| pub async fn get_mod_feedback( | ||
| data: web::Data<AppData>, | ||
|
|
@@ -43,14 +47,11 @@ pub async fn get_mod_feedback( | |
| return Err(ApiError::Forbidden); | ||
| } | ||
|
|
||
| let mut note_only = false; | ||
| if !access && !dev.admin { | ||
| note_only = true; | ||
| } | ||
| let note_only = !access && !dev.admin; | ||
|
|
||
| let mod_version = { | ||
| if path.version == "latest" { | ||
| ModVersion::get_latest_for_mod(&path.id, None, vec![], None, vec![ModVersionStatusEnum::Accepted, ModVersionStatusEnum::Pending, ModVersionStatusEnum::Rejected, ModVersionStatusEnum::Unlisted], &mut pool).await? | ||
| ModVersion::get_latest_for_mod(&path.id, None, vec![], None, &mut pool).await? | ||
| } else { | ||
| ModVersion::get_one(path.id.strip_prefix('v').unwrap_or(&path.id), &path.version, false, false, &mut pool).await? | ||
| } | ||
|
|
@@ -85,19 +86,15 @@ pub async fn post_mod_feedback( | |
| return Err(ApiError::Forbidden); | ||
| } | ||
|
|
||
| if !access && payload.feedback_type == FeedbackTypeEnum::Note { | ||
| return Err(ApiError::BadRequest("Only mod owners can leave notes".to_string())); | ||
| } | ||
|
|
||
| let mod_version = { | ||
| if path.version == "latest" { | ||
| ModVersion::get_latest_for_mod(&path.id, None, vec![], None, vec![ModVersionStatusEnum::Accepted, ModVersionStatusEnum::Pending, ModVersionStatusEnum::Rejected, ModVersionStatusEnum::Unlisted], &mut transaction).await? | ||
| ModVersion::get_latest_for_mod(&path.id, None, vec![], None, &mut transaction).await? | ||
| } else { | ||
| ModVersion::get_one(path.id.strip_prefix('v').unwrap_or(&path.id), &path.version, false, false, &mut transaction).await? | ||
| } | ||
| }; | ||
|
|
||
| let result = ModFeedback::set(&mod_version, dev.id, payload.feedback_type.clone(), &payload.feedback, false, &mut transaction).await; | ||
| let result = ModFeedback::set(&mod_version, dev.id, payload.feedback_type.clone(), &payload.feedback, false, access, &mut transaction).await; | ||
|
|
||
| if result.is_err() { | ||
| transaction | ||
|
|
@@ -112,34 +109,31 @@ pub async fn post_mod_feedback( | |
| .await | ||
| .or(Err(ApiError::TransactionError))?; | ||
|
|
||
| Ok(HttpResponse::NoContent()) | ||
| Ok(web::Json(ApiResponse { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this behavior is somewhat inconsistent considering the rest of the post endpoints don't do this, but i can see why you did it. i'll probably think about it further
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, i'll leave it as it is rn then
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. on second thought, nocontent is probably the generally the best move
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how would you get the id? through the GET endpoint?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ye, i think if the get feedback returns the author's feedback as well, then it makes it easy to associate feedback with the id on the client (so they can delete) i wouldn't assume people are storing the id locally anyways
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
| error: "".to_string(), | ||
| payload: result?, | ||
| })) | ||
| } | ||
|
|
||
| #[delete("/v1/mods/{id}/versions/{version}/feedback")] | ||
| pub async fn delete_mod_feedback( | ||
| data: web::Data<AppData>, | ||
| path: web::Path<GetModFeedbackPath>, | ||
| payload: web::Json<DeleteModFeedbackPayload>, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of payload, put the id as part of the path: this is more consistent with the rest of the api and also consistent with what a delete request is
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah ok |
||
| auth: Auth, | ||
| ) -> Result<impl Responder, ApiError> { | ||
| let dev = auth.developer()?; | ||
| let mut pool = data.db.acquire().await.or(Err(ApiError::DbAcquireError))?; | ||
| let mut transaction = pool.begin().await.or(Err(ApiError::TransactionError))?; | ||
|
|
||
| let access = Developer::has_access_to_mod(dev.id, &path.id, &mut transaction).await?; | ||
|
|
||
| if !access && !dev.verified && !dev.admin { | ||
| return Err(ApiError::Forbidden); | ||
| } | ||
|
|
||
| let mod_version = { | ||
| if path.version == "latest" { | ||
| ModVersion::get_latest_for_mod(&path.id, None, vec![], None, vec![ModVersionStatusEnum::Accepted, ModVersionStatusEnum::Pending, ModVersionStatusEnum::Rejected, ModVersionStatusEnum::Unlisted], &mut transaction).await? | ||
| } else { | ||
| ModVersion::get_one(path.id.strip_prefix('v').unwrap_or(&path.id), &path.version, false, false, &mut transaction).await? | ||
| if !dev.admin { | ||
| let feedback = ModFeedback::get_feedback_by_id(payload.id, &mut transaction).await?; | ||
| if feedback.reviewer.id != dev.id { | ||
| return Err(ApiError::Forbidden); | ||
| } | ||
| }; | ||
| } | ||
|
|
||
| let result = ModFeedback::remove(&mod_version, dev.id, &mut transaction).await; | ||
| let result = ModFeedback::remove(payload.id, &mut transaction).await; | ||
|
|
||
| if result.is_err() { | ||
| transaction | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.