diff --git a/backend-services/feed-service/app/controllers/QuestionController.scala b/backend-services/feed-service/app/controllers/QuestionController.scala index 36c53a668b81229e7609a1fd5dd0bcb4e26f9ffa..9cb8c1c0b5cd5b50ac300046db7a175069270c57 100644 --- a/backend-services/feed-service/app/controllers/QuestionController.scala +++ b/backend-services/feed-service/app/controllers/QuestionController.scala @@ -64,17 +64,17 @@ class QuestionController @Inject()(val controllerComponents: ControllerComponent } /** - * Create an Action to delete a Question in the DB. + * Create an Action to disable a Question in the DB. */ - def deleteQuestion(questionId: String) = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] => - println("QuestionController:deleteQuestion") + def disableQuestion(questionId: String) = authenticatedUserAction { implicit request: AuthenticationRequest[AnyContent] => + println("QuestionController:disableQuestion") try { if (!ObjectId.isValid(questionId)) throw new InvalidQueryParameterException("Invalid query parameter ID format: questionId") - if (!request.isAdmin) throw new ForbiddenException("You must be an admin to delete a question.") + if (!request.isAdmin) throw new ForbiddenException("You must be an admin to disable a question.") - Question.deleteQuestionAsync(new ObjectId(questionId)) - Ok("Deleted question") + Question.disableQuestionAsync(new ObjectId(questionId)) + Ok("Disabled question") } catch { case _: TimeoutException => BadRequest("Request timed out") case ex: InvalidQueryParameterException => BadRequest(ex.getMessage()) diff --git a/backend-services/feed-service/app/models/Question.scala b/backend-services/feed-service/app/models/Question.scala index 58652c4531b63ea9bab27746e680a384c6806583..e4ea5254fe7b9767f9476cadb7bd11ab76e6a2ca 100644 --- a/backend-services/feed-service/app/models/Question.scala +++ b/backend-services/feed-service/app/models/Question.scala @@ -17,7 +17,7 @@ import org.bson.conversions.Bson import org.mongodb.scala.model.{Filters, Updates, Sorts} -import play.api.libs.json.{Json, JsValue, JsString, JsObject, JsNumber, JsArray} +import play.api.libs.json.{Json, JsValue, JsString, JsObject, JsNumber, JsBoolean, JsArray} import scala.math.BigDecimal import java.text.SimpleDateFormat @@ -26,6 +26,7 @@ case class Question ( id: Option[ObjectId], content: String, used: Integer, + disabled: Boolean, createdAt: Date, updatedAt: Date ) @@ -34,13 +35,13 @@ object Question { val questionRepo = new QuestionRepository() def getQuestionsAsync(timeout: Int = 4): Seq[Question] = { - val result: Future[Seq[Question]] = questionRepo.getAll(None, Some(Sorts.descending("createdAt")), None, None) + val result: Future[Seq[Question]] = questionRepo.getAll(Some(Filters.eq("disabled", false)), Some(Sorts.descending("createdAt")), None, None) Await.result[Seq[Question]](result, timeout.seconds) } def createQuestionAsync(content: String, timeout: Int = 4): Question = { val now: Date = Date.from(Instant.now()) - val question: Question = Question(None, content, 0, now, now) + val question: Question = Question(None, content, 0, false, now, now) val newQuestion = for { questionExists <- questionRepo.getAll(Some(Filters.eq("content", question.content)), None, None, None).map(_.isEmpty) @@ -51,10 +52,12 @@ object Question { Await.result[Question](newQuestion, timeout.seconds) } - def deleteQuestionAsync(questionId: ObjectId, timeout: Int = 4): Unit = { - val delete: Future[Unit] = questionRepo.deleteOne(questionId) - Await.result[Unit](delete, timeout.seconds) - } + def disableQuestionAsync(questionId: ObjectId, timeout: Int = 4): Unit = { + val update: Bson = Updates.set("disabled", true) + val disable: Future[Unit] = questionRepo.updateOne(questionId, Seq(update)) + + Await.result[Unit](disable, timeout.seconds) + } def getLeastUsed(): Future[Question] = { questionRepo.getFirst(None, Some(Sorts.ascending("used")), None).map((question: Option[Question]) => { @@ -80,6 +83,7 @@ object Question { "id" -> JsString(question.id.getOrElse("").toString()), "content" -> JsString(question.content), "used" -> JsNumber(BigDecimal(question.used)), + "disabled" -> JsBoolean(question.disabled), "createdAt" -> JsString(formattedCreatedAt), "updatedAt" -> JsString(formattedUpdatedAt) ) @@ -101,6 +105,7 @@ object Question { writer.writeStartDocument() writer.writeString("content", value.content) writer.writeInt32("used", value.used) + writer.writeBoolean("disabled", value.disabled) writer.writeDateTime("createdAt", value.createdAt.getTime()) writer.writeDateTime("updatedAt", value.updatedAt.getTime()) writer.writeEndDocument() @@ -111,6 +116,7 @@ object Question { val id = reader.readObjectId("_id") val content = reader.readString("content") val used = reader.readInt32("used") + val disabled = reader.readBoolean("disabled") val createdAt = reader.readDateTime("createdAt") val updatedAt = reader.readDateTime("updatedAt") reader.readEndDocument() @@ -118,7 +124,7 @@ object Question { val createdAtDate: Date = Date.from(Instant.ofEpochMilli(createdAt)) val updatedAtDate: Date = Date.from(Instant.ofEpochMilli(updatedAt)) - Question(Some(id), content, used, createdAtDate, updatedAtDate) + Question(Some(id), content, used, disabled, createdAtDate, updatedAtDate) } override def getEncoderClass: Class[Question] = classOf[Question] diff --git a/backend-services/feed-service/conf/routes b/backend-services/feed-service/conf/routes index c4d70c1b77ae33a4544848ef4dc890d73abea5fe..e8e358f46ce4e3fbfa7c553bdc99e431713c9710 100644 --- a/backend-services/feed-service/conf/routes +++ b/backend-services/feed-service/conf/routes @@ -31,6 +31,6 @@ GET /question controllers.DailyQuestionController.getDailyQues GET /questions controllers.QuestionController.getQuestions() -POST /question controllers.QuestionController.insertQuestion() +POST /insertQuestion controllers.QuestionController.insertQuestion() -DELETE /question controllers.QuestionController.deleteQuestion(questionId: String) +POST /disableQuestion controllers.QuestionController.disableQuestion(questionId: String)