Implement contracts
This commit is contained in:
parent
31014d1a0c
commit
efdc50eb1d
33 changed files with 879 additions and 173 deletions
7
model/src/lu/foyer/AppError.scala
Normal file
7
model/src/lu/foyer/AppError.scala
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package lu.foyer
|
||||
|
||||
import zio.schema.*
|
||||
|
||||
enum AppError(description: String) extends Throwable:
|
||||
case NotFound(desc: String) extends AppError(desc)
|
||||
case Unexpected(desc: String) extends AppError(desc)
|
||||
10
model/src/lu/foyer/CommonTypes.scala
Normal file
10
model/src/lu/foyer/CommonTypes.scala
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package lu.foyer
|
||||
|
||||
import zio.schema.*
|
||||
import java.util.UUID
|
||||
|
||||
opaque type ClientEntityId <: UUID = UUID
|
||||
object ClientEntityId extends RefinedUUID[ClientEntityId]
|
||||
|
||||
opaque type Email <: String = String
|
||||
object Email extends NonBlankString[Email]
|
||||
|
|
@ -4,6 +4,7 @@ import zio.prelude.*
|
|||
import zio.schema.Schema
|
||||
|
||||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
trait RefinedType[Base, New]:
|
||||
inline def assume(value: Base): New = value.asInstanceOf[New]
|
||||
|
|
@ -15,6 +16,15 @@ trait RefinedString[New <: String] extends RefinedType[String, New]:
|
|||
Right(_)
|
||||
)
|
||||
|
||||
trait RefinedUUID[New <: UUID] extends RefinedType[UUID, New]:
|
||||
def apply(value: UUID): New = assume(value)
|
||||
override def validation(value: UUID): Validation[String, New] =
|
||||
Validation.succeed(assume(value))
|
||||
given Schema[New] = Schema[UUID].transformOrFail(
|
||||
validation(_).toEither.left.map(_.toList.mkString(", ")),
|
||||
Right(_)
|
||||
)
|
||||
|
||||
trait RefinedLocalDate[New <: LocalDate] extends RefinedType[LocalDate, New]:
|
||||
def apply(value: LocalDate): New = assume(value)
|
||||
override def validation(value: LocalDate): Validation[String, New] =
|
||||
|
|
|
|||
|
|
@ -18,21 +18,9 @@ object ClientBirthDate extends RefinedLocalDate[ClientBirthDate]
|
|||
opaque type ClientDrivingLicenseDate <: LocalDate = LocalDate
|
||||
object ClientDrivingLicenseDate extends RefinedLocalDate[ClientDrivingLicenseDate]
|
||||
|
||||
opaque type Email <: String = String
|
||||
object Email extends NonBlankString[Email]
|
||||
|
||||
opaque type NationalNumber <: String = String
|
||||
object NationalNumber extends NonBlankString[NationalNumber]
|
||||
|
||||
case class Client(
|
||||
lastName: ClientFirstName,
|
||||
firstName: ClientLastName,
|
||||
drivingLicenseDate: ClientDrivingLicenseDate,
|
||||
phoneNumber: PhoneNumber,
|
||||
email: Email,
|
||||
address: Address)
|
||||
derives Schema
|
||||
|
||||
case class PhoneNumber(
|
||||
country: Country,
|
||||
nationalNumber: NationalNumber,
|
||||
|
|
@ -45,4 +33,4 @@ case class PhoneNumberInput(
|
|||
derives Schema
|
||||
|
||||
enum ClientDisabledReason derives Schema:
|
||||
case GDPR, Death
|
||||
case gdpr, death
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ package clients
|
|||
import zio.schema.*
|
||||
|
||||
enum Country derives Schema:
|
||||
case LU, FR, BE
|
||||
case LU, FR, BE, CH
|
||||
|
|
|
|||
11
model/src/lu/foyer/contracts/Employee.scala
Normal file
11
model/src/lu/foyer/contracts/Employee.scala
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import zio.schema.*
|
||||
import java.util.Currency
|
||||
|
||||
opaque type EmployeeDisplayName <: String = String
|
||||
object EmployeeDisplayName extends NonBlankString[EmployeeDisplayName]
|
||||
|
||||
final case class Employee(uid: String, displayName: EmployeeDisplayName, email: Email)
|
||||
derives Schema
|
||||
27
model/src/lu/foyer/contracts/FormulaType.scala
Normal file
27
model/src/lu/foyer/contracts/FormulaType.scala
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import zio.schema.*
|
||||
|
||||
enum FormulaType(val maxCoverage: Long, val basePremium: BigDecimal):
|
||||
case Bronze extends FormulaType(10_000, 600)
|
||||
case Silver extends FormulaType(25_000, 900)
|
||||
case Gold extends FormulaType(250_000, 1500)
|
||||
|
||||
object FormulaType:
|
||||
enum Json:
|
||||
case bronze, silver, gold
|
||||
|
||||
given Schema[FormulaType] = DeriveSchema
|
||||
.gen[Json].transform(
|
||||
{
|
||||
case Json.bronze => FormulaType.Bronze
|
||||
case Json.silver => FormulaType.Silver
|
||||
case Json.gold => FormulaType.Gold
|
||||
},
|
||||
{
|
||||
case FormulaType.Bronze => Json.bronze
|
||||
case FormulaType.Silver => Json.silver
|
||||
case FormulaType.Gold => Json.gold
|
||||
}
|
||||
)
|
||||
8
model/src/lu/foyer/contracts/ProductType.scala
Normal file
8
model/src/lu/foyer/contracts/ProductType.scala
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import zio.schema.*
|
||||
import zio.schema.annotation.caseName
|
||||
|
||||
enum ProductType derives Schema:
|
||||
@caseName("car") case Car
|
||||
7
model/src/lu/foyer/contracts/TerminationReasonType.scala
Normal file
7
model/src/lu/foyer/contracts/TerminationReasonType.scala
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import zio.schema.*
|
||||
|
||||
enum TerminationReasonType derives Schema:
|
||||
case Rejected, HolderDeceased, TerminatedByClient
|
||||
16
model/src/lu/foyer/contracts/Vehicle.scala
Normal file
16
model/src/lu/foyer/contracts/Vehicle.scala
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package lu.foyer
|
||||
package contracts
|
||||
|
||||
import zio.schema.*
|
||||
import java.util.Currency
|
||||
|
||||
opaque type VehiclePlate <: String = String
|
||||
object VehiclePlate extends NonBlankString[VehiclePlate]
|
||||
|
||||
opaque type VehicleBrand <: String = String
|
||||
object VehicleBrand extends NonBlankString[VehicleBrand]
|
||||
|
||||
final case class Amount(value: BigDecimal, currency: Currency) derives Schema
|
||||
|
||||
final case class Vehicle(plate: VehiclePlate, brand: VehicleBrand, insuredValue: Amount)
|
||||
derives Schema
|
||||
Loading…
Add table
Add a link
Reference in a new issue