{-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell #-} -- | Abstraction to fetch and store feature values from and to the database. module Galley.Cassandra.MakeFeature where import Cassandra import Cassandra qualified as C import Data.Functor import Data.Functor.Identity import Data.Id import Data.Kind import Data.List.Singletons (Length) import Data.Misc (HttpsUrl) import Data.Singletons (demote) import Data.Time import Data.Time.Clock.POSIX import GHC.TypeNats import Galley.Cassandra.FeatureTH import Galley.Cassandra.Instances () import Generics.SOP import Imports hiding (Generic, Map) import Wire.API.Conversation.Protocol (ProtocolTag) import Wire.API.MLS.CipherSuite import Wire.API.Team.Feature -- [Note: default values for configuration fields] -- -- When reading values for configuration types with multiple fields, we fall -- back to default values for each field independently, instead of treating the -- whole configuration as a single value that can be set or not. -- -- In most cases, either strategy would produce the same result, because there -- is no way to set only *some* fields using the public API. However, that can -- happen when a feature flag changes over time and gains new fields, as it has -- been the case for mlsE2EId. -- -- Therefore, we use the first strategy consistently for all feature flags, -- even when it does not matter. -- | This is necessary in order to convert an @NP f xs@ type to something that -- CQL can understand. -- -- The generated code looks like: -- @@ -- instance TupleP xs where -- TupleP '[] = () -- TupleP '[a] = Identity a -- TupleP '[a, b] = (a, b) -- ... -- @@ $