in client/src/main/scala/com.gu.contentapi.client/utils/CapiModelEnrichment.scala [20:56]
def tagExistsWithId(tagId: String): ContentFilter = content => content.tags.exists(tag => tag.id == tagId)
def displayHintExistsWithName(displayHintName: String): ContentFilter = content => content.fields.flatMap(_.displayHint).contains(displayHintName)
def isLiveBloggingNow: ContentFilter = content => content.fields.flatMap(_.liveBloggingNow).contains(true)
val isImmersive: ContentFilter = content => displayHintExistsWithName("immersive")(content)
val isPhotoEssay: ContentFilter = content => displayHintExistsWithName("photoEssay")(content)
val isMedia: ContentFilter = content => tagExistsWithId("type/audio")(content) || tagExistsWithId("type/video")(content) || tagExistsWithId("type/gallery")(content)
val isReview: ContentFilter = content => tagExistsWithId("tone/reviews")(content) || tagExistsWithId("tone/livereview")(content) || tagExistsWithId("tone/albumreview")(content)
val isLiveBlog: ContentFilter = content => isLiveBloggingNow(content) && tagExistsWithId("tone/minutebyminute")(content)
val isDeadBlog: ContentFilter = content => !isLiveBloggingNow(content) && tagExistsWithId("tone/minutebyminute")(content)
val isInteractive: ContentFilter = content => content.`type` == ContentType.Interactive
val isPictureContent: ContentFilter = content => content.`type` == ContentType.Picture
val isGallery: ContentFilter = tagExistsWithId("type/gallery")
// The date used here is arbitrary and will be moved nearer to the present when the new template feature is ready to be used in production
val immersiveInteractiveSwitchoverDate = ZonedDateTime.of(2025, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)
val publishedBeforeInteractiveImmersiveSwitchover: ContentFilter = content => content.fields.flatMap(_.creationDate).exists(date => ZonedDateTime.parse(date.iso8601).isBefore(immersiveInteractiveSwitchoverDate))
val isLegacyImmersiveInteractive: ContentFilter = content => isInteractive(content) && isImmersive(content) && publishedBeforeInteractiveImmersiveSwitchover(content)
val isObituary: ContentFilter = content => (tagExistsWithId("tone/obituaries")(content) && !tagExistsWithId("tone/letters")(content))
val isFullPageInteractive: ContentFilter = content => isInteractive(content) && (displayHintExistsWithName("fullPageInteractive")(content) || isLegacyImmersiveInteractive(content))
implicit class RichCapiDateTime(val cdt: CapiDateTime) extends AnyVal {
def toOffsetDateTime: OffsetDateTime = OffsetDateTime.parse(cdt.iso8601)
}