Alcance. Este documento describe lo que Éxito Marketing implementará para FUSADES: la arquitectura, las medidas de seguridad, el modelo de accesos y el plan de mantenimiento del nuevo sitio. Todo lo aquí descrito forma parte del alcance del proyecto.
Con qué se construye
Un solo lenguaje —TypeScript— desde la base de datos hasta el navegador. No se utiliza PHP, ni Python, ni WordPress, ni plugins de terceros.
- Lenguaje
- TypeScriptv5 · modo estricto
- Framework
- Next.js16 · App Router
- Interfaz
- React19
- Base de datos
- PostgreSQL17 · con pgvector
- Acceso a datos
- Drizzle ORMconsultas tipadas
- Validación
- Zodesquemas en servidor
- Ejecución
- Node.js24 LTS
- Pruebas
- Vitest + Playwrightautomatizadas
Aclaración sobre el lenguaje. Todo el sistema —servidor, interfaz, scripts de importación de datos y pruebas— está escrito en TypeScript sobre Node.js. No hay componentes en Python ni en PHP. Si en documentación previa se mencionó Python, corresponde a un error de redacción: este documento refleja la arquitectura definitiva.
Dependencias
El proyecto se construye sobre 14 dependencias de ejecución. Ese número importa: cada dependencia es código de terceros que corre en el servidor, y cada una es una vulnerabilidad potencial que hay que vigilar. Un sitio WordPress institucional típico corre entre 25 y 40 plugins, cada uno con su propio autor, su propio ciclo de actualizaciones y su propio historial de fallas.
Pruebas automatizadas
Antes de cada publicación se ejecuta una batería completa de pruebas: cerca de 530 pruebas de lógica (búsqueda, permisos, cálculos, importación de datos) y 61 pruebas de navegador real —Chrome de escritorio a 1280px y móvil a 390px—. Si alguna falla, el cambio no se publica. Esto es lo que permite actualizar el sitio sin miedo, y es precisamente lo que WordPress no ofrece.
Qué es TypeScript y por qué lo elegimos
La decisión técnica de fondo del proyecto. Explicada sin jerga, porque determina el costo de mantenimiento durante los próximos años.
Qué es
JavaScript es el lenguaje que entienden todos los navegadores del mundo; es el único que se ejecuta de forma nativa en la web. TypeScript es JavaScript con una capa de verificación encima: el mismo lenguaje, más la obligación de declarar qué tipo de dato es cada cosa —un texto, un número, una fecha, un documento con autor y departamento—.
Esa declaración se revisa antes de publicar. TypeScript es un producto de Microsoft, de código abierto, y hoy es el estándar de facto para aplicaciones web serias: lo usan Airbnb, Slack, Shopify, Bloomberg y el propio Visual Studio Code.
Por qué importa en la práctica
Un ejemplo concreto. Supongamos que alguien renombra el campo
fecha_publicacion a fecha en la base de datos:
| En PHP / WordPress | En TypeScript | |
|---|---|---|
| Cuándo se detecta | Cuando un visitante abre la página y ve un error o una fecha vacía. | Al instante, en el editor del programador. El proyecto no compila. |
| Quién lo descubre | El usuario final, o FUSADES cuando alguien reporta el problema. | Nadie externo: el error nunca sale del computador del desarrollador. |
| Costo de arreglarlo | Diagnóstico en producción, corrección urgente, posible pérdida de confianza. | Treinta segundos. Es una corrección, no un incidente. |
Los cuatro beneficios concretos
1 · Una clase entera de errores desaparece antes de publicar
Campos mal escritos, datos ausentes, funciones llamadas con los argumentos equivocados: TypeScript los rechaza en el momento de escribirlos. En la práctica esto elimina la mayoría de los errores que en otros sistemas se descubren en producción.
2 · Un solo lenguaje en todo el sistema
La base de datos, el servidor, la interfaz y las pruebas hablan TypeScript. No hay traducción entre PHP en el servidor y JavaScript en el navegador, que es donde se producen las incoherencias clásicas. Un desarrollador que entiende una parte del sistema entiende todas.
3 · El código se puede modificar con seguridad
Cambiar algo en un sistema grande da miedo cuando no se sabe qué más depende de ello. Con tipos, el compilador señala todos los lugares afectados por un cambio. Esto es lo que hace viable seguir mejorando el sitio dentro de tres o cinco años, en lugar de tener que reconstruirlo.
4 · El código se documenta a sí mismo
Los tipos describen qué es cada cosa y qué se puede hacer con ella. Un desarrollador nuevo —o una herramienta de inteligencia artificial, como se explica en la sección de continuidad— puede leer el proyecto y entenderlo sin depender de quien lo escribió.
En una frase: TypeScript traslada los errores desde el sitio publicado hacia el momento de escribir el código. Cuesta un poco más escribirlo y cuesta bastante menos mantenerlo — que es exactamente el reparto correcto para una institución que necesita este sitio funcionando durante años, no durante meses.
Seguridad de la aplicación
Medidas escritas en el código, que viajan con la aplicación a cualquier servidor. Cambiar de proveedor no puede desactivarlas.
| Medida | Qué previene |
|---|---|
| Consultas parametrizadas sin concatenación de texto |
Inyección SQL. Ningún valor introducido por un usuario se concatena a una consulta; todos viajan como parámetros separados. |
| Validación de entrada con esquemas Zod, en el servidor |
Datos malformados y campos inesperados. Se valida en el servidor, no solo en el navegador, donde cualquiera puede saltarse la validación. |
| Cabeceras de seguridad HTTP HSTS · nosniff · frame DENY · Referrer-Policy · Permissions-Policy |
Degradación de HTTPS a HTTP, clickjacking, adivinación de tipos MIME, y fuga de los términos de búsqueda de un lector hacia otros sitios. |
| Content-Security-Policy | Ejecución de scripts inyectados. Se despliega primero en modo observación y se endurece con evidencia: una política demasiado estricta rompe el sitio en silencio. |
| Archivos con URL firmada y temporal | Acceso directo a documentos. Los PDF no quedan públicos en el almacenamiento: se sirven mediante un enlace firmado que expira. |
| Verificación del tipo real de archivo | Subir un ejecutable renombrado a .pdf. Se leen los bytes del archivo, no su extensión ni lo que declara el navegador. |
| Guarda contra path traversal | Que una ruta con ../ escape del directorio permitido y alcance archivos del sistema. |
| Analítica sin datos personales hash con sal, nunca IP |
Rastreo de lectores. Se cuenta una visita sin poder identificar a quien la hizo. Nunca se almacena una dirección IP. |
| Secretos solo en el servidor | Claves filtradas al navegador. Las credenciales nunca se envían al cliente. |
| Límite de peticiones rate limiting |
Inflado artificial de los contadores de descarga y abuso automatizado de los formularios. |
| Protección anti-spam Turnstile o hCaptcha |
Envíos automatizados en los formularios públicos, sin recurrir a un captcha que estorbe a personas con discapacidad. |
| Análisis continuo de dependencias Dependabot + npm audit |
Vulnerabilidades conocidas en librerías. Aviso automático el mismo día en que una se publica. |
Verificable de forma independiente. Una vez publicado, el
equipo de FUSADES podrá comprobar las cabeceras de seguridad desde
cualquier terminal con curl -I sobre el dominio, o pegando
la dirección en securityheaders.com. No hace falta
creernos.
Seguridad en la infraestructura AWS
Arquitectura para alojar el sitio en la cuenta de AWS de FUSADES.
| Componente | Configuración | Por qué |
|---|---|---|
| Red VPC |
Base de datos en subred privada, sin dirección pública. La aplicación accede mediante grupo de seguridad; nada más. | La base de datos no será alcanzable desde internet, ni siquiera con la contraseña correcta. |
| Base de datos RDS PostgreSQL |
Cifrado en reposo con KMS y en tránsito con TLS obligatorio. Multi-AZ opcional. Snapshots automáticos diarios. | Un disco robado o un snapshot filtrado no revela nada legible. |
| Documentos S3 |
Bucket privado con Block Public Access, cifrado SSE-S3 y versionado activo. Acceso únicamente por URL prefirmada temporal. | Ningún PDF será accesible adivinando su nombre. El versionado revierte un borrado accidental. |
| Permisos IAM |
Rol de aplicación con permiso mínimo: leer y escribir en un prefijo de un bucket y conectarse a una base de datos. Nada más. | Si la aplicación se viera comprometida, el atacante heredaría solo esos permisos. |
| Credenciales Secrets Manager |
Contraseñas y claves de API cifradas y rotables, nunca en el código ni en el repositorio. | Una clave no se filtra por un commit ni por un respaldo del código fuente. |
| Borde CloudFront + WAF |
TLS 1.2 o superior obligatorio, HTTP redirigido a HTTPS, reglas administradas de AWS WAF y límite de peticiones por IP. | Absorbe picos de tráfico y bloquea patrones de ataque conocidos antes de que alcancen la aplicación. |
| Registro CloudWatch + CloudTrail |
Registros de aplicación y de acceso con retención definida. CloudTrail registra toda acción administrativa sobre la cuenta. | Queda constancia de quién cambió qué en la infraestructura, y cuándo. |
| Gobierno de la cuenta | MFA obligatorio en la cuenta raíz y en todo usuario administrativo. Alertas de facturación configuradas. | Un uso anómalo —minería, exfiltración— aparece primero en la factura. |
Sobre Plesk. Entendemos que FUSADES cuenta hoy con acceso a Plesk. Este sitio no lo necesitará ni lo usará: no hay PHP que administrar ni plugins que actualizar desde un panel. La publicación ocurrirá desde el repositorio de código, de forma versionada y reversible. Plesk puede seguir existiendo para otros servicios sin relación alguna con este sitio.
Accesos y roles
Tres niveles. Cada persona recibirá el menor permiso que le permita hacer su trabajo.
- Todo lo que pueden hacer los demás roles
- Crear, editar y eliminar páginas institucionales
- Gestionar el menú principal del sitio
- Editar los indicadores y el documento destacado de la portada
- Dar de alta y de baja usuarios, y asignarles rol
- Eliminar publicaciones de forma permanente
- Publicar y editar documentos de cualquier departamento
- Revisar y aprobar los borradores de los investigadores
- Editar los perfiles de personas y sus fotografías
- No podrá gestionar usuarios ni el menú del sitio
- Subir un PDF y crear la publicación que lo acompaña
- Redactar el artículo con asistencia de IA y corregirlo
- Editar sus propias publicaciones
- Editar su propio perfil
- Sus publicaciones pasarán a revisión antes de aparecer en el sitio
- No podrá editar el trabajo de otros ni eliminar nada
Autenticación
| Medida | Detalle |
|---|---|
| Cuentas individuales | Una cuenta por persona, ligada a su correo institucional. Nunca contraseñas compartidas entre varias personas. |
| Enlace mágico por correo | Sin contraseña que recordar, reutilizar o filtrar. El enlace expira y es de un solo uso. |
| Segundo factor con app (2FA) | TOTP estándar, compatible con Google Authenticator, Microsoft Authenticator, 1Password o Authy. Opcional por usuario y obligatorio para administradores si FUSADES así lo define. |
| Registro de actividad | Quién publicó, editó o eliminó qué, y cuándo. Visible para los administradores. |
| Cierre de sesión por inactividad | La sesión caduca sola; una computadora compartida no queda abierta. |
Respaldos y recuperación
Automáticos, verificados y en más de un lugar. Un respaldo que nunca se ha restaurado no es un respaldo: es una suposición.
| Qué | Frecuencia | Retención | Cómo se restaura |
|---|---|---|---|
| Base de datos | Diario, automático | 30 días | Snapshot de RDS. Recuperación a un punto exacto en el tiempo, con precisión de segundos. |
| Documentos PDF | Continuo | Indefinida | Versionado de S3: se conserva cada versión de cada archivo, y un borrado se revierte. |
| Copia externa | Semanal | 90 días | Copia a una segunda región de AWS. Protege ante una falla regional o un borrado en cadena. |
| Código fuente | Cada cambio | Permanente | Historial completo en Git. Cualquier versión anterior del sitio se puede reconstruir. |
| Prueba de restauración | Trimestral | — | Se restaura un respaldo en un entorno aparte y se confirma que el sitio levanta correctamente. |
Reversión de una publicación errónea: el sitio se despliega desde Git, de modo que volver a la versión anterior será una operación de un minuto que no depende de ningún respaldo. En WordPress, revertir una actualización de plugin que rompió el sitio normalmente significa restaurar una copia completa y perder el contenido publicado desde entonces.
Mantenimiento
Qué se revisa, cada cuánto, y qué incluye la cuota anual.
Automático
- Respaldo diario de base de datos
- Versionado de cada archivo subido
- Batería completa de pruebas antes de publicar
- Verificación de enlaces internos en cada despliegue
- Renovación del certificado TLS
- Aviso de vulnerabilidad en dependencias
- Alerta si el sitio deja de responder
Revisión semanal
- Disponibilidad y tiempos de respuesta
- Errores registrados en los logs
- Que los respaldos efectivamente se hicieron
- Almacenamiento utilizado y su crecimiento
- Alertas de seguridad de dependencias
- Formularios: que sigan enviando y llegando
Revisión mensual
- Actualización de dependencias y del framework
- Ejecución completa de pruebas tras actualizar
- Rastreo completo de enlaces rotos, internos y externos
- Core Web Vitals y velocidad de carga
- Revisión de cabeceras y del certificado
- Reporte de métricas de uso a FUSADES
- Revisión de la cuenta de AWS y su gasto
Revisión trimestral
- Prueba real de restauración de respaldo
- Auditoría de usuarios y permisos activos
- Rotación de claves de API
- Auditoría de accesibilidad
- Revisión de permisos IAM
- Actualización de la documentación del proyecto
Enlaces rotos: en dos niveles
Los enlaces se verifican con dos frecuencias distintas, porque se rompen por motivos distintos.
| Tipo | Cuándo se revisa | Por qué esa frecuencia |
|---|---|---|
| Enlaces internos dentro de fusades.org |
En cada despliegue, de forma automática. | Se rompen por nuestros propios cambios, así que se detectan en el mismo momento en que se introducen — antes de publicar, no después. |
| Enlaces externos a otros sitios |
Mensual, mediante rastreo completo del sitio. | Se rompen porque otra institución reorganizó su web, sin avisar a nadie. Un mes es el equilibrio entre detectarlos a tiempo y no generar tráfico innecesario hacia terceros. |
| Enlaces a PDF de FUSADES | Mensual, junto al rastreo anterior. | Son el activo principal del repositorio: un documento que no descarga es una falla visible para el lector. |
Los enlaces rotos encontrados se reportan a FUSADES con el reporte mensual, y los que dependen de nosotros se corrigen dentro de ese mismo ciclo.
Qué no incluye
La cuota cubre que el sitio siga funcionando, seguro y actualizado. No cubre desarrollo de funcionalidad nueva, rediseños ni redacción de contenido: eso se cotiza aparte, para que ninguna de las dos partes tenga que adivinar qué estaba incluido.
Por qué el mantenimiento cuesta menos que en WordPress
No es una opinión sobre el software: es una diferencia de superficie de mantenimiento y de riesgo.
| WordPress institucional | Este sitio | |
|---|---|---|
| Código de terceros | 25–40 plugins, cada uno de un autor distinto, con su propio ritmo de actualización y de abandono. | 14 dependencias, todas de proyectos mayores con mantenimiento activo. |
| Superficie de ataque | Panel /wp-admin público, XML-RPC, PHP ejecutable en el servidor, subidas al directorio web. |
Sin panel público. Sin PHP. Los archivos subidos se guardan fuera del servidor web y se sirven firmados. |
| Origen de las brechas | Los plugins y temas concentran la gran mayoría de las vulnerabilidades reportadas del ecosistema. | No hay plugins. La superficie es el código propio, que está cubierto por pruebas. |
| Actualizar | Se actualiza y se espera lo mejor. Sin pruebas: si un plugin rompe el sitio, se descubre en producción. | Cientos de pruebas corren antes de publicar. Si algo se rompe, no llega al público. |
| Revertir | Restaurar una copia completa, perdiendo el contenido publicado desde el respaldo. | Volver al despliegue anterior. Un minuto, sin pérdida de contenido. |
| Rendimiento | Cada visita ejecuta PHP y consulta la base de datos; se compensa con plugins de caché que a su vez hay que mantener. | Páginas precompiladas servidas desde CDN. La velocidad es del diseño, no de un parche. |
| Trabajo mensual real | Actualizar decenas de plugins, resolver incompatibilidades, limpiar spam, revisar intentos de acceso. | Revisar métricas, aplicar actualizaciones ya verificadas por las pruebas, atender alertas. |
El mantenimiento de WordPress se cotiza caro porque es caro: la mayor parte del tiempo se va en administrar plugins de terceros y en reparar lo que rompen. Aquí ese trabajo no existe, y por eso la cuota es menor.
No se está ofreciendo menos servicio por menos dinero: se está cobrando por un sistema que requiere menos trabajo.
Revisión antes del lanzamiento
Treinta y siete verificaciones, agrupadas por materia. Cada una se comprueba y se documenta antes de publicar.
href="#" ni controles decorativos.rel="noopener".font-display, para que el texto sea legible desde el primer instante.