package controllers import actors.auctions.AuctionPublisher import controllers.authentication.AuthenticatedAction import dao.{AuctionsDAO, AuthTokensDAO} import models.Auction import org.apache.pekko.actor.typed.ActorRef import play.api.libs.functional.syntax.toFunctionalBuilderOps import play.api.libs.json.{JsError, JsPath, JsValue, Json, Reads, Writes} import play.api.mvc.{BaseController, ControllerComponents} import java.security.SecureRandom import javax.inject.{Inject, Singleton} import scala.concurrent.{ExecutionContext, Future} @Singleton class AuctionsController @Inject()(val controllerComponents: ControllerComponents, val auctionsDAO: AuctionsDAO, val authTokensDAO: AuthTokensDAO, val auctionPublisher: ActorRef[AuctionPublisher.Command], implicit val ec: ExecutionContext) extends BaseController { def create = Action.andThen(AuthenticatedAction(authTokensDAO)).async(parse.json) { implicit request => val auctionCreateDataResult = request.body.validate[AuctionCreateData] auctionCreateDataResult.fold( errors => Future.successful(BadRequest(JsError.toJson(errors))), auctionCreateData => { for { auction <- auctionsDAO.create(auctionCreateData.name, auctionCreateData.startingPrice, request.user) json = Json.toJson(auction) response = Created(json) _ = auctionPublisher ! AuctionPublisher.Publish(auction, request.user) } yield response } ) } private case class AuctionCreateData(name: String, startingPrice: BigDecimal) private implicit val auctionCreateDataReads: Reads[AuctionCreateData] = ( (JsPath \ "name").read[String] and (JsPath \ "starting_price").read[BigDecimal] )(AuctionCreateData.apply) }