// Expediente de evidencia
Web Prevención de Riesgos
De la consulta comercial a la autogestión: una web de servicios profesionales con contenido editable desde el teléfono, páginas por servicio y sector, y contacto directo. Desarrollo integral y puesta en producción propios; validación técnica local con límites explícitos.
- Para quién
Soledad Barrera, consultora en prevención de riesgos en Atacama, y empresas que buscan conocer sus servicios y contactarla.
- Mi responsabilidad
Desarrollo integral individual: interfaz pública, panel de contenidos, integración con Firebase, SEO técnico y puesta en marcha.
- Estado actual
Web y panel en producción activa con edición móvil desde el teléfono. Esta revisión comprobó una copia local aislada.
- Qué permite hacer
La profesional puede mantener su oferta sin solicitar cambios de código. Los visitantes encuentran servicios y un camino directo de consulta. No hay métricas comerciales disponibles.
Contexto
Una web de servicios profesionales debe ayudar a una empresa a entender qué puede contratar, dónde se presta el servicio y cómo iniciar una conversación. Aquí el público objetivo son empresas de Atacama que consultan asesoría en prevención de riesgos; la administradora es la profesional responsable de esa oferta.
El código presenta servicios, sectores, experiencia, preguntas frecuentes y contacto. Las afirmaciones sobre trayectoria y testimonios son contenido comercial de la web fuente; esta revisión de software no audita esas afirmaciones ni acredita cumplimiento normativo.
Problema
El problema abordado es mantener una presencia digital propia y comprensible, con un camino claro desde el servicio hasta la consulta y con edición de contenido sin modificar el código. El panel evita que cada actualización dependa de una nueva entrega del desarrollador.
No se dispone de una medición del proceso anterior ni de una comparación comercial antes y después. Por eso el resultado se expresa como capacidad entregada y uso reportado, sin atribuirle aumentos de ventas o reducción cuantificada de trabajo.
Mi rol
Realicé el desarrollo integral del proyecto de forma individual y autónoma: diseño y programación de la web, panel, integración de contenidos e imágenes, preparación de SEO y puesta en producción.
La revisión del historial explica cambios en autenticación, compatibilidad de Firebase, administración móvil y páginas indexables. El historial de versiones se utiliza para documentar la evolución técnica del código y las decisiones de implementación.
Restricciones y autonomía móvil
La edición desde el teléfono debía encajar con el trabajo de una profesional que no administra infraestructura. El panel organiza las secciones con formularios, previsualización externa y un guardado disponible en móvil. La interfaz mantiene la identidad de la consultora.
Los servicios gestionados reducen tareas de servidor, pero no acreditan costo cero: cuotas, facturación y condiciones de proveedor no se revisaron. Firebase, el correo y los canales externos conservan sus propias dependencias. La validación utilizó una copia aislada, sin credenciales ni datos operativos.
Solución
La solución combina una página principal de servicios, páginas específicas de servicios y sectores, FAQ, formulario y enlaces de contacto. El panel permite modificar textos, visibilidad y fotografías, guardando las secciones mediante el servidor.
El recorrido público se comprobó sobre una compilación local: inicio → página de servicio → contacto → validación del formulario → respuesta visible. El éxito y el error de red usaron un proveedor interceptado. En los módulos reales se comprobó también guardar → releer → entregar contenido a la capa pública, con almacenamiento simulado.
Arquitectura y diagramas
Next.js 16.3.2 utiliza App Router, React 19.2.3 y TypeScript, con Tailwind CSS v4 para la interfaz. El servidor obtiene cada sección de Firestore y combina campos con contenido predeterminado; la lectura remota se valida antes de entregarse a los componentes. Firebase Auth, Firebase Admin y Storage cubren identidad, operaciones en servidor e imágenes.
Las 13 secciones se consultan en paralelo. La página principal configura regeneración cada 300 segundos y el guardado solicita su invalidación. Las páginas de servicio y sector toman sus textos específicos y configuración compartida desde archivos de código, no desde el CMS. La edición del panel no actualiza esa configuración en estas vistas. El diagrama representa la implementación, no una medición de disponibilidad de la nube.
Leer el diagrama y sus límites
El visitante llega a la web pública y sus canales de contacto. La profesional edita el panel con Firebase Auth. El servidor Next.js guarda secciones en Firestore e imágenes en Storage. La web lee las secciones; dispone de contenido predeterminado cuando una lectura rechaza.
WhatsApp es un canal de contacto separado; el formulario envía sus datos a Web3Forms. Las imágenes son recursos públicos. El respaldo no es una copia de la última edición.
Mapa de implementación. Sistema en producción activa; identidad, almacenamiento y contacto se probaron localmente con dobles.
Concurrencia, integridad y recuperación
El contenido predeterminado permite renderizar sin configuración de Firebase y recuperar una lectura que rechaza o devuelve contenido inválido. Esto se comprobó con el lector real y errores simulados. El mecanismo no conserva la última edición válida y no impone un plazo máximo propio para una lectura remota pendiente.
Los guardados reemplazan una sección completa. Dos solicitudes solapadas alcanzaron una barrera en el doble de almacenamiento y ambas fueron aceptadas; no existe detección de versión en ese recorrido. Esta prueba describe el control de la aplicación, no concurrencia de un Firestore real.
Un fallo simulado después de persistir produjo una respuesta de error con el contenido ya guardado. La carga de imágenes también tiene pasos separados, por lo que puede quedar un archivo guardado si falla su publicación. No se acreditan recuperación automática, historial de versiones ni eliminación de archivos huérfanos.
Decisiones y alternativas
Contenido en servidor con valores predeterminados: mantiene una representación pública y evita depender exclusivamente de una consulta del navegador. El costo es que el contenido de respaldo puede quedar desactualizado. Una página exclusivamente estática sería más simple, pero no resolvería la edición por la profesional.
Firebase como servicio gestionado: reúne identidad, documentos e imágenes y reduce administración de servidores. Un backend propio daría más control operativo a cambio de mantenimiento adicional; no consta una comparativa formal de proveedores.
Páginas por servicio y sector: una iteración posterior añadió rutas, metadatos y datos estructurados. La decisión favorece contenido legible e indexable, pero esos textos específicos necesitan cambios de código. La evolución también separó la carga del módulo de autenticación para evitar errores en el renderizado público.
Motion y GSAP organizan interacciones y animaciones, mientras Lenis gestiona el desplazamiento. El informe frontend documenta mantener la identidad y evitar un entorno 3D sin utilidad para esta web. No se encontraron ADR numerados; estos son compromisos observados en código e historial, no documentos inventados.
Seguridad y privacidad
La identidad administrativa y la autorización se comprueban en el servidor antes del guardado. El código incluye validación de la estructura de contenido, límites de entrada y controles de imágenes. Las reglas incluidas separan la lectura del contenido público de las operaciones de escritura. Su despliegue efectivo en Firebase no se comprobó.
Se verificaron respuestas denegadas y preservación del estado ante entradas inválidas con dobles de identidad y almacenamiento. Eso no sustituye una revisión independiente del proveedor ni demuestra protección absoluta. Las imágenes publicadas son recursos públicos; su validación no equivale a un análisis completo de archivos.
El formulario envía los datos de consulta a Web3Forms. WhatsApp es otro proveedor y otra conversación. Durante las pruebas de navegador se interceptó el envío y se respondió localmente, sin correo real. La ficha excluye credenciales, datos de cuentas y detalles operativos reservados.
Pruebas y alcance de validación
En base a la revisión técnica sobre el estado local registrado. El repositorio remoto apuntaba a la misma versión. Se copió el código a un laboratorio persistente en Windows y se instalaron las versiones del lockfile con scripts de instalación desactivados. No se copiaron archivos de entorno. Node.js 22.23.2 y npm 10.9.8.
La suite original aprobó 13/13 pruebas en cuatro archivos: seis de validación de contenido, una del cursor retirado, dos de importaciones y cabeceras, y cuatro de SEO y ejecución. Parte de esas pruebas inspecciona texto fuente; no es evidencia de un servicio externo en funcionamiento. Las 12 pruebas adicionales importaron módulos reales y sustituyeron Firebase y la invalidación de caché por dobles.
La compilación generó 22 entradas estáticas; tipos aprobaron y ESLint dejó cuatro advertencias. El navegador comprobó la web local en escritorio y móvil, un servicio, validación del formulario, éxito y error con contacto simulado, menú con Escape y redirección al login. No se ejecutaron emuladores Firebase, autenticación real, un recorrido autenticado del panel en navegador, entrega de correo ni un benchmark Lighthouse reproducible.
| Comprobación | Resultado | Alcance |
|---|---|---|
| Suite original | 13/13 · 4 archivos | 6 contenido; 1 cursor retirado; 2 importaciones/cabeceras; 4 SEO. Incluye inspección de fuente. |
| Comprobaciones adicionales | 12/12 | Módulos reales; identidad, almacenamiento y caché simulados. Incluye escenarios que reproducen limitaciones. |
| Análisis estático y tipos | 0 errores · 4 advertencias | Dos imports sin uso, navegación interna y uso de imagen nativa. TypeScript aprobado. |
| Compilación y arranque | Aprobados · 22 entradas estáticas | Next.js 16.3.2. Sin credenciales Firebase: contenido predeterminado, no datos de producción. |
| Recorrido público | Comprobado en navegador | Servicio → contacto en móvil; validación nativa; éxito y fallo de red interceptados; menú y login. |
| Muestra de la ficha | 4/4 por idioma | Se ejecutan exactamente código y prueba mostrados. Adaptación didáctica, sin red. |
| Producción y resultados | En producción / sin métricas | Web y panel en uso con edición desde teléfono. Sin medición de conversión, disponibilidad o Lighthouse. |
Despliegue y operación
La web y el panel operan en producción y permiten edición directa desde el teléfono móvil. Vercel y Firebase forman parte de la arquitectura de entrega descrita en el proyecto; esta revisión técnica local no inspeccionó cuentas remotas, despliegues de hosting, reglas en la nube, cuotas o registros operativos.
Localmente se arrancó la compilación de producción en loopback sin credenciales, utilizando el contenido predeterminado. Se observaron cabeceras defensivas y la redirección del panel al login. Que una ruta administrativa no se indexe no constituye un control de acceso. La invalidez de caché de la portada no demuestra actualización simultánea de todas las rutas.
Resultado e impacto profesional
La entrega permite a la consultora presentar su oferta con una web propia y mantener contenido desde el teléfono en producción activa. Mi aportación fue conectar esa autonomía con una experiencia pública de servicios y contacto, además de resolver las necesidades de integración y publicación.
No hay métricas disponibles de visitas, consultas, contratos, tiempo ahorrado o retorno comercial. Se retiraron las cifras de Lighthouse y las garantías de costo cero o disponibilidad continua que no tenían una medición reproducible. Los resultados locales son evidencia de ingeniería bajo las condiciones declaradas.
Evidencia y límites
Implementado: sitio público, panel editable, lectura de contenido, validaciones, SEO técnico y carga de imágenes, observados en la versión revisada.
Comprobado localmente: 13 pruebas originales, tipos, compilación, arranque y recorrido público. Las 12 pruebas adicionales ejercitan código real, pero dependen de los dobles descritos. La muestra visible aprobó sus cuatro casos en ambos idiomas.
Simulado: identidad Firebase, persistencia de documentos e imágenes, fallos posteriores al guardado, caché y respuestas del proveedor de contacto. No se apagó ni se probó un servicio cloud real.
Estado reportado: desarrollo individual, uso de web y panel en producción y edición desde el teléfono. Pendiente: métricas comerciales, Lighthouse con condiciones registradas, auditoría de accesibilidad completa y recorrido autenticado con Firebase real. Los resultados y el laboratorio se conservan en un registro interno saneado; la evidencia se explica aquí.
Comprobaciones de fallos y concurrencia
El solapamiento de dos guardados fue real dentro del proceso de prueba, pero el almacenamiento era un doble. Ambos guardados fueron aceptados. Los fallos simulados permitieron observar qué queda persistido y qué puede recuperarse al reintentar; no establecen capacidad, disponibilidad ni transacciones del proveedor.
Observaciones operativas y autonomía móvil
El uso en producción y desde el teléfono corresponde a la operación real del sistema entregado. El navegador local verificó presentación y contacto con datos predeterminados. El video es material de presentación y la captura corresponde al sitio público local; ninguno acredita el estado de una cuenta administrativa remota.
Calidad de software y UX móvil
La edición agrupa contenido por secciones, muestra confirmación y errores de guardado y ofrece controles móviles. El sitio público organiza servicios y FAQ con enlaces y formularios etiquetados; la navegación móvil cerró con Escape. Ante el fallo simulado de contacto, el formulario conservó los datos introducidos y mostró un error.
Lenis evita su desplazamiento animado cuando se solicita movimiento reducido; eso no prueba que todas las animaciones respeten esa preferencia. A 1280 px se observó un corte de palabra en el título animado de la web fuente, mientras a 1440 px se leía completo. Las reparaciones del producto quedan fuera de este encargo. No se otorga una certificación WCAG ni una puntuación de accesibilidad a partir de esta revisión parcial.
La ficha permite consultar decisiones, pruebas y límites por separado, con índice, diagrama legible en móvil, tabla con desplazamiento propio y código con ajuste de líneas. No hay documentación técnica para descargar desde la página.
Muestra de código y prueba de ingeniería
Adaptación didáctica pequeña de la lectura pública con contenido predeterminado. Utiliza datos sintéticos ya validados y una función de lectura inyectada: combina campos o recupera el respaldo cuando la lectura rechaza. No reproduce el acceso a Firebase, la validación completa del CMS ni un tiempo límite.
Requisito: Node.js 22 o superior. El primer bloque y la prueba forman un único módulo; se ejecutó exactamente el texto mostrado. No necesita archivos auxiliares, credenciales ni conexiones externas.
// Node.js 22+. Contenido sintético previamente validado. |
async function readPublicSection(read, defaults) { |
try { |
const stored = await read(); |
return { ...defaults, ...(stored ?? {}) }; |
} catch { |
return { ...defaults }; |
} |
} |
Prueba de la muestra aislada
import assert from 'node:assert/strict'; |
import { test } from 'node:test'; |
|
const defaults = { heading: 'Services', visible: true }; |
test('el contenido guardado conserva los valores predeterminados ausentes', async () => { |
const read = async () => ({ heading: 'Training' }); |
assert.deepEqual(await readPublicSection(read, defaults), |
{ heading: 'Training', visible: true }); |
}); |
test('un documento ausente utiliza los valores predeterminados', async () => { |
assert.deepEqual(await readPublicSection(async () => null, defaults), defaults); |
}); |
test('una lectura fallida utiliza los valores predeterminados', async () => { |
const read = async () => { throw new Error('Fallo simulado'); }; |
assert.deepEqual(await readPublicSection(read, defaults), defaults); |
}); |
test('los datos de entrada permanecen intactos', async () => { |
const stored = { heading: 'Training' }; |
const result = await readPublicSection(async () => stored, defaults); |
result.heading = 'Edited'; |
assert.equal(stored.heading, 'Training'); |
assert.equal(defaults.heading, 'Services'); |
}); |
4/4 casos aprobados: campos ausentes, documento ausente, lectura rechazada y entradas preservadas. La ficha en español e inglés utiliza la misma muestra. Este resultado verifica el ejemplo; las comprobaciones adicionales del proyecto usan sus módulos reales y se registran por separado.