¡Gracias a ti! 🙂 Con lo que describes ya se puede concretar bastante. Tu enfoque va bien, con algunos matices para que los cambios de SEO no te creen problemas de URLs, renderizado o sesiones.
Primero, esos indicios son compatibles con Rails, pero no permiten fechar la versión: una aplicación actualizada puede conservar plantillas y dependencias antiguas. Gemfile.lock te dará una referencia mucho más fiable; conviene contrastarla con lo que realmente está desplegado. Si se confirma Rails 5.x, está fuera del mantenimiento oficial y habría que planificar su actualización, sin mezclar una migración grande con todos estos cambios a la vez.
1. Sitemap y dobles barras
Lo corregiría donde se generan las URLs, después de localizar la concatenación concreta. No daría por hecho que la causa es default_host sin ver ese código.
Si usa la gema sitemap_generator, revisaría config/sitemap.rb: default_host con la URL base HTTPS, sin barra final, y las rutas generadas con los helpers *_path que se pasan a add. Si es una vista .builder propia, preferiría los helpers *_url, con host y protocolo de producción configurados explícitamente cuando se ejecuten fuera de una petición web.
Son dos formas de construir la URL; no concatenaría otra vez el host delante de un helper que ya devuelve una URL completa. Tampoco haría una sustitución global de dobles barras, porque podrías estropear https://.
Después regeneraría el XML y comprobaría que sus URLs son las canónicas, responden 200 y coinciden con los enlaces internos. Si las variantes con doble barra ya existen públicamente y representan la misma página, añadiría una redirección permanente a la correcta, sin cadenas. Arreglar únicamente el sitemap no elimina esas variantes.
2. JSON-LD, content_for y escape
Sí, content_for :json_ld en las vistas y yield :json_ld en el layout es un enfoque válido. Cuidaría el orden: el bloque tiene que estar definido antes de que el layout lo emita. Para mantenerlo, construiría los datos mediante un helper o presenter que lea los modelos, y dejaría la vista encargada de renderizarlos.
Para el escape, dentro de la etiqueta script de tipo application/ld+json, el patrón ERB es:
<%= raw(json_escape(datos_schema.to_json)) %>
Aquí datos_schema es el Hash/Array que construyes con los campos públicos que quieres marcar. Primero se serializa a JSON válido; después json_escape protege caracteres que podrían cerrar la etiqueta script. raw se aplica al resultado escapado. No usaría .html_safe directamente sobre texto de usuarios ni volcaría un modelo completo con datos privados. Este patrón también está documentado en Rails 5.2, aunque debes contrastarlo con la versión real del proyecto.
La distribución que propones tiene sentido: RealEstateAgent con un @id estable; RealEstateListing para la ficha, con su Offer; ItemList para el listado, Article para noticias y BreadcrumbList para las migas. Distinguiría la ficha del inmueble físico y conectaría las entidades mediante @id, usando propiedades válidas para cada tipo. availability va en Offer y debe reflejar el estado real que también ve el visitante.
Puedes conectar las entidades por @id, en uno o varios bloques. No es obligatorio reunirlo todo en un único script. Al cambiar el estado del inmueble, invalida también la caché de la ficha para que el marcado no siga ofreciendo algo vendido.
Sustituiría el marcado data-vocabulary.org obsoleto, conservando el contenido visible del footer que sí sea necesario. Y validaría dos cosas distintas: el vocabulario con Schema Markup Validator y la elegibilidad de los tipos que Google admite con su prueba de resultados enriquecidos. Un RealEstateListing válido no garantiza un resultado especial en Google.
3. Entidades y sameAs
No hay un mínimo de cinco sameAs. Pondría solo referencias que identifiquen inequívocamente a esa misma entidad: perfiles oficiales o fichas fiables, si existen. No rellenaría la lista con directorios dudosos para alcanzar una cantidad.
about hacia la Organization correspondiente encaja si esa página realmente trata sobre ella. Mantendría @id distintos para la agencia, cada grupo empresarial y cada inmueble. Compartir nombre o pertenecer al mismo grupo no convierte dos sociedades en la misma entidad. Esa coherencia ayuda a describirlas; no garantiza por sí sola su reconciliación en Google.
4. Slug + ID y redirección
Sí: si varias URLs representan exactamente la misma noticia, redirigiría las variantes a su URL canónica. Lo haría en la acción de lectura, después de cargar el registro y comprobar que sea público y accesible, generando el destino con el helper y el slug canónico del propio registro.
Compararía la ruta recibida con esa ruta canónica; no construiría el destino con un host o una URL aportados por el visitante. Para GET/HEAD, una 301 es adecuada. No extendería esa regla indiscriminadamente a formularios o peticiones POST.
La prueba sería: slug correcto devuelve 200; slug inventado con ID válido devuelve una sola redirección a la noticia correcta; ID inexistente devuelve 404; y no aparece ningún bucle. Después alinearía canonical, enlaces internos y sitemap con ese mismo destino.
5. WAF, CSRF, reCAPTCHA y caché
Puedes poner Cloudflare delante de Rails, pero no esperaría a posicionar para revisar seguridad. Si hay componentes sin soporte, el WAF complementa la actualización.
Empezaría con caché de estáticos y exclusiones claras para login, administración, respuestas personalizadas y formularios con tokens de sesión. Evitaría un Cache Everything global: compartir HTML con un token CSRF entre visitantes puede romper formularios o exponer contenido de otra sesión.
Mantendría la protección CSRF de Rails y la validación de reCAPTCHA en el servidor. Si algo falla al activar el proxy, revisaría cookies, caché, protocolo y reglas concretas antes de desactivar esas validaciones.
También comprobaría HTTPS hasta el origen, sin modo Flexible; que Rails reciba el host/protocolo correctos a través de proxies de confianza; y que la IP del cliente se obtenga de cabeceras confiables, no de cualquier cabecera enviada por el visitante. Si el WAF debe proteger todo el tráfico web, hay que controlar también el acceso directo al origen.
Probaría navegación y envío de formularios con dos sesiones independientes, sesión iniciada/cerrada, reCAPTCHA y rastreo de las páginas públicas. Las excepciones del WAF se ajustan sobre bloqueos comprobados, no desactivándolo entero.
Lo haría por cambios pequeños en un entorno de pruebas: primero generación de URLs y redirecciones, después marcado por tipo de página y por último reglas de proxy/caché. Así puedes comprobar cada efecto y revertirlo sin mezclar causas.
Te dejo las referencias para contrastarlo con la agencia:
Escape JSON en Rails:
Configuración de sitemap_generator:
SitemapGenerator is a framework-agnostic XML Sitemap generator written in Ruby with automatic Rails integration. It supports Video, News, Image, Mobile, PageMap and Alternate Links sitemap extensio...
github.com
Definición de sameAs:
Schema.org Property: sameAs - URL of a reference Web page that unambiguously indicates the item's identity. E.g. the URL of the item's Wikipedia page, Wikidata entry, or official website.
schema.org
Canonicalización y redirecciones:
Si en un sitio hay contenido duplicado, Google elige la URL canónica. Consulta más información sobre las URLs canónicas y cómo unificar URLs duplicadas.
developers.google.com
Caché, sesiones y CSRF con Cloudflare:
Troubleshoot login failures, missing session cookies, and challenge loops caused by caching dynamic content.
developers.cloudflare.com