{"id":48515206,"url":"https://github.com/pedrazamiguez/split-trip","last_synced_at":"2026-06-13T01:01:10.232Z","repository":{"id":308743891,"uuid":"1033929837","full_name":"pedrazamiguez/split-trip","owner":"pedrazamiguez","description":"SplitTrip is a modular Android application designed for travelers to manage shared expenses efficiently.","archived":false,"fork":false,"pushed_at":"2026-06-07T14:11:29.000Z","size":6525,"stargazers_count":1,"open_issues_count":33,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-06-07T14:17:01.636Z","etag":null,"topics":["android","clean-architecture","detekt","firebase-auth","firebase-cloud-functions","firebase-firestore","firebase-storage","github-actions","jetpack-compose","konsist","kotlin","kotlin-flow","material3-expressive","multi-module","mvi","offline-first","room-database"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedrazamiguez.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2025-08-07T15:09:15.000Z","updated_at":"2026-06-07T14:11:32.000Z","dependencies_parsed_at":"2025-10-03T17:20:29.718Z","dependency_job_id":null,"html_url":"https://github.com/pedrazamiguez/split-trip","commit_stats":null,"previous_names":["pedrazamiguez/expense-share-app","pedrazamiguez/split-trip"],"tags_count":113,"template":false,"template_full_name":null,"purl":"pkg:github/pedrazamiguez/split-trip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrazamiguez%2Fsplit-trip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrazamiguez%2Fsplit-trip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrazamiguez%2Fsplit-trip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrazamiguez%2Fsplit-trip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedrazamiguez","download_url":"https://codeload.github.com/pedrazamiguez/split-trip/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedrazamiguez%2Fsplit-trip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34268189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","clean-architecture","detekt","firebase-auth","firebase-cloud-functions","firebase-firestore","firebase-storage","github-actions","jetpack-compose","konsist","kotlin","kotlin-flow","material3-expressive","multi-module","mvi","offline-first","room-database"],"created_at":"2026-04-07T19:00:20.679Z","updated_at":"2026-06-13T01:01:10.190Z","avatar_url":"https://github.com/pedrazamiguez.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SplitTrip\n\n[![Build \u0026 Test](https://github.com/pedrazamiguez/split-trip/actions/workflows/build-and-test.yml/badge.svg)](https://github.com/pedrazamiguez/split-trip/actions/workflows/build-and-test.yml)\n[![Static Analysis](https://github.com/pedrazamiguez/split-trip/actions/workflows/static-analysis.yml/badge.svg)](https://github.com/pedrazamiguez/split-trip/actions/workflows/static-analysis.yml)\n[![Coverage \u0026 Architecture](https://github.com/pedrazamiguez/split-trip/actions/workflows/coverage-and-architecture.yml/badge.svg)](https://github.com/pedrazamiguez/split-trip/actions/workflows/coverage-and-architecture.yml)\n\n## Overview\n\n**SplitTrip** is a modular Android application designed for travelers to manage shared\nexpenses efficiently. It allows users to create expense groups, track spending in multiple\ncurrencies, calculate debts, and sync data across devices.\n\nBuilt with modern Android practices—including **Jetpack Compose**, **Clean Architecture**, and\n**Offline-First** principles—the app serves as a reference for scalable, multi-module Android\ndevelopment.\n\n### ✨ Key Features\n\n* **User Authentication**: Secure login (Email/Password) via Firebase Authentication.\n* **Group Management**: Create and join expense groups with unique invite codes.\n* **Smart Expense Tracking**: Support for custom split strategies (Equal, Percentage, Shares).\n* **Multi-Currency Support**: Real-time currency conversion using Open Exchange Rates.\n* **Debt Simplification**: Automatically calculates \"Who owes Whom\" balances.\n* **Offline-First**: Full functionality without internet; syncs automatically when online.\n* **Push Notifications**: Instant updates when members add or modify expenses.\n\n## 🛠️ Tech Stack\n\n* **Language**: [Kotlin](https://kotlinlang.org/) (100%)\n* **UI**: [Jetpack Compose](https://developer.android.com/jetpack/compose) (Material 3 Expressive\n  Design)\n* **Architecture**: Clean Architecture + MVVM + MVI patterns\n* **Dependency Injection**: [Koin](https://insert-koin.io/)\n* **Asynchronous Programming**: Coroutines \u0026 Flow\n* **Local Data**: [Room Database](https://developer.android.com/training/data-storage/room) (Single\n  Source of Truth)\n* **Remote Data**: [Retrofit](https://square.github.io/retrofit/) (Currency APIs)\n* **Backend (BaaS)**: Firebase (Auth, Firestore, Cloud Messaging)\n* **Navigation**: Jetpack Navigation Compose (Feature-based modular navigation)\n* **Code Quality**: Detekt, Ktlint, CPD, JaCoCo, Konsist, CodeQL\n\n## 📂 Project Structure\n\nThe app follows a strict **Multi-Module** architecture to ensure separation of concerns and faster\nbuild times:\n\n* **`:app`**: The application entry point. Wiring and DI setup.\n* **`:core`**: Shared foundational components.\n* **`:core:common`**: Utilities, Constants, and DataStore preferences.\n* **`:core:design-system`**: Reusable UI components (`ExpressiveFab`, `DynamicTopAppBar`), Themes,\n  and the `ScreenUiProvider` system.\n\n\n* **`:data`**: The Data Layer implementation.\n* **`:data:local`**: Room Database entities and DAOs.\n* **`:data:remote`**: Retrofit services for external APIs.\n* **`:data:firebase`**: Firestore and Auth implementations.\n\n\n* **`:domain`**: Pure Kotlin business logic (Use Cases, Models, Repository Interfaces).\n* **`:features`**: Standalone feature modules containing UI and ViewModels.\n\n## 🚀 Setup Instructions\n\n### Prerequisites\n\n* Android Studio Ladybug or newer.\n* JDK 21.\n* A Firebase Project with Authentication (Email) and Firestore enabled.\n* An API Key from [Open Exchange Rates](https://openexchangerates.org/) (optional, for currency\n  features).\n\n### Steps\n\n1. **Clone the Repository**:\n\n```bash\ngit clone https://github.com/pedrazamiguez/split-trip.git\ncd split-trip\n```\n\n2. **Run the bootstrap script** (installs git hooks, scaffolds `local.properties`, and checks prerequisites):\n\n```bash\nmake setup\n```\n\n\u003e Run `make help` to see all available targets.\n\n3. **Firebase Configuration**:\n\n* Go to the [Firebase Console](https://console.firebase.google.com).\n* Create a project and add an Android app (package: `es.pedrazamiguez.splittrip`).\n* Download `google-services.json` and place it in the `app/` directory.\n\n4. **API Keys (Secrets)**:\n\n* The Open Exchange Rates key is a **Gradle property** read by `data/remote/build.gradle.kts` via `providers.gradleProperty()`. It must be added to your **user-level** `~/.gradle/gradle.properties` (not `local.properties`, which is only for `sdk.dir`):\n\n```properties\n# ~/.gradle/gradle.properties\nOER_APP_ID_DEBUG=your_debug_key_here\nOER_APP_ID_RELEASE=your_release_key_here\n```\n\n\u003e For release CI builds, `OER_APP_ID_RELEASE` can also be supplied as an environment variable (env var takes precedence over the Gradle property).\n\n5. **Build \u0026 Run**:\n\n* Sync Gradle files in Android Studio.\n* Select the `app` configuration and run on an Emulator (API 26+ recommended).\n\n### Verify your setup\n\n```bash\nmake doctor   # checks JDK, SDK path, google-services.json, API key, and git hook\nmake check    # runs Konsist architecture tests + unit tests + compilation\n```\n\n## 🧪 Testing\n\nThe project uses a comprehensive testing strategy:\n\n* **Unit Tests**: JUnit 5 \u0026 MockK for Domain and Data layers.\n\n```bash\n./gradlew test\n\n```\n\n* **UI Tests**: Compose Testing for Screens and Navigation flows.\n\n```bash\n./gradlew connectedAndroidTest\n\n```\n\n## 📐 Architecture \u0026 Patterns\n\nThis project adheres to the **\"Strict Visibility\"** principle:\n\n1. **Features** cannot see other **Features** (they communicate via `:domain`).\n2. **Features** cannot see **Data** implementation details (only Domain interfaces).\n3. **App** module is the only one that sees everything to wire up the Dependency Injection.\n\n**Key Patterns:**\n\n* **Navigation Discovery**: Features expose `NavigationProvider` interfaces so the App module can \"\n  plug them in\" dynamically.\n* **Repository Pattern**: Mediates between Local (Room) and Cloud (Firestore) data sources.\n* **ScreenUiProvider**: Decouples the Main Activity's Scaffold (TopBar/FAB) from individual screens.\n\n## Licence\n\nThis project is proprietary. See the [LICENSE](LICENSE) file for full terms.\n\n© 2026 Andrés Pedraza Míguez. All Rights Reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrazamiguez%2Fsplit-trip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedrazamiguez%2Fsplit-trip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedrazamiguez%2Fsplit-trip/lists"}