app/model/UserData.scala (65 lines of code) (raw):

package model import com.gu.facia.client.models.Trail import model.editions.client.EditionsClientCard import org.scanamo.{DynamoFormat, TypeCoercionError} import play.api.libs.json.{JsValue, Json, OFormat} import scala.util.{Failure, Success, Try} object UserData { implicit val jsonFormat: OFormat[UserData] = Json.format[UserData] implicit val jsValueFormat: DynamoFormat[JsValue] = DynamoFormat.xmap[JsValue, String]( x => Try(Json.parse(x)) match { case Success(y) => Right(y) case Failure(f) => Left(TypeCoercionError(f)) }, Json.stringify(_) ) } /** Example of frontIdsByPriority data model: "favouriteFrontIdsByPriority": { * "editorial": [ "uk/news", "au/news" ] } * @TODO * make these strongly typed via com.gu.facia.client.models package */ case class UserData( email: String, clipboardArticles: Option[List[Trail]] = None, editionsClipboardArticles: Option[List[EditionsClientCard]] = None, feastEditionsClipboardCards: Option[List[EditionsClientCard]] = None, frontIds: Option[List[String]] = None, frontIdsByPriority: Option[Map[String, List[String]]] = None, favouriteFrontIdsByPriority: Option[Map[String, List[String]]] = None, featureSwitches: Option[List[FeatureSwitch]] = Some( List.empty[FeatureSwitch] ) ) object UserDataForDefaults { implicit val jsonFormat: OFormat[UserDataForDefaults] = Json.format[UserDataForDefaults] def fromUserData( userData: UserData, clipboardArticles: Option[List[ClipboardCard]] ): UserDataForDefaults = { val featureSwitches = userData.featureSwitches.fold(FeatureSwitches.all) { userFeatureSwitches => val userFeatureSwitchKeys = userFeatureSwitches.map(_.key) val unsetFeatureSwitches = FeatureSwitches.all.filter(featureSwitch => !userFeatureSwitchKeys.contains(featureSwitch.key) ) unsetFeatureSwitches ++ FeatureSwitches.removeUnknownSwitches( userFeatureSwitches ) } UserDataForDefaults( clipboardArticles, userData.frontIds, userData.frontIdsByPriority, userData.favouriteFrontIdsByPriority, Some(featureSwitches) ) } } case class UserDataForDefaults( clipboardArticles: Option[List[ClipboardCard]], frontIds: Option[List[String]], frontIdsByPriority: Option[Map[String, List[String]]], favouriteFrontIdsByPriority: Option[Map[String, List[String]]], featureSwitches: Option[List[FeatureSwitch]] = Some( List.empty[FeatureSwitch] ) )