PRODUCTO SAAS v1.0

RutaFácil

PWA for delivery couriers: capture locations from WhatsApp and generate the shortest delivery route right on the device.

Timeline

2 Weeks

Role

Frontend & PWA Developer

Slide 1
1 / 6

The Problem

Independent delivery couriers receive dozens of orders daily via WhatsApp or messaging apps. Manually planning the sequence of stops leads to significant fuel and time waste, while commercial routing tools require expensive subscriptions or heavy APIs.

  • ✕Wasted fuel and delivery time from estimating stop sequences manually.
  • ✕High friction when copying and pasting addresses between chat apps and navigation tools.
  • ✕Expensive routing subscriptions and API fees that are unviable for independent couriers and local stores.
  • ✕Fragile internet connectivity on the road requiring offline-first capabilities.

The Solution

I designed and engineered RutaFácil, an ultra-fast mobile-first PWA with $0 infrastructure cost. It empowers delivery riders to share addresses directly from WhatsApp to their system Share menu, optimizing delivery sequences locally via heuristic algorithms.

On-Device TSP Optimization

Nearest Neighbor heuristic combined with 2-opt local search running in milliseconds on-device, minimizing travel distance without server dependencies.

Web Share Target Integration

Leverages the Web Share Target API to receive location links directly from WhatsApp, Google Maps, or Waze in two taps.

Offline-First PWA

Installable as a standalone app on mobile devices with local state persistence via Zustand, working reliably in low-connectivity areas.

Zero-Cost Vector Maps

Powered by MapLibre GL and Esri World Street Map tiles, delivering smooth vector mapping without recurring commercial API keys.

Turn-by-Turn Delivery Workflow

Stop-by-stop guidance with instant Google Maps/Waze launching and one-tap delivery completion.

Cash Collection & Dispatch Tools

Track cash-on-delivery payments per stop, generate WhatsApp dispatch notifications, and export route traces to GPX.

Tech Stack

React 18

Frontend

Vite 6

Build Tool

TypeScript

Language

PWA

Mobile & Offline

MapLibre GL

Mapping / GIS

Zustand

State Management

Framer Motion

Animations

Vitest

Testing

Technical Challenges

Zero-Cost On-Device TSP Optimization

Solving the Traveling Salesperson Problem (TSP) without paying for Google Directions or cloud matrix APIs required implementing a client-side solution combining a Nearest Neighbor greedy baseline with 2-opt segment reversals on Haversine distances. It computes near-optimal routes for up to 30 stops in under 5ms right on the courier's phone.

tsp.ts
// Heurística de Vecino Más Cercano + Mejora 2-Opt (Cálculo On-Device $0)
export function optimizeOrder(
  origin: LatLng,
  stops: LatLng[],
  fixedEnd?: LatLng,
): number[] {
  const n = stops.length;
  if (n <= 1) return stops.map((_, i) => i);

  const points = fixedEnd ? [origin, ...stops, fixedEnd] : [origin, ...stops];
  const dist: number[][] = points.map((a) =>
    points.map((b) => haversineKm(a, b)),
  );
  const endIdx = fixedEnd ? n + 1 : null;

  // 1. Vecino más cercano desde el origen
  const visited = new Array<boolean>(n + 1).fill(false);
  visited[0] = true;
  const path: number[] = [0];
  let current = 0;
  for (let step = 0; step < n; step++) {
    let best = -1;
    let bestDist = Infinity;
    for (let j = 1; j <= n; j++) {
      if (!visited[j] && dist[current][j] < bestDist) {
        bestDist = dist[current][j];
        best = j;
      }
    }
    visited[best] = true;
    path.push(best);
    current = best;
  }
  if (endIdx !== null) path.push(endIdx);

  // 2. Optimización 2-opt: invierte segmentos mientras acorte el camino
  let improved = true;
  while (improved) {
    improved = false;
    for (let i = 1; i < n; i++) {
      for (let k = i + 1; k <= n; k++) {
        const a = path[i - 1];
        const b = path[i];
        const c = path[k];
        const d = k + 1 <= n ? path[k + 1] : endIdx;
        const before = dist[a][b] + (d !== null ? dist[c][d] : 0);
        const after = dist[a][c] + (d !== null ? dist[b][d] : 0);
        if (after < before - 1e-9) {
          let lo = i;
          let hi = k;
          while (lo < hi) {
            [path[lo], path[hi]] = [path[hi], path[lo]];
            lo++;
            hi--;
          }
          improved = true;
        }
      }
    }
  }

  return path.slice(1, n + 1).map((p) => p - 1);
}

Multi-Format Location Parsing & Share Target

Couriers receive locations in wildly varied formats: shortened Google Maps URLs, raw coordinate pairs, Waze links, or copied chat transcripts. Built a resilient regex parser capable of scanning full multi-line conversations and extracting every stop in one pass.