Sprint 2 - mobile-dev-16/S1-G16-planning GitHub Wiki
Business Questions (BQ)
The business questions were modified from Sprint 1, due to direct feedback from the professor regarding the need to correct them and do them again.
Type 1: App's Telemetry
- What is the average loading time of the app from launch to the main page?
Actionable Insight: Understanding loading times helps the development team identify performance issues and improve the app's responsiveness.
Type 2: User experience
- Is there a surplus of your favorite cuisine available today near your location?
- Are there new surplus food deals available that match the user’s dietary preferences today?
- Is the user currently located far from their saved address?
- Are there any new partner businesses offering surplus deals near the user's saved address today?
These questions aim to enhance the user's daily experience by providing personalized, relevant information. They utilize the user's preferences and location to deliver tailored content. Also The questions are based on measurable data such as cuisine types, available deals, and geographic distance. The insights are used to inform the user through app notifications or personalized recommendations and respect user privacy by using data appropriately and ensuring consent is obtained as per the app's terms and conditions.
Type 3: Feature Analysis
- How frequently do users use the "Order Again"?
- Which filter options (e.g., price, cuisine type, distance) are most frequently used by users when searching for deals?
- Which app features are used less than once per week by active users?
Actionable Outcomes: Insights guide resource allocation to improve or discontinue features, optimizing the app's functionality.
Type 4: Benefit from Data
- At what times do users most frequently buy surplus food, and can we sell this non-personal aggregated data to logistics companies to optimize delivery services?
It involves sharing non-personal, aggregated data to protect user privacy. Considers market trends and external partnerships to generate profit.And finally, ensures that data sharing complies with privacy laws and that users are informed per the app's terms and conditions.
Type 5: Multi-type
- How does the app's performance (loading times, crash rates) correlate with user retention rates?
Helps prioritize technical improvements that can enhance user satisfaction and reduce churn.
Implemented in the app
- What is the average loading time of the app from launch to the main page? (Type 1) ( Raul )
- Is there a surplus of your favorite cuisine available today near your location? (Type 2) ( Abel )
- Is the user currently located far from their saved address? (Type 2) ( Raul )
Analytics pipeline (AP)
-
Data Source Layer:
- Logs: Collects raw logs from the app to capture every interaction, error, or event.
- User Devices: Obtains data from mobile devices, such as GPS location, interaction events, or sensor data.
- Google Maps API: Provides geographic data, allowing the app to map and geocode user addresses.
- Firebase Services: Firebase Firestore and Supabase Realtime Database are used to gather structured data, including user preferences, addresses, and orders.
- Supabase Auth: Handles user authentication and session management, ensuring secure login and access control.
This layer is essential for gathering all relevant raw data from various sources, ensuring the pipeline has comprehensive input from which insights can be drawn.
-
Ingestion and Integration Layer:
- Firebase / Supabase REST API: Serves as the connector that ingests raw data from the source layer into Firebase or Supabase for further processing. This ensures that data from mobile devices, logs, and external APIs like Google Maps are seamlessly integrated into the Firebase or Supabase ecosystem.
- Supabase Edge Functions: Supabase's server-side functions process and transform incoming data as it's ingested.
The ingestion layer enables data from different sources to be standardized and formatted so that the subsequent layers can interpret and act on it efficiently.
-
Storage Layer:
- Firestore: Stores user data such as addresses and order history in a structured format.
- Firebase Realtime Database: Ensures real-time syncing of data, particularly useful for live updates like order tracking or address changes.
- Supabase Postgres Database: Stores structured data such as user profiles, order history, and other application data.
- Firebase Analytics Storage: Houses all the behavioral and event-based data collected from Firebase Analytics, allowing for historical analysis.
- Supabase Storage: Used for storing media files such as user-uploaded images or restaurant logos.
The storage layer ensures that all processed and raw data is safely stored and easily retrievable, either for further processing or direct consumption by other services.
-
Processing/Computing Layer:
- Cloud Functions: These serverless functions process real-time events like address validation, push notifications, and real-time user actions, ensuring a scalable backend that can respond to user input instantly.
- Supabase Functions: Supabase's server-side functions handle real-time updates, event processing (e.g., user location changes), and notifications.
- Firebase Crashlytics: Analyzes app crashes and performance issues to provide insights into app stability.
- Supabase Analytics: Processes and aggregates data related to app usage, session duration, and feature engagement.
This layer performs calculations, aggregates data, and pre-processes information for visualization or real-time actions like push notifications. By leveraging Cloud Functions and Supabase Functions, you ensure a cost-efficient and scalable processing environment.
-
Presentation Layer:
- Firebase Notifications: Pushes messages and notifications based on user behavior or app events.
- Supabase Realtime Notifications: Sends notifications to users based on new deals, location updates, or user preferences.
- Power BI: Provides detailed dashboards and visualizations for app administrators to monitor business KPIs, such as user behavior and orders.
- Supabase Dashboard: Provides real-time insights into app usage and key metrics, allowing administrators to view user activity and system performance.
- Realtime Dashboard: Displays live updates on user interactions, location data, and crash reports, offering immediate insights for monitoring app performance.
The presentation layer ensures insights are visualized and accessible to both end-users (through notifications) and app administrators (through dashboards and Power BI), improving decision-making and enhancing the user experience.
Using both Firebase and Supabase, we ensure that data flows smoothly from raw collection to real-time processing. This dual-system approach allows for flexibility, scalability, and secure data handling. Additionally, the integration of Google Maps ensures accurate geolocation data, and the real-time dashboard and Power BI visualizations enable continuous monitoring of user engagement and system performance, optimizing the app’s efficiency and user experience.
Architectural design (AD)
Flutter App - Abel and Raul
Bloc Pattern (Event-Driven Architecture)
The BLoC (Business Logic Component) pattern forms the foundation of the application's state management and business logic handling. In Flutter, this pattern is especially advantageous due to its clear separation between the UI and the business logic, ensuring that the codebase remains modular, reusable, and scalable, which is key for complex apps.
At its core, the BlocListener listens for specific state changes (e.g., LoginLoading, LoginSuccess, LoginFailure) and triggers corresponding UI responses such as showing a loading spinner, navigating to the main dashboard, or displaying an error message. This keeps the UI layer clean and focused purely on rendering, while the BLoC manages the underlying logic and state transitions.
The LoginBloc is responsible for processing events (like LoginSubmitted) and emitting the appropriate states. For instance, upon receiving a LoginSubmitted event, the BLoC initiates the authentication process and emits states such as LoginLoading while the request is ongoing, LoginSuccess when authentication succeeds, or LoginFailure if an error occurs. The UI listens passively to these state changes and updates accordingly, maintaining a stateless approach.
In Flutter, the reactive programming model aligns perfectly with the BLoC pattern. It leverages streams, enabling a reactive, event-driven architecture that fits seamlessly into Flutter's widget tree. This allows developers to build scalable applications where the UI remains stateless, focused only on rendering, while all business logic, side effects, and state transitions are managed within the BLoC.
Advantages:
- Testability: Since the business logic is decoupled from the UI, unit testing becomes more straightforward. BLoC's event-driven architecture allows developers to easily mock events and test state transitions without needing to test the UI.
- Maintainability: BLoC encourages a modular approach. Changes to business logic or states can be made independently without affecting the UI. This separation of concerns simplifies code management, making the application more maintainable as it grows.
- Scalability: The BLoC pattern makes it easier to scale the application as additional features can be added without disrupting existing functionality. The well-structured separation of UI and logic allows for seamless feature expansion.
Repository (Abstraction)
The Repository pattern is employed in the application's architecture to abstract and decouple the data layer from the rest of the app, ensuring that the Bloc or any other layer doesn't need to know the details of where data comes from. Instead of directly interacting with APIs or databases, repositories are responsible for handling all data-fetching logic, providing a clean and consistent API for the rest of the app to interact with.
For instance, repositories like AuthRepository
encapsulate the user authentication logic. This repository is responsible for interacting with the authentication API or local storage mechanisms, and the LoginBloc
uses it to handle events such as logging in. The Bloc sends requests to the repository, and the repository returns the necessary data or state, whether it’s fetched from a remote API or a local database.
In the structure shown in the image, you can see the following repositories:
- AddressRepository: Handles the data logic for addresses, possibly fetching or storing user address data from a remote source or local database.
- AuthRepository: Manages user authentication, including login, sign-up, and session management.
The repository abstracts the underlying data sources (whether APIs or databases), keeping the implementation details hidden from the business logic (Bloc).
Advantages:
- Testability: Repositories can be easily mocked during unit testing since they provide a clean interface for fetching data. This makes it easier to test business logic in isolation, without the need to worry about the actual data source.
- Separation of Concerns: The Bloc does not need to concern itself with how or where data comes from. It simply interacts with the repository, which in turn manages the underlying data retrieval. This ensures that the logic for fetching data is encapsulated in one place, enhancing code modularity and readability.
Kotlin App Mario and Luimarco
MVVM Design Pattern Explanation
The Model-View-ViewModel (MVVM) architecture is implemented within this project, ensuring a clear separation of concerns between the business logic, the UI, and the underlying data. This architectural approach aligns well with Kotlin and Jetpack Compose, providing a highly modular and testable structure.
Model Layer:
The Model layer represents the data and logic of the application. It includes the data sources, such as Supabase, where user data, orders, and preferences are stored. This layer is responsible for handling communication with the database via repository classes that abstract the data source.
- Supabase Repository: Handles all interactions with the Supabase backend, including authentication, CRUD operations, and querying the database.
- AuthRepository: Manages user authentication (login, sign-up, session management).
- OrderRepository: Manages order-related data such as order history, available deals, and user-specific preferences.
ViewModel Layer:
The ViewModel holds the business logic for the UI and serves as an intermediary between the Model and the View. It maintains the UI-related data and ensures it survives configuration changes.
- LoginViewModel: Manages the login and authentication logic. It observes user input from the
LoginScreen
and updates the UI state accordingly based on authentication success or failure. - OrderViewModel: Handles the user's orders and deal interactions. It fetches available surplus food deals from Supabase and manages user-specific filters like dietary preferences.
The ViewModel communicates with the repository to fetch or manipulate data. It then prepares that data to be displayed in the UI, exposing live data objects to the View.
View Layer:
The View layer represents the user interface (UI) of the application. This layer is built using Jetpack Compose, which provides declarative UI components that update automatically when the underlying state in the ViewModel changes.
- LoginScreen: The UI for user login and sign-up, directly interacting with the
LoginViewModel
for login status and error handling. - MainScreen: The main interface for the app, showing available deals, user preferences, and other features. It interacts with
OrderViewModel
to display user-specific deals and food options.
This separation of concerns, facilitated by the MVVM architecture, ensures that each part of the app remains modular and easy to maintain, allowing independent updates to UI components, business logic, and data access layers.
Repository Pattern
The Repository Pattern is utilized to abstract the data source and manage communication between the ViewModel and the data layers (Supabase). This abstraction ensures that the ViewModel is decoupled from the specifics of data retrieval and storage.
- AuthRepository: Provides an interface to authenticate users, utilizing Supabase’s authentication services.
- OrderRepository: Handles querying and filtering of available deals from Supabase, including applying user preferences like dietary restrictions or location-based filters.
Advantages:
- Testability: With a clear separation between the UI, ViewModel, and data, unit testing becomes much simpler. The ViewModel can be tested independently from the data source.
- Maintainability: This architecture ensures a clean separation of concerns. Any changes in the backend (Supabase) or business logic (ViewModel) do not affect the UI and vice versa.
- Scalability: MVVM and the repository pattern allow the app to scale easily as new features are added. Since the architecture enforces modularity, adding new ViewModels or repositories is straightforward.
List of implemented features (IF)
- User Authentication (Google and Email Sign-In).
- Address Management with GPS and Google Maps API.
- Calculate loading time of the app from launch to the main page and loading with splash.
- Add and delete cart items.
- Scrollable order items.