Files
vuelato/CLAUDE.md
Alejandro Martinez b8906efc80
Some checks failed
ci / ci (22, ubuntu-latest) (push) Has been cancelled
Initial commit: Vuelato - buscador de vuelos
Nuxt 4 + Supabase + Flightics API. Incluye búsqueda de vuelos,
inspiraciones, watchlist, tracking de precios y mapa interactivo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 23:37:06 +02:00

4.6 KiB

CLAUDE.md — Guia para trabajar en Vuelato

Comandos rapidos

pnpm dev              # Dev server (localhost:3000)
pnpm supabase:up      # Levantar Supabase Docker
pnpm supabase:down    # Parar Supabase
pnpm supabase:reset   # Reset completo (borra datos)
pnpm lint             # ESLint
pnpm typecheck        # Vue type checking

Estructura del proyecto

app/
  pages/              # 10 paginas (Nuxt file-based routing)
  components/         # 27 componentes organizados por dominio (auth/, search/, results/, detail/, map/, inspiration/)
  composables/        # 9 composables (useFlightSearch, useAuth, useWatchlist, etc.)
  assets/css/         # Tailwind CSS
server/
  api/                # 13 endpoints Nitro (proxy Flightics + sync + flight-info + airlines)
  utils/flightics.ts  # Cliente API Flightics completo (tipos + 9 funciones)
  utils/wikidata.ts   # Cliente SPARQL Wikidata (aerolineas)
supabase/
  migrations/         # SQL init (tablas cache + usuario + RLS + trigger)
  volumes/db/         # roles.sql, jwt.sql (config Supabase internal)
  volumes/api/        # kong.yml (API gateway config)
docker-compose.yml    # Supabase stack completo (6 servicios)

Convenciones

Nuxt 4

  • El directorio raiz de la app es app/ (no src/).
  • Los server utils (server/utils/) se auto-importan en server routes. No usar import ... from '~/server/utils/...' — causa error porque ~ apunta a app/.
  • Componentes se auto-importan con prefijo de directorio: search/AirportInput.vue -> <SearchAirportInput />.

Componentes

  • Usar @nuxt/ui v4 components (UCard, UButton, UInput, UBadge, UFormField, UPopover, etc.).
  • Iconos: @iconify-json/lucide con prefijo i-lucide-*.
  • No usar emojis en la UI.
  • Idioma de la UI: espanol (es).

Composables

  • Cada composable maneja su propio estado reactivo.
  • Los composables de usuario (useWatchlist, useRecentSearches, useUserPreferences) hacen watch del user y cargan/limpian datos automaticamente al login/logout.
  • useAirlineNames es un cache reactivo global — aprende nombres de aerolineas de cualquier respuesta API y los resuelve en la vista.

Server routes

  • Los endpoints de Flightics son proxy directos (sin cache, excepto locations y countries que cachean 24h).
  • defineCachedEventHandler para cachear respuestas (flight-info: 5 min, locations/countries/airlines: 24h).
  • Usar serverSupabaseServiceRole para operaciones server-side que necesitan bypass de RLS (ej: sync/locations, sync/airlines).

Base de datos

  • Tablas publicas (airports, countries, airlines, etc.) accesibles por anon y authenticated (SELECT).
  • Tablas de usuario protegidas con RLS: auth.uid() = user_id.
  • Trigger on_auth_user_created crea profile automaticamente.
  • Para resetear: pnpm supabase:reset (borra volumen Docker y reinicia).
  • Para re-sincronizar aeropuertos: curl -X POST http://localhost:3000/api/sync/locations.
  • Para re-sincronizar aerolineas: curl -X POST http://localhost:3000/api/sync/airlines (datos de Wikidata: IATA, ICAO, nombre, logo).

Gotchas

Flightics API

  • La busqueda requiere polling: primera respuesta tiene notComplete: true. El composable hace hasta 3 rondas automaticamente.
  • company.name viene vacio en rondas de polling posteriores. Se resuelve via useAirlineNames (cache reactivo).
  • Fechas vacias en el payload causan 400. useFlightSearch.buildPayload genera fechas por defecto (hoy + 30 dias).
  • getRouteFlights devuelve trips ida+vuelta, no vuelos individuales.
  • getInspirations puede devolver vacio para aeropuertos pequenos — es normal.

Supabase Docker

  • La imagen supabase/postgres crea roles internos automaticamente. Los SQL de init solo ajustan passwords.
  • Si GoTrue falla al arrancar, verificar que el volumen este limpio: docker compose down -v && docker compose up -d.
  • Studio corre en puerto 3100 (no 3000, que es Nuxt).
  • Meta corre en 8085 (remapeado de 8080 que suele estar ocupado).

Frontend

  • AirportInput busca sin acentos (normaliza NFD). "malaga" encuentra "Malaga".
  • Modo multiple en AirportInput: badges + input. Backspace borra ultimo. Enter/click selecciona.
  • Leaflet se renderiza solo client-side (<ClientOnly>). Requiere import 'leaflet/dist/leaflet.css'.
  • El v-if="seg.company.name" falla con string vacio — usar useAirlineNames().resolve() en su lugar.

Variables de entorno

SUPABASE_URL=http://localhost:8000          # Kong gateway
SUPABASE_KEY=eyJ...                         # anon key (demo JWT)
SUPABASE_SERVICE_ROLE_KEY=eyJ...            # service_role key (para server-side)

Las keys demo estan en .env.example. Para produccion, generar nuevas con un JWT_SECRET propio.