From 3f9023fc9af324889320836d019358e667faf6b1 Mon Sep 17 00:00:00 2001 From: motola Date: Mon, 5 May 2025 14:30:00 +0100 Subject: [PATCH 1/3] improve clarity and maintainability of codebase --- .../data/datasource/ArtistDataSource.kt | 18 +++++ .../mapper/ArtistAlbumDataToDomainMapper.kt | 11 +++ .../data/mapper/ArtistDataToDomainMapper.kt | 12 ++- .../muryno/data/model/ArtistAlbumDataModel.kt | 16 ++++ .../com/muryno/data/model/ArtistDataModel.kt | 15 +++- .../data/repository/ArtistLiveRepository.kt | 22 ++++- .../artist_datasource/api/MusicApiService.kt | 19 +++++ .../datasource/ArtistRemoteDataSource.kt | 22 ++++- .../ArtistAlbumApiToResponseDataMapper.kt | 12 ++- .../mapper/ArtistApiToResponseDataMapper.kt | 12 ++- .../muryno/artist_datasource/model/Aliase.kt | 12 +++ .../muryno/artist_datasource/model/Area.kt | 10 +++ .../artist_datasource/model/ArtistApiModel.kt | 24 ++++++ .../model/ArtistListApiModel.kt | 8 ++ .../artist_datasource/model/BeginArea.kt | 11 +++ .../artist_datasource/model/LifeSpan.kt | 5 ++ .../artist_datasource/model/LifeSpanXX.kt | 6 ++ .../com/muryno/artist_datasource/model/Tag.kt | 6 ++ .../model/album/AlbumReleaseGroupApiModel.kt | 15 ++++ .../model/album/AristAlbumApiModel.kt | 7 ++ buildSrc/src/main/java/BuildAndroidConfig.kt | 45 +++++++++++ buildSrc/src/main/java/BuildDepVersions.kt | 50 ++++++++++++ buildSrc/src/main/java/BuildModules.kt | 17 +++- buildSrc/src/main/java/BuildPlugins.kt | 16 ++++ buildSrc/src/main/java/Libs.kt | 80 +++++++++++++++++++ buildSrc/src/main/java/TestLibs.kt | 50 ++++++++++++ 26 files changed, 514 insertions(+), 7 deletions(-) diff --git a/artist-data/src/main/java/com/muryno/data/datasource/ArtistDataSource.kt b/artist-data/src/main/java/com/muryno/data/datasource/ArtistDataSource.kt index 814b07f2..c7a85499 100644 --- a/artist-data/src/main/java/com/muryno/data/datasource/ArtistDataSource.kt +++ b/artist-data/src/main/java/com/muryno/data/datasource/ArtistDataSource.kt @@ -3,7 +3,25 @@ package com.muryno.data.datasource import com.muryno.data.model.ArtistAlbumDataModel import com.muryno.data.model.ArtistDataModel +/** + * Data source interface for retrieving artist and album information. + * This interface defines the contract for fetching data from external sources + * (typically remote APIs). Implementations handle the actual data retrieval logic. + */ interface ArtistDataSource { + /** + * Retrieves a list of artists matching the search query. + * + * @param artistName The name of the artist to search for + * @return List of [ArtistDataModel] containing matching artists + */ suspend fun getArtistListFromApi(artistName: String): List + + /** + * Retrieves album releases for a specific artist. + * + * @param artistId The unique identifier of the artist + * @return List of [ArtistAlbumDataModel] containing the artist's albums + */ suspend fun getArtistAlbumFromApi(artistId: String): List } \ No newline at end of file diff --git a/artist-data/src/main/java/com/muryno/data/mapper/ArtistAlbumDataToDomainMapper.kt b/artist-data/src/main/java/com/muryno/data/mapper/ArtistAlbumDataToDomainMapper.kt index f38334a9..ef86ec97 100644 --- a/artist-data/src/main/java/com/muryno/data/mapper/ArtistAlbumDataToDomainMapper.kt +++ b/artist-data/src/main/java/com/muryno/data/mapper/ArtistAlbumDataToDomainMapper.kt @@ -3,8 +3,19 @@ package com.muryno.data.mapper import com.muryno.data.model.ArtistAlbumDataModel import com.muryno.domain.artistAlbulm.model.ArtistAlbumDomainModel +/** + * Mapper class for converting album data models to domain models. + * Transforms [ArtistAlbumDataModel] from the data layer into [ArtistAlbumDomainModel] + * used in the domain layer. + */ class ArtistAlbumDataToDomainMapper { + /** + * Converts an [ArtistAlbumDataModel] to an [ArtistAlbumDomainModel]. + * + * @param input The album data model to convert + * @return [ArtistAlbumDomainModel] with mapped album information + */ fun toDomain(input: ArtistAlbumDataModel): ArtistAlbumDomainModel { return ArtistAlbumDomainModel( id = input.id, diff --git a/artist-data/src/main/java/com/muryno/data/mapper/ArtistDataToDomainMapper.kt b/artist-data/src/main/java/com/muryno/data/mapper/ArtistDataToDomainMapper.kt index 916b672d..5301d94c 100644 --- a/artist-data/src/main/java/com/muryno/data/mapper/ArtistDataToDomainMapper.kt +++ b/artist-data/src/main/java/com/muryno/data/mapper/ArtistDataToDomainMapper.kt @@ -3,8 +3,18 @@ package com.muryno.data.mapper import com.muryno.data.model.ArtistDataModel import com.muryno.domain.artist.model.ArtistDomainModel - +/** + * Mapper class for converting artist data models to domain models. + * Transforms [ArtistDataModel] from the data layer into [ArtistDomainModel] + * used in the domain layer. + */ class ArtistDataToDomainMapper { + /** + * Converts an [ArtistDataModel] to an [ArtistDomainModel]. + * + * @param input The artist data model to convert + * @return [ArtistDomainModel] with mapped artist information + */ fun toDomain(input: ArtistDataModel): ArtistDomainModel { return ArtistDomainModel( id = input.id, diff --git a/artist-data/src/main/java/com/muryno/data/model/ArtistAlbumDataModel.kt b/artist-data/src/main/java/com/muryno/data/model/ArtistAlbumDataModel.kt index cc169f58..215f7c22 100644 --- a/artist-data/src/main/java/com/muryno/data/model/ArtistAlbumDataModel.kt +++ b/artist-data/src/main/java/com/muryno/data/model/ArtistAlbumDataModel.kt @@ -1,5 +1,21 @@ package com.muryno.data.model +/** + * Data layer model representing album/release information for an artist. + * This model is used in the data layer to transfer album data between + * the data source and repository. + * + * @property primaryType Primary type of the release (Album, Single, EP, etc.) + * @property genre Musical genre of the album + * @property label Record label that released the album + * @property shortDescription Brief description of the album + * @property fullDescription Complete description of the album + * @property albumImage URL or path to the album cover image + * @property releaseDate Date when the album was released + * @property title Title of the album + * @property id Unique identifier for the album + * @property disambiguation Additional text to distinguish similar albums + */ data class ArtistAlbumDataModel( val primaryType: String, diff --git a/artist-data/src/main/java/com/muryno/data/model/ArtistDataModel.kt b/artist-data/src/main/java/com/muryno/data/model/ArtistDataModel.kt index 77810131..4a316166 100644 --- a/artist-data/src/main/java/com/muryno/data/model/ArtistDataModel.kt +++ b/artist-data/src/main/java/com/muryno/data/model/ArtistDataModel.kt @@ -2,7 +2,20 @@ package com.muryno.data.model import java.io.Serializable - +/** + * Data layer model representing artist information. + * This model is used in the data layer to transfer artist data between + * the data source and repository. + * + * @property id Unique identifier for the artist + * @property name Name of the artist + * @property gender Gender of the artist (if applicable) + * @property type Type/classification of the artist + * @property state State or region information + * @property country Country of origin + * @property disambiguation Additional information to distinguish similar artists + * @property score Relevance score from search results + */ data class ArtistDataModel( val id: String, val name: String, diff --git a/artist-data/src/main/java/com/muryno/data/repository/ArtistLiveRepository.kt b/artist-data/src/main/java/com/muryno/data/repository/ArtistLiveRepository.kt index db2b7eb2..1a66719f 100644 --- a/artist-data/src/main/java/com/muryno/data/repository/ArtistLiveRepository.kt +++ b/artist-data/src/main/java/com/muryno/data/repository/ArtistLiveRepository.kt @@ -8,19 +8,39 @@ import com.muryno.domain.artistAlbulm.model.ArtistAlbumDomainModel import com.muryno.domain.artist.model.ArtistDomainModel import com.muryno.domain.artist.repository.ArtistRepository - +/** + * Repository implementation for managing artist data operations. + * This class implements the [ArtistRepository] interface from the domain layer, + * coordinating between the data source and mappers to provide domain models. + * + * @property artistDataSource Data source for fetching raw artist data + * @property artistDataToDomainMapper Mapper for converting artist data models to domain models + * @property artistAlbumDataToDomainMapper Mapper for converting album data models to domain models + */ class ArtistLiveRepository( private val artistDataSource: ArtistDataSource, private val artistDataToDomainMapper: ArtistDataToDomainMapper, private val artistAlbumDataToDomainMapper: ArtistAlbumDataToDomainMapper, ) : ArtistRepository { + /** + * Retrieves a list of artists matching the search query and maps them to domain models. + * + * @param artistName The name of the artist to search for + * @return List of [ArtistDomainModel] containing matching artists + */ override suspend fun artistList(artistName: String): List = artistDataSource.getArtistListFromApi(artistName).map( artistDataToDomainMapper::toDomain ) + /** + * Retrieves album releases for a specific artist and maps them to domain models. + * + * @param artistId The unique identifier of the artist + * @return List of [ArtistAlbumDomainModel] containing the artist's albums + */ override suspend fun artistAlbum(artistId: String): List = artistDataSource.getArtistAlbumFromApi( artistId diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/api/MusicApiService.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/api/MusicApiService.kt index cd96b0b8..bd039365 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/api/MusicApiService.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/api/MusicApiService.kt @@ -7,7 +7,18 @@ import retrofit2.http.GET import retrofit2.http.Headers import retrofit2.http.Query +/** + * Retrofit service interface for interacting with the MusicBrainz API. + * Provides endpoints for fetching artist information and album data. + */ interface MusicApiService { + /** + * Fetches a list of artists from the MusicBrainz API based on search query. + * + * @param artistName The name of the artist to search for + * @param fmt Response format (defaults to "json") + * @return [ArtistListApiModel] containing the list of matching artists + */ @Headers( "Accept: application/json", "User-Agent: com.ubn.musicbrainz_place/1.0" @@ -19,6 +30,14 @@ interface MusicApiService { ): ArtistListApiModel + /** + * Fetches album releases for a specific artist from the MusicBrainz API. + * + * @param artistId The unique identifier of the artist + * @param type The type of releases to fetch (defaults to "album") + * @param fmt Response format (defaults to "json") + * @return [AristAlbumApiModel] containing the artist's album releases + */ @Headers( "Accept: application/json", "User-Agent: com.ubn.musicbrainz_place/1.0" diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/datasource/ArtistRemoteDataSource.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/datasource/ArtistRemoteDataSource.kt index 2f7322f7..6cfee80b 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/datasource/ArtistRemoteDataSource.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/datasource/ArtistRemoteDataSource.kt @@ -7,18 +7,38 @@ import com.muryno.data.datasource.ArtistDataSource import com.muryno.data.model.ArtistAlbumDataModel import com.muryno.data.model.ArtistDataModel - +/** + * Remote data source implementation for fetching artist data from the MusicBrainz API. + * This class implements the [ArtistDataSource] interface and handles API calls, + * mapping API models to data layer models. + * + * @property musicApiService The Retrofit service for making API requests + * @property artistAlbumApiToResponseDataMapper Mapper for converting album API models to data models + * @property artistApiToResponseDataMapper Mapper for converting artist API models to data models + */ class ArtistRemoteDataSource( private val musicApiService: MusicApiService, private val artistAlbumApiToResponseDataMapper: ArtistAlbumApiToResponseDataMapper, private val artistApiToResponseDataMapper: ArtistApiToResponseDataMapper ) : ArtistDataSource { + /** + * Retrieves a list of artists from the API based on the search query. + * + * @param artistName The name of the artist to search for + * @return List of [ArtistDataModel] containing artist information + */ override suspend fun getArtistListFromApi(artistName: String): List { val data = musicApiService.fetchArtistFromServer(artistName = artistName) return data.artists.map { artistApiToResponseDataMapper.toData(it) } } + /** + * Retrieves album releases for a specific artist from the API. + * + * @param artistId The unique identifier of the artist + * @return List of [ArtistAlbumDataModel] containing album information + */ override suspend fun getArtistAlbumFromApi( artistId: String ): List { diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistAlbumApiToResponseDataMapper.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistAlbumApiToResponseDataMapper.kt index 829da541..7c138e87 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistAlbumApiToResponseDataMapper.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistAlbumApiToResponseDataMapper.kt @@ -3,8 +3,18 @@ package com.muryno.artist_datasource.mapper import com.muryno.artist_datasource.model.album.AlbumReleaseGroupApiModel import com.muryno.data.model.ArtistAlbumDataModel - +/** + * Mapper class for converting album API models to data layer models. + * Transforms [AlbumReleaseGroupApiModel] from the MusicBrainz API into [ArtistAlbumDataModel] + * used in the data layer. + */ class ArtistAlbumApiToResponseDataMapper { + /** + * Converts an [AlbumReleaseGroupApiModel] to an [ArtistAlbumDataModel]. + * + * @param input The album API model to convert + * @return [ArtistAlbumDataModel] with mapped album information + */ fun toData(input: AlbumReleaseGroupApiModel): ArtistAlbumDataModel { return ArtistAlbumDataModel( id = input.id, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistApiToResponseDataMapper.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistApiToResponseDataMapper.kt index 299f6693..de7c671c 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistApiToResponseDataMapper.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/mapper/ArtistApiToResponseDataMapper.kt @@ -3,8 +3,18 @@ package com.muryno.artist_datasource.mapper import com.muryno.artist_datasource.model.ArtistApiModel import com.muryno.data.model.ArtistDataModel - +/** + * Mapper class for converting artist API models to data layer models. + * Transforms [ArtistApiModel] from the MusicBrainz API into [ArtistDataModel] + * used in the data layer. + */ class ArtistApiToResponseDataMapper { + /** + * Converts an [ArtistApiModel] to an [ArtistDataModel]. + * + * @param input The artist API model to convert + * @return [ArtistDataModel] with mapped artist information + */ fun toData(input: ArtistApiModel): ArtistDataModel { return ArtistDataModel( id = input.id, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Aliase.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Aliase.kt index 84179156..1d4af4c1 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Aliase.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Aliase.kt @@ -2,6 +2,18 @@ package com.muryno.artist_datasource.model import com.google.gson.annotations.SerializedName +/** + * API model representing an alternative name or alias for an artist. + * + * @property beginDate Date when this alias started being used + * @property endDate Date when this alias stopped being used + * @property locale Language/region code for the alias + * @property name The alias name + * @property primary Whether this is the primary name in its locale + * @property sortName Alias name formatted for sorting + * @property type Type of alias (e.g., Legal name, Stage name) + * @property typeId Unique identifier for the alias type + */ data class Aliase( @SerializedName("begin-date") val beginDate: Any, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Area.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Area.kt index 01c4fcd0..ada55c23 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Area.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Area.kt @@ -2,6 +2,16 @@ package com.muryno.artist_datasource.model import com.google.gson.annotations.SerializedName +/** + * API model representing a geographic area in MusicBrainz. + * + * @property id Unique identifier for the area + * @property lifeSpan Time period the area existed (for historical areas) + * @property name Name of the area + * @property sortName Name formatted for sorting + * @property type Type of area (e.g., Country, City, State) + * @property typeId Unique identifier for the area type + */ data class Area( val id: String, @SerializedName("life-span") diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistApiModel.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistApiModel.kt index ddfdaf02..d8705e4d 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistApiModel.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistApiModel.kt @@ -2,6 +2,30 @@ package com.muryno.artist_datasource.model import com.google.gson.annotations.SerializedName +/** + * API model representing an artist from the MusicBrainz database. + * Contains comprehensive information about an artist including metadata, geographic data, + * and identification information. + * + * @property aliases List of alternative names for the artist + * @property area Geographic area associated with the artist + * @property beginArea Area where the artist was founded/born + * @property disambiguation Additional text to distinguish between similar artists + * @property state State or province information + * @property country Country code for the artist + * @property gender Gender of the artist (for individuals) + * @property genderId Unique identifier for the gender + * @property id Unique MusicBrainz identifier for the artist + * @property ipis List of IPI (Interested Parties Information) codes + * @property isnis List of ISNI (International Standard Name Identifier) codes + * @property lifeSpan Birth and death dates or formation period + * @property name Primary name of the artist + * @property score Relevance score from search results + * @property sortName Name formatted for sorting + * @property tags List of tags describing the artist + * @property type Artist type (e.g., Person, Group, Orchestra) + * @property typeId Unique identifier for the artist type + */ data class ArtistApiModel( val aliases: List?, val area: Area?, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistListApiModel.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistListApiModel.kt index 1ec54d5b..b28f68d8 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistListApiModel.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/ArtistListApiModel.kt @@ -1,5 +1,13 @@ package com.muryno.artist_datasource.model +/** + * API response model for artist search results from MusicBrainz. + * + * @property artists List of artist results matching the search query + * @property count Total number of results found + * @property created Timestamp when the response was created + * @property offset Pagination offset for the results + */ data class ArtistListApiModel( val artists: List, val count: Int, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/BeginArea.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/BeginArea.kt index 6f8cba01..b9797891 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/BeginArea.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/BeginArea.kt @@ -2,6 +2,17 @@ package com.muryno.artist_datasource.model import com.google.gson.annotations.SerializedName +/** + * API model representing the starting/birth area of an artist. + * Contains geographic information about where an artist was founded or born. + * + * @property id Unique identifier for the area + * @property lifeSpan Historical period information for the area + * @property name Name of the area + * @property sortName Name formatted for sorting + * @property type Type of area (e.g., Country, City) + * @property typeId Unique identifier for the area type + */ data class BeginArea( val id: String, @SerializedName("life-span") diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpan.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpan.kt index 9cdaf2d6..6faa55f2 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpan.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpan.kt @@ -1,5 +1,10 @@ package com.muryno.artist_datasource.model +/** + * API model representing a time period for an area or entity. + * + * @property ended Whether the time period has ended + */ data class LifeSpan( val ended: Any ) \ No newline at end of file diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpanXX.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpanXX.kt index 7a100ec6..9362e5f2 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpanXX.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/LifeSpanXX.kt @@ -1,5 +1,11 @@ package com.muryno.artist_datasource.model +/** + * API model representing the life span or active period of an artist. + * + * @property begin Start date (birth date for persons, formation date for groups) + * @property ended Whether the artist is deceased or disbanded + */ data class LifeSpanXX( val begin: String, val ended: Any diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Tag.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Tag.kt index 4801d070..cda9f5a5 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Tag.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/Tag.kt @@ -1,5 +1,11 @@ package com.muryno.artist_datasource.model +/** + * API model representing a tag or genre classification for an artist. + * + * @property count Number of users who have applied this tag + * @property name The tag/genre name + */ data class Tag( val count: Int, val name: String diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AlbumReleaseGroupApiModel.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AlbumReleaseGroupApiModel.kt index eee9e6f7..ae16ab8c 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AlbumReleaseGroupApiModel.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AlbumReleaseGroupApiModel.kt @@ -2,6 +2,21 @@ package com.muryno.artist_datasource.model.album import com.google.gson.annotations.SerializedName +/** + * API model representing an album release group from MusicBrainz. + * A release group represents all releases of the same album across different formats. + * + * @property disambiguation Text to distinguish between similarly titled albums + * @property firstReleaseDate Date of the first release in this group + * @property id Unique MusicBrainz identifier for the release group + * @property primaryType Primary type of the release (e.g., Album, Single, EP) + * @property primaryTypeId Unique identifier for the primary type + * @property secondaryTypeIds List of secondary type identifiers + * @property secondaryTypes List of secondary release types (e.g., Compilation, Live) + * @property title Title of the album/release group + * @property genre Musical genre classification + * @property label Record label that released the album + */ data class AlbumReleaseGroupApiModel( val disambiguation: String, @SerializedName("first-release-date") val firstReleaseDate: String, diff --git a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AristAlbumApiModel.kt b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AristAlbumApiModel.kt index 7ce7aaa6..e54a7a26 100644 --- a/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AristAlbumApiModel.kt +++ b/artist-datasource/src/main/java/com/muryno/artist_datasource/model/album/AristAlbumApiModel.kt @@ -2,6 +2,13 @@ package com.muryno.artist_datasource.model.album import com.google.gson.annotations.SerializedName +/** + * API response model for artist album/release group data from MusicBrainz. + * + * @property releaseGroupCount Total number of release groups for the artist + * @property releaseGroupOffset Pagination offset for release groups + * @property albumReleaseGroupApiModels List of release group/album data + */ data class AristAlbumApiModel( @SerializedName("release-group-count") val releaseGroupCount: Int, diff --git a/buildSrc/src/main/java/BuildAndroidConfig.kt b/buildSrc/src/main/java/BuildAndroidConfig.kt index 6cdb2f4c..03729d44 100644 --- a/buildSrc/src/main/java/BuildAndroidConfig.kt +++ b/buildSrc/src/main/java/BuildAndroidConfig.kt @@ -1,23 +1,68 @@ +/** + * Configuration object containing Android build settings and application identifiers. + * This object centralizes all build configuration constants used across the multi-module project. + */ object BuildAndroidConfig { + /** + * Main application ID for the app module + */ const val APPLICATION_ID = "com.muryno.muzic" + /** + * Package identifier for the data layer module + */ const val APPLICATION_DATA = "com.muryno.data" + + /** + * Package identifier for the domain layer module + */ const val APPLICATION_DOMAIN = "com.muryno.domain" + + /** + * Package identifier for the presentation layer module + */ const val APPLICATION_PRESENTATION = "com.muryno.presentation" + /** + * Package identifier for the artist UI module + */ const val APPLICATION_ARTIST_UI = "com.muryno.artist" + /** + * Android SDK version to compile against + */ const val COMPILE_SDK_VERSION = 34 + + /** + * Minimum Android SDK version supported by the app + */ const val MIN_SDK_VERSION = 21 + + /** + * Target Android SDK version for the app + */ const val TARGET_SDK_VERSION = 34 + /** + * Version code for the application (used for versioning in Play Store) + */ const val VERSION_CODE = 1 + + /** + * Version name for the application (user-visible version string) + */ const val VERSION_NAME = "1.0" + /** + * Test runner class for Android instrumented tests + */ const val ANDROID_JUNIT_RUNNER = "androidx.test.runner.AndroidJUnitRunner" + /** + * JVM bytecode target version + */ const val JVM_TARGET = "1.8" } \ No newline at end of file diff --git a/buildSrc/src/main/java/BuildDepVersions.kt b/buildSrc/src/main/java/BuildDepVersions.kt index 9239a8f9..7cf60440 100644 --- a/buildSrc/src/main/java/BuildDepVersions.kt +++ b/buildSrc/src/main/java/BuildDepVersions.kt @@ -1,69 +1,119 @@ +/** + * Centralized version management object for all project dependencies. + * This object defines version numbers for libraries used throughout the application + * to maintain consistency and easy version updates. + */ object BuildDepVersions { //----------------------------------------------------------------------------------------------------- //CORE + /** AndroidX Core KTX version */ const val CORE_KTX = "1.7.0" + + /** AndroidX AppCompat version */ const val CORE_APP = "7.1.2" + + /** Kotlin Standard Library JDK version */ const val KOTLIN_STDLIB_JDK = "1.6.10" + + /** Kotlin language version */ const val KOTLIN = "1.6.10" //----------------------------------------------------------------------------------------------------- //TEST LIBS + /** JUnit testing framework version */ const val JUNIT = "4.13.2" + + /** AndroidX JUnit extension version */ const val JUNIT_EXT_ANDROID = "1.1.3" + + /** Espresso UI testing framework version */ const val EXPRESSO = "3.4.0" //----------------------------------------------------------------------------------------------------- //JETPACK COMPOSE + /** Jetpack Compose UI toolkit version */ const val COMPOSE = "1.1.1" + + /** Compose compiler version */ const val COMPOSE_COMPILER = "1.5.1" + + /** Compose Activity integration version */ const val COMPOSE_ACTIVITY = "1.3.1" + + /** Accompanist navigation animation version */ const val COMPOSE_NAV_ANIM = "0.24.8-beta" + + /** Material 3 Design for Compose version */ const val COMPOSE_MATERIAL_3 = "1.3.1" + + /** Compose LiveData integration version */ const val COMPOSE_LIVEDATA = "1.7.8" + + /** Compose UI tooling preview version */ const val COMPOSE_PREVIEW = "1.7.8" //COIL (IMAGE LOADING) + /** Accompanist Coil integration version */ const val COIL_ACCOMPANIST = "0.15.0" + + /** Coil image loading library version */ const val COIL = "2.1.0" //PAGING + /** Jetpack Paging library version */ const val PAGING = "1.0.0-alpha14" //----------------------------------------------------------------------------------------------------- //KTX + /** AndroidX Lifecycle components version */ const val LIFECYCLE = "2.3.1" + + /** AndroidX Lifecycle extensions version */ const val LIFECYCLE_EXTS = "2.2.0" //----------------------------------------------------------------------------------------------------- //KOTLIN COROUTINES + /** Kotlin Coroutines library version */ const val COROUTINES = "1.3.9" //----------------------------------------------------------------------------------------------------- //STORE (local + network cache) + /** Dropbox Store library version for caching */ const val STORE_DROPBOX = "4.0.5" //----------------------------------------------------------------------------------------------------- //HILT + /** Hilt dependency injection framework version */ const val HILT = "2.38.1" + + /** Hilt Compose integration version */ const val HILT_COMPOSE = "1.0.0" //----------------------------------------------------------------------------------------------------- //RETROFIT & OKHTTP & GSON + /** Retrofit REST client version */ const val RETROFIT = "2.9.0" + + /** OkHttp HTTP client version */ const val OKHTTP = "4.9.3" + + /** Gson JSON serialization library version */ const val GSON = "2.9.0" //----------------------------------------------------------------------------------------------------- //MULTIDEX + /** Multidex support library version */ const val MULTIDEX = "1.0.3" //----------------------------------------------------------------------------------------------------- //ROOM + /** Room database library version */ const val ROOM = "2.4.2" //----------------------------------------------------------------------------------------------------- //MAP STRUCT + /** MapStruct object mapping library version */ const val MAP_STRUCT = "1.5.0.RC1" diff --git a/buildSrc/src/main/java/BuildModules.kt b/buildSrc/src/main/java/BuildModules.kt index 8a2efb1c..ad979bb5 100644 --- a/buildSrc/src/main/java/BuildModules.kt +++ b/buildSrc/src/main/java/BuildModules.kt @@ -1,24 +1,39 @@ +/** + * Module path constants for the multi-module Android project. + * This object provides centralized module references for Gradle dependency declarations, + * following clean architecture principles with separated layers. + */ object BuildModules { //:core + /** Core module containing shared utilities and base classes */ const val CORE = ":core" + + /** Core Android module with Android-specific shared components */ const val CORE_ANDROID = ":core-android" //data + /** Artist data layer module handling data operations and repository implementations */ const val DATA = ":artist-data" + + /** Artist data source module containing remote API and data source implementations */ const val DATA_SOURCE = ":artist-datasource" //domain + /** Artist domain layer module containing business logic and use cases */ const val DOMAIN = ":artist-domain" - //domain + //presentation + /** Artist presentation layer module containing ViewModels and presentation logic */ const val PRESENTATION = ":artist-presentation" //artist + /** Artist UI module containing fragments, composables, and UI components */ const val ARTIST = ":artist-ui" //:APP + /** Main app module that integrates all feature modules */ const val APP = ":app" diff --git a/buildSrc/src/main/java/BuildPlugins.kt b/buildSrc/src/main/java/BuildPlugins.kt index 533f9117..25c88f41 100644 --- a/buildSrc/src/main/java/BuildPlugins.kt +++ b/buildSrc/src/main/java/BuildPlugins.kt @@ -1,22 +1,38 @@ +/** + * Gradle plugin identifiers used across the project build configuration. + * This object centralizes plugin references for consistent application throughout modules. + */ object BuildPlugins { //----------------------------------------------------------------------------------------------------- //ANDROID + /** Gradle plugin for Android application modules */ const val ANDROID_APPLICATION = "com.android.application" + + /** Gradle plugin for Android library modules */ const val ANDROID_LIBRARY = "com.android.library" //----------------------------------------------------------------------------------------------------- //KOTLIN + /** Kotlin annotation processing tool plugin */ const val KAPT = "kapt" + + /** Kotlin KAPT plugin (full identifier) */ const val KOTLIN_KAPT = "kotlin-kapt" + + /** Kotlin Android plugin (short identifier) */ const val KOTLIN_ANDROID = "kotlin-android" + + /** Kotlin Android plugin from JetBrains (full identifier) */ const val KOTLIN_ANDROID_JETBRAINS = "org.jetbrains.kotlin.android" //----------------------------------------------------------------------------------------------------- //HILT + /** Dagger Hilt dependency injection plugin for Android */ const val DAGGER_HILT = "com.google.dagger.hilt.android" //Nav + /** AndroidX Navigation Safe Args plugin for type-safe navigation */ const val NAV_GRAPH = "androidx.navigation.safeargs.kotlin" } \ No newline at end of file diff --git a/buildSrc/src/main/java/Libs.kt b/buildSrc/src/main/java/Libs.kt index f2252814..c38f8d8a 100644 --- a/buildSrc/src/main/java/Libs.kt +++ b/buildSrc/src/main/java/Libs.kt @@ -1,102 +1,182 @@ +/** + * Centralized library dependency coordinates for the project. + * This object contains Maven coordinates for all libraries used in the application, + * referencing versions from [BuildDepVersions] where applicable. + */ object Libs { + /** Reference to version constants */ private val v = BuildDepVersions //Circle Imageview //----------------------------------------------------------------------------------------------------- + /** Circle ImageView library for displaying circular images */ const val CircleImage = "de.hdodenhof:circleimageview:3.1.0" //Glide //----------------------------------------------------------------------------------------------------- + /** Glide image loading and caching library */ const val GLIDE = "com.github.bumptech.glide:glide:4.12.0" + + /** Glide annotation processor for code generation */ const val Glidekapt = "com.github.bumptech.glide:compiler:4.12.0" //lottie //----------------------------------------------------------------------------------------------------- + /** Lottie animation library for rendering Adobe After Effects animations */ const val Lottie = "com.airbnb.android:lottie:5.2.0" //shimmer //----------------------------------------------------------------------------------------------------- + /** Facebook Shimmer effect library for loading placeholders */ const val Shimmer = "com.facebook.shimmer:shimmer:0.5.0" //Android Component //----------------------------------------------------------------------------------------------------- + /** AndroidX AppCompat library for backward compatibility */ const val AppCompat = "androidx.appcompat:appcompat:1.5.1" + + /** AndroidX Core KTX library with Kotlin extensions */ const val Core = "androidx.core:core-ktx:1.9.0" + + /** AndroidX RecyclerView for displaying scrollable lists */ const val RecyclerView = "androidx.recyclerview:recyclerview:1.2.1" + + /** ConstraintLayout for building responsive UI layouts */ const val constraintlayout = "androidx.constraintlayout:constraintlayout:2.1.4" + + /** Fragment KTX library with Kotlin extensions */ const val fragment = "androidx.fragment:fragment-ktx:1.5.3" //GOOGLE Material design //----------------------------------------------------------------------------------------------------- + /** Material Design Components library */ const val MaterialDesign = "com.google.android.material:material:1.6.1" //SWIPE REFRESH //----------------------------------------------------------------------------------------------------- + /** SwipeRefreshLayout for pull-to-refresh functionality */ const val swiperefreshlayout = "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" //----------------------------------------------------------------------------------------------------- //KTX + /** LiveData KTX with Kotlin coroutine support */ const val LIFECYCLE_LIVEDATA = "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" + + /** Lifecycle runtime KTX library */ const val LIFECYCLE_KTX = "androidx.lifecycle:lifecycle-runtime-ktx:2.5.1" + + /** ViewModel KTX with Kotlin extensions */ const val VIEWMODEL_KTX = "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1" + + /** Lifecycle common Java 8 support */ const val LIFECYCLE_COMMON = "androidx.lifecycle:lifecycle-common-java8:2.5.1" + + /** Lifecycle annotation processor */ const val LIFECYCLE_COMPILER = "androidx.lifecycle:lifecycle-compiler:2.5.1" //----------------------------------------------------------------------------------------------------- //RETROFIT + /** Retrofit REST client library */ const val RETROFIT = "com.squareup.retrofit2:retrofit:2.9.0" + + /** Retrofit Gson converter for JSON serialization */ const val RETROFIT_CONVERTER_GSON = "com.squareup.retrofit2:converter-gson:2.9.0" //----------------------------------------------------------------------------------------------------- //OKHTTP + /** OkHttp HTTP client library */ const val OKHTTP = "com.squareup.okhttp3:okhttp:4.9.3" + + /** OkHttp logging interceptor for debugging */ const val OKHTTP_LOGGING = "com.squareup.okhttp3:logging-interceptor:4.9.3" + + /** OkHttp URL connection support */ const val OKHTTP_urlconnection = "com.squareup.okhttp3:okhttp-urlconnection:4.9.3" //----------------------------------------------------------------------------------------------------- //GSON + /** Gson library for JSON parsing and serialization */ const val GSON = "com.google.code.gson:gson:${v.GSON}" //----------------------------------------------------------------------------------------------------- //HILT + /** Hilt dependency injection framework */ const val HILT = "com.google.dagger:hilt-android:2.51.1" + + /** Hilt annotation processor */ const val HILT_COMPILER = "com.google.dagger:hilt-compiler:2.51.1" + + /** Hilt navigation integration for Jetpack Compose */ const val HILT_COMPOSE_NAV = "androidx.hilt:hilt-navigation-compose:${v.HILT_COMPOSE}" //----------------------------------------------------------------------------------------------------- //ROOM DATABASE + /** Room database runtime library */ const val ROOM = "androidx.room:room-runtime:2.4.3" + + /** Room annotation processor */ const val ROOM_COMPILER_Kap = "androidx.room:room-compiler:2.4.3" + + /** Room KTX with Kotlin coroutine support */ const val ROOMKTX = "androidx.room:room-ktx:2.4.3" + + /** Room testing utilities */ const val ROOM_TESTING = "androidx.room:room-testing:2.4.3" //----------------------------------------------------------------------------------------------------- //NAVIGATION + /** Navigation Fragment KTX for fragment navigation */ const val NAVIGATION_FRAGMENT = "androidx.navigation:navigation-fragment-ktx:2.7.7" + + /** Navigation UI KTX for UI components integration */ const val NAVIGATION_UI = "androidx.navigation:navigation-ui-ktx:2.7.7" //JETPACK COMPOSE //----------------------------------------------------------------------------------------------------- + /** Compose UI core library */ const val COMPOSE_UI = "androidx.compose.ui:ui:${v.COMPOSE}" + + /** Material Design components for Compose */ const val MATERIAL_COMPOSE = "androidx.compose.material:material:${v.COMPOSE}" + + /** Compose UI tooling for previews */ const val COMPOSE_TOOLING = "androidx.compose.ui:ui-tooling:${v.COMPOSE}" + + /** Compose UI tooling preview annotations */ const val COMPOSE_PREVIEW = "androidx.compose.ui:ui-tooling-preview:${v.COMPOSE}" + + /** Activity Compose integration */ const val COMPOSE_ACTIVITY = "androidx.activity:activity-compose:${v.COMPOSE_ACTIVITY}" + + /** Navigation component for Compose */ const val COMPOSE_NAVIGATION = "androidx.navigation:navigation-compose:${v.COMPOSE}" + + /** Accompanist navigation animation library */ const val COMPOSE_NAV_ANIM = "com.google.accompanist:accompanist-navigation-animation:${v.COMPOSE_NAV_ANIM}" + + /** Compose runtime library */ const val COMPOSE_RUNTIME = "androidx.compose.runtime:runtime:${v.COMPOSE_COMPILER}" + + /** Material 3 Design components for Compose */ const val COMPOSE_MATERIAL_3 = "androidx.compose.material3:material3-android:${v.COMPOSE_MATERIAL_3}" + + /** LiveData integration for Compose */ const val COMPOSE_LIVE_DATA = "androidx.compose.runtime:runtime-livedata:${v.COMPOSE_LIVEDATA}" + + /** Compose UI tooling preview for Android */ const val COMPOSE_TOOLING_PREVIEW = "androidx.compose.ui:ui-tooling-preview-android:${v.COMPOSE_PREVIEW}" //----------------------------------------------------------------------------------------------------- //KOTLIN COROUTINES + /** Kotlin Coroutines core library */ const val COROUTINES_CORE = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${v.COROUTINES}" + + /** Kotlin Coroutines Android integration */ const val COROUTINES_ANDROID = "org.jetbrains.kotlinx:kotlinx-coroutines-android:${v.COROUTINES}" diff --git a/buildSrc/src/main/java/TestLibs.kt b/buildSrc/src/main/java/TestLibs.kt index 1e1e1910..b06732dc 100644 --- a/buildSrc/src/main/java/TestLibs.kt +++ b/buildSrc/src/main/java/TestLibs.kt @@ -1,37 +1,87 @@ +/** + * Test library dependency coordinates for the project. + * This object contains Maven coordinates for testing frameworks and tools + * used in unit tests, instrumented tests, and UI tests. + */ object TestLibs { + /** Reference to version constants */ private val v = BuildDepVersions //TEST ----------------------------------------------------------------------------------------------- + /** JUnit 4 testing framework for unit tests */ const val JUNIT = "junit:junit:4.13.2" + + /** AndroidX Core testing utilities */ const val CORE_TEST = "androidx.arch.core:core-testing:2.1.0" + + /** Mockito inline for mocking final classes */ const val MOCKITO_INLINE = "org.mockito:mockito-inline:4.5.1" + + /** Mockito Kotlin extensions */ const val MOKITO_KOTLIN = "org.mockito.kotlin:mockito-kotlin:4.0.0" + + /** MockK mocking library for Kotlin */ const val MOCKK = "io.mockk:mockk:1.12.4" + + /** MockK Android variant for instrumented tests */ const val IOMOCKK_ANDROID = "io.mockk:mockk-android:1.12.4" + + /** AndroidX test runner for instrumented tests */ const val TEST_RUNNER = "androidx.test:runner:1.4.0" + + /** AndroidX test runner JUnit extension */ const val TEST_RUNNER_EXT = "androidx.test.ext:junit:1.1.3" + + /** Espresso UI testing framework */ const val EXPRESSO_TEST = "androidx.test.espresso:espresso-core:3.4.0" + + /** AndroidX test rules */ const val TEST_RULE = "androidx.test:core:1.4.0" + + /** OkHttp MockWebServer for testing network calls */ const val MOCKWEBSERVER = "com.squareup.okhttp3:mockwebserver:4.9.0" + + /** Kotlin Coroutines test library */ const val kOTLINX_COUROUTINE = "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" + + /** Kotlin Coroutines test utilities */ const val kOTLINX_COUROUTINE_TEST = "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" + + /** Hilt Android compiler for test modules */ const val HILT_ANDROID_COMPILER = "com.google.dagger:hilt-android-compiler:2.38.1" //ANDROID TEST----------------------------------------------------------------------------------------- + /** JUnit for Android instrumented tests */ const val JUNIT_ANDROID = "junit:junit:4.13.2" + + /** Test runner for Android instrumented tests */ const val TEST_RUNNER_ANDROID = "androidx.test:runner:1.4.0" + + /** Coroutines test support for Android tests */ const val kOTLINX_COUROUTINE_ANDROID = "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" + + /** Core testing utilities for Android */ const val CoreTesting_ANDROID = "androidx.arch.core:core-testing:2.1.0" + + /** Hilt testing library for Android */ const val Hilt_ANDROID = "com.google.dagger:hilt-android-testing:2.44" + + /** Google Truth assertion library */ const val Truth_ANDROID = "com.google.truth:truth:1.1.3" + /** AndroidX JUnit extension for instrumented tests */ const val JUNIT_EXT_ANDROID = "androidx.test.ext:junit:${v.JUNIT_EXT_ANDROID}" + + /** Espresso core for UI testing */ const val EXPRESSO = "androidx.test.espresso:espresso-core:${v.EXPRESSO}" + + /** Compose UI test library for JUnit 4 */ const val COMPOSE_UI_TEST = "androidx.compose.ui:ui-test-junit4:${v.COMPOSE}" //DEBUG ----------------------------------------------------------------------------------------- + /** Compose UI tooling for debug builds */ const val COMPOSE_TOOLING = "androidx.compose.ui:ui-tooling:${v.COMPOSE}" From 7cd1b800d61ca3c28e067050ae0ea91e43eb441c Mon Sep 17 00:00:00 2001 From: motola Date: Mon, 5 May 2025 15:30:00 +0100 Subject: [PATCH 2/3] uplift artist album folder and schema with more clarity --- .../artist/repository/ArtistRepository.kt | 19 ++++++++++++++++++- .../model/ArtistAlbumDomainModel.kt | 16 ++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/artist-domain/src/main/java/com/muryno/domain/artist/repository/ArtistRepository.kt b/artist-domain/src/main/java/com/muryno/domain/artist/repository/ArtistRepository.kt index 187be16f..539adec3 100644 --- a/artist-domain/src/main/java/com/muryno/domain/artist/repository/ArtistRepository.kt +++ b/artist-domain/src/main/java/com/muryno/domain/artist/repository/ArtistRepository.kt @@ -3,8 +3,25 @@ package com.muryno.domain.artist.repository import com.muryno.domain.artistAlbulm.model.ArtistAlbumDomainModel import com.muryno.domain.artist.model.ArtistDomainModel - +/** + * Repository interface for artist-related data operations in the domain layer. + * This interface defines the contract for accessing artist and album data, + * abstracting the implementation details from the business logic. + */ interface ArtistRepository { + /** + * Retrieves a list of artists matching the search query. + * + * @param artistName The name of the artist to search for + * @return List of [ArtistDomainModel] containing matching artists + */ suspend fun artistList(artistName: String): List + + /** + * Retrieves album releases for a specific artist. + * + * @param artistId The unique identifier of the artist + * @return List of [ArtistAlbumDomainModel] containing the artist's albums + */ suspend fun artistAlbum(artistId: String): List } \ No newline at end of file diff --git a/artist-domain/src/main/java/com/muryno/domain/artistAlbulm/model/ArtistAlbumDomainModel.kt b/artist-domain/src/main/java/com/muryno/domain/artistAlbulm/model/ArtistAlbumDomainModel.kt index 72806cea..62667d79 100644 --- a/artist-domain/src/main/java/com/muryno/domain/artistAlbulm/model/ArtistAlbumDomainModel.kt +++ b/artist-domain/src/main/java/com/muryno/domain/artistAlbulm/model/ArtistAlbumDomainModel.kt @@ -1,5 +1,21 @@ package com.muryno.domain.artistAlbulm.model +/** + * Domain model representing album information in the business logic layer. + * This model encapsulates album data used throughout the domain layer, + * independent of data sources or presentation concerns. + * + * @property primaryType Primary type of the release (Album, Single, EP, etc.) + * @property genre Musical genre of the album + * @property releaseDate Date when the album was released + * @property label Record label that released the album + * @property title Title of the album + * @property shortDescription Brief description of the album + * @property fullDescription Complete description of the album + * @property albumImage URL or path to the album cover image + * @property id Unique identifier for the album + * @property disambiguation Additional text to distinguish similar albums + */ data class ArtistAlbumDomainModel( val primaryType: String, val genre: String, From 1cefad5cd2f704325235853c5993770fb50ee37e Mon Sep 17 00:00:00 2001 From: motola Date: Tue, 6 May 2025 09:30:00 +0100 Subject: [PATCH 3/3] update readme documentation to enable connecting developers onboard better --- README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ac561899..1646eb90 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,58 @@ +# Clean Architecture Modularization + The "Practical Guide to Building Android Apps with Clean Architecture, Modularization, and Unit Testing" is a comprehensive resource that outlines best practices for developing robust and maintainable Android applications. Detailed in a Medium article [ Practical Guide to Building Powerful and Easy-to-Maintain Android Apps with Clean Architecture, Modularization ](https://murainoyakubu.medium.com/practical-guide-to-building-powerful-and-easy-to-maintain-android-apps-with-clean-architecture-c6c8b592a0f2), this guide emphasizes on the importance of using Clean Architecture, modularization, and unit testing to enhance app quality and scalability. ## Project Modules -* artist-domain -* artist-data -* artist-datasource -* artist-presentation -* artist-ui -* app +### **artist-domain** +Business logic layer - Contains use cases, domain models, and repository interfaces (pure Kotlin, no Android dependencies) + +### **artist-data** +Data layer - Implements repositories and handles data mapping between data sources and domain + +### **artist-datasource** +Remote data layer - Handles API calls using Retrofit and maps API responses to data models + +### **artist-presentation** +Presentation layer - Contains ViewModels, presentation models, and UI state management + +### **artist-ui** +UI layer - Contains Fragments, Compose screens, and UI components + +### **app** +Application module - App entry point, dependency injection setup (Hilt), and navigation + + +## Features +- Search for artists (default: Drake) using MusicBrainz API +- View artist albums and release information +- Dark/light mode support with Material Design +- Built with Jetpack Compose and traditional Views + + +## Tech Stack +- **Architecture**: Clean Architecture, MVVM, Repository Pattern +- **DI**: Hilt +- **UI**: Jetpack Compose + XML Views +- **Networking**: Retrofit, OkHttp, Gson +- **Async**: Kotlin Coroutines +- **Testing**: JUnit, Mockito, MockK, Espresso + + +## Getting Started + +1. Clone the repository +2. Open in Android Studio +3. Build and run -### Features -- search for list of artist.. default is drake as he is my favorite -- dark/light mode supported +```bash +./gradlew build +./gradlew installDebug +``` -### Screen +## Screen Screenshot 2022-10-25 at 22 43 48