Skip to content

DEW - Desarrollo web en entorno cliente

Arquitectura cliente

La capa cliente de SEO Growth Engine cubre el acceso, la navegacion del workspace y la visualizacion de runs mediante una SPA construida con Vue 3 + TypeScript.

Hemos situado el frontend en frontend/ y lo hemos integrado con la aplicacion Django real. Consume usuarios, sitios y ejecuciones del backend, por lo que no depende de datos simulados.

Evidencias directas

  • frontend/src/main.ts
  • frontend/src/router/index.ts
  • frontend/src/stores/session.ts
  • frontend/src/composables/useApi.ts
  • frontend/src/composables/usePersistedState.ts
  • frontend/src/views/LoginView.vue
  • frontend/src/views/DashboardView.vue
  • frontend/src/views/RunDetailView.vue
  • frontend/src/components/AppShell.vue
  • frontend/src/components/PanelCard.vue
  • frontend/src/components/OptionToggle.vue
  • frontend/README.md
  • docs/vue-client.md

Cumplimiento de los requisitos de DEW

Requisito Como lo hemos resuelto Evidencia real
Vue + TS + SFC + Composition API El cliente esta construido con componentes .vue, script setup lang="ts" y API de composicion LoginView.vue, DashboardView.vue, RunDetailView.vue, AppShell.vue, PanelCard.vue
Pagina no continua / SPA La navegacion principal del cliente se realiza sin recarga completa entre login, dashboard y detalle frontend/src/router/index.ts
Router Hemos definido rutas, redireccion inicial y guardas de acceso createRouter, beforeEach, ensureAuthenticated
Reactividad Usamos ref, reactive y computed en vistas, store y componentes LoginView.vue, DashboardView.vue, stores/session.ts, StatusPill.vue
localStorage Persistimos el ultimo usuario usado en login para reducir friccion al volver usePersistedState("vue-client:last-username", ..., { storage: "local" })
sessionStorage Hemos implementado un composable comun que soporta tanto almacenamiento local como de sesion, preparado para persistencias temporales de navegacion frontend/src/composables/usePersistedState.ts
props y emits Los componentes reciben configuracion por props y emiten cambios al padre cuando hace falta OptionToggle.vue, AppShell.vue, PanelCard.vue
Pinia Toda la sesion del cliente y la carga de datos principales se centralizan en un store frontend/src/stores/session.ts
Slots Hemos dejado el layout y las tarjetas preparados para composicion flexible slot name="hero-actions" en AppShell.vue, slot name="actions" en PanelCard.vue
Composables Reutilizamos logica de peticiones y persistencia en funciones propias useApi.ts, usePersistedState.ts
Documentacion tecnica Hemos documentado el cliente por capas: arranque, rutas, store y flujo de sesion frontend/README.md, docs/vue-client.md, esta presentacion

Arquitectura del frontend

Nosotros hemos organizado la capa cliente de forma clara:

  • main.ts monta la app, registra Pinia y activa el Router.
  • router/index.ts define rutas y protege acceso con beforeEach.
  • stores/session.ts centraliza usuario, bootstrap, sitios, runs y detalle de run.
  • views/ contiene las pantallas principales.
  • components/ agrupa piezas reutilizables.
  • composables/ concentra logica transversal.

No hemos construido solo vistas. Hemos organizado una arquitectura cliente mantenible.

Componentes y pantallas principales

LoginView

frontend/src/views/LoginView.vue concentra el flujo de acceso:

  • reactive para el formulario;
  • ref para estado de error y loading;
  • computed para resolver la ruta de retorno;
  • usePersistedState para recordar el usuario;
  • llamada real al backend por medio del store.

DashboardView

frontend/src/views/DashboardView.vue convierte datos reales del backend en una pantalla operativa.

RunDetailView

frontend/src/views/RunDetailView.vue demuestra que la parte cliente consume un payload real de detalle de ejecucion y lo convierte en una vista clara con estado, progreso, duracion, artefactos y logs.

Estado global con Pinia

Hemos usado Pinia porque el proyecto necesitaba una fuente de verdad clara para:

  • usuario autenticado;
  • sitios disponibles;
  • runs recientes;
  • detalle de ejecuciones;
  • bootstrap inicial de sesion.

En frontend/src/stores/session.ts destacan funciones como:

  • bootstrap()
  • refreshSession()
  • loginWithPassword()
  • logoutCurrentUser()
  • fetchSites()
  • fetchRuns()
  • fetchRunDetail()

Con esto evitamos repartir estado por varias vistas y mantenemos una arquitectura cliente limpia.

Comunicacion entre componentes

Tambien hemos trabajado bien la comunicacion interna del frontend:

  • AppShell.vue recibe title y subtitle por props y expone slot para acciones del hero.
  • PanelCard.vue recibe title y description y permite inyectar acciones y cuerpo.
  • OptionToggle.vue recibe opciones por props y propaga cambios con emit("update:modelValue").

Con esto demostramos que hemos creado componentes reutilizables y desacoplados, no pantallas monoliticas.

Justificacion de las decisiones del frontend

  • Vue 3 y Composition API nos permiten crecer sin duplicar logica.
  • TypeScript reduce errores de tipado entre API, store y vistas.
  • Router convierte varias pantallas en un flujo continuo.
  • Pinia ordena la sesion y los datos.
  • Composables evitan repetir codigo de fetch y persistencia.

La parte cliente no se limita a pintar plantillas. Conecta con la API, conserva estado de sesion, organiza rutas y reutiliza componentes para que la navegacion del dashboard y del detalle de run sea coherente.