Skip to content

Feature Spec

HlexNC edited this page Feb 9, 2026 · 1 revision

Feature Spec & Requirements

Source of truth for the iTravel v2 rewrite.


Constraints

Constraint Decision
Language Java 17
UI Toolkit XML layouts + Material Design 3
Architecture MVVM + Repository pattern
Backend None — local Room DB + direct 3rd-party API calls
Min SDK 26 (Android 8.0)
Target SDK 34 (Android 14)
Build System Gradle 8.13 + AGP 8.13.2

Architecture

┌─────────────────────────────────────────────┐
│  UI Layer (Activities, Fragments, Adapters)  │
│  ↕ observes LiveData                         │
├─────────────────────────────────────────────┤
│  ViewModel Layer                             │
│  ↕ calls repositories, exposes LiveData      │
├─────────────────────────────────────────────┤
│  Repository Layer                            │
│  ↕ coordinates local + remote sources        │
├──────────────────────┬──────────────────────┤
│  Local Data Sources  │  Remote Data Sources  │
│  Room DB             │  Retrofit (Countries) │
│  SharedPreferences   │  Retrofit (Unsplash)  │
│  (Encrypted)         │  Retrofit (Weather)   │
└──────────────────────┴──────────────────────┘

Package Structure

com.itravel.app
├── ui/
│   ├── splash/          # SplashActivity
│   ├── auth/            # AuthActivity, Welcome/Login/Register Fragments + ViewModel
│   ├── main/            # MainActivity (bottom nav host)
│   ├── discover/        # DiscoverFragment + ViewModel
│   ├── feed/            # FeedFragment + FeedAdapter + ViewModel
│   ├── search/          # SearchFragment + SearchAdapter + ViewModel
│   ├── profile/         # ProfileFragment + ViewModel
│   ├── location/        # LocationDetailActivity + AddReviewFragment + ViewModel
│   └── common/          # Shared custom views
├── data/
│   ├── repository/      # UserRepo, LocationRepo, FeedRepo, WeatherRepo
│   ├── local/
│   │   ├── db/          # AppDatabase, DAOs, Entities
│   │   └── prefs/       # SessionManager (EncryptedSharedPreferences)
│   └── remote/
│       ├── api/         # Retrofit interfaces
│       ├── dto/         # Network DTOs
│       └── client/      # RetrofitClient singleton
├── model/               # Domain models (User, Location, Review, FeedItem)
└── util/                # Constants, GPSValidator, ValidationUtils

Key Rules

  1. Fragments never touch repositories directly — always through a ViewModel.
  2. ViewModels never hold View/Fragment/Activity references.
  3. Repositories are the single source of truth — they coordinate Room vs Retrofit.
  4. DTOs map to domain models inside the repository layer.
  5. One ViewModel per screen.

Screens

1. Splash

  • 2-second branded screen (logo + tagline).
  • Check SessionManager for active session → route to AuthActivity or MainActivity.

2. Auth Flow

Welcome — Logo, tagline, Login/Register buttons over full-bleed background image.

Login — Email + Password fields with real-time validation on TextInputLayout. Auth against Room UserEntity. Success → save session, navigate to MainActivity. Error → Snackbar.

Register — Name + Email + Password. Validate, check duplicate email in Room, insert user. Auto-login on success.

3. Discover (Map)

  • Google Maps SupportMapFragment with location markers from Room.
  • Category filter chips: All · Restaurant · Hotel · Attraction · Nature.
  • Marker click → bottom sheet preview → tap to open LocationDetailActivity.
  • FAB to center on user GPS (permission request if needed).
  • DiscoverViewModel exposes LiveData<List<Location>> filtered by category.

4. Feed

  • Vertical RecyclerView with CardView items.
  • Each card: location image (Glide), title, description, author, like count, weather icon + temp.
  • Weather fetched per location via WeatherApi.
  • Like toggle persisted in Room.
  • Tap card → LocationDetailActivity.
  • FeedViewModel exposes LiveData<List<FeedItem>>.

5. Search

  • SearchView or TextInputEditText at top.
  • Filter by location name, category, or country.
  • Results in RecyclerView list.
  • Tap result → LocationDetailActivity.
  • SearchViewModel with debounced query → LiveData<List<Location>>.

6. Profile

  • Display user info: name, email, traveler type, profile image, bio.
  • Edit profile (name, bio, traveler type, profile image via camera/gallery).
  • List of user's reviews.
  • Logout button → clear session → AuthActivity.
  • ProfileViewModel exposes LiveData<User> and LiveData<List<Review>>.

7. Location Detail

  • Header image (Unsplash or local).
  • Name, category, address, description.
  • Current weather overlay.
  • Reviews list (RecyclerView).
  • "Add Review" button (only enabled if GPS-verified nearby).
  • LocationDetailViewModel exposes location + reviews + weather.

8. Add Review

  • Rating bar (1–5 stars).
  • Review text (EditText, min length enforced).
  • Photo attachment (camera or gallery, up to 5 images).
  • GPS check via GPSValidator before submission.
  • Save ReviewEntity to Room.

Data Models

Room Entities

Entity Key Fields
UserEntity id (PK, auto), email (unique), name, passwordHash, bio, travelerType, profileImageUri
LocationEntity id (PK, auto), name, category, description, address, latitude, longitude, imageUrl, country
ReviewEntity id (PK, auto), locationId (FK), userId (FK), rating, text, imageUris (JSON string), timestamp
LikeEntity id (PK, auto), userId (FK), locationId (FK), unique(userId, locationId)

Domain Models

User, Location, Review, FeedItem — clean POJOs mapped from entities/DTOs in repositories.


External APIs (unchanged)

API Usage Auth
REST Countries Country metadata + flags None
Unsplash Location/feed photos Authorization header
OpenWeatherMap Weather overlays appid query param
Google Maps SDK Map display + markers Manifest API key

Pre-Seeded Data

The Room database will ship with a pre-populated set of ~20 locations across several countries/categories so the app is usable immediately without requiring user-generated content.


Out of Scope

  • Backend server / user-to-user sync.
  • Real-time chat or social features.
  • Offline map tiles.
  • Kotlin migration.
  • Jetpack Compose.
  • Multi-module Gradle setup (single :app module is fine).