Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c199e00
Unlock payment route and functionality, no op cassandra impl yet
battermann Nov 9, 2021
a87fe0c
removed payment status for app lock team feature from C* schema, and …
battermann Nov 18, 2021
9a09469
This is a delta for #1916 (#1935)
fisx Nov 18, 2021
9982454
improve comment
Nov 18, 2021
0a51b92
simplification
battermann Nov 18, 2021
f0f50cc
require HasPaymentStatusCol for setting the payment status
battermann Nov 18, 2021
c1a1307
clean up
battermann Nov 18, 2021
17d6c54
FeatureStatus with and without PaymentStatus
battermann Nov 18, 2021
9d419ba
integration tests + implementation of business logic
battermann Nov 22, 2021
d235a3f
reduce # of db roundtrips
battermann Nov 23, 2021
80b9b8c
renamed migration
battermann Nov 23, 2021
f1824ef
Merge branch 'develop' into SQSERVICES-960-distinguish-between-unlock…
fisx Nov 23, 2021
95fc91a
Simplify.
fisx Nov 23, 2021
187da92
Factor out feature locking function.
fisx Nov 23, 2021
1a2b7dc
FeatureHasNoConfig with PaymentStatus parameter
battermann Nov 24, 2021
dc9c717
Merge branch 'SQSERVICES-960-distinguish-between-unlock-team-feature-…
battermann Nov 24, 2021
d37484a
remove comment
Nov 24, 2021
f3d8cdd
additional roundtrip test
Nov 24, 2021
f1f35f6
typo
Nov 24, 2021
d401dda
clean up
Nov 24, 2021
b268c10
more explicit pattern match
battermann Nov 24, 2021
743da2f
simplify payment status to payment status value
battermann Nov 24, 2021
151f712
typo
Nov 24, 2021
fe9fce9
changelog
battermann Nov 24, 2021
1f0c701
update schema docs
battermann Nov 24, 2021
4823614
Merge branch 'SQSERVICES-960-distinguish-between-unlock-team-feature-…
battermann Nov 24, 2021
43b1be0
typo
battermann Nov 24, 2021
e7cbecc
s/payment/lock/gi;
fisx Nov 24, 2021
56d787b
Make default behavior on-prem-compatible.
fisx Nov 25, 2021
9cb5dcd
fix integrationtest, regenerate cql docs
battermann Nov 25, 2021
7369d68
formatting
battermann Nov 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions libs/galley-types/src/Galley/Types/Teams.hs
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,11 @@ data FeatureFlags = FeatureFlags
{ _flagSSO :: !FeatureSSO,
_flagLegalHold :: !FeatureLegalHold,
_flagTeamSearchVisibility :: !FeatureTeamSearchVisibility,
_flagAppLockDefaults :: !(Defaults (TeamFeatureStatus 'TeamFeatureAppLock)),
_flagClassifiedDomains :: !(TeamFeatureStatus 'TeamFeatureClassifiedDomains),
_flagFileSharing :: !(Defaults (TeamFeatureStatus 'TeamFeatureFileSharing)),
_flagConferenceCalling :: !(Defaults (TeamFeatureStatus 'TeamFeatureConferenceCalling)),
_flagSelfDeletingMessages :: !(Defaults (TeamFeatureStatus 'TeamFeatureSelfDeletingMessages))
_flagAppLockDefaults :: !(Defaults (TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureAppLock)),
_flagClassifiedDomains :: !(TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureClassifiedDomains),
_flagFileSharing :: !(Defaults (TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureFileSharing)),
_flagConferenceCalling :: !(Defaults (TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureConferenceCalling)),
_flagSelfDeletingMessages :: !(Defaults (TeamFeatureStatus 'WithPaymentStatus 'TeamFeatureSelfDeletingMessages))
}
deriving (Eq, Show, Generic)

Expand Down
4 changes: 2 additions & 2 deletions libs/wire-api/src/Wire/API/Routes/Internal/Brig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type GetAccountFeatureConfig =
:> Capture "uid" UserId
:> "features"
:> "conferenceCalling"
:> Get '[Servant.JSON] (ApiFt.TeamFeatureStatus 'ApiFt.TeamFeatureConferenceCalling)
:> Get '[Servant.JSON] (ApiFt.TeamFeatureStatus 'ApiFt.WithPaymentStatus 'ApiFt.TeamFeatureConferenceCalling)

type PutAccountFeatureConfig =
Summary
Expand All @@ -75,7 +75,7 @@ type PutAccountFeatureConfig =
:> Capture "uid" UserId
:> "features"
:> "conferenceCalling"
:> Servant.ReqBody '[Servant.JSON] (ApiFt.TeamFeatureStatus 'ApiFt.TeamFeatureConferenceCalling)
:> Servant.ReqBody '[Servant.JSON] (ApiFt.TeamFeatureStatus 'ApiFt.WithoutPaymentStatus 'ApiFt.TeamFeatureConferenceCalling)
:> Put '[Servant.JSON] NoContent

type DeleteAccountFeatureConfig =
Expand Down
44 changes: 22 additions & 22 deletions libs/wire-api/src/Wire/API/Routes/Public/Galley.hs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ data Api routes = Api
:- FeatureStatusPut 'TeamFeatureSearchVisibility,
teamFeatureStatusSearchVisibilityDeprecatedGet ::
routes
:- FeatureStatusDeprecatedGet 'TeamFeatureSearchVisibility,
:- FeatureStatusDeprecatedGet 'WithoutPaymentStatus 'TeamFeatureSearchVisibility,
teamFeatureStatusSearchVisibilityDeprecatedPut ::
routes
:- FeatureStatusDeprecatedPut 'TeamFeatureSearchVisibility,
Expand All @@ -632,13 +632,13 @@ data Api routes = Api
:- FeatureStatusGet 'TeamFeatureValidateSAMLEmails,
teamFeatureStatusValidateSAMLEmailsDeprecatedGet ::
routes
:- FeatureStatusDeprecatedGet 'TeamFeatureValidateSAMLEmails,
:- FeatureStatusDeprecatedGet 'WithoutPaymentStatus 'TeamFeatureValidateSAMLEmails,
teamFeatureStatusDigitalSignaturesGet ::
routes
:- FeatureStatusGet 'TeamFeatureDigitalSignatures,
teamFeatureStatusDigitalSignaturesDeprecatedGet ::
routes
:- FeatureStatusDeprecatedGet 'TeamFeatureDigitalSignatures,
:- FeatureStatusDeprecatedGet 'WithoutPaymentStatus 'TeamFeatureDigitalSignatures,
teamFeatureStatusAppLockGet ::
routes
:- FeatureStatusGet 'TeamFeatureAppLock,
Expand Down Expand Up @@ -668,34 +668,34 @@ data Api routes = Api
:- AllFeatureConfigsGet,
featureConfigLegalHoldGet ::
routes
:- FeatureConfigGet 'TeamFeatureLegalHold,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureLegalHold,
Comment thread
fisx marked this conversation as resolved.
Outdated
featureConfigSSOGet ::
routes
:- FeatureConfigGet 'TeamFeatureSSO,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureSSO,
featureConfigSearchVisibilityGet ::
routes
:- FeatureConfigGet 'TeamFeatureSearchVisibility,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureSearchVisibility,
featureConfigValidateSAMLEmailsGet ::
routes
:- FeatureConfigGet 'TeamFeatureValidateSAMLEmails,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureValidateSAMLEmails,
featureConfigDigitalSignaturesGet ::
routes
:- FeatureConfigGet 'TeamFeatureDigitalSignatures,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureDigitalSignatures,
featureConfigAppLockGet ::
routes
:- FeatureConfigGet 'TeamFeatureAppLock,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureAppLock,
featureConfigFileSharingGet ::
routes
:- FeatureConfigGet 'TeamFeatureFileSharing,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureFileSharing,
featureConfigClassifiedDomainsGet ::
routes
:- FeatureConfigGet 'TeamFeatureClassifiedDomains,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureClassifiedDomains,
featureConfigConferenceCallingGet ::
routes
:- FeatureConfigGet 'TeamFeatureConferenceCalling,
:- FeatureConfigGet 'WithoutPaymentStatus 'TeamFeatureConferenceCalling,
featureConfigSelfDeletingMessagesGet ::
routes
:- FeatureConfigGet 'TeamFeatureSelfDeletingMessages
:- FeatureConfigGet 'WithPaymentStatus 'TeamFeatureSelfDeletingMessages
}
deriving (Generic)

Expand All @@ -708,7 +708,7 @@ type FeatureStatusGet featureName =
:> Capture "tid" TeamId
:> "features"
:> KnownTeamFeatureNameSymbol featureName
:> Get '[Servant.JSON] (TeamFeatureStatus featureName)
:> Get '[Servant.JSON] (TeamFeatureStatus 'WithPaymentStatus featureName)

type FeatureStatusPut featureName =
Summary (AppendSymbol "Put config for " (KnownTeamFeatureNameSymbol featureName))
Expand All @@ -717,18 +717,18 @@ type FeatureStatusPut featureName =
:> Capture "tid" TeamId
:> "features"
:> KnownTeamFeatureNameSymbol featureName
:> ReqBody '[Servant.JSON] (TeamFeatureStatus featureName)
:> Put '[Servant.JSON] (TeamFeatureStatus featureName)
:> ReqBody '[Servant.JSON] (TeamFeatureStatus 'WithoutPaymentStatus featureName)
:> Put '[Servant.JSON] (TeamFeatureStatus 'WithoutPaymentStatus featureName)
Comment thread
fisx marked this conversation as resolved.
Outdated

-- | A type for a GET endpoint for a feature with a deprecated path
type FeatureStatusDeprecatedGet featureName =
type FeatureStatusDeprecatedGet ps featureName =
Summary (AppendSymbol "[deprecated] Get config for " (KnownTeamFeatureNameSymbol featureName))
:> ZUser
:> "teams"
:> Capture "tid" TeamId
:> "features"
:> DeprecatedFeatureName featureName
:> Get '[Servant.JSON] (TeamFeatureStatus featureName)
:> Get '[Servant.JSON] (TeamFeatureStatus ps featureName)

-- | A type for a PUT endpoint for a feature with a deprecated path
type FeatureStatusDeprecatedPut featureName =
Expand All @@ -738,15 +738,15 @@ type FeatureStatusDeprecatedPut featureName =
:> Capture "tid" TeamId
:> "features"
:> DeprecatedFeatureName featureName
:> ReqBody '[Servant.JSON] (TeamFeatureStatus featureName)
:> Put '[Servant.JSON] (TeamFeatureStatus featureName)
:> ReqBody '[Servant.JSON] (TeamFeatureStatus 'WithoutPaymentStatus featureName)
:> Put '[Servant.JSON] (TeamFeatureStatus 'WithoutPaymentStatus featureName)
Comment thread
fisx marked this conversation as resolved.
Outdated

type FeatureConfigGet featureName =
type FeatureConfigGet ps featureName =
Summary (AppendSymbol "Get feature config for feature " (KnownTeamFeatureNameSymbol featureName))
:> ZUser
:> "feature-configs"
:> KnownTeamFeatureNameSymbol featureName
:> Get '[Servant.JSON] (TeamFeatureStatus featureName)
:> Get '[Servant.JSON] (TeamFeatureStatus ps featureName)

type AllFeatureConfigsGet =
Summary "Get configurations of all features"
Expand Down
4 changes: 2 additions & 2 deletions libs/wire-api/src/Wire/API/Routes/Public/LegalHold.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ type PublicAPI =

type InternalAPI =
"i" :> "teams" :> Capture "tid" TeamId :> "legalhold"
:> Get '[JSON] (TeamFeatureStatus 'TeamFeatureLegalHold)
:> Get '[JSON] (TeamFeatureStatus 'WithPaymentStatus 'TeamFeatureLegalHold)
:<|> "i" :> "teams" :> Capture "tid" TeamId :> "legalhold"
:> ReqBody '[JSON] (TeamFeatureStatus 'TeamFeatureLegalHold)
:> ReqBody '[JSON] (TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureLegalHold)
:> Put '[] NoContent

swaggerDoc :: Swagger
Expand Down
1 change: 1 addition & 0 deletions libs/wire-api/src/Wire/API/Swagger.hs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ models =
Team.Feature.modelTeamFeatureAppLockConfig,
Team.Feature.modelTeamFeatureClassifiedDomainsConfig,
Team.Feature.modelTeamFeatureSelfDeletingMessagesConfig,
Team.Feature.modelPaymentStatus,
Team.Invitation.modelTeamInvitation,
Team.Invitation.modelTeamInvitationList,
Team.Invitation.modelTeamInvitationRequest,
Expand Down
147 changes: 129 additions & 18 deletions libs/wire-api/src/Wire/API/Team/Feature.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,12 @@ module Wire.API.Team.Feature
KnownTeamFeatureName (..),
TeamFeatureStatusNoConfig (..),
TeamFeatureStatusWithConfig (..),
TeamFeatureStatusWithConfigAndPaymentStatus (..),
HasDeprecatedFeatureName (..),
AllFeatureConfigs (..),
PaymentStatus (..),
PaymentStatusValue (..),
IncludePaymentStatus (..),
defaultAppLockStatus,
defaultClassifiedDomains,
defaultSelfDeletingMessagesStatus,
Expand All @@ -44,16 +48,19 @@ module Wire.API.Team.Feature
modelTeamFeatureAppLockConfig,
modelTeamFeatureClassifiedDomainsConfig,
modelTeamFeatureSelfDeletingMessagesConfig,
modelTeamFeatureStatusWithConfigAndPaymentStatus,
modelForTeamFeature,
modelPaymentStatus,
)
where

import qualified Cassandra.CQL as Cass
import Control.Lens.Combinators (dimap)
import qualified Data.Aeson as Aeson
import qualified Data.Attoparsec.ByteString as Parser
import Data.ByteString.Conversion (FromByteString (..), ToByteString (..), toByteString')
import Data.ByteString.Conversion (FromByteString (..), ToByteString (..), fromByteString, toByteString')
import Data.Domain (Domain)
import Data.Either.Extra (maybeToEither)
import Data.Kind (Constraint)
import Data.Schema
import Data.String.Conversions (cs)
Expand All @@ -64,6 +71,7 @@ import qualified Data.Text.Encoding as T
import Deriving.Aeson
import GHC.TypeLits (Symbol)
import Imports
import Servant (FromHttpApiData (..))
import Test.QuickCheck.Arbitrary (arbitrary)
import Wire.API.Arbitrary (Arbitrary, GenericUniform (..))

Expand Down Expand Up @@ -272,8 +280,8 @@ instance Cass.Cql TeamFeatureStatusValue where
ctype = Cass.Tagged Cass.IntColumn

fromCql (Cass.CqlInt n) = case n of
0 -> pure $ TeamFeatureDisabled
1 -> pure $ TeamFeatureEnabled
0 -> pure TeamFeatureDisabled
1 -> pure TeamFeatureEnabled
_ -> Left "fromCql: Invalid TeamFeatureStatusValue"
fromCql _ = Left "fromCql: TeamFeatureStatusValue: CqlInt expected"

Expand All @@ -283,19 +291,22 @@ instance Cass.Cql TeamFeatureStatusValue where
----------------------------------------------------------------------
-- TeamFeatureStatus

type family TeamFeatureStatus (a :: TeamFeatureName) :: * where
TeamFeatureStatus 'TeamFeatureLegalHold = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureSSO = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureSearchVisibility = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureValidateSAMLEmails = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureDigitalSignatures = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureAppLock = TeamFeatureStatusWithConfig TeamFeatureAppLockConfig
TeamFeatureStatus 'TeamFeatureFileSharing = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureClassifiedDomains = TeamFeatureStatusWithConfig TeamFeatureClassifiedDomainsConfig
TeamFeatureStatus 'TeamFeatureConferenceCalling = TeamFeatureStatusNoConfig
TeamFeatureStatus 'TeamFeatureSelfDeletingMessages = TeamFeatureStatusWithConfig TeamFeatureSelfDeletingMessagesConfig
data IncludePaymentStatus = WithPaymentStatus | WithoutPaymentStatus

type FeatureHasNoConfig (a :: TeamFeatureName) = (TeamFeatureStatus a ~ TeamFeatureStatusNoConfig) :: Constraint
type family TeamFeatureStatus (ps :: IncludePaymentStatus) (a :: TeamFeatureName) :: * where
TeamFeatureStatus _ 'TeamFeatureLegalHold = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureSSO = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureSearchVisibility = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureValidateSAMLEmails = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureDigitalSignatures = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureAppLock = TeamFeatureStatusWithConfig TeamFeatureAppLockConfig
TeamFeatureStatus _ 'TeamFeatureFileSharing = TeamFeatureStatusNoConfig
TeamFeatureStatus _ 'TeamFeatureClassifiedDomains = TeamFeatureStatusWithConfig TeamFeatureClassifiedDomainsConfig
TeamFeatureStatus _ 'TeamFeatureConferenceCalling = TeamFeatureStatusNoConfig
TeamFeatureStatus 'WithoutPaymentStatus 'TeamFeatureSelfDeletingMessages = TeamFeatureStatusWithConfig TeamFeatureSelfDeletingMessagesConfig
TeamFeatureStatus 'WithPaymentStatus 'TeamFeatureSelfDeletingMessages = TeamFeatureStatusWithConfigAndPaymentStatus TeamFeatureSelfDeletingMessagesConfig

type FeatureHasNoConfig (a :: TeamFeatureName) = (TeamFeatureStatus 'WithoutPaymentStatus a ~ TeamFeatureStatusNoConfig) :: Constraint
Comment thread
battermann marked this conversation as resolved.
Outdated

-- if you add a new constructor here, don't forget to add it to the swagger (1.2) docs in "Wire.API.Swagger"!
modelForTeamFeature :: TeamFeatureName -> Doc.Model
Expand Down Expand Up @@ -360,6 +371,32 @@ instance ToSchema cfg => ToSchema (TeamFeatureStatusWithConfig cfg) where
<$> tfwcStatus .= field "status" schema
<*> tfwcConfig .= field "config" schema

data TeamFeatureStatusWithConfigAndPaymentStatus (cfg :: *) = TeamFeatureStatusWithConfigAndPaymentStatus
{ tfwcapsStatus :: TeamFeatureStatusValue,
tfwcapsConfig :: cfg,
tfwcapsPaymentStatus :: PaymentStatusValue
}
deriving stock (Eq, Show, Generic, Typeable)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema (TeamFeatureStatusWithConfigAndPaymentStatus cfg))

instance Arbitrary cfg => Arbitrary (TeamFeatureStatusWithConfigAndPaymentStatus cfg) where
arbitrary = TeamFeatureStatusWithConfigAndPaymentStatus <$> arbitrary <*> arbitrary <*> arbitrary

modelTeamFeatureStatusWithConfigAndPaymentStatus :: TeamFeatureName -> Doc.Model -> Doc.Model
modelTeamFeatureStatusWithConfigAndPaymentStatus name cfgModel = Doc.defineModel (cs $ show name) $ do
Doc.description $ "Status and config of " <> cs (show name)
Doc.property "status" typeTeamFeatureStatusValue $ Doc.description "status"
Doc.property "config" (Doc.ref cfgModel) $ Doc.description "config"
Doc.property "paymentStatus" typePaymentStatusValue $ Doc.description "config"

instance ToSchema cfg => ToSchema (TeamFeatureStatusWithConfigAndPaymentStatus cfg) where
schema =
object "TeamFeatureStatusWithConfigAndPaymentStatus" $
TeamFeatureStatusWithConfigAndPaymentStatus
<$> tfwcapsStatus .= field "status" schema
<*> tfwcapsConfig .= field "config" schema
<*> tfwcapsPaymentStatus .= field "paymentStatus" schema

----------------------------------------------------------------------
-- TeamFeatureClassifiedDomainsConfig

Expand All @@ -383,7 +420,10 @@ modelTeamFeatureClassifiedDomainsConfig =
Doc.property "domains" (Doc.array Doc.string') $ Doc.description "domains"

defaultClassifiedDomains :: TeamFeatureStatusWithConfig TeamFeatureClassifiedDomainsConfig
defaultClassifiedDomains = TeamFeatureStatusWithConfig TeamFeatureDisabled (TeamFeatureClassifiedDomainsConfig [])
defaultClassifiedDomains =
TeamFeatureStatusWithConfig
TeamFeatureDisabled
(TeamFeatureClassifiedDomainsConfig [])

----------------------------------------------------------------------
-- TeamFeatureAppLockConfig
Expand Down Expand Up @@ -445,11 +485,82 @@ modelTeamFeatureSelfDeletingMessagesConfig =
Doc.defineModel "TeamFeatureSelfDeletingMessagesConfig" $ do
Doc.property "enforcedTimeoutSeconds" Doc.int32' $ Doc.description "optional; default: `0` (no enforcement)"

defaultSelfDeletingMessagesStatus :: TeamFeatureStatusWithConfig TeamFeatureSelfDeletingMessagesConfig
defaultSelfDeletingMessagesStatus :: TeamFeatureStatusWithConfigAndPaymentStatus TeamFeatureSelfDeletingMessagesConfig
defaultSelfDeletingMessagesStatus =
TeamFeatureStatusWithConfig
TeamFeatureStatusWithConfigAndPaymentStatus
TeamFeatureEnabled
(TeamFeatureSelfDeletingMessagesConfig 0)
PaymentLocked

----------------------------------------------------------------------
-- PaymentStatus

instance FromHttpApiData PaymentStatusValue where
parseUrlPiece = maybeToEither "Invalid payment status" . fromByteString . cs

data PaymentStatusValue = PaymentLocked | PaymentUnlocked
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform PaymentStatusValue)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema PaymentStatusValue)

newtype PaymentStatus = PaymentStatus
{ paymentStatus :: PaymentStatusValue
}
deriving stock (Eq, Show, Generic)
deriving (FromJSON, ToJSON, S.ToSchema) via (Schema PaymentStatus)
deriving (Arbitrary) via (GenericUniform PaymentStatus)

instance ToSchema PaymentStatus where
schema =
object "PaymentStatus" $
PaymentStatus
<$> paymentStatus .= field "paymentStatus" schema

modelPaymentStatus :: Doc.Model
modelPaymentStatus =
Doc.defineModel "PaymentStatus" $ do
Doc.property "paymentStatus" typePaymentStatusValue $ Doc.description ""

typePaymentStatusValue :: Doc.DataType
typePaymentStatusValue =
Doc.string $
Doc.enum
[ "locked",
"unlocked"
]

instance ToSchema PaymentStatusValue where
schema =
enum @Text "PaymentStatusValue" $
mconcat
[ element "locked" PaymentLocked,
element "unlocked" PaymentUnlocked
]

instance ToByteString PaymentStatusValue where
builder PaymentLocked = "locked"
builder PaymentUnlocked = "unlocked"

instance FromByteString PaymentStatusValue where
parser =
Parser.takeByteString >>= \b ->
case T.decodeUtf8' b of
Right "locked" -> pure PaymentLocked
Right "unlocked" -> pure PaymentUnlocked
Right t -> fail $ "Invalid PaymentStatusValue: " <> T.unpack t
Left e -> fail $ "Invalid PaymentStatusValue: " <> show e

instance Cass.Cql PaymentStatusValue where
ctype = Cass.Tagged Cass.IntColumn

fromCql (Cass.CqlInt n) = case n of
0 -> pure PaymentLocked
1 -> pure PaymentUnlocked
_ -> Left "fromCql: Invalid PaymentStatusValue"
fromCql _ = Left "fromCql: PaymentStatusValue: CqlInt expected"

toCql PaymentLocked = Cass.CqlInt 0
toCql PaymentUnlocked = Cass.CqlInt 1

----------------------------------------------------------------------
-- internal
Expand Down
Loading