DSW - Desarrollo web en entorno servidor¶
El backend como nucleo de la aplicacion¶
La capa servidor de SEO Growth Engine concentra la logica principal del proyecto. Aqui definimos el dominio, controlamos accesos, lanzamos procesos, construimos respuestas API y guardamos trazabilidad de las ejecuciones.
Hemos utilizado Django como framework principal y lo hemos llevado a un uso bastante completo: modelos, ORM, formularios, vistas web, admin, autenticacion, API JSON y tareas desacopladas.
Evidencias directas¶
dashboard/models.pydashboard/admin.pydashboard/web/forms.pydashboard/web/views.pydashboard/api/urls.pydashboard/api/views.pymain/settings.pymain/urls.pydashboard/tasks/queue.pydashboard/tasks/services.pydashboard/management/commands/runworker.pyengine/runner.pyengine/gsc.pyengine/ga4.pyengine/report_data.pyengine/ai_visibility.py
Cumplimiento de los requisitos de DSW¶
| Requisito | Como lo hemos resuelto | Evidencia real |
|---|---|---|
| Django como backend | Hemos construido la aplicacion principal sobre Django y la hemos organizado por apps, vistas y settings |
manage.py, main/, dashboard/ |
| Modelos y ORM | Hemos modelado sitios, accesos, runs y visibilidad IA con relaciones y consultas ORM | dashboard/models.py |
| Interfaz administrativa | Registramos modelos clave para administracion interna | dashboard/admin.py |
| API | La capa cliente consume una API JSON real construida dentro del proyecto | dashboard/api/views.py, dashboard/api/urls.py |
| Autenticacion | Usamos usuarios Django, cookies de sesion, CSRF y permisos por acceso a sitio |
main/settings.py, dashboard/api/views.py, dashboard/web/views.py |
| Tareas desacopladas | Los procesos largos se mandan a Redis + RQ y se ejecutan en worker |
dashboard/tasks/queue.py, dashboard/tasks/services.py, runworker.py |
| Documentacion tecnica | El backend esta documentado con rutas, evidencias y decisiones tecnicas | docs/documentacion-del-proyecto.md, docs de despliegue y esta seccion |
El dominio que hemos modelado¶
En dashboard/models.py se ve bien que no estamos ante una base de datos improvisada. Hemos creado un dominio coherente:
Site: representa el activo principal sobre el que trabaja la plataforma.SiteAccess: relaciona usuarios con sitios y permisos operativos.AnalysisRun: guarda cada ejecucion con estado, progreso, artefactos y tiempos.AIVisibilityPrompt: define prompts configurables por sitio.AIVisibilityRun: registra ejecuciones de visibilidad IA.AIVisibilityObservation: persiste observaciones y resultados.
Ademas, los modelos incluyen helpers que convierten datos crudos en comportamiento util:
Site.save()genera el slug automaticamente.Site.integration_cards()resume el estado de integraciones.AnalysisRun.is_finished,is_active,is_cancellableayudan a la interfaz y al flujo.AnalysisRun.duration_displayydate_range_labeltraducen datos a informacion operativa legible.
Arquitectura backend en detalle¶
API y serializacion¶
En dashboard/api/views.py hay una API JSON propia que alimenta la capa cliente y expone datos operativos del workspace:
_serialize_user()prepara la informacion del usuario para el cliente._serialize_run_summary()y_serialize_run_detail()convierten unAnalysisRunen un payload reutilizable._serialize_site()y_serialize_dashboard_site()construyen la vista resumida que necesita el dashboard.api_bootstrap()resuelve el arranque de la sesion cliente.api_session_login()yapi_session_logout()conectan el login Vue con la autenticacion Django.api_sites_list(),api_runs_list(),api_run_detail()yapi_dashboard_summary()exponen los datos reales del workspace.
Con esta API alimentamos la interfaz con datos de sesion, sitios, runs, detalle de ejecucion y resumen del dashboard.
Logica web y flujos operativos¶
En dashboard/web/views.py se concentran varios flujos operativos del backend:
_build_site_summary()resume el estado operativo de un sitio para listados y paneles._build_run_setup_warnings()detecta carencias de configuracion antes de lanzar una ejecucion.launch_run()crea y arranca analisis tecnicos.cancel_run()yretry_run()controlan el ciclo de vida de una ejecucion.launch_ai_visibility_run(),cancel_ai_visibility_run()yretry_ai_visibility_run()hacen lo mismo con la parte de IA.run_status(),run_report()yrun_artifact()exponen seguimiento, informe y archivos generados.
Con estas funciones mostramos que nuestra aplicacion no solo presenta datos: tambien orquesta procesos reales.
Formularios con validacion de negocio¶
En dashboard/web/forms.py no hay formularios planos. Hemos anadido validaciones que protegen nuestra operativa:
AnalysisRunForm.clean()obliga a seleccionar al menos un modulo, valida rangos de fechas y comprueba siGSC,GA4oAI Visibilityestan realmente preparados.ClientAccountForm.clean()ysave()gestionan alta de clientes, asignacion de sitios y permisos finos de run y IA.PublicContactFormprepara entradas de contacto con una estructura valida para revision interna.
Aqui se ve que usamos Django Forms no solo para pintar campos, sino para reforzar las reglas de nuestro sistema.
Crawler tecnico¶
El crawler vive en engine/crawler.py y se ejecuta desde engine/runner.py. Su responsabilidad es transformar una URL inicial en datos tecnicos medibles: paginas HTML, assets, enlaces internos, metadatos, contenido, canonicals, hreflang y redirecciones.
El control de alcance se hace con CrawlConfig:
max_pageslimita cuantas URLs se visitan.delayintroduce pausa entre peticiones para no saturar el sitio.timeoutevita que una URL lenta bloquee todo el proceso.concurrencydefine cuantos workers rastrean a la vez.
El crawler separa dos tipos de salida:
pages: documentos HTML con contenido, metadatos y enlaces internos.assets: recursos no HTML o respuestas que parecen assets.
Despues, engine/analysis.py convierte ese material en informacion SEO:
audit_pages()detecta errores HTTP, titulos ausentes, H1 ausentes, contenido fino y duplicados.internal_link_graph()calcula inlinks, outlinks, paginas huerfanas, hubs y autoridad interna.audit_redirects()identifica redirecciones simples, cadenas y paginas rotas.audit_canonical()revisa canonicals ausentes, self-canonical, cross-canonical y conflictos.audit_url_structure()analiza profundidad y patrones de URL.
Con este flujo el crawler no se queda en "visitar paginas". Produce una base de datos tecnica que luego alimenta CSVs, plan de accion, informe HTML e historico de ejecuciones.
Tareas desacopladas, workers y ejecucion en segundo plano¶
Con esta capa resolvemos un problema real: un crawl, una consulta a GSC, una consulta a GA4 o un analisis de AI Visibility pueden tardar bastante. Si todo eso se ejecutara dentro de la peticion HTTP, el usuario esperaria con la pantalla bloqueada y el servidor podria agotar timeouts.
Por eso en nuestro proyecto separamos dos responsabilidades:
- la web recibe la accion del usuario, valida permisos y crea el
AnalysisRuno elAIVisibilityRun; - el worker ejecuta el trabajo pesado fuera del ciclo de peticion/respuesta.
En dashboard/tasks/queue.py se decide si se usa Redis + RQ o un fallback por thread:
get_active_queue_backend()eligerqsi hayREDIS_URLothreadsi no hay cola disponible.enqueue_analysis_run()enviadashboard.tasks.jobs.run_analysis_joba la cola de analisis.enqueue_ai_visibility_run()enviadashboard.tasks.jobs.run_ai_visibility_joba la cola de IA.get_worker_queues()prepara las colas que escuchara el worker.
En dashboard/tasks/services.py se coordina la ejecucion real:
start_analysis_in_background()conecta la accion web con la cola.start_ai_visibility_in_background()hace lo mismo para IA._execute_run()marca el run comoRUNNING, llama aengine.runner.run_full(), actualiza progreso y guarda artefactos._execute_ai_visibility_run()procesa prompts, llama arun_visibility_analysis()y guarda observaciones._set_run_progress()actualiza porcentaje, paso actual y mensaje visible._append_log()deja rastro cronologico enlog_output.request_analysis_cancellation()yrequest_ai_visibility_cancellation()permiten cancelar de forma controlada.
La interfaz no se bloquea porque la peticion HTTP solo dispara el trabajo. Nuestro worker trabaja aparte y la UI consulta o muestra el estado guardado en base de datos.
Con esta separacion conseguimos varios resultados practicos:
- la peticion HTTP no queda bloqueada por procesos largos;
- menos riesgo de timeouts;
- posibilidad de cancelar o reintentar;
- logs visibles para diagnostico;
- arquitectura preparada para crecer con mas workers si hubiera mas carga;
- separacion limpia entre capa web y procesamiento pesado.
Motor y funciones analiticas relevantes¶
Nuestro backend no termina en dashboard/. El motor tecnico vive en engine/:
engine/gsc.pyincluye funciones comofetch(),quick_wins(),ctr_leaks(),cannibalization()ybigram_clusters().engine/ga4.pyincluyefetch()y la construccion de metricas derivadas.engine/report_data.pyconcentrabuild_report_data()y la comparativa entre ejecuciones.engine/ai_visibility.pyculmina enrun_visibility_analysis().
El backend no es solo CRUD: tambien incorpora analitica, tratamiento de datos y generacion de resultados SEO.
Autenticacion y seguridad basica¶
La autenticacion se apoya en usuarios Django, sesion y CSRF. En main/settings.py quedan configurados:
LOGIN_URL,LOGIN_REDIRECT_URLyLOGOUT_REDIRECT_URL;CSRF_TRUSTED_ORIGINS;- cookies de sesion con opciones de seguridad;
- separacion de secretos mediante variables de entorno.
Con esto dejamos una base coherente para una aplicacion con usuarios autenticados, sesiones y variables de entorno.
Resultado del bloque servidor¶
Nuestro backend no se limita a responder peticiones. Es la capa que modela el dominio, protege el acceso, organiza procesos, genera resultados y alimenta las vistas y la API.
Evolucion natural¶
La API del proyecto esta hecha con vistas JSON propias y no con Django REST Framework. Esta decision es suficiente para el alcance actual, aunque una evolucion posterior podria usar DRF si quisieramos ampliar integraciones externas o estandarizar mas la capa API.