Created
February 21, 2022 11:15
-
-
Save gcoda/d4f395b90f243d36d167f25253acc054 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Domain | |
open Fable.Core | |
open Fable.Import | |
open System | |
// type Guid = Guid of string | |
type NoneEmptyString = private NoneEmptyString of string | |
module NoneEmptyString = | |
let create str = | |
if String.IsNullOrWhiteSpace str then | |
"Cannot be empty" |> Error | |
else | |
str |> NoneEmptyString |> Ok | |
type CustomerId = private CustomerId of Guid | |
module CustomerId = | |
let create id = | |
if id = Guid.Empty then | |
"Cannot be empty" |> Error | |
else | |
id |> CustomerId |> Ok | |
let newPerson = Guid.NewGuid() | |
let newCustomerId = CustomerId.create newPerson | |
type Email = Email of NoneEmptyString | |
type CheckInDate = CheckInDate of DateTime | |
type AcceptDate = AcceptedDate of DateTime | |
type VerifiedDate = VerifiedDate of DateTime | |
type ContactInformation = | |
{ FirstName: NoneEmptyString | |
LastName: NoneEmptyString | |
Email: Email | |
PhoneNumber: NoneEmptyString option } | |
type Address = | |
{ StreetAddress1: NoneEmptyString | |
StreetAddress2: NoneEmptyString option | |
ZipCode: NoneEmptyString | |
City: NoneEmptyString | |
Country: NoneEmptyString } | |
type CustomerDetails = | |
{ ContactInformation: ContactInformation | |
Address: Address } | |
type InvitedCustomer = | |
private | |
{ Id: CustomerId | |
Email: Email } | |
type DetailsOnly = | |
private | |
{ Id: CustomerId | |
Details: CustomerDetails } | |
type AcceptedGDPR = | |
private | |
{ Id: CustomerId | |
AcceptDate: AcceptDate | |
Details: CustomerDetails } | |
type CheckedIn = | |
private | |
{ Id: CustomerId | |
CheckInDate: CheckInDate | |
Details: CustomerDetails } | |
type Complete = | |
private | |
{ Id: CustomerId | |
AcceptDate: AcceptDate | |
CheckInDate: CheckInDate | |
Details: CustomerDetails } | |
type VerifiedCustomer = | |
private | |
{ Id: CustomerId | |
AcceptDate: AcceptDate | |
CheckedInDate: CheckInDate | |
VerifiedDate: VerifiedDate | |
Details: CustomerDetails } | |
type ActiveCustomer = | |
private | |
| DetailsOnly of DetailsOnly | |
| AcceptedGDPR of AcceptedGDPR | |
| CheckedIn of CheckedIn | |
| Complete of Complete | |
type UnverifiedCustomer = | |
private | |
| Invited of InvitedCustomer | |
| Active of ActiveCustomer | |
let invite id email = { Id = id; Email = email } | |
// UnverifiedCustomer -> CustomerDetails -> ActiveCustomer | |
let updateDetails (customer: UnverifiedCustomer) details = | |
match customer with | |
| Invited { Id = id } -> DetailsOnly { Id = id; Details = details } | |
| Active activeCustomer -> | |
match activeCustomer with | |
| DetailsOnly c -> DetailsOnly { c with Details = details } | |
| AcceptedGDPR c -> AcceptedGDPR { c with Details = details } | |
| CheckedIn c -> CheckedIn { c with Details = details } | |
| Complete c -> Complete { c with Details = details } | |
// ActiveCustomer -> AcceptDate -> ActiveCustomer | |
let acceptGDPR (customer: ActiveCustomer) date = | |
match customer with | |
| DetailsOnly c -> | |
AcceptedGDPR | |
{ Id = c.Id | |
Details = c.Details | |
AcceptDate = date } | |
| AcceptedGDPR c -> AcceptedGDPR { c with AcceptDate = date } | |
| CheckedIn c -> | |
Complete | |
{ Id = c.Id | |
Details = c.Details | |
CheckInDate = c.CheckInDate | |
AcceptDate = date } | |
| Complete c -> Complete { c with AcceptDate = date } | |
// ActiveCustomer -> CheckInDate -> ActiveCustomer | |
let checkIn (customer: ActiveCustomer) date = | |
match customer with | |
| DetailsOnly c -> | |
CheckedIn | |
{ Id = c.Id | |
Details = c.Details | |
CheckInDate = date } | |
| AcceptedGDPR c -> | |
Complete | |
{ Id = c.Id | |
Details = c.Details | |
AcceptDate = c.AcceptDate | |
CheckInDate = date } | |
| CheckedIn c -> CheckedIn { c with CheckInDate = date } | |
| Complete c -> Complete { c with CheckInDate = date } | |
// ActiveCustomer -> VerifiedDate -> VerifiedCustomer | |
let verify (customer: Complete) date = | |
{ Id = customer.Id | |
Details = customer.Details | |
AcceptDate = customer.AcceptDate | |
CheckedInDate = customer.CheckInDate | |
VerifiedDate = date } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment