mirror of
https://github.com/AdrianKuta/KahootQuiz.git
synced 2025-09-16 18:14:22 +02:00
feat: Expand domain models and implement full DTO to domain mapping
This commit significantly expands the domain models to fully represent the quiz structure and implements the complete mapping logic in `QuizMapper` to convert `QuizResponseDto` and its nested DTOs to their corresponding domain models. Key changes: - **Domain Layer (`domain` module):** - Introduced a `QuizId` value class for type safety. - Added comprehensive domain models for all aspects of a quiz, including: - `Quiz`: Updated to include all fields from the DTO. - `Question`, `Choice`, `Video`, `ImageMetadata`, `MediaItem`, `ChoiceRange`: For question details. - `CoverMetadata`, `ExtractedColor`, `Crop`, `Point`: For cover image information. - `ContentTags`: For curriculum and generated codes. - `Metadata`, `Access`, `FeaturedListMembership`, `LastEdit`, `VersionMetadata`: For quiz metadata. - `LanguageInfo`, `Channel`: Common reusable models. - Organized domain models into separate files for better maintainability (e.g., `Question.kt`, `CoverMetadata.kt`). - Added a placeholder `QuestionModels.kt` to indicate that models were moved. - **Data Layer (`model:data` module):** - Implemented a complete `toDomainModel()` extension function in `QuizMapper.kt` to map all fields from `QuizResponseDto` and its nested DTOs (like `CoverMetadataDto`, `QuestionDto`, etc.) to the new domain models. - This includes mapping for lists and nullable fields. - **App Module (`app` module):** - Updated `MainActivity` to access `quizId.value` due to `QuizId` being a value class. - **Network Layer (`core:network` module):** - Changed `QuizResponseDto.uuid` to be non-nullable (`String`) as it's essential for mapping to `QuizId`. - Removed `QuizResponse.kt` as DTOs were previously split into individual files.
This commit is contained in:
@@ -1,7 +1,176 @@
|
||||
package dev.adriankuta.kahootquiz.model.data.mappers
|
||||
|
||||
import dev.adriankuta.kahootquiz.core.network.models.QuizResponseDto
|
||||
import dev.adriankuta.kahootquiz.domain.models.Quiz
|
||||
import dev.adriankuta.kahootquiz.core.network.models.*
|
||||
import dev.adriankuta.kahootquiz.domain.models.*
|
||||
|
||||
internal fun QuizResponseDto.toDomainModel(): Quiz =
|
||||
Quiz(this.uuid ?: "")
|
||||
Quiz(
|
||||
id = QuizId(uuid),
|
||||
language = language,
|
||||
creator = creator,
|
||||
creatorUsername = creatorUsername,
|
||||
compatibilityLevel = compatibilityLevel,
|
||||
creatorPrimaryUsage = creatorPrimaryUsage,
|
||||
folderId = folderId,
|
||||
themeId = themeId,
|
||||
visibility = visibility,
|
||||
audience = audience,
|
||||
title = title,
|
||||
description = description,
|
||||
quizType = quizType,
|
||||
cover = cover,
|
||||
coverMetadata = coverMetadata?.toDomain(),
|
||||
questions = questions?.map { it.toDomain() } ?: emptyList(),
|
||||
contentTags = contentTags?.toDomain(),
|
||||
metadata = metadata?.toDomain(),
|
||||
resources = resources,
|
||||
slug = slug,
|
||||
languageInfo = languageInfo?.toDomain(),
|
||||
inventoryItemIds = inventoryItemIds ?: emptyList(),
|
||||
channels = channels?.map { it.toDomain() } ?: emptyList(),
|
||||
isValid = isValid,
|
||||
playAsGuest = playAsGuest,
|
||||
hasRestrictedContent = hasRestrictedContent,
|
||||
type = type,
|
||||
created = created,
|
||||
modified = modified
|
||||
)
|
||||
|
||||
private fun CoverMetadataDto.toDomain(): CoverMetadata = CoverMetadata(
|
||||
id = id,
|
||||
altText = altText,
|
||||
contentType = contentType,
|
||||
origin = origin,
|
||||
externalRef = externalRef,
|
||||
resources = resources,
|
||||
width = width,
|
||||
height = height,
|
||||
extractedColors = extractedColors?.map { it.toDomain() },
|
||||
blurhash = blurhash,
|
||||
crop = crop?.toDomain()
|
||||
)
|
||||
|
||||
private fun ExtractedColorDto.toDomain(): ExtractedColor = ExtractedColor(
|
||||
swatch = swatch,
|
||||
rgbHex = rgbHex
|
||||
)
|
||||
|
||||
private fun CropDto.toDomain(): Crop = Crop(
|
||||
origin = origin?.toDomain(),
|
||||
target = target?.toDomain(),
|
||||
circular = circular
|
||||
)
|
||||
|
||||
private fun PointDto.toDomain(): Point = Point(x = x, y = y)
|
||||
|
||||
private fun ContentTagsDto.toDomain(): ContentTags = ContentTags(
|
||||
curriculumCodes = curriculumCodes,
|
||||
generatedCurriculumCodes = generatedCurriculumCodes
|
||||
)
|
||||
|
||||
private fun MetadataDto.toDomain(): Metadata = Metadata(
|
||||
access = access?.toDomain(),
|
||||
duplicationProtection = duplicationProtection,
|
||||
featuredListMemberships = featuredListMemberships?.map { it.toDomain() },
|
||||
lastEdit = lastEdit?.toDomain(),
|
||||
versionMetadata = versionMetadata?.toDomain()
|
||||
)
|
||||
|
||||
private fun AccessDto.toDomain(): Access = Access(
|
||||
groupRead = groupRead,
|
||||
folderGroupIds = folderGroupIds,
|
||||
features = features
|
||||
)
|
||||
|
||||
private fun FeaturedListMembershipDto.toDomain(): FeaturedListMembership = FeaturedListMembership(
|
||||
list = list,
|
||||
addedAt = addedAt
|
||||
)
|
||||
|
||||
private fun LastEditDto.toDomain(): LastEdit = LastEdit(
|
||||
editorUserId = editorUserId,
|
||||
editorUsername = editorUsername,
|
||||
editTimestamp = editTimestamp
|
||||
)
|
||||
|
||||
private fun VersionMetadataDto.toDomain(): VersionMetadata = VersionMetadata(
|
||||
version = version,
|
||||
created = created,
|
||||
creator = creator
|
||||
)
|
||||
|
||||
private fun LanguageInfoDto.toDomain(): LanguageInfo = LanguageInfo(
|
||||
language = language,
|
||||
lastUpdatedOn = lastUpdatedOn,
|
||||
readAloudSupported = readAloudSupported
|
||||
)
|
||||
|
||||
private fun ChannelDto.toDomain(): Channel = Channel(id = id)
|
||||
|
||||
private fun QuestionDto.toDomain(): Question = Question(
|
||||
type = type,
|
||||
question = question,
|
||||
time = time,
|
||||
points = points,
|
||||
pointsMultiplier = pointsMultiplier,
|
||||
choices = choices?.map { it.toDomain() },
|
||||
layout = layout,
|
||||
image = image,
|
||||
imageMetadata = imageMetadata?.toDomain(),
|
||||
resources = resources,
|
||||
video = video?.toDomain(),
|
||||
questionFormat = questionFormat,
|
||||
languageInfo = languageInfo?.toDomain(),
|
||||
media = media?.map { it.toDomain() },
|
||||
choiceRange = choiceRange?.toDomain()
|
||||
)
|
||||
|
||||
private fun ChoiceDto.toDomain(): Choice = Choice(
|
||||
answer = answer,
|
||||
correct = correct,
|
||||
languageInfo = languageInfo?.toDomain()
|
||||
)
|
||||
|
||||
private fun VideoDto.toDomain(): Video = Video(
|
||||
id = id,
|
||||
startTime = startTime,
|
||||
endTime = endTime,
|
||||
service = service,
|
||||
fullUrl = fullUrl
|
||||
)
|
||||
|
||||
private fun ImageMetadataDto.toDomain(): ImageMetadata = ImageMetadata(
|
||||
id = id,
|
||||
altText = altText,
|
||||
contentType = contentType,
|
||||
origin = origin,
|
||||
externalRef = externalRef,
|
||||
resources = resources,
|
||||
width = width,
|
||||
height = height,
|
||||
effects = effects,
|
||||
crop = crop?.toDomain()
|
||||
)
|
||||
|
||||
private fun MediaItemDto.toDomain(): MediaItem = MediaItem(
|
||||
type = type,
|
||||
zIndex = zIndex,
|
||||
isColorOnly = isColorOnly,
|
||||
id = id,
|
||||
altText = altText,
|
||||
contentType = contentType,
|
||||
origin = origin,
|
||||
externalRef = externalRef,
|
||||
resources = resources,
|
||||
width = width,
|
||||
height = height,
|
||||
crop = crop?.toDomain()
|
||||
)
|
||||
|
||||
private fun ChoiceRangeDto.toDomain(): ChoiceRange = ChoiceRange(
|
||||
start = start,
|
||||
end = end,
|
||||
step = step,
|
||||
correct = correct,
|
||||
tolerance = tolerance
|
||||
)
|
||||
|
Reference in New Issue
Block a user