passengers-app — CONTEXT.md
Ionic 8 / Angular 20 passenger-facing mobile app. Route search, real-time bus tracking, QR check-in/out, and wallet payments. Deployed via Capacitor to iOS and Android. For global conventions (branding, Angular patterns, GIS overview), see
/CLAUDE.md.
1. Tech Stack
| Layer | Technology | Version |
|---|---|---|
| Framework | Ionic + Angular | Ionic ^8.0, Angular ^20.0.0 |
| Maps | Leaflet | ^1.9.4 |
| Native | Capacitor | ^8.2.0 |
| GPS | @capacitor/geolocation | ^8.1.0 |
| Storage | @capacitor/preferences | ^8.0.1 |
| Notifications | @capacitor/local-notifications | ^8.0.2 |
| QR Generate | qrcode | ^1.5.4 |
| QR Scan | html5-qrcode | ^2.3.8 |
| Real-time | socket.io-client | ^4.8.3 |
| Styling | Tailwind CSS | ^3.4.19 |
| Particles | tsparticles | ^3.9.1 |
| Build | @angular/build (esbuild) | ^20.0.0 |
Capacitor Config
- appId:
com.syncc.passengers - appName:
Syncc Pasajero - webDir:
www - Android scheme:
https - iOS:
contentInset: automatic,limitsNavigationsToAppBoundDomains: true
2. Routes
| Path | Component | Notes |
|---|---|---|
/home |
HomePage |
Route search, suggestions, real-time map |
/route-detail/:lineId/:routeId |
RouteDetailPage |
Route detail with map + checkpoints |
/gtfs-route-detail |
GtfsRouteDetailPage |
GTFS route detail (state-passed data) |
/nearby |
NearbyPage |
Nearby stops/lines |
/lines |
LinesPage |
Browse all lines |
/lines/:id |
LineDetailPage |
Single line detail |
/favorites |
FavoritesPage |
Saved routes/lines |
/login |
LoginPage |
OTP-based passenger auth |
/profile |
ProfilePage |
Profile, balance, recharge |
/my-qr |
MyQrPage |
Passenger QR display |
/scanner |
ScannerPage |
QR scanner (check-in) |
/ |
Redirects to /home |
— |
** |
Redirects to /home |
— |
All routes use lazy loading via loadComponent.
3. Core Services
All services in src/app/core/services/, providedIn: 'root'.
| Service | Purpose |
|---|---|
| AuthService | Passenger login/signup; OTP flow; currentUser signal; JWT validation |
| TokenService | JWT persistence via Capacitor Preferences (syncc_pax_token) |
| RealtimeService | Socket.IO connection; buses signal (Map |
| LinesService | HTTP calls for lines, routes, checkpoints, stops |
| BoardingService | QR check-in/out; active boarding session; state persistence |
| PaymentIntentService | "Pagar con saldo" intent signals (enabled, amount) |
| PaymentService | Recharge flow; payment gateway integration |
| FavoritesService | Favorite routes/lines; persisted to Preferences |
| HistoryService | Search history; persisted storage |
| SuggestionsService | Route suggestions based on history/favorites |
| PermissionService | Capacitor permissions (geolocation, camera, notifications) |
| DrawerService | Navigation drawer state (isOpen, overlayOpen signals) |
| OsrmService | Road-snapping via OSRM public server (foot profile, 6s timeout) |
4. OSRM Walking Legs
Walking legs (origin → board stop, alight stop → destination) use the OSRM foot profile:
- Called from the browser/device — never proxied through the backend
- URL: https://router.project-osrm.org/route/v1/foot/{lng1},{lat1};{lng2},{lat2}?overview=full&geometries=polyline
- Timeout: 6 seconds
- Falls back to straight line if OSRM is unreachable
- Used in home.page.ts → drawTripOnMap() and route-detail.page.ts → initMap()
5. Environment Config
set-env.cjs reads --environment=local|dev|prod and generates environment files:
- Local: loads .env → writes environment.local.ts (localhost:3000)
- Dev: loads .env.development → writes environment.ts (api.dev.syncc.me)
- Prod: loads .env.production → writes environment.prod.ts
- Searches for .env in: ./, ../api-server/, ../../
- Required env var: API_URL
6. QR / Payment Feature — Restore Instructions
Trigger: "implement the QR functionality" or "activate the QR functionality".
All QR/payment UI is hidden with @if (false) blocks (not deleted). To restore:
src/app/app.component.html — Three blocks:
-
"En el bus" boarding banner (line ~155):
@if (false)→@if (activeBoarding())Shows boarding status banner with line name and elapsed time. -
QR floating action button (line ~188):
@if (false)→@if (isLoggedIn() && !overlayOpen())Circular FAB at bottom-center that opens QR modal. -
QR modal full screen (line ~201):
@if (false)→@if (qrModalOpen())Contains scan tab (html5-qrcode scanner), show-QR tab, and "Pagar con saldo" toggle with amount input.
src/app/pages/profile/profile.page.html — Two blocks:
-
Balance card (line ~25): HTML comment block
<!-- NOT LAUNCHING YET: Balance card ... END NOT LAUNCHING YET -->— delete the comment wrapper lines. Shows "Saldo disponible" with Bs. amount and "Agregar saldo" button. -
Recharge modal (line ~107):
@if (false)→@if (rechargeStep() !== 'idle')Multi-step modal: amount → processing → success/error.
What does NOT need to change
- All TypeScript services are intact (
BoardingService,PaymentIntentService,PaymentService) - Routes
/my-qrand/scannerexist and are routed — just not reachable from hidden UI DrawerService.overlayOpen/showOverlay()/hideOverlay()already wired
After restoring
npm run cap:ios # or npm run cap:android
No backend changes needed — all API endpoints are already live.
7. Dev Workflow
cd apps/passengers-app
npm install
npm start # Dev server at http://localhost:4200
npm run build:prod # Production build
npx cap sync # Sync Capacitor native projects
npx cap run android # Run on Android
npx cap run ios # Run on iOS
8. Key File Paths
| What | Path |
|---|---|
| Routes | src/app/app.routes.ts |
| App component | src/app/app.component.ts / .html |
| Services | src/app/core/services/ |
| Pages | src/app/pages/ |
| OSRM service | src/app/core/services/osrm.service.ts |
| Profile page | src/app/pages/profile/profile.page.ts / .html |
| Environment config | set-env.cjs |
| Capacitor config | capacitor.config.ts |
| Tailwind config | tailwind.config.js |
Last updated: 2026-06-05.