Architecture & Tech choices - Fabryo/PokeManiac GitHub Wiki

Architecture

The application is developed using a modular architecture that follows the Android Architecture Components principles. This structure ensures the scalability of the app when new features need to be added.

Module Dependency Diagram

flowchart TD

    %% Global style for dark mode
    classDef darkMode fill:#000000,stroke:#FFFFFF,stroke-width:2px,color:#FFFFFF;
    
    subgraph Presentation_Layer
        direction TB
        App["App (Main entry)"]
        Dashboard["Dashboard Feature"]
        SearchFriends["SearchFriends Feature"]
        MyFriends["MyFriends Feature"]
        MyProfile["MyProfile Feature"]
        NewPost["NewPost Feature"]
        CoreUI["CoreUI Module (Shared Compose Views)"]
    end

    subgraph Domain_Layer
        direction TB
        Domain["Domain (Repository Interfaces + Entities)"]
    end

    subgraph Data_Layer
        direction TB
        Data["Data Module (Repository Implementations)"]
        Api["API Module (Networking Services)"]
        Database["Database Module (Room Persistence)"]
    end

    subgraph Tracking_Layer
        Tracking["Tracking Module (Analytics + Events Storage)"]
    end

    %% -- Flows inside Presentation Layer
    App --> Dashboard
    App --> SearchFriends
    App --> MyFriends
    App --> MyProfile
    App --> NewPost

    App --> CoreUI
    Dashboard --> CoreUI
    SearchFriends --> CoreUI
    MyFriends --> CoreUI
    MyProfile --> CoreUI
    NewPost --> CoreUI

    %% -- External Flows
    Presentation_Layer --> Domain_Layer
    Presentation_Layer --> Tracking_Layer
    Tracking_Layer --> Domain_Layer

    Data_Layer --> Domain_Layer
    Database --> Data

    %% Apply dark mode style
    linkStyle default stroke:#FFFFFF,stroke-width:1.5px
    class App,Dashboard,SearchFriends,MyFriends,MyProfile,NewPost,CoreUI,Domain,Data,Api,Database,Tracking darkMode

The implemented modules are:

  • App module: the main entry point of the application. It also contains the Splash and SignIn/SignUp screens.
  • One module per Dynamic Feature, such as:
    • Dashboard: the news feed where all transactions from the user’s friends (and the user) appear.
    • SearchFriends: the feature for finding friends.
    • MyFriends: the feature to browse your friend list and view detailed one-to-one transaction history.
    • MyProfile: the user’s profile feature.
    • NewPost: the feature to create and share new posts.
    • CoreUI module: contains shared Compose Views, resources, and utilities used across feature modules.

All UI modules follow the MVVM design pattern, with ViewModels exposing state objects. All screens are implemented using Jetpack Compose. All Features contain one Activity accessible from the other Features. The Navigation inside each feature (module) is made with the Compose Navigation.

Additional layers include:

  • Domain module, containing:
    • Repository interfaces
    • Model Entities
    • Note : Choice was made not to implement UseCases and to call the Repositories directly from the ViewModels. Indeed, introducing UseCases would add unnecessary complexity and boilerplate in a context where the features are relatively simple.
  • Data module, containing:
    • Request interfaces
    • Repository implementations
  • Api module: introduced to separate networking logic from the rest of the data layer. It includes:
    • The HTTP client and API services
    • API request implementations
  • Database module: separates local persistence logic (implemented with Room) from the rest of the data layer.
  • Tracking module: allows integration of third-party libraries for analytics and user tracking. The goal is to monitor feature usage and leverage this data to make meaningful decisions about future app evolution. All Presentation modules implement the Tracking module.
  • Dependenty Injection Module: allows the presentation layer to have knowledge only of the domain layer module, and not of the data layer modules to respect the Clean Architecture principles.

Architecture Data Flow

flowchart TD

    %% Global style for dark mode
    classDef darkMode fill:#000000,stroke:#FFFFFF,stroke-width:2px,color:#FFFFFF;

    subgraph Presentation_Module
        direction TB
        Activity["Activity / Composable"]
        ViewModel["ViewModel"]
    end

    subgraph Domain_Module
        direction TB
        RepositoryInterface["Repository Interface"]
    end

    subgraph Data_Module
        direction TB
        RepositoryImpl["Repository Implementation"]
        RequestInterface["Request Interface"]
        DataStoreInterface["DataStore Interface"]
    end

    subgraph Database_Module
        direction TB
        DataStoreImpl["DataStore Implementation"]
        RoomDatabase["Room Database"]
    end

    subgraph API_Module
        direction TB
        RequestImpl["Request Implementation"]
    end

    subgraph External_Services
        direction TB
        RemoteApi["Remote API"]
    end

    %% Calls (flow top-down)
    Activity -->|User Actions| ViewModel
    ViewModel -->|Call Repository| Domain_Module
    RepositoryInterface -->|Implementation| RepositoryImpl
    RepositoryImpl -->|Fetch Remote Data| RequestInterface
    RepositoryImpl -->|Fetch Local Data| DataStoreInterface
    RequestInterface -->|Implementation| RequestImpl
    DataStoreInterface --> |Implementation| DataStoreImpl
    RequestImpl -->|Call External API| RemoteApi
    DataStoreImpl -->|Fetch Local Data| RoomDatabase

    %% Responses (horizontal dotted lines, no "up")
    ViewModel -.->|StateFlow/SharedFlow| Activity
    Domain_Module -.->|Flow Data| ViewModel
    RemoteApi -.->|API Response| RequestImpl
    RoomDatabase -.->|Flow DB Entities| DataStoreImpl
    RequestInterface -.->|Remote Data| RepositoryImpl
    DataStoreInterface -.->|Flow Local Data| RepositoryImpl

    %% Styling for dark mode
    linkStyle default stroke:#FFFFFF,stroke-width:1.5px
    class Activity,ViewModel,RepositoryInterface,RepositoryImpl,RequestInterface,DataStoreInterface,RequestImpl,DataStoreImpl,RoomDatabase,RemoteApi darkMode

Tech choices

The application is built using the following libraries: