diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala new file mode 100644 index 0000000..ae34fa2 --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala @@ -0,0 +1,17 @@ +package mdr.pdb +package proof +package query.repo + +import zio.* + +object ProofRepository: + sealed trait Criteria + case class WithId(id: Proof.Id) extends Criteria + case class OfPerson(osc: OsobniCislo) extends Criteria + +trait ProofRepository: + import ProofRepository.* + def matching(criteria: Criteria): Task[Seq[Proof]] + +private[query] trait ProofRepositoryWrite extends ProofRepository: + def put(proof: Proof): Task[Unit] diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala new file mode 100644 index 0000000..ae34fa2 --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala @@ -0,0 +1,17 @@ +package mdr.pdb +package proof +package query.repo + +import zio.* + +object ProofRepository: + sealed trait Criteria + case class WithId(id: Proof.Id) extends Criteria + case class OfPerson(osc: OsobniCislo) extends Criteria + +trait ProofRepository: + import ProofRepository.* + def matching(criteria: Criteria): Task[Seq[Proof]] + +private[query] trait ProofRepositoryWrite extends ProofRepository: + def put(proof: Proof): Task[Unit] diff --git a/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala new file mode 100644 index 0000000..bef8a2b --- /dev/null +++ b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala @@ -0,0 +1,12 @@ +package mdr.pdb.proof +package json + +import zio.json.* + +trait Codecs extends mdr.pdb.json.Codecs: + + given JsonCodec[Authorization] = DeriveJsonCodec.gen + given JsonCodec[Revocation] = DeriveJsonCodec.gen + given JsonCodec[Proof] = DeriveJsonCodec.gen + +object Codecs extends Codecs diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala new file mode 100644 index 0000000..ae34fa2 --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala @@ -0,0 +1,17 @@ +package mdr.pdb +package proof +package query.repo + +import zio.* + +object ProofRepository: + sealed trait Criteria + case class WithId(id: Proof.Id) extends Criteria + case class OfPerson(osc: OsobniCislo) extends Criteria + +trait ProofRepository: + import ProofRepository.* + def matching(criteria: Criteria): Task[Seq[Proof]] + +private[query] trait ProofRepositoryWrite extends ProofRepository: + def put(proof: Proof): Task[Unit] diff --git a/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala new file mode 100644 index 0000000..bef8a2b --- /dev/null +++ b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala @@ -0,0 +1,12 @@ +package mdr.pdb.proof +package json + +import zio.json.* + +trait Codecs extends mdr.pdb.json.Codecs: + + given JsonCodec[Authorization] = DeriveJsonCodec.gen + given JsonCodec[Revocation] = DeriveJsonCodec.gen + given JsonCodec[Proof] = DeriveJsonCodec.gen + +object Codecs extends Codecs diff --git a/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala new file mode 100644 index 0000000..7052edc --- /dev/null +++ b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala @@ -0,0 +1,32 @@ +package mdr.pdb +package proof + +import java.time.Instant +import java.time.LocalDate + +case class Authorization( + time: Instant, + person: OsobniCislo +) + +case class Revocation( + time: Instant, + person: OsobniCislo, + explanation: String, + documents: List[DocumentRef] +) + +case class Proof( + person: OsobniCislo, + id: Proof.Id, + parameterId: String, + criterionId: String, + documents: List[DocumentRef], + note: String, + authorizations: List[Authorization], + expiration: Option[LocalDate], + revocation: Option[Revocation] +) + +object Proof: + type Id = String diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala new file mode 100644 index 0000000..ae34fa2 --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala @@ -0,0 +1,17 @@ +package mdr.pdb +package proof +package query.repo + +import zio.* + +object ProofRepository: + sealed trait Criteria + case class WithId(id: Proof.Id) extends Criteria + case class OfPerson(osc: OsobniCislo) extends Criteria + +trait ProofRepository: + import ProofRepository.* + def matching(criteria: Criteria): Task[Seq[Proof]] + +private[query] trait ProofRepositoryWrite extends ProofRepository: + def put(proof: Proof): Task[Unit] diff --git a/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala new file mode 100644 index 0000000..bef8a2b --- /dev/null +++ b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala @@ -0,0 +1,12 @@ +package mdr.pdb.proof +package json + +import zio.json.* + +trait Codecs extends mdr.pdb.json.Codecs: + + given JsonCodec[Authorization] = DeriveJsonCodec.gen + given JsonCodec[Revocation] = DeriveJsonCodec.gen + given JsonCodec[Proof] = DeriveJsonCodec.gen + +object Codecs extends Codecs diff --git a/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala new file mode 100644 index 0000000..7052edc --- /dev/null +++ b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala @@ -0,0 +1,32 @@ +package mdr.pdb +package proof + +import java.time.Instant +import java.time.LocalDate + +case class Authorization( + time: Instant, + person: OsobniCislo +) + +case class Revocation( + time: Instant, + person: OsobniCislo, + explanation: String, + documents: List[DocumentRef] +) + +case class Proof( + person: OsobniCislo, + id: Proof.Id, + parameterId: String, + criterionId: String, + documents: List[DocumentRef], + note: String, + authorizations: List[Authorization], + expiration: Option[LocalDate], + revocation: Option[Revocation] +) + +object Proof: + type Id = String diff --git a/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala b/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala new file mode 100644 index 0000000..eff2357 --- /dev/null +++ b/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala @@ -0,0 +1,53 @@ +package fiftyforms.mongo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import org.mongodb.scala.model.ReplaceOptions +import org.mongodb.scala.bson.conversions.Bson + +case class MongoConfig(uri: String) + +object MongoConfig: + val configDesc = + import ConfigDescriptor.* + nested("MONGO")(string("URI").default("mongodb://localhost:27017")) + .to[MongoConfig] + val fromEnv = ZConfig.fromSystemEnv(configDesc) + +val client: RLayer[MongoConfig, MongoClient] = + (for + config <- ZIO.service[MongoConfig] + client <- Task.attempt(MongoClient(config.uri)) + yield client).toLayer + +class MongoJsonRepository[Elem, Key, Criteria]( + collection: MongoCollection[JsonObject], + toFilter: Criteria => Bson, + idFilter: Elem => (String, Key) +)(using JsonCodec[Elem]) { + def matching(criteria: Criteria): Task[Seq[Elem]] = + val filter = toFilter(criteria) + val query = collection.find(filter) + + for + result <- ZIO.fromFuture(_ => query.toFuture) + proof <- ZIO.collect(result)(j => + ZIO.fromOption(j.getJson.fromJson[Elem].toOption) + ) + yield proof + + def put(elem: Elem): Task[Unit] = + Task.async(cb => + collection + .replaceOne( + equal.tupled(idFilter(elem)), + JsonObject(elem.toJson), + ReplaceOptions().upsert(true) + ) + .subscribe(_ => cb(Task.unit), t => cb(Task.fail(t))) + ) +} diff --git a/build.sbt b/build.sbt index 91b192f..a533b1e 100644 --- a/build.sbt +++ b/build.sbt @@ -8,6 +8,13 @@ ThisBuild / scalaVersion := scala3Version +lazy val proof = entityProject("proof", file("domain/proof")) + .components(_.dependsOn(ui)) + .model(_.dependsOn(core)) + .json(_.dependsOn(json)) + .repo(_.dependsOn(`mongo-support`)) + .endpoints(_.dependsOn(`tapir-support`)) + lazy val parameters = entityProject("parameters", file("domain/parameters")) .components(_.dependsOn(ui)) .model(_.dependsOn(core)) @@ -55,6 +62,16 @@ .jsSettings(IWDeps.tapirSttpClient) .jvmSettings(IWDeps.tapirZIO, IWDeps.tapirZIOHttp4sServer) +lazy val `mongo-support` = project + .in(file("fiftyforms/mongo")) + .settings( + IWDeps.useZIO(Test), + IWDeps.zioJson, + IWDeps.zioConfig, + libraryDependencies += ("org.mongodb.scala" %% "mongo-scala-driver" % "4.2.3") + .cross(CrossVersion.for3Use2_13) + ) + lazy val app = (project in file("app")) .enablePlugins(ScalaJSPlugin, VitePlugin) .settings( @@ -85,6 +102,8 @@ parameters.command.client, users.query.client, users.command.client, + proof.query.client, + proof.command.client, endpoints.js ) @@ -134,6 +153,8 @@ parameters.command.api, users.query.api, users.command.api, + proof.query.api, + proof.command.api, endpoints.jvm ) diff --git a/core/src/main/scala/mdr/pdb/DocumentRef.scala b/core/src/main/scala/mdr/pdb/DocumentRef.scala new file mode 100644 index 0000000..42d4108 --- /dev/null +++ b/core/src/main/scala/mdr/pdb/DocumentRef.scala @@ -0,0 +1,3 @@ +package mdr.pdb + +type DocumentRef = String diff --git a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala index 4f1db43..2aaa7b8 100644 --- a/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala +++ b/domain/parameters/command/json/src/main/scala/mdr/pdb/parameters/command/Codecs.scala @@ -6,4 +6,4 @@ trait Codecs extends mdr.pdb.json.Codecs: - given JsonCodec[AutorizujDukaz] = DeriveJsonCodec.gen + given JsonCodec[AuthorizeProof] = DeriveJsonCodec.gen diff --git a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala index 5f0f74c..a030e98 100644 --- a/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala +++ b/domain/parameters/command/model/src/main/scala/mdr/pdb/parameters/command/commands.scala @@ -7,9 +7,7 @@ sealed trait Command -type DocumentRef = String - -case class AutorizujDukaz( +case class AuthorizeProof( osoba: OsobniCislo, parametr: Parameter.Id, kriterium: ParameterCriterion.Id, diff --git a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala index 07eb9a6..95df195 100644 --- a/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala +++ b/domain/parameters/query/repo/src/main/scala/mdr/pdb/parameters/query/repo/ParametersRepository.scala @@ -6,7 +6,21 @@ import zio.* +object ParametersRepository: + sealed trait Criteria: + type Result + trait MultiResultCriteria extends Criteria: + override type Result = List[Parameter] + trait SingleResultCriteria extends Criteria: + override type Result = Option[Parameter] + + case object Any extends MultiResultCriteria + case class WithId(id: Parameter.Id) extends SingleResultCriteria + case class OfUser(osc: OsobniCislo) extends MultiResultCriteria + trait ParametersRepository: - def allParameters(): Task[List[Parameter]] - def parametersOfUser(user: OsobniCislo): Task[List[Parameter]] - def proofsOfUser(user: OsobniCislo): Task[List[Proof]] + import ParametersRepository.Criteria + def matching(criteria: Criteria): Task[criteria.Result] + +private[query] trait ParametersRepositoryWrite extends ParametersRepository: + def put(parameter: Parameter): Task[Unit] diff --git a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala index 04cc1d7..6cc8bf7 100644 --- a/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala +++ b/domain/parameters/shared/model/src/main/scala/mdr/pdb/parameters/Parameter.scala @@ -3,10 +3,7 @@ import java.math.BigInteger import java.security.MessageDigest - -case class Proof( - criterionId: ParameterCriterion.Id -) +import java.time.LocalDate object ParameterCriterion: type Id = String diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala new file mode 100644 index 0000000..fad055c --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/MongoProofRepository.scala @@ -0,0 +1,63 @@ +package mdr.pdb.proof +package query.repo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import fiftyforms.mongo.MongoJsonRepository + +case class MongoProofConfig(db: String, collection: String) + +object MongoProofConfig { + val configDesc = + import ConfigDescriptor.* + nested("MONGO")( + nested("PROOF")( + string("DB").default("mdrpdb") zip string("COLL").default("proof") + ) + ) + .to[MongoProofConfig] + val fromEnv: ZLayer[System, ReadError[String], MongoProofConfig] = + ZConfig.fromSystemEnv(configDesc) +} + +object MongoProofRepository: + private val repo = + for + config <- ZIO.service[MongoProofConfig] + client <- ZIO.service[MongoClient] + coll <- Task.attempt { + client + .getDatabase(config.db) + .getCollection[JsonObject](config.collection) + } + yield MongoProofRepository(coll) + + val layer: RLayer[MongoProofConfig & MongoClient, ProofRepository] = + repo.toLayer + + private[query] val writeLayer + : RLayer[MongoProofConfig & MongoClient, ProofRepositoryWrite] = + repo.toLayer + +private[query] class MongoProofRepository( + collection: MongoCollection[JsonObject] +) extends ProofRepositoryWrite: + import ProofRepository.* + import mdr.pdb.proof.json.Codecs.given + + private val jsonRepo = MongoJsonRepository[Proof, String, Criteria]( + collection, { + _ match + case WithId(id) => equal("id", id) + case OfPerson(osc) => equal("person", osc.toString) + }, + p => ("id", p.id) + ) + + export jsonRepo.matching + + export jsonRepo.put diff --git a/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala new file mode 100644 index 0000000..ae34fa2 --- /dev/null +++ b/domain/proof/query/repo/src/main/scala/mdr/pdb/query/repo/ProofRepository.scala @@ -0,0 +1,17 @@ +package mdr.pdb +package proof +package query.repo + +import zio.* + +object ProofRepository: + sealed trait Criteria + case class WithId(id: Proof.Id) extends Criteria + case class OfPerson(osc: OsobniCislo) extends Criteria + +trait ProofRepository: + import ProofRepository.* + def matching(criteria: Criteria): Task[Seq[Proof]] + +private[query] trait ProofRepositoryWrite extends ProofRepository: + def put(proof: Proof): Task[Unit] diff --git a/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala new file mode 100644 index 0000000..bef8a2b --- /dev/null +++ b/domain/proof/shared/json/src/main/scala/mdr/pdb/proof/json/Codecs.scala @@ -0,0 +1,12 @@ +package mdr.pdb.proof +package json + +import zio.json.* + +trait Codecs extends mdr.pdb.json.Codecs: + + given JsonCodec[Authorization] = DeriveJsonCodec.gen + given JsonCodec[Revocation] = DeriveJsonCodec.gen + given JsonCodec[Proof] = DeriveJsonCodec.gen + +object Codecs extends Codecs diff --git a/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala new file mode 100644 index 0000000..7052edc --- /dev/null +++ b/domain/proof/shared/model/src/main/scala/mdr/pdb/proof/Proof.scala @@ -0,0 +1,32 @@ +package mdr.pdb +package proof + +import java.time.Instant +import java.time.LocalDate + +case class Authorization( + time: Instant, + person: OsobniCislo +) + +case class Revocation( + time: Instant, + person: OsobniCislo, + explanation: String, + documents: List[DocumentRef] +) + +case class Proof( + person: OsobniCislo, + id: Proof.Id, + parameterId: String, + criterionId: String, + documents: List[DocumentRef], + note: String, + authorizations: List[Authorization], + expiration: Option[LocalDate], + revocation: Option[Revocation] +) + +object Proof: + type Id = String diff --git a/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala b/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala new file mode 100644 index 0000000..eff2357 --- /dev/null +++ b/fiftyforms/mongo/src/main/scala/fiftyforms/mongo/MongoJsonRepository.scala @@ -0,0 +1,53 @@ +package fiftyforms.mongo + +import zio.* +import zio.json.* +import zio.config.* +import org.mongodb.scala.* +import org.mongodb.scala.model.Filters.* +import org.bson.json.JsonObject +import org.mongodb.scala.model.ReplaceOptions +import org.mongodb.scala.bson.conversions.Bson + +case class MongoConfig(uri: String) + +object MongoConfig: + val configDesc = + import ConfigDescriptor.* + nested("MONGO")(string("URI").default("mongodb://localhost:27017")) + .to[MongoConfig] + val fromEnv = ZConfig.fromSystemEnv(configDesc) + +val client: RLayer[MongoConfig, MongoClient] = + (for + config <- ZIO.service[MongoConfig] + client <- Task.attempt(MongoClient(config.uri)) + yield client).toLayer + +class MongoJsonRepository[Elem, Key, Criteria]( + collection: MongoCollection[JsonObject], + toFilter: Criteria => Bson, + idFilter: Elem => (String, Key) +)(using JsonCodec[Elem]) { + def matching(criteria: Criteria): Task[Seq[Elem]] = + val filter = toFilter(criteria) + val query = collection.find(filter) + + for + result <- ZIO.fromFuture(_ => query.toFuture) + proof <- ZIO.collect(result)(j => + ZIO.fromOption(j.getJson.fromJson[Elem].toOption) + ) + yield proof + + def put(elem: Elem): Task[Unit] = + Task.async(cb => + collection + .replaceOne( + equal.tupled(idFilter(elem)), + JsonObject(elem.toJson), + ReplaceOptions().upsert(true) + ) + .subscribe(_ => cb(Task.unit), t => cb(Task.fail(t))) + ) +} diff --git a/project/DomainProjectsPlugin.scala b/project/DomainProjectsPlugin.scala index b52edb1..6aad728 100644 --- a/project/DomainProjectsPlugin.scala +++ b/project/DomainProjectsPlugin.scala @@ -37,6 +37,7 @@ query(_.endpoints(upd)).command(_.endpoints(upd)) def components(upd: Project => Project): EntityProject = query(_.components(upd)).command(_.components(upd)) + def repo(upd: Project => Project): EntityProject = query(_.repo(upd)) override def componentProjects: Seq[Project] = Seq(model, json).flatMap( _.componentProjects