Saltearse al contenido

13 - Mapa de Páginas del Frontend

Notas Clave sobre Desviaciones de Contrato

  • resources/js/pages/settings/Profile.vue envía form.useForm({ name, email }) (líneas 31-34) y el Input del formulario solo enlaza form.name, mientras que ProfileUpdateRequest valida nombres y apellidos (app/Http/Requests/Settings/ProfileUpdateRequest.php:19-20). El envío del formulario de perfil en settings siempre falla la validación.
  • useWishlist() (resources/js/composables/useWishlist.ts:29) consume la respuesta como Array.isArray(data) ? data.map(...) : [], pero ListaDeseoController@index retorna ListaDeseoService::obtenerListaDeseos() que es un objeto JSON LengthAwarePaginator. Por lo tanto, el load() del composable siempre asigna items a [] e isInWishlist siempre retorna false.
  • resources/js/pages/Wishlist/Index.vue maneja el paginador correctamente a través de data?.data ?? data (línea 56), por lo que la página dedicada de wishlist funciona mientras que el composable usado por home/tarjetas de producto no.
  • resources/js/pages/ally/ventas/Page.vue:88 colorea el badge para un valor de EstadoVenta 'cancelada', pero el enum real (app/Enum/Facturacion/EstadoVenta.php) solo tiene RECHAZADA y ABANDONADA para estados terminales de falla. La rama es inalcanzable.
  • Conteo de páginas: find resources/js/pages -type f -name '*.vue' | wc -l retorna 58. Ese total incluye sub-componentes embebidos (home/*, product/Seller|Similar|Recently, user/*Modal*, ally/auth/register/steps/Step1..4, ally/empresas/components/*, ally/usuarios/components/*) que no son páginas Inertia independientes. Las rutas Inertia independientes contadas en la sección 1 son aproximadamente 41.

1. Inventario Completo de Páginas

1.1 Páginas del Marketplace (Orientadas al Cliente)

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/Index.vuehomeMarketLayoutNoSolo compartidas (user_stats, brands_allied, popular_categories, is_logged)
pages/ErrorPage.vue(fallback)ErrorLayoutNostatus (código HTTP)
pages/ConsultarCupo/Index.vueconsultar-cupo.viewNinguno (standalone)NoNinguna (formulario standalone)
pages/product/Detail.vueproductos.showMarketLayoutNoproduct, preview
pages/product/Search/List.vueproductos.searchMarketLayoutNoinitialProdcutos, pagination
pages/Simulator/Index.vuesimulador.viewMarketLayoutNo (auth removido vía withoutMiddleware)Config credito compartida
pages/Wishlist/Index.vuelista-deseos.viewMarketLayoutSí (auth)Ninguna (obtiene vía axios)
pages/Checkout/Index.vuecheckout.viewMarketLayoutSí (auth + cliente_registro_completo + verificar_cliente_presenta_mora)Compartidas carritoData, clienteData, credito
pages/Compras/Index.vuecliente.compras.indexMarketLayoutSí (auth)ordenes (paginadas), filtros
pages/Compras/Show.vuecliente.compras.showMarketLayoutSí (auth)orden (con ventas, detalles, user)

1.2 Páginas de Auth del Cliente

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/auth/Register.vueregisterMarketLayoutSolo invitadoCompartidas links (terms, privacy)
pages/auth/ConfirmPassword.vuepassword.confirmAuthLayoutSí (auth:web)Ninguna
pages/auth/ResetPassword.vuepassword.resetMarketLayoutSolo invitadotoken, email
pages/auth/VerifyEmail.vueverification.noticeMarketLayoutSí (auth:web)Controller: status, email. Compartidas: resend_wait_seconds

1.3 Páginas de Usuario del Cliente

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/user/Perfil.vueuser.perfilMarketLayoutSí (auth + verified)Controller: userData, personaData, clienteData
pages/user/Completar.vueuser.completar-registro.renderMarketLayoutSí (auth + verified)Ninguna (formulario standalone)
pages/user/ModalValidate.vue(componente en Perfil)open, closable (props del padre)
pages/user/ChangePasswordModal.vue(componente en Perfil)open, closable
pages/user/UpdatePhoneModal.vue(componente en Perfil)open, closable, initialPhone

1.4 Páginas de Settings del Cliente

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/settings/Profile.vueprofile.editAppLayout > SettingsLayoutSí (auth:web)mustVerifyEmail, status
pages/settings/Password.vuepassword.editAppLayout > SettingsLayoutSí (auth:web)Ninguna
pages/settings/Appearance.vueappearanceAppLayout > SettingsLayoutSí (auth:web)Ninguna

1.5 Páginas del Portal de Aliados

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/ally/Dashboard.vuealiado.dashboardAllyLayoutSí (auth:app)sucursalId, sucursales, isGlobalRole
pages/ally/ventas/Page.vuealiado.ventas.renderAllyLayoutSí (auth:app)sucursalId, sucursales, isGlobalRole
pages/ally/ventas/Show.vuealiado.ventas.showAllyLayoutSí (auth:app)venta (con detalles, user, cuotas)
pages/ally/ventas/create/create.vuealiado.ventas.createAllyLayoutSí (auth:app)Controller: sucursalId, sucursales. Compartidas: credito, lineas
pages/ally/productos/Page.vuealiado.productos.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/productos/Revision.vuealiado.productos.revisionAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/productos/crear/AddProduct.vue(componente)Props de edición de producto
pages/ally/pedidos/Page.vuealiado.pedidos.renderAllyLayoutSí (auth:app)sucursalId, sucursales
pages/ally/marcas/Page.vuealiado.marcas.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/empresas/Page.vuealiado.empresas.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/sucursales/Page.vuealiado.sucursales.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/empleados/Page.vuealiado.empleados.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/usuarios/Page.vuealiado.usuarios.renderAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)
pages/ally/postulaciones/Page.vuealiado.postulacion.revisionAllyLayoutSí (auth:app)Ninguna (obtiene vía axios)

1.6 Páginas de Auth del Aliado

Ruta del ArchivoNombre de RutaLayoutRequiere AuthProps Recibidas
pages/ally/auth/Login.vuelogin (guard app)Ninguno (standalone + AllyFooter)Invitado (guest:app)errors del servidor vía $page.props.errors
pages/ally/auth/ForgotPassword.vuealiado.password.requestNinguno (standalone + AllyFooter)Invitado (guest:app)Ninguna
pages/ally/auth/ResetPassword.vuealiado.password.resetNinguno (standalone + AllyFooter)Invitado (guest:app)token, email
pages/ally/auth/Postulacion.vuealiado-postulacion.createNinguno (standalone + AllyFooter)NoCompartidas lineas, links.terms
pages/ally/auth/register/Page.vuealiado-postulacion.registerNinguno (standalone + AllyFooter)Sí (auth:app + signed)postulacion, compartidas lineas

Nota: resources/js/services/errorLogger.ts existe como un servicio central usado por ambos plugins de errores (errorHandling y errorInterceptor) pero no es un componente de página y por lo tanto no se lista en el inventario de páginas anterior.

Nota: pages/ally/auth/register/steps/Step1.vue hasta Step4.vue existen como sub-componentes del flujo de registro de aliado (pages/ally/auth/register/Page.vue) y no son páginas standalone.

1.7 Sub-componentes del Home (No son páginas standalone — embebidos en Index.vue)

Ruta del ArchivoFuente de DatosComposables Usados
pages/home/Brand.vue$page.props.brands_allied
pages/home/Ofertas.vue$page.props.user_stats.ofertas_del_diauseWishlist
pages/home/MasVendidos.vue$page.props.user_stats.mas_vendidosuseWishlist
pages/home/Encantar.vue$page.props.user_stats.encantaruseWishlist
pages/home/Intereses.vue$page.props.user_stats.interesesuseWishlist
pages/home/ProductCategories.vue$page.props.popular_categories, $page.props.user_stats
pages/home/Join.vue
pages/home/Info.vue— (actualmente comentado)

1.8 Sub-componentes de Producto (Embebidos en Detail.vue)

Ruta del ArchivoFuente de Datos
pages/product/Seller.vue$page.props.user_stats.intereses + prop seller
pages/product/Similar.vue$page.props.user_stats.intereses
pages/product/Recently.vue$page.props.user_stats.intereses

2. Jerarquía de Layouts

2.1 Inventario de Layouts

LayoutArchivoProveeUsado Por
MarketLayoutlayouts/MarketLayout.vueNavbar (header de market con búsqueda, carrito, menú de usuario, categorías) + FooterAppIndex, Register, ResetPassword, VerifyEmail, Perfil, Completar, Compras/, Checkout, Wishlist, Simulator, product/
AllyLayoutlayouts/AllyLayout.vueAlly Navbar (navegación de sidebar)Todas las páginas autenticadas de ally/* (Dashboard, Ventas, Productos, Marcas, etc.)
AuthLayoutlayouts/AuthLayout.vueEnvuelve AuthSimpleLayout — formulario centrado minimalistaConfirmPassword
AppLayoutlayouts/AppLayout.vueEnvuelve AppSidebarLayout — sidebar + breadcrumbspáginas de settings/* (Profile, Password, Appearance)
ErrorLayoutlayouts/ErrorLayout.vueHeader minimalista (logo + “Marketplace”) + contenido centrado + footerErrorPage
Ninguno (standalone)Layouts standalone personalizados con AllyFooter o markup desnudoPáginas de auth del Aliado (Login, ForgotPassword, ResetPassword, Postulacion, Register), ConsultarCupo

2.2 Sub-componentes de Layout

Sub-layoutArchivoPadre
AppSidebarLayoutlayouts/app/AppSidebarLayout.vueUsado por AppLayout
AppHeaderLayoutlayouts/app/AppHeaderLayout.vueLayout alternativo de app (no usado actualmente)
AuthSimpleLayoutlayouts/auth/AuthSimpleLayout.vueUsado por AuthLayout
AuthCardLayoutlayouts/auth/AuthCardLayout.vueLayout alternativo de auth (no usado actualmente)
AuthSplitLayoutlayouts/auth/AuthSplitLayout.vueLayout alternativo de auth (no usado actualmente)
SettingsLayoutlayouts/settings/Layout.vueAnidado dentro de AppLayout en páginas de settings

2.3 Mapeo de Layout a Página

MarketLayout
+-- Index.vue (home)
+-- auth/Register.vue
+-- auth/ResetPassword.vue
+-- auth/VerifyEmail.vue
+-- product/Detail.vue
+-- product/Search/List.vue
+-- Checkout/Index.vue
+-- Compras/Index.vue
+-- Compras/Show.vue
+-- Wishlist/Index.vue
+-- Simulator/Index.vue
+-- user/Perfil.vue
+-- user/Completar.vue
AllyLayout
+-- ally/Dashboard.vue
+-- ally/ventas/Page.vue
+-- ally/ventas/Show.vue
+-- ally/ventas/create/create.vue
+-- ally/productos/Page.vue
+-- ally/productos/Revision.vue
+-- ally/pedidos/Page.vue
+-- ally/marcas/Page.vue
+-- ally/empresas/Page.vue
+-- ally/sucursales/Page.vue
+-- ally/empleados/Page.vue
+-- ally/usuarios/Page.vue
+-- ally/postulaciones/Page.vue
AppLayout > SettingsLayout
+-- settings/Profile.vue
+-- settings/Password.vue
+-- settings/Appearance.vue
AuthLayout
+-- auth/ConfirmPassword.vue
ErrorLayout
+-- ErrorPage.vue
Standalone (sin envoltura de layout)
+-- ConsultarCupo/Index.vue
+-- ally/auth/Login.vue
+-- ally/auth/ForgotPassword.vue
+-- ally/auth/ResetPassword.vue
+-- ally/auth/Postulacion.vue
+-- ally/auth/register/Page.vue

3. Props Inertia Compartidas (HandleInertiaRequests)

Todas las páginas reciben estas props vía el middleware HandleInertiaRequests:

Clave de PropTipoDescripción
namestringNombre de la app desde config('app.name')
quote{message, author}Frase inspiracional aleatoria
ziggyobjectDefiniciones de rutas Ziggy + URL actual
is_loggedbooleanSi el usuario está autenticado
is_register_viewbooleanVerdadero cuando está en la ruta de registro
sidebarOpenbooleanEstado del sidebar desde cookie
links.faqstringURL del FAQ
links.aboutstringURL de la página About
links.sicstringURL del SIC
links.termsstringURL de términos y condiciones
links.privacystringURL de política de privacidad
resend_wait_secondsnumberSegundos a esperar antes de reenviar correo de verificación (predeterminado 60)
max_search_resultsnumberMáximo de resultados de búsqueda (predeterminado 10)
credito.dias_desfasenumberDías de desfase del crédito
credito.tasa_nominalnumberTasa de interés nominal mensual (decimal)
credito.seguro_vidanumberTasa de seguro de vida (decimal)
credito.porcentaje_fianzanumberPorcentaje de fianza
credito.monto_estudio_creditonumberTarifa de estudio de crédito (absoluta)
lineasarrayLíneas de productos (cacheadas, vía LineaService)
brands_alliedarrayTodas las marcas (cacheadas, Marca::all())
popular_categoriesarrayTop 8 categorías populares (cacheadas)
auth.userUser|nullObjeto del usuario autenticado
auth.rolestring|nullRol del usuario vía $user->rol()

Props Compartidas Condicionales

Cuando el usuario tiene una empresa (aliado/admin):

Clave de PropTipoDescripción
empresaobjectRegistro de Empresa con la relación lineas cargada

Cuando el usuario es un cliente (sin empresa):

Clave de PropTipoDescripción
user_statsobjectEstadísticas de productos: intereses, ofertas_del_dia, mas_vendidos, encantar
auth.clienteDataobject|nullRegistro de Cliente (cupo_disponible, cupo_asignado, etc.)
auth.carritoDataarrayÍtems del carrito de compras con información de producto/precio/línea

4. Props Específicas por Página

PáginaProps del Controlador
ErrorPagestatus (código de estado HTTP: 403, 404, 419, 500, 503)
product/Detailproduct (producto completo con precios, imagenes), preview (boolean)
product/Search/ListinitialProdcutos (array de productos), pagination (meta del paginador de Laravel)
Compras/Indexordenes (paginadas: data, current_page, last_page, links), filtros (estado, search, fecha_inicio, fecha_fin)
Compras/Showorden (con relaciones ventas, detalles, user, sucursal)
auth/ResetPasswordtoken (string), email (string)
settings/ProfilemustVerifyEmail (boolean), status (string, opcional)
ally/DashboardsucursalId (number), sucursales (array), isGlobalRole (boolean)
ally/ventas/PagesucursalId, sucursales, isGlobalRole
ally/ventas/Showventa (con detalles, user, persona, cuotas, sucursal)
ally/pedidos/PagesucursalId, sucursales
ally/auth/ResetPasswordtoken, email
ally/auth/register/Pagepostulacion (objeto postulacion con datos de empresa)

5. Llamadas API del Frontend

5.1 Marketplace del Cliente

Página / ComponenteMétodoEndpoint (Nombre de Ruta)Propósito
Compras/IndexGETcliente.compras.indexObtener órdenes filtradas/paginadas
Compras/Show(Inertia router.get)Navegar al detalle de la orden
Checkout/IndexPUTcarrito.updateActualizar cantidad de ítem del carrito
Checkout/IndexPOSTcarrito.storeAgregar ítem al carrito
Checkout/IndexDELETEcarrito.destroyRemover ítem del carrito
Checkout/IndexPOSTcliente.compras.storeEnviar orden de compra
product/DetailPOSTcarrito.storeAgregar producto al carrito
Wishlist/IndexGETlista-deseos.indexObtener wishlist paginada
Wishlist/IndexDELETElista-deseos.destroyRemover de la wishlist
ConsultarCupo/IndexPOSTconsultar-cupo.storeConsultar cupo de crédito por contrato
user/PerfilGETcliente.compras.indexObtener compras recientes (per_page=5)
user/PerfilGETuser.aprobar-cupo.verificar-limite-intentosVerificar límites diarios de intentos de crédito
user/CompletarPOSTuser.completar-registro.storeEnviar formulario de completar registro
user/ChangePasswordModalPUTuser.password.updateActualizar contraseña
user/UpdatePhoneModalPUTuser.phone.updateActualizar número de teléfono
user/ModalValidateGETuser.aprobar-cupo.legal-checkPaso 1: Verificación legal
user/ModalValidateGETuser.aprobar-cupo.identity-validationPaso 2: Validación de identidad
user/ModalValidateGETuser.aprobar-cupo.identity-validation-generate-otpPaso 3: Generar OTP
user/ModalValidatePOSTuser.aprobar-cupo.identity-validation-verify-otpPaso 4: Verificar OTP
user/ModalValidateGETuser.aprobar-cupo.identity-validation-generate-questionsPaso 5: Generar preguntas de seguridad
user/ModalValidatePOSTuser.aprobar-cupo.identity-validation-verify-questionsPaso 6: Verificar preguntas de seguridad
user/ModalValidateGETuser.aprobar-cupo.hdc-validationPaso 7: Validación HDC
user/ModalValidateGETuser.aprobar-cupo.obtener-cupoPaso 8: Aprobar cupo de crédito
auth/VerifyEmailPOSTverification.sendReenviar correo de verificación (Inertia router)
auth/ConfirmPasswordPOSTpassword.confirmConfirmar contraseña (Inertia useForm)
auth/ResetPasswordPOSTpassword.storeGuardar nueva contraseña (Inertia useForm)
auth/RegisterPOSTregisterEnviar registro (Inertia router)
settings/PasswordPUTpassword.updateActualizar contraseña (Inertia useForm)
settings/ProfilePATCHprofile.updateActualizar perfil (Inertia useForm)

5.2 Llamadas API de Composables

ComposableMétodoEndpointPropósito
useWishlistGETlista-deseos.indexCargar ítems de la wishlist
useWishlistPOSTlista-deseos.storeAgregar a la wishlist
useWishlistDELETElista-deseos.destroyRemover de la wishlist

5.3 Portal de Aliados

Página / ComponenteMétodoEndpoint (Nombre de Ruta)Propósito
ally/DashboardGETaliado.dashboard.resumenObtener resumen del dashboard (ventas, productos, top ítems)
ally/DashboardGETaliado.dashboard.rendimientoObtener datos de rendimiento (serie temporal)
ally/ventas/PageGETaliado.ventas.indexObtener ventas paginadas
ally/ventas/PageGETaliado.ventas.estadisticasObtener estadísticas de ventas
ally/ventas/create/createPOSTaliado.ventas.storeCrear nueva venta
ally/productos/PageDELETEaliado.productos.destroyEliminar producto
ally/productos/PagePOSTaliado.productos.carga-masivaCarga masiva de productos
ally/productos/PageGETaliado.productos.downloadDescargar plantilla de productos
ally/productos/PageGETaliado.marcas.downloadDescargar catálogo de marcas
ally/productos/PageGETaliado.lineas.downloadDescargar catálogo de líneas
ally/productos/RevisionPUTaliado.productos.updateAprobar/rechazar producto
ally/productos/RevisionGETaliado.productos.indexObtener productos para revisión
ally/marcas/PageGETmarcas.indexObtener listado de marcas
ally/marcas/PagePOSTaliado.marcas.storeCrear marca
ally/marcas/PagePOSTaliado.marcas.updateActualizar marca (multipart)
ally/marcas/PageDELETEaliado.marcas.destroyEliminar marca
ally/empresas/PageGETaliado.empresas.indexObtener listado de empresas
ally/empresas/EditEmpresaLinesModalPUTaliado.empresas.updateActualizar líneas de empresa
ally/sucursales/PagePOSTaliado.sucursales.storeCrear sucursal
ally/sucursales/PagePUTaliado.sucursales.updateActualizar sucursal
ally/sucursales/PageDELETEaliado.sucursales.destroyEliminar sucursal
ally/empleados/PageGETaliado.empleados.indexObtener empleados
ally/empleados/PagePOSTaliado.empleados.storeCrear empleado
ally/empleados/PagePUTaliado.empleados.updateActualizar empleado
ally/empleados/PageDELETEaliado.empleados.destroyEliminar empleado
ally/usuarios/PageGETaliado.usuarios.indexObtener usuarios
ally/usuarios/PageGETaliado.usuarios.showObtener detalle del usuario
ally/usuarios/PagePUTaliado.usuarios.updateActualizar usuario
ally/usuarios/PageDELETEaliado.usuarios.destroyEliminar usuario
ally/usuarios/PagePOSTaliado.usuarios.resend-verificationReenviar verificación de correo
ally/usuarios/CreateAdminModalPOSTaliado.usuarios.admin.storeCrear usuario admin
ally/postulaciones/PageGETaliado.postulacion.indexObtener postulaciones
ally/postulaciones/PagePOSTaliado.postulacion.actionAprobar/rechazar/descartar postulacion
ally/pedidos/PageGETaliado.ventas.indexObtener pedidos
ally/pedidos/PagePUTaliado.ventas.updateActualizar estado del pedido (entregada)
ally/auth/PostulacionPOSTaliado-postulacion.storeEnviar solicitud de aliado
ally/auth/LoginPOSTaliado.loginLogin (Inertia router)
ally/auth/ResetPasswordPOSTaliado.password.storeRestablecer contraseña (Inertia useForm)
ally/auth/register/PagePOSTaliado-postulacion.register.storeCompletar registro del aliado

6. Uso de Composables

ComposablePropósitoPáginas / Componentes que lo Usan
useWishlistGestionar wishlist (agregar/remover/toggle/verificar) vía axios a los endpoints de lista-deseosproduct/Detail.vue, home/Ofertas.vue, home/MasVendidos.vue, home/Encantar.vue, home/Intereses.vue
useAppearanceAlternar tema oscuro/claro/sistema, persiste en localStorage + cookiesettings/Appearance.vue (vía componente AppearanceTabs)
useInitialsExtraer iniciales de un string de nombre completoUsado en componentes de avatar de usuario en header/sidebar

Uso de Utilidades de Lib

UtilidadArchivoPropósitoUsado Por
formatCOPlib/format.tsFormatear números como moneda COP (con decimales)Wishlist, Checkout, componentes home, product/*, ally/productos, ally/ventas/create
formatCOP (sin decimales)lib/formatters.tsFormatear COP sin decimales + formatDateTimeISOCompras/Index
calculateCreditlib/credit.tsCálculo de amortización francesa con seguro/fianza/tarifa de estudioCheckout/Index, Simulator/Index, ally/ventas/create
cnlib/utils.tsUtilidad de merge de clases Tailwind (clsx + twMerge)Componentes UI
extraerPrincipalesProductolib/utils.tsExtraer precio/imagen principal del objeto productoSub-componentes Home, product/*, ally/productos, ally/ventas/create
placeholderImagelib/utils.tsRetornar la ruta de la imagen placeholder predeterminada del productoComponentes relacionados con productos
useDarkModeReactivelib/utils.tsRef reactiva de modo oscuro desde localStoragecomponents/Footer/AllyFooter.vue, components/form/MultiSelect.vue
formatearFechaColombialib/utils.tsFormatear fechas en locale/timezone de Colombiauser/Perfil
sanitizePhonelib/utils.tsEliminar caracteres no numéricos del teléfono (mantener +)ally/auth/Postulacion

Plugins

PluginArchivoPropósito
errorHandlingplugins/errorHandling.tsManejador global de errores de Vue + listeners de rechazos/errores no manejados; registra vía el servicio errorLogger
errorInterceptorplugins/errorInterceptor.tsInterceptores de request/response de axios; añade IDs de tracking; registra errores y éxitos vía errorLogger

7. Diagrama de Sitemap

graph TB
    subgraph "Páginas Públicas"
        HOME["/ <br/> Index.vue <br/> (MarketLayout)"]
        SEARCH["/resultados <br/> product/Search/List.vue"]
        DETAIL["/productos/{id} <br/> product/Detail.vue"]
        CUPO["/consultar-cupo <br/> ConsultarCupo/Index.vue <br/> ruta: consultar-cupo.view <br/> (Standalone)"]
        ERROR["Fallback <br/> ErrorPage.vue <br/> (ErrorLayout)"]
    end

    subgraph "Auth Cliente (Invitado)"
        REG["/registro <br/> auth/Register.vue"]
        RESET["/restablecer-contrasena <br/> auth/ResetPassword.vue"]
    end

    subgraph "Auth Cliente (Conectado)"
        VERIFY["/verificar-correo <br/> auth/VerifyEmail.vue"]
        CONFIRM["/confirmar-contrasena <br/> auth/ConfirmPassword.vue"]
    end

    subgraph "Cliente Autenticado"
        PERFIL["/usuario/perfil <br/> user/Perfil.vue"]
        COMPLETAR["/usuario/completar-registro <br/> user/Completar.vue"]
        WISHLIST["/lista-deseos/vista <br/> Wishlist/Index.vue <br/> ruta: lista-deseos.view"]
        SIMULATOR["/simulador-cuotas <br/> Simulator/Index.vue <br/> ruta: simulador.view"]
        CHECKOUT["/checkout <br/> Checkout/Index.vue <br/> ruta: checkout.view"]
        COMPRAS_I["/mis-compras <br/> Compras/Index.vue"]
        COMPRAS_S["/mis-compras/{id} <br/> Compras/Show.vue"]
    end

    subgraph "Settings Cliente"
        SET_PROFILE["/settings/profile <br/> settings/Profile.vue <br/> (AppLayout)"]
        SET_PASS["/settings/password <br/> settings/Password.vue"]
        SET_APPEAR["/settings/appearance <br/> settings/Appearance.vue"]
    end

    subgraph "Auth Aliado (Invitado)"
        ALLY_LOGIN["/aliados/ingresar <br/> ally/auth/Login.vue"]
        ALLY_FORGOT["/aliados/olvidar <br/> ally/auth/ForgotPassword.vue"]
        ALLY_RESET["/aliados/restablecer <br/> ally/auth/ResetPassword.vue"]
        ALLY_POST["/aliados/postulacion <br/> ally/auth/Postulacion.vue"]
    end

    subgraph "Portal Aliado (Autenticado)"
        ALLY_DASH["/aliados <br/> ally/Dashboard.vue <br/> (AllyLayout)"]
        ALLY_VENTAS["/aliados/ventas/listado <br/> ally/ventas/Page.vue"]
        ALLY_VENTA_S["/aliados/ventas/{id} <br/> ally/ventas/Show.vue"]
        ALLY_VENTA_C["/aliados/ventas/crear <br/> ally/ventas/create/create.vue"]
        ALLY_PROD["/aliados/productos <br/> ally/productos/Page.vue"]
        ALLY_PROD_R["/aliados/productos/revision <br/> ally/productos/Revision.vue"]
        ALLY_PED["/aliados/pedidos/listado <br/> ally/pedidos/Page.vue"]
        ALLY_MARCAS["/aliados/marcas/listado <br/> ally/marcas/Page.vue"]
        ALLY_EMP["/aliados/empresas/listado <br/> ally/empresas/Page.vue"]
        ALLY_SUC["/aliados/sucursales/listado <br/> ally/sucursales/Page.vue"]
        ALLY_EMPL["/aliados/empleados/listado <br/> ally/empleados/Page.vue"]
        ALLY_USR["/aliados/usuarios/listado <br/> ally/usuarios/Page.vue"]
        ALLY_POSTUL["/aliados/postulacion/revision <br/> ally/postulaciones/Page.vue"]
        ALLY_REG["/aliados/postulacion/{id}/registro <br/> ally/auth/register/Page.vue"]
    end

    HOME --> SEARCH
    HOME --> DETAIL
    HOME --> REG
    DETAIL --> CHECKOUT
    PERFIL --> COMPLETAR
    PERFIL --> COMPRAS_I
    COMPRAS_I --> COMPRAS_S
    CHECKOUT --> COMPRAS_I

    ALLY_LOGIN --> ALLY_DASH
    ALLY_LOGIN --> ALLY_FORGOT
    ALLY_DASH --> ALLY_VENTAS
    ALLY_DASH --> ALLY_PROD
    ALLY_DASH --> ALLY_PED
    ALLY_VENTAS --> ALLY_VENTA_S
    ALLY_VENTAS --> ALLY_VENTA_C
    ALLY_POSTUL --> ALLY_REG