Skip to content

estebankt/toposApp

Repository files navigation

Topos

A community-driven mobile guidebook for outdoor climbers. Replaces fragmented guidebooks, forums, and notes with a single platform for discovering crags, accessing route topos, logging sends, and contributing verified beta—with full offline support in the field.


Architecture & Design Decisions

Offline-First Data Layer

The core architectural constraint is that climbers use the app in areas with no cellular coverage. The solution is a hybrid local/remote architecture:

  • WatermelonDB (SQLite) serves as the authoritative local store. All UI reads go through the repository layer against the local DB.
  • SyncEngine handles bidirectional sync with Firebase: incremental pulls on connectivity restoration and push of local mutations with last-write-wins conflict resolution.
  • React Query sits on top of the repository layer for caching, background refetch, and optimistic updates for the social feed—where real-time freshness matters more than offline availability.

This separates the offline-capable content domain (areas, sectors, routes) from the real-time social domain (feed, likes, follows), each with appropriate consistency guarantees.

Repository Pattern

Direct Firestore calls are encapsulated in service wrappers (src/services/firebase/). All UI components interact with the database exclusively through repository classes (src/database/repositories/). This decouples the data access strategy from the UI layer—the same hook works whether data is served from SQLite or fetched from Firestore.

State Partitioning

Client state (auth session, UI preferences) is managed by Zustand. Server/async state (feed posts, area details, leaderboards) is managed by TanStack Query. Mixing these concerns into a single store was rejected because it conflates synchronization semantics with application state.

Search Without a Search Engine

Firestore has no native full-text search. Rather than introduce Algolia or a secondary index service, all searchable entities carry a name_lowercase field. Queries use a prefix range scan (>= query, <= query + '\uf8ff'). This covers the primary use case (searching by name prefix) with no operational overhead.

Ownership Enforcement

Edit and delete permissions are gated on created_by === currentUser.uid, enforced at both the application layer and in Firestore Security Rules. Client-side checks are for UX (hiding buttons); the Firestore rules are the security boundary.


Core Tech Stack

Layer Technology
Framework React Native 0.81 + Expo SDK 54
Navigation Expo Router (file-based)
Language TypeScript 5.9
Styling NativeWind 4 (Tailwind CSS)
Local Database WatermelonDB 0.28 (SQLite)
Remote Database Firebase Firestore
Auth Firebase Authentication
File Storage Firebase Storage
Server State TanStack Query 5
Client State Zustand 5
Push Notifications expo-notifications
i18n i18next + react-i18next (ES/EN)
Maps react-native-maps
Vector Graphics react-native-svg (topo line drawing)

Engineering Standards

Testing

Manual end-to-end test cases are defined in TEST_PLAN.md, covering auth flows, content creation, social interactions, and offline behavior. Playwright is included for future E2E automation targeting web/simulator targets.

All features require passing the TEST_PLAN.md checklist before being marked complete in PROGRESS.md.

Commit Convention

Conventional Commits: feat:, fix:, chore:, refactor:. Enforced by team convention.

CI/CD

Not yet configured. EAS Build and EAS Submit (Expo Application Services) are the planned path for TestFlight and Play Store distribution.


Getting Started

Prerequisites: Node.js LTS, iOS Simulator (Xcode) or Android Emulator (Android Studio), or a physical device.

# Install dependencies
npm install

# Start development server (Expo Go compatible)
npm start

# Run native build on iOS simulator (required for WatermelonDB)
npm run ios

# Run native build on Android emulator
npm run android

WatermelonDB requires a native build. Features that depend on the offline database (useOfflineAreas, SyncEngine, area downloads) will not function in Expo Go. Use npm run ios or npm run android for a full development build.

Firebase credentials are read from environment variables. Copy .env.example to .env.local and populate with your Firebase project config before starting.


Documentation

Document Purpose
TECH_SPEC.md Architecture, data models, directory structure, design tokens, development guidelines
PRD.md Product requirements, user personas, screen specifications, success metrics
PROGRESS.md Completed waves, current status, known issues, roadmap
TEST_PLAN.md Manual test cases for all critical flows

About

A community-driven mobile application that serves as the definitive outdoor climbing guidebook, enabling climbers to discover areas, view detailed route topos, log their sends, and contribute to a growing database of climbing information

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors