Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion apps/rule-manager/app/AppComponents.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import play.api.ApplicationLoader.Context
import play.filters.HttpFiltersComponents
import play.api.BuiltInComponentsFromContext
import play.api.libs.ws.ahc.AhcWSComponents
import controllers.{AssetsComponents, HomeController, RulesController, TagsController}
import controllers.{
AssetsComponents,
HomeController,
RulesController,
TagsController,
UserFeedbackController
}
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider
Expand Down Expand Up @@ -81,11 +87,17 @@ class AppComponents(
config
)

val userFeedbackController = new UserFeedbackController(
controllerComponents,
config
)

lazy val router = new Routes(
httpErrorHandler,
homeController,
rulesController,
tagsController,
userFeedbackController,
assets
)
}
9 changes: 4 additions & 5 deletions apps/rule-manager/app/controllers/RulesController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import play.api.libs.json.{JsValue, Json}
import db.DbRuleDraft
import model.{BatchUpdateRuleForm, CreateRuleForm, PublishRuleForm, UpdateRuleForm}
import play.api.mvc._
import service.RuleManager.revertDraftRule
import service.{DictionaryResource, RuleManager, RuleTesting, SheetsRuleResource, TestRuleCapiQuery}
import utils.{FormErrorEnvelope, FormHelpers, PermissionsHandler, RuleManagerConfig}

Expand Down Expand Up @@ -100,7 +99,7 @@ class RulesController(
.fold(
form => BadRequest(Json.toJson(FormErrorEnvelope(form.errors))),
reason => {
DbRuleDraft.find(id) match {
DbRuleDraft.findById(id) match {
case None => NotFound
case _ =>
RuleManager
Expand Down Expand Up @@ -239,7 +238,7 @@ class RulesController(
hasPermission(request.user, PermissionDefinition("manage_rules", "typerighter")) match {
case false => Unauthorized("You don't have permission to edit rules")
case true =>
revertDraftRule(id, request.user.email) match {
RuleManager.revertDraftRule(id, request.user.email) match {
case Left(throwable) => InternalServerError(throwable.getMessage)
case Right(data) => Ok(Json.toJson(data))
}
Expand All @@ -249,7 +248,7 @@ class RulesController(
def testWithBlock(id: Int) = APIAuthAction[JsValue](parse.json).async { implicit request =>
request.body.validate[Document].asEither match {
case Right(document) =>
DbRuleDraft.find(id) match {
DbRuleDraft.findById(id) match {
case Some(rule) =>
ruleTesting
.testRule(rule, List(document))
Expand All @@ -269,7 +268,7 @@ class RulesController(
def testWithCapiQuery(id: Int) = APIAuthAction[JsValue](parse.json) { implicit request =>
request.body.validate[TestRuleCapiQuery].asEither match {
case Right(query) =>
DbRuleDraft.find(id) match {
DbRuleDraft.findById(id) match {
case Some(rule) =>
val matchStream = ruleTesting.testRuleWithCapiQuery(rule, query)
Ok.chunked(matchStream.map(record => JsonHelpers.toJsonSeq(record)))
Expand Down
38 changes: 38 additions & 0 deletions apps/rule-manager/app/controllers/UserFeedbackController.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package controllers

import com.gu.typerighter.controllers.PandaAuthController
import db.{UserFeedback => DbUserFeedback}
import models.{UserFeedback, UserFeedbackWithEmail}
import play.api.libs.json.Json
import play.api.mvc._
import utils.{FormHelpers, RuleManagerConfig}

import scala.util.{Failure, Success}

class UserFeedbackController(
controllerComponents: ControllerComponents,
val config: RuleManagerConfig
) extends PandaAuthController(controllerComponents, config)
with FormHelpers {

def create = APIAuthAction { implicit request =>
UserFeedback.form
.bindFromRequest()
.fold(
formWithErrors => {
BadRequest(Json.toJson(formWithErrors.errors))
},
userFeedback => {
val feedbackWithAuth =
UserFeedbackWithEmail.fromUserFeedback(userFeedback, request.user.email)
DbUserFeedback.create(
feedbackWithAuth
) match {
case Success(created) => Ok(Json.toJson(created))
case Failure(e) =>
InternalServerError(s"Failed to create user feedback: ${e.getMessage}")
}
}
)
}
}
82 changes: 69 additions & 13 deletions apps/rule-manager/app/db/DbRuleDraft.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ case class DbRuleDraft(
isPublished: Boolean,
isArchived: Boolean,
ruleOrder: Int,
hasUnpublishedChanges: Boolean
hasUnpublishedChanges: Boolean,
feedbackCount: Int = 0
) extends DbRuleCommon {

def toLive(reason: String, isActive: Boolean = false): DbRuleLive = {
Expand Down Expand Up @@ -102,7 +103,8 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
isPublished = rs.boolean("is_published"),
isArchived = rs.boolean("is_archived"),
ruleOrder = rs.int("rule_order"),
hasUnpublishedChanges = rs.boolean("has_unpublished_changes")
hasUnpublishedChanges = rs.boolean("has_unpublished_changes"),
feedbackCount = rs.int("feedback_count")
)
}

Expand Down Expand Up @@ -151,7 +153,8 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
isPublished = false,
isArchived = false,
ruleOrder = ruleOrder,
hasUnpublishedChanges = false
hasUnpublishedChanges = false,
feedbackCount = 0
)
}

Expand All @@ -167,15 +170,24 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
val hasUnpublishedChangesColumn =
sqls"(${rl.revisionId} IS NOT NULL AND ${rl.revisionId} < ${rd.revisionId}) AS has_unpublished_changes"

val feedbackCountColumn =
sqls"(SELECT COUNT(*) FROM user_feedback WHERE user_feedback.rule_id = ${rd.id})::int AS feedback_count"

val draftRuleColumns = SQLSyntax.createUnsafely(
rd.columns.filter(_.value != "tags").map(c => s"${rd.tableAliasName}.${c.value}").mkString(", ")
)

override val autoSession = AutoSession

def find(id: Int)(implicit session: DBSession = autoSession): Option[DbRuleDraft] = {
def findById(id: Int)(implicit session: DBSession = autoSession): Option[DbRuleDraft] = {
withSQL {
select(draftRuleColumns, isPublishedColumn, hasUnpublishedChangesColumn, tagColumn)
select(
draftRuleColumns,
isPublishedColumn,
hasUnpublishedChangesColumn,
feedbackCountColumn,
tagColumn
)
.from(DbRuleDraft as rd)
.leftJoin(DbRuleLive as rl)
.on(sqls"${rd.externalId} = ${rl.externalId} and ${rl.isActive} = true")
Expand All @@ -190,9 +202,40 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
.apply()
}

def findRules(ids: List[Int])(implicit session: DBSession = autoSession): List[DbRuleDraft] = {
def findByExternalId(
externalId: String
)(implicit session: DBSession = autoSession): Option[DbRuleDraft] = {
withSQL {
select(
draftRuleColumns,
isPublishedColumn,
hasUnpublishedChangesColumn,
feedbackCountColumn,
tagColumn
)
.from(DbRuleDraft as rd)
.leftJoin(DbRuleLive as rl)
.on(sqls"${rd.externalId} = ${rl.externalId} and ${rl.isActive} = true")
.leftJoin(RuleTagDraft as rt)
.on(rd.id, rt.ruleId)
.where
.eq(rd.externalId, externalId)
.groupBy(draftRuleColumns, rl.externalId, rl.revisionId)
.orderBy(rd.ruleOrder)
}.map(DbRuleDraft.fromRow)
.single()
.apply()
}

def findByIds(ids: List[Int])(implicit session: DBSession = autoSession): List[DbRuleDraft] = {
withSQL {
select(draftRuleColumns, isPublishedColumn, hasUnpublishedChangesColumn, tagColumn)
select(
draftRuleColumns,
isPublishedColumn,
hasUnpublishedChangesColumn,
feedbackCountColumn,
tagColumn
)
.from(DbRuleDraft as rd)
.leftJoin(DbRuleLive as rl)
.on(sqls"${rd.externalId} = ${rl.externalId} and ${rl.isActive} = true")
Expand All @@ -210,7 +253,13 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {

def findAll()(implicit session: DBSession = autoSession): List[DbRuleDraft] = {
withSQL {
select(draftRuleColumns, isPublishedColumn, hasUnpublishedChangesColumn, tagColumn)
select(
draftRuleColumns,
isPublishedColumn,
hasUnpublishedChangesColumn,
feedbackCountColumn,
tagColumn
)
.from(DbRuleDraft as rd)
.leftJoin(DbRuleLive as rl)
.on(sqls"${rd.externalId} = ${rl.externalId} and ${rl.isActive} = true")
Expand Down Expand Up @@ -312,6 +361,7 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
$draftRuleColumns,
$isPublishedColumn,
$hasUnpublishedChangesColumn,
$feedbackCountColumn,
rule_count,
CEIL(rule_count / $pageSize) as page_count,
$tagColumn
Expand Down Expand Up @@ -360,7 +410,13 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {

def findAllDictionaryRules()(implicit session: DBSession = autoSession): List[DbRuleDraft] = {
withSQL {
select(draftRuleColumns, isPublishedColumn, hasUnpublishedChangesColumn, tagColumn)
select(
draftRuleColumns,
isPublishedColumn,
hasUnpublishedChangesColumn,
feedbackCountColumn,
tagColumn
)
.from(DbRuleDraft as rd)
.leftJoin(DbRuleLive as rl)
.on(sqls"${rd.externalId} = ${rl.externalId} and ${rl.isActive} = true")
Expand Down Expand Up @@ -450,7 +506,7 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
val tagRelations = tags.map(tagId => RuleTagDraft(id, tagId))
RuleTagDraft.batchInsert(tagRelations)

find(id) match {
findById(id) match {
case Some(rule) => Success(rule)
case None =>
Failure(
Expand Down Expand Up @@ -486,7 +542,7 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
user: String
)(implicit session: DBSession = autoSession): Either[Result, DbRuleDraft] = {
val updatedRule = DbRuleDraft
.find(id)
.findById(id)
.toRight(NotFound("Rule not found matching ID"))
.map(existingRule =>
existingRule.copy(
Expand Down Expand Up @@ -532,7 +588,7 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
}

withSQL(updateColumns).update().apply()
val rules = findRules(ids)
val rules = findByIds(ids)
rules
}
}
Expand Down Expand Up @@ -652,7 +708,7 @@ object DbRuleDraft extends SQLSyntaxSupport[DbRuleDraft] {
val tagRelations = entity.tags.map(tagId => RuleTagDraft(id, tagId))
RuleTagDraft.batchInsert(tagRelations)

find(entity.id.get)
findById(entity.id.get)
.toRight(
new Exception(s"Error updating rule with id ${entity.id}: could not read updated rule")
)
Expand Down
Loading
Loading