by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    docker run --name bootzooka-postgres -p 5432:5432 -e POSTGRES_PASSWORD=bootzooka -e POSTGRES_DB=bootzooka -d postgres
    Adam Warski
    @adamw
    CREATE TABLE "hikers"
    (
      "id"              TEXT        NOT NULL,
      "user_id"         TEXT        NOT NULL,
      "route_name"      TEXT        NOT NULL
    );
    ALTER TABLE "hikers" ADD CONSTRAINT "hikers_id" PRIMARY KEY ("id");
    ALTER TABLE "hikers"
      ADD CONSTRAINT "hikers_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE;
    Adam Warski
    @adamw
    package io.scalaworld.hiking.hikers
    
    import io.scalaworld.hiking.http.{Error_OUT, Http}
    import io.scalaworld.hiking.infrastructure.Json._
    import io.scalaworld.hiking.security.{ApiKey, Auth}
    import tapir.Endpoint
    import tapir.model.StatusCode
    import tsec.common.SecureRandomId
    
    class HikersApi(http: Http, auth: Auth[ApiKey], hikersService: HikersService) {
    
      import http._
    
      val createHikerEndpoint = secureEndpoint
        .in("hikers")
        .post
        .in(jsonBody[CreateHiker_IN])
        .out(stringBody)
        .serverLogic {
          case (apiKeyId, hikerIn) =>
            (for {
              userId <- auth(apiKeyId)
              _ <- hikersService.newHiker(userId, hikerIn.routeName)
            } yield "ok").toOut
        }
    }
    
    case class CreateHiker_IN(routeName: String)
    package io.scalaworld.hiking.hikers
    
    import com.softwaremill.tagging.@@
    import io.scalaworld.hiking.user.User
    import io.scalaworld.hiking.util.Id
    import io.scalaworld.hiking.infrastructure.Doobie._
    
    class HikersModel {
      def insert(hiker: Hiker): ConnectionIO[Unit] = {
        sql"""INSERT INTO hiker (id, user_id, route_name)
             |VALUES (${hiker.id}, ${hiker.userId}, ${hiker.routeName})""".stripMargin.update.run.map(_ => ())
      }
    }
    
    case class Hiker(id: Id @@ Hiker, userId: Id @@ User, routeName: String)
    package io.scalaworld.hiking.hikers
    
    import com.softwaremill.tagging.@@
    import io.scalaworld.hiking.email.EmailData
    import io.scalaworld.hiking.email.sender.EmailSender
    import io.scalaworld.hiking.user.User
    import io.scalaworld.hiking.util.{Id, IdGenerator}
    import monix.eval.Task
    import io.scalaworld.hiking.infrastructure.Doobie._
    
    class HikersService(hikersModel: HikersModel, emailSender: EmailSender, xa: Transactor[Task], idGenerator: IdGenerator) {
      def newHiker(userId: Id @@ User, routeName: String): Task[Unit] = {
        val dbOp: ConnectionIO[Unit] = hikersModel.insert(Hiker(idGenerator.nextId(), userId, routeName))
        val dbResult: Task[Unit] = dbOp.transact(xa)
        val sendEmail: Task[Unit] = emailSender(EmailData("admin@scalaworld.io", "New hiker!", s"New hiker: $userId"))
    
        sendEmail.flatMap(_ => dbResult)
      }
    }