- 
                Notifications
    You must be signed in to change notification settings 
- Fork 9
[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, | ||
| 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 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 { | ||
| 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 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 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 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? 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 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>, | ||
| 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 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.