Initial commit

This commit is contained in:
Paul-Henri Froidmont 2025-02-27 18:45:46 +01:00
commit 1919e4b72c
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
14 changed files with 640 additions and 0 deletions

View file

@ -0,0 +1,26 @@
package lu.foyer
import zio.prelude.*
import zio.schema.Schema
import java.time.LocalDate
trait RefinedType[Base, New]:
inline def assume(value: Base): New = value.asInstanceOf[New]
def validation(value: Base): Validation[String, New]
trait RefinedString[New <: String] extends RefinedType[String, New]:
given Schema[New] = Schema[String].transformOrFail(
validation(_).toEither.left.map(_.toList.mkString(", ")),
Right(_)
)
trait RefinedLocalDate[New <: LocalDate] extends RefinedType[LocalDate, New]:
override def validation(value: LocalDate): Validation[String, New] =
Validation.succeed(assume(value))
given Schema[New] = Schema[LocalDate].transform(assume, identity)
trait NonBlankString[New <: String] extends RefinedString[New]:
override def validation(value: String): Validation[String, New] =
if value.isBlank then Validation.fail("Cannot be blank")
else Validation.succeed(assume(value))

View file

@ -0,0 +1,20 @@
package lu.foyer
package clients
import zio.schema.*
opaque type AddressStreet <: String = String
object AddressStreet extends NonBlankString[AddressStreet]
opaque type AddressPostalCode <: String = String
object AddressPostalCode extends NonBlankString[AddressPostalCode]
opaque type AddressLocality <: String = String
object AddressLocality extends NonBlankString[AddressLocality]
case class Address(
street: AddressStreet,
postalCode: AddressPostalCode,
locality: AddressLocality,
country: Country)
derives Schema

View file

@ -0,0 +1,49 @@
package lu.foyer
package clients
import zio.schema.*
import java.time.Instant
import java.time.LocalDate
opaque type ClientLastName <: String = String
object ClientLastName extends NonBlankString[ClientLastName]
opaque type ClientFirstName <: String = String
object ClientFirstName extends NonBlankString[ClientFirstName]
opaque type ClientBirthDate <: LocalDate = LocalDate
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
// TODO validate using libphonenumber
case class PhoneNumber(
country: Country,
nationalNumber: NationalNumber,
lastVerifiedAt: Option[Instant])
derives Schema
case class PhoneNumberInput(
country: Country,
nationalNumber: String)
derives Schema
enum ClientDisabledReason derives Schema:
case GDPR, Death

View file

@ -0,0 +1,7 @@
package lu.foyer
package clients
import zio.schema.*
enum Country derives Schema:
case LU, FR, BE