← Blog | Producto 13 Mar 2026 · 16 min lectura

FarmaMap: Farmacias de Guardia en Tiempo Real

Estamos construyendo una PWA que encuentra la farmacia de guardia más cercana en 3 segundos. Para toda España. Desde cualquier dispositivo. Con datos oficiales, modo offline, IA conversacional y coste de infraestructura cero — el segundo producto de salud de Cadences, junto a NutriNen.

Un producto de Cadences · Junto a NutriNen

1 El problema que nadie ha resuelto bien

Son las 23:40 de un domingo. Tu hijo tiene fiebre. Necesitas ibuprofeno infantil. Abres Google y buscas "farmacia de guardia cerca".

Lo que encuentras: una web del colegio de farmacéuticos de tu provincia hecha en 2008, un PDF escaneado con los turnos del mes, o una app llena de anuncios con datos de hace tres días. 1.5 millones de búsquedas al mes de "farmacia de guardia" en España — y ninguna solución lo resuelve de verdad.

Tras construir NutriNen — donde aprendimos a producir herramientas de salud que capturan tráfico orgánico masivo con coste cero — nos dimos cuenta de que este problema tiene exactamente las mismas propiedades: demanda enorme, soluciones actuales penosas, y ejecutable con el stack que ya tenemos.

Solución actual Problema
Webs de colegios farmacéuticos UX de los 2000, no responsive, datos dispersos por provincia
Google Maps "farmacia" No distingue guardia vs abierta vs cerrada
Apps existentes Datos desactualizados, ads invasivos, solo Android o solo iOS
PDFs del BOE / boletines Formato no parseado, requiere descarga, imposible buscar

2 La visión: 3 segundos para encontrar tu farmacia

FarmaMap es una Progressive Web App — funciona como app nativa cuando la instalas, pero también como web cuando la abres desde Google. Un único desarrollo que cubre iOS, Android, desktop y web. Sin App Store fees. Sin Apple Developer Program. Sin fragmentación.

💡 Value Proposition

"Encuentra la farmacia de guardia más cercana en 3 segundos. En cualquier ciudad de España. Desde cualquier dispositivo."

🗺️

Mapa interactivo

Pins con color por estado: verde (abierta), azul (guardia), gris (cerrada). Clusters inteligentes. Geolocalización automática.

📴

Offline-first

Service Worker cachea farmacias cercanas y map tiles. Funciona sin conexión. Banner "datos de hace Xh" cuando está offline.

🤖

IA conversacional

"¿Hay farmacia 24h cerca de Atocha?" — chatbot RAG con datos en tiempo real. Misma arquitectura que el chatbot de Codex.

🔍

SEO masivo

~30.000 páginas estáticas indexables: cada farmacia, municipio, provincia y CCAA. Schema.org Pharmacy en cada ficha.

3 Por qué ahora, por qué nosotros

FarmaMap no es un side project que necesita levantar infra desde cero. Todo lo que necesitamos ya existe en Cadences: D1 para datos, Workers para API edge, KV para cache, Vectorize para IA, Cron Workers para scraping automático y Synapse Studio para el admin. El coste marginal de añadir este producto es literalmente cero a nivel de infraestructura.

Además, con NutriNen hemos probado un patrón que funciona: herramientas de salud gratuitas que capturan tráfico orgánico masivo. NutriNen genera miles de visitas mensuales con 29 herramientas SEO que no cuestan nada de servir. FarmaMap replica este modelo pero con una ventaja adicional: las búsquedas "farmacia de guardia [ciudad]" son transaccionales — el usuario necesita ir a una farmacia ahora, lo que abre oportunidades de monetización directas.

🔗 Conexión NutriNen + FarmaMap

Mismo stack: Astro 5 + React + Tailwind + Cloudflare (Workers, D1, KV, Vectorize)

Mismo patrón: Herramientas gratuitas → tráfico orgánico → monetización indirecta

Mismo vertical: Ambos viven en el espacio de salud familiar

Cross-pollination: Un padre buscando farmacia de guardia para su hijo es exactamente el usuario de NutriNen. Y viceversa.

4 Arquitectura edge-native

FarmaMap se despliega como storefront de Cadences — exactamente igual que Codex, GoViajes o cualquier otro. La diferencia es que tiene un data pipeline de scraping que alimenta la base de datos cada 6 horas con fuentes oficiales de colegios farmacéuticos.

📱 Frontend — Astro 5 + React Islands

PWA con Service Worker (Workbox), IndexedDB para cache local, Mapbox GL JS para mapas interactivos. SSG para ~30K páginas estáticas (SEO). React islands para componentes dinámicos: mapa, búsqueda, filtros.

API — Cloudflare Workers (Edge)

8 endpoints REST bajo /api/farmamap/*. Búsqueda geoespacial por geohash (sin extensiones GIS), full-text search (FTS5), chat IA y estadísticas. Cache con KV + CDN headers.

🔄 Data Pipeline — Cron Workers (cada 6h)

Scrapers por CCAA con adapter pattern. Scrape → Parse → Normalize → Geocode → Geohash → Dedupe → Upsert en D1. Alertas en Synapse si una fuente falla.

🗄️ Storage — D1 + KV + Vectorize

D1: 5 tablas (pharmacies, schedules, data_sources, favorites, analytics). KV: cache de guardia diaria por provincia. Vectorize: embeddings para chatbot IA. Todo gratis en el free tier de Cloudflare.

5 El truco del geohash: búsqueda espacial sin PostGIS

D1 es SQLite — no tiene extensiones geoespaciales. Pero no necesitamos PostGIS para buscar "farmacias cerca de mí". Usamos geohash: un sistema que codifica coordenadas GPS en un string alfanumérico donde los prefijos comunes indican proximidad geográfica.

-- Búsqueda de farmacias cercanas por prefijo geohash
-- Almacenamos geohash de 7 chars (~76m precisión)
-- pharmacies.geohash = 'ezjmgpu'

-- Query "farmacias a ~1.2km": prefijo de 6 chars
SELECT * FROM farmamap_pharmacies
WHERE geohash LIKE 'ezjmgp%'
ORDER BY geohash;

-- Query "farmacias a ~2.4km": prefijo de 5 chars
SELECT * FROM farmamap_pharmacies
WHERE geohash LIKE 'ezjmg%'
AND is_24h = 1  -- solo 24h
ORDER BY geohash;
Prefijo Precisión Radio aprox. Uso
4 chars ±20 km Ciudad Búsqueda provincial
5 chars ±2.4 km Barrio "Cerca de mí" en ciudad
6 chars ±610 m Manzanas "Muy cerca" walking
7 chars ±76 m Calle Almacenamiento

El cálculo fino de distancia (Haversine) se hace client-side con los ~20-50 resultados que devuelve D1, no en la query SQL. Resultado: queries de <5ms en una tabla de 22.000 farmacias sin ninguna extensión GIS.

6 Data pipeline: de 17 colegios farmacéuticos a una sola API

España no tiene una API centralizada de farmacias. Cada Comunidad Autónoma tiene su propio sistema, gestionado por su Colegio Oficial de Farmacéuticos. Eso significa que necesitamos un scraper adaptado por fuente — pero con un patrón común: adapter pattern donde cada módulo exporta scrape(), parse() y normalize().

FETCH Descargar HTML/JSON de fuentes oficiales

Colegios farmacéuticos (COFM, COFB, MICOF...), portales de datos abiertos autonómicos, OpenStreetMap como seed complementario.

NORMALIZE Unificar formatos dispares

Cada fuente tiene su formato. Normalizamos: nombres (Title Case), direcciones (Av. → Avenida), teléfonos (+34), horarios (JSON estándar).

GEOCODE Coordenadas + Geohash

Muchas fuentes no incluyen lat/lng. Geocodificamos con Mapbox (batch), cacheamos en D1 para no repetir, calculamos geohash de 7 chars.

DEDUPE Eliminar duplicados

Exact match (source_id), fuzzy match (nombre similar + distancia <50m), merge de datos de múltiples fuentes.

UPSERT D1 + KV cache

Insert/update en D1, invalidar KV cache por provincia/fecha, log en data_sources con timestamp y estado.

7 30.000 páginas para Google: la estrategia SEO

La misma lección que NutriNen: el SEO orgánico no es un canal de marketing — es el producto mismo. Cada farmacia es una página. Cada municipio es una página. Cada provincia es una página. Google indexa todo y el usuario llega directamente a lo que busca.

Tipo de página Ejemplo de URL Volumen Target keyword
Ficha farmacia /farmacia/garcia-lopez-gran-via-madrid ~22.400 "farmacia [nombre]"
Municipio /municipio/alcala-de-henares ~8.131 "farmacia guardia [municipio]"
Provincia /provincia/madrid 52 "farmacias guardia [provincia]"
Comunidad /comunidad/comunidad-de-madrid 17 "farmacias [CCAA]"
Schema.org — Cada ficha de farmacia incluye structured data
{
  "@context": "https://schema.org",
  "@type": "Pharmacy",
  "name": "Farmacia García López",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "Calle Gran Vía, 42",
    "addressLocality": "Madrid",
    "postalCode": "28013"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 40.420041,
    "longitude": -3.705764
  },
  "openingHoursSpecification": [...],
  "telephone": "+34 91 123 4567"
}

📊 Keywords de oro

"farmacia de guardia [ciudad]" — ~50K/mes
"farmacia 24 horas [ciudad]" — ~30K/mes
"farmacia abierta ahora" — ~20K/mes
"farmacia cerca de mí" — ~100K/mes (mobile)

8 22.400 farmacias, 47M de usuarios potenciales

España tiene 22.400+ farmacias. Cada noche, miles de ellas entran en turno de guardia. El sistema de turnos es obligatorio y regulado — no es opcional. Eso significa datos estables, predecibles y de fuente pública.

22.4K farmacias en España
47M usuarios potenciales
1.5M búsquedas/mes
$0 coste infra marginal

La monetización tiene múltiples vectores, todos complementarios al modelo NutriNen de valor primero, ingresos después:

Stream Modelo Target
Farmacia Destacada €10-30/mes por posición preferente en resultados Farmacias individuales
API comercial Acceso a datos consolidados de farmacias Empresas, apps, seguros
White-label FarmaMap con branding del colegio farmacéutico Colegios oficiales
Cadences upsell Farmacias interesadas en web propia → storefront template Farmacias digitalizándose

9 Roadmap: de Madrid al mapa completo

Filosofía: ship fast, iterate faster. Cada fase es deployable y usable. No hay big bang release.

Phase 0 Research & Data 1 semana

Validar fuentes de Madrid (COFM), descargar seed de OpenStreetMap, crear primer scraper, geocodificar farmacias sin coordenadas, cargar ~3.400 farmacias en D1.

Phase 1 MVP Madrid 2 semanas

PWA funcional con mapa interactivo, búsqueda por ubicación/texto/municipio, filtros (guardia, 24h, abiertas), fichas de farmacia con Schema.org, Service Worker offline, cron cada 6h.

Phase 2 Multi-ciudad 2 semanas

Barcelona, Valencia, Sevilla, Bilbao, Zaragoza. Scrapers adaptados por CCAA. Favoritos en IndexedDB. Páginas de provincia y CCAA. Install prompt PWA. ~8.000+ farmacias.

Phase 3 IA + SEO 1 semana

Chatbot RAG ("¿hay farmacia 24h cerca de Atocha?"), sitemap.xml con 30K+ URLs, Open Graph, analytics ligero, push notifications opt-in.

Phase 4 Toda España 2 semanas

Cobertura nacional: 22.400+ farmacias, 17 CCAA. Multi-idioma (ES/CA/EU/GL/EN). Performance a escala. Load testing.

Phase 5 Monetización ongoing

Farmacia Destacada, API comercial, white-label para colegios, Cadences upsell, premium features.

10 Coste real: probablemente $0

Uno de los beneficios de construir sobre Cadences: el coste marginal de añadir un producto nuevo es casi nulo.

Recurso Free Tier Necesitamos Coste
Cloudflare Pages 500 deploys/mes ~10/mes $0
Workers (API) 100K req/día ~10K/día est. $0
D1 (base de datos) 5GB storage ~50MB $0
KV (cache) 100K reads/día ~5K/día $0
Vectorize (IA) 200K vectors ~25K vectors $0
Mapbox GL JS 50K loads/mes ~5K/mes est. $0
Total $0/mes

Si superamos el free tier (buena señal — significaría tracción real), el coste escala de forma lineal y predecible. Cloudflare Workers Paid es $5/mes + $0.50 por millón de requests adicionales.

📋 FarmaMap en números (objetivo)

22.4K farmacias indexadas
~30K páginas SEO
8 endpoints REST
<5ms query geohash
17 CCAA cubiertas
6h ciclo de scraping
5 idiomas (ES/CA/EU/GL/EN)
$0 coste mensual
C

Cadences Engineering

Documentación técnica del equipo de ingeniería

Newsletter

No te pierdas ninguna historia

Suscríbete para recibir nuevos lanzamientos, capítulos exclusivos y contenido detrás de cámaras.

  • Insights y artículos semanales
  • Contenido exclusivo y acceso anticipado
  • Sin spam, cancela cuando quieras

Respetamos tu privacidad. Puedes darte de baja cuando quieras.