Saltar al contenido

Requisitos Funcionales, No Funcionales y Atributos de Calidad

Uno de los primeros pasos que debes realizar como arquitecto de software cuando te enfrentas a un nuevo proyecto es la obtención de requisitos.

Recuerda que lo que diferencia a un programador de un ingeniero de software (también llamado arquitecto de software) es que, aparte de saber programar, como ingeniero debes ser capaz de:

  • Definir la estructura completa del sistema.
  • Definir sus componentes y las relaciones que existen entre ellos, mediante patrones (soluciones probadas a problemas típicos) y abstracciones (componentes genéricos reutilizables).
  • Conseguir que dichos componentes sean fáciles de implementar, mantener y escalar.
  • Asegurar la calidad del desarrollo de todas las partes del sistema.
  • Y, sobre todo, conocer las necesidades reales del cliente, analizarlas, sintetizarlas y crear un documento de requisitos.

Te recuerdo que un arquitecto de software no es el CTO (que no se dedica a programar, tan solo a gestionar la parte tecnológica de la empresa y ser la persona de enlace con el CEO) ni tampoco un arquitecto de infraestructura (que se encarga de los sistemas, servidores, redes, etc.). El arquitecto de software colabora estrechamente con ellos, pero se centra más en el código.

Aclarado esto, te voy a explicar en qué consiste una toma de requisitos y cómo debes crear el documento de requisitos de tu proyecto.

¿Qué es un Requisitos?

Es toda necesidad que debe cumplir tu solución de software para que aporte valor a sus usuarios.

Todo software es creado para solucionar un problema y transformar, no solo mejorar, la vida de sus usuarios.

Siempre se parte de una necesidad, un problema que tiene tu cliente y que debes resolver creando un software. Cuanto mejor resuelvas esa necesidad, más valor percibido por tu cliente y más estará dispuesto a pagarte por dicha solución.

Tipos de Requisitos

Funcionales

Son los que te pide el cliente, de forma explícita, y representan las reglas de su negocio (también llamado dominio). A partir de ellos, se definirán los casos de uso.

Imagina que un cliente que posee una tienda física te pide que le crees una tienda online que le permita vender sus productos a través de Internet. Antes de definir ducha solución, debes conocer cómo funciona actualmente su negocio: qué tipo de productos tiene, como se agrupan, cuáles son los procesos internos de su empresa, los flujos de entrada y salida, cómo se relacionan con sus proveedores y sus clientes, etc. En definitiva, cómo trabajan en la actualidad. Eso va a imponer una serie de requisitos a la hora de definir el nuevo software.

Por otro lado, habrá cosas que tu cliente querrá cambiar y mejorar. Habrá detectado ciertos problemas a los que querrá darle una solución, por ejemplo, automatizando ciertos procesos manuales que a día de hoy les lleva mucho tiempo y dinero gestionar. Este será otro conjunto de requisitos funcionales a tener en cuenta.

En definitiva, hay 2 tipos de requisitos funcionales:

  • Lo Que Es: son procesos y requisitos que actualmente existen en el negocio de tu cliente en cuanto a su forma de funcionar y que debes respetar.
  • Lo Que Debe Ser: son cambios que tu cliente quiere introducir en su forma de trabajar para transformar su negocio, reducir costes y aumentar beneficios.

Muy Importante: algunas veces encontrarás clientes que tienen claro lo que quieren, pero lo normal es que no sea así y que ni siquiera conozcan sus necesidades reales. Tu cliente no suele ser un experto en tecnología y te va a transmitir lo que él o ella creen que necesitan, pero quizá eso no sea lo que realmente necesitan. Será tú labor descubrir esa necesidad real y darle la mejor solución tecnológica. Escucha y pregunta, buscando siempre las razones de todo.

No Funcionales

Son los que tu cliente no te pedirá porque, de forma implícita, los dará por hecho (lo que puede ser peligroso). Tienen que ver con la calidad del software. Es por ello, que también se les llama atributos de calidad.

Pueden tener un impacto grande en el coste de tu solución de software, tanto en tiempo como en dinero, y la mayoría de las veces se suelen descuidar hasta que aparecen los problemas, creando insatisfacción en tu cliente.

Se pueden resumir de la siguiente forma: tu solución software debe ser rápida, segura, confiable y fácil de mantener. Tan sencillo (y tan difícil) como eso.

Cómo es algo que tu cliente no te va a transmitir la mayoría de las veces, es tu labor como arquitecto de software preguntar por ellos. Sobre todo, dejarlos claros para que luego no haya sorpresas o malentendidos.

Ten en cuenta que, cuanta más calidad le quieras dar a tu software, más costoso va a resultar. Tendrás que buscar un equilibrio para aportar la mayor calidad en base al presupuesto de tu cliente y el tiempo de desarrollo.

Aunque existen multitud de ellos, que tendrán mayor o menor importancia según el problema que debas solucionar, los que suelen ser comunes en todos los proyectos son los siguientes:

  • Rendimiento: para una misma carga, se evalúa la latencia, es decir, el tiempo que tarda en responder el sistema ante una petición de un usuario. Se puede mejorar de diferentes maneras:
    • Hardware: aumentando CPU, RAM, almacenamiento en disco o capacidades de la red.
    • Software: mejorando los algoritmos, utilizando asincronía y concurrencia, o mediante el uso de cachés.
  • Escalado: es lo contrario al rendimiento: es la forma en la que el sistema se adapta a una carga variable, es decir, que para diferentes números de peticiones simultáneas se debe tardar siempre el mismo tiempo en responder. Existen 2 tipos de escalado:
    • Vertical: aumentando o reduciendo procesador, memoria, almacenamiento o red de forma dinámica. Tiene sus límites y, en la medida de lo posible, es mejor usar escalado horizontal.
    • Horizontal: es una combinación de patrones y estilos de arquitectura que ayudarán a soportar mejor las altas carga de trabajo, así como no desperdiciar recursos en los momentos en los que el sistema esté más relajado. Todo de forma rápida y dinámica.
      • Replicación: se basa en crear sobre la marcha duplicados de servicios y datos. Cuando haya una alta carga se crearán nuevas instancias para dar soporte a las mismas y, cuando el sistema esté más ocioso, se reducirán las mismas para no desperdiciar recursos.
      • Balanceo de Carga: se basa en repartir el trabajo entre varios servicios que, como se ha comentado, se podrán ir creando o destruyendo de forma dinámica.
      • Caché: sistemas más cercanos al usuario que permiten dar una respuesta más rápida a peticiones similares a las que tanto él como otros usuarios han realizado anteriormente. Además, esto libera a los servidores de peticiones repetitivas, pudiendo dar servicio a más usuarios a la vez.
      • Asincronía: hay procesos que se pueden ejecutar en segundo plano sin que el usuario deba estar esperando una respuesta. Así, el sistema podrá llevar a cabo otras tareas y el usuario no perderá su tiempo.
  • Confianza: tiene que ver con el número de fallos (que los habrá, seguro) y el tiempo que tardará tu sistema en recuperarse de ellos:
    • SLA: es el porcentaje de tiempo que el sistema puede estar caído. Por ejemplo, si de media un sistema está inoperativo 10 minutos al mes, se dirá que el sistema estará operativo el 99,97% del tiempo. A esto se le llama SLA (Acuerdo de Nivel de Servicio). Es muy importante que hagas entender a tu cliente que el sistema no va a estar siempre funcionando (no existe el 100% de SLA) y debes acordar con él un SLA de antemano. Son típicos el 99%, 99.9%, 99.95%, 99.999%, etc. Es una de las cosas que más encarecen una solución de software, así que tenlo muy en cuenta.
    • Redundancia: para sistemas críticos, deberás tener dos o más copias del mismo componente para que, si uno falla, otro pueda tomar el relevo. Por ejemplo, servicios duplicados tras un balanceador de carga, réplicas de bases de datos que operan a la vez o backups completos del sistema en caso de desastre.
    • Monitoreo: sistemas que supervisan el estado de cada componente. Sirven tanto para informar a los administradores de la salud del sistema, como para detectar e informar lo antes posible de cualquier fallo que se produzca. Todo software debe tener un sistema de monitorización, es imprescindible.
    • Recuperación: existen varias formas de recuperarse de un fallo. Ten en cuenta que, cuando más rápido quieras recuperarte de un fallo, más costoso va a ser tanto en tiempo como en dinero:
      • Hot: sistemas que toman el control de forma automática en cuanto se produce un fallo. Por ejemplo, un balanceador de carga que inmediatamente detecta que uno de sus servicios falla y deja de enviarle peticiones. O un gestor de contenedores que detecta que uno de sus instancias ha caído y la elimina, creando una nueva, lo antes posible. El usuario no nota ninguna caída del sistema o de rendimiento.
      • Warm: son duplicados que están a la espera por si el principal falla. Por ejemplo, una replica de una base de datos que, en caso de fallar la principal, asume su función. Se diferencian de los Hot en que no se ponen en marcha de forma automática, sino que que se llevan a cabo de forma manual. El usuario puede sufrir una caída momentánea del sistema (desde unos segundos a varios minutos).
      • Backup: son copias de seguridad que se realizan del sistema y que se usan en casos de catástrofes. Suelen tardar un tiempo en ser montados y desplegados (incluso varias horas), ya que hay que hacerlo de forma manual. Son menos costosos y más rápidos de implementar que el resto de sistemas de recuperación.
  • Seguridad: todo lo que tiene que ver con autenticación, autorización, certificación y protección de los datos. La gestión de usuarios, sus roles y permisos, el cifrado de los datos sensibles y las comunicaciones, los sistema de firma electrónica, la detección y respuesta a ciertos ataques o el uso de firewalls y otros sistemas de seguridad son algunos de los aspectos a tener en cuenta, pero hay muchos más. Según lo sensible que sea la información del sistema, se deberá invertir más o menos recursos en este aspecto. Lo que no es aceptable es no tener en cuenta un mínimo nivel de seguridad en todos y cada uno de los componentes del sistema.
  • Despliegue (DevOps): debe automatizarse en la medida de lo posible. Tanto para poner en producción nuevas versiones como para volver a versiones anteriores en caso de fallo lo antes posible. Es común el uso de contenedores, máquinas virtuales, CI/CD o diversos tests automatizados, entre otros.

En base a todos ellos, como mínimo, deberás preguntar a tu cliente sobre:

  • Rendimiento: como te he comentado, es el número de tareas por unidad de tiempo, pero se suele hablar más de tiempos de respuesta. Debes aclarar tanto el tiempo normal de respuesta de cada petición como el tiempo máximo aceptable para tu cliente.
  • Carga: número de tareas simultáneas que debe realizar el sistema sin colapsarse y sin una pérdida significativa de rendimiento.
  • Volumen de Datos: tipo de almacén a usar, tipos de peticiones que se llevarán a cabo y la cantidad inicial en bytes, así como la tasa de crecimiento que se espera.
  • Concurrencia: cuántos usuarios van a usar el sistema a la vez. Suele ser 10 veces la carga. Importante conocer los momentos de inactividad del sistema, así como los picos máximos que suele tener.
  • SLA: porcentaje de tiempo que se espera que el sistema esté funcionando. Recuerda que un 100% del tiempo no es realista.

Como ejemplo, pensemos en una tienda online de productos físicos que solo vende y distribuye dentro de su país pero no en el extranjero:

  • Rendimiento: todas las pantallas deben responder en menos de 1 segundo, no superando los 5 segundos en ningún momento.
  • Carga: la empresa posee actualmente cerca de 1.000 usuario activos, que realizan una media de 100 compras al mes. Se espera un crecimiento anual del 10%.
  • Volumen de Datos: la base de datos inicial ocupa 500 MB y se espera que crezca en 100 MB al mes. Lo que supone que, cada año, el espacio ocupado crezca en algo más de 1 GB. Por otro lado, las fotos y vídeos de los productos, que se almacenarán en disco, ocupan 3 GB y se espera que crezcan en 500 MB al año.
  • Concurrencia: el sistema debe ser capaz dar soporte a 100 personas navegando por el catálogo y 10 usuarios realizando compras a la vez. Habrá momentos en los que no haya nadie (por ejemplo, por las noches) y habrá momentos en los que haya picos elevados de trabajo (por ejemplo, días con ofertas limitadas en tiempo). Los picos máximos pueden ser de hasta 1.000 clientes viendo el catálogo y 100 realizando compras a la vez.
  • SLA: 99,95%, ya que menos es inaceptable para el cliente y más es demasiado costoso. Esto supone que el sistema no puede estar inoperativo, de media, más de 13 minutos al mes.

Restricciones

Son todos aquellos requisitos impuestos por terceros, es decir, que no provienen del cliente.

Para empezar, toda actividad económica debe cumplir una legislación vigente que, además, suele ir cambiando con el tiempo. Aunque hay leyes que son comunes a toda actividad económica (por ejemplo, la que tiene que ver con la privacidad y la protección de los datos) existen otras leyes que son específicas de cada sector o cada zona territorial.

Además, el sitio donde se lleva a cabo el trabajo, o los colaboradores de tu cliente, suelen imponer también una serie de restricciones. Por ejemplo, quizá tu cliente no desee enviar sus productos a ciertos territorios por el coste que le supone los gastos de envío. O quizá se deba exigir un número mínimo de unidades en un pedido debido a que su proveedor no admite cantidades pequeñas.

A veces, se incluyen las restricciones dentro de los requisitos formales, pero creo que es mejor que las trates aparte. Sus cambios no provienen del cliente y deben llevarse a cabo de forma más rápida que los cambios que suele proponer tu cliente. Por ejemplo, podrás negociar con tu cliente el tiempo que te llevará implementar una nueva funcionalidad, pero las leyes suelen entrar en vigor en una fecha concreta, y tu cliente espera que los cambios necesarios estén lo antes posible, ya que se arriesga a pagar multas elevadas si no es así.

Atributos de Calidad

Los requisitos no funcionales que te he comentado hasta ahora son los más comunes e importantes debido a que son observables por parte del cliente. Pero existen también otros muchos que no son tan visibles por su parte, al menos de forma directa.

Por completar la lista anterior, te la voy a ampliar con una lista de los más usados, tanto observables como no observables. Deberías tenerlos todos en cuenta en mayor o menor medida según la importancia que tengan para el sistema que debes desarrollar para tu cliente, pero no deberías descuidar demasiado ninguno de ellos si quieres darle un mínimo de calidad a tu software.

Por cierto, en la Wikipedia tienes una lista más amplia de requisitos no funcionales.

Observables

  • Rendimiento: tiene que ver con los tiempos de respuesta, es decir, el número de transacciones por unidad de tiempo. Va a depender de:
    • Número de usuarios o procesos simultáneos.
    • Cantidad de datos a transmitir.
    • Latencias (de red, de lectura/escritura de disco, de petición a servicios externos, etc.)
    • Anchos de banda.
    • Rapidez de procesadores y memorias.
    • Picos puntuales.
  • Seguridad: evitar el uso no autorizado del sistema (te recomiendo echarle un vistazo a OWASP). Un sistema seguro debe aportar:
    • No repudio (mediante el uso de logs, certificados o cifrado).
    • Autenticación (mediante certificados, firmas y sellos digitales).
    • Confidencialidad (con el uso de cifrado).
    • Integridad (usando firma digital).
    • Auditoría (explotando la información que haya en los logs para saber qué ha pasado).
  • Disponibilidad (SLA): porcentaje de tiempo en funcionamiento.
    • Alta disponibilidad: si es igual o mayor que 99.999% (aunque para la mayoría de sistemas es suficiente con valores entre un 99.9% y un 99.99%). Menos de un 99% suele ser inaceptable para la mayoría de los clientes (algo más de 7 horas de caída al mes).
    • Uso de balanceo de carga, redundancia, alertas, planes de contingencia, etc.
  • Funcionalidad: realizar el trabajo para el cual el sistema fue diseñado. Para asegurarlo, es imprescindible el uso de tests automatizados, siendo los más comunes:
    • Tests unitarios (prueba un método concreto, de forma aislada).
    • Tests de integración (prueba si los componentes trabajan bien juntos).
    • Tests de aceptación (prueba cada caso de uso solicitado por el cliente).
    • Tests de usuario o de interfaz (también llamados tests end-to-end).
  • Usabilidad: satisfacción del usuario con el aprendizaje y uso del sistema:
    • Tiempo y dificultad de aprendizaje (también llamada curva de aprendizaje).
    • Facilidad de lectura, visualización y contraste de los elementos.
    • Número de clicks para hacer una tarea (esfuerzo).
    • Internacionalización y localización
    • Usabilidad y accesibilidad.
  • Confiabilidad: seguridad del usuario de que el sistema no le fallará cuando más lo necesite.
    • Número de fallos o cuelgues por unidad de tiempo.
    • Facilidad de instalación, actualización, mantenimiento y desinstalación.
  • Interoperabilidad: capacidad del sistema para intercambiar datos con otros sistemas.
    • Tipos de archivos que es capaz de leer, importar o exportar (XML, JSON, PDF, etc.)
    • API que expone sus datos y servicios al exterior.
    • Plugins o extensiones que se podrán instalar en el sistema.
  • Despliegue: facilidad para hacer nuevas instalaciones, realizar actualizaciones o revertir cambios. Cuanto más automatizado, mejor (investiga sobre CI/CD y DevOps).
    • Número de pasos para instalarlo y complejidad de los mismos.
    • Necesidades de conocimientos técnicos para llevarlo a cabo (dependencias con terceros).
    • Tiempos de parada para actualizarlo y número de veces que hay que hacerlo por unidad de tiempo.

No Observables

  • Modificaciones: costo y riesgo de realizar un cambio de código.
    • ¿Qué puede cambiar?
    • ¿Cuál es la probabilidad de dicho cambio?
    • ¿Quién debe hacer el cambio?
    • ¿Cuánto cuesta el cambio, en tiempo y dinero?
  • Mantenimiento: costo y tiempos que conlleva tener en funcionamiento el software, sin hacer cambios en el código.
    • ¿Qué tareas deben realizar los administradores asiduamente?
    • ¿Opera de forma automática o necesita de intervención humana?
    • ¿Requiere de cambios en la configuración a menudo?
  • Portabilidad: capacidad para adaptarse a otra plataforma.
    • Cambios en lenguajes de programación o librerías.
    • Uso de máquinas virtuales o de contenedores.
    • Necesidad de realizar o no recompilar para usarlo en otro sistema.
    • Uso de APIs para que aplicaciones desarrolladas en otras plataformas o lenguajes puedan hacer uso del mismo.
    • Uso de estándares.
  • Reusabilidad: si parte o todo el código se podrá reutilizar más de una vez:
    • División del código en librerías y paquetes.
    • Creación y mantenimiento de una buena documentación.
    • Uso de buenas prácticas y principios (SOLID, GRASP, Clean Architecture, Clean Code, etc.)
    • Uso de patrones y estándares como REST, JSON, SOA, SOAP, XML, microservicios, etc.
  • Testabilidad: cómo de fácil es hacer pruebas para que los errores salgan a la luz lo antes posible. Tus componentes deben poseer una alta cohesión y un bajo acoplamiento.
    • Inversión de dependencias.
    • Depender de interfaces y abstracciones, no de clases concretas.
    • Responsabilidades únicas en componentes, clases y métodos.
    • Refactorización y revisión de código a menudo.
  • Escalabilidad: adaptación del sistema al aumento o descenso de la carga de trabajo.
    • Vertical: aumento o disminución del hardware de un servidor (procesador, memoria, disco o red).
    • Horizontal: aumento o disminución dinámica en el número de servidores y servicios.
  • Uso de Estándares: número de estándares con los que se cumple.
  • Desarrollo Ágil: cómo se adapta tu desarrollo a las metodologías ágiles tipo XP, Scrum o Kanban.
  • Desarrollo Fácil: tiempos de aprendizaje y de desarrollos, si se puede distribuir el desarrollo en varios equipos, etc.

Pasos a Seguir en el Desarrollo de una Solución de Software

  1. Establecer los objetivos: descubrir las necesidades reales de tu cliente, reuniéndote con los directivos, que te transmitirán lo que se pretende lograr y solucionar.
  2. Entender los requisitos funcionales: los analistas del sistema y los jefes de proyecto deberán pasarte cada uno de los casos de uso que tu solución debe implementar. También deben transmitirte las restricciones de terceros, especialmente las legales.
  3. Entender los requisitos no funcionales: preguntarle al cliente acerca de los atributos de calidad que tu solución debe cumplir, llegando a un equilibrio entre calidad y coste.
  4. Crear mapa de componentes y servicios: uno o varios diagramas que permitan demostrar a tu cliente que has entendido todo bien y para que luego no haya malentendidos. Evita las palabras técnicas, este mapa va dirigido a gestores y directivos, no a los técnicos.
  5. Diseñar la arquitectura: es hora de reunirte con el equipo de desarrollo e ir definiendo todos los detalles a nivel de arquitectura (aún no estarías trabajando a nivel de código). Lo normal es ir haciéndolo de forma iterativa, no tiene que estar absolutamente todo definido para comenzar a desarrollar.
  6. Seleccionar la tecnología: para cada componente hay que elegir el lenguaje, librerías y tecnologías que se va a usar. A esto también se le suele llamar stack tecnológico.
  7. Infraestructura y plataforma: también se va definiendo de forma iterativa. Según vayáis teniendo claro las necesidades en cuanto a sistemas, debéis ir solicitando (o realizando) su montaje y configuración. Mi consejo es que pospongas las decisiones de infraestructura lo máximo posible (para más información sobre este tema infórmate acerca de las Clean Architectures).
  8. Módulos y clases: es hora de comenzar a codificar. De igual forma, lo ideal es que lo vayáis haciendo de forma iterativa. Te recomiendo echar un vistazo tanto a la metodología XP como a Clean Architecture, DDD, TDD y Clean Code.
  9. Escribir la documentación: en realidad hay que ir haciéndolo a la par con el resto de pasos, es decir, según se vayan tomando decisiones, hay que ir documentándolo todo, sobre todo los «porqués». El «qué» y el «cómo» es fácil verlo en la infraestructura, plataforma y código, pero las razones por las que se tomaron una u otra decisión se pierden si no se documentan. También sirve para que la comunicación con tus clientes sea más fluida y para que las nuevas incorporaciones al equipo de desarrollo se pongan al día lo antes posible.
  10. Dar soporte al equipo de desarrollo: como ingeniero de software no te desentenderás del producto en ningún momento, y estarás disponible y colaborando con el equipo de desarrollo en todo momento. Además, deberás ver si se cumplen los estándares de calidad establecidos.

Documento de Requisitos

No hay un único estándar de documento de requisitos y, según el tamaño del proyecto, será más o menos extenso. Aún así, para un proyecto típico, ésta es la estructura y extensión que debería tener tu documento de requisitos.

Ten en cuenta que las primeras páginas van más dirigidas a perfiles de más alto nivel, gestores y directivos. Por lo tanto, deja las partes más técnicas para el final.

  1. Trasfondo, motivaciones y objetivos (1 página).
  2. Requisitos funcionales y no funcionales (1 página, una 2-3 líneas por cada requisito).
  3. Resumen ejecutivo (dirigido a gestores y directivos, con gráficos y diagramas, unas 3 páginas).
  4. Resumen de la arquitectura, infraestructura y plataforma (unas 10 páginas).
  5. Componentes detallados (aquí te puedes ir a las 100 páginas fácilmente, detallando cada caso de uso con UML u otro sistema de documentación técnica).

Conclusión

Los requisitos son cada una de las necesidades y requisitos que tu solución de software debe tener para generar una transformación en tu cliente y aportarle el máximo de valor.

Escucha a tu cliente, sobre todo para conocer sus necesidades reales. Tu software debe solucionar sus problemas de raíz. Nunca te quedes en la superficie y entiende que tu cliente no tiene conocimientos profundos de tecnología.

Los requisitos funcionales y las restricciones impuestas por terceros te las dará tu cliente. Los requisitos no funcionales deberás obtenerlo tú preguntando a tu cliente, dejándolos claros para que no haya malentendidos y buscando un equilibrio entre coste y calidad.

Los atributos de calidad más básicos que debes tener claros siempre antes de comenzar ningún desarrollo son el rendimiento esperado, las posibles cargas, el volumen de datos a almacenar, la cantidad de procesos que se ejecutarán de forma concurrente, y el SLA, o porcentaje de tiempo máximo que el sistema puede estar caído.

Aunque hay atributos de calidad que no son observables, no los descuides. Aunque, según el proyecto, unos serán más importantes que otros. Debes intentar cubrir el máximo posible de ellos en base al presupuesto y el tiempo del que dispongas.

Debes documentar cada paso del desarrollo. Intenta usar gráficos y diagramas en la medida de lo posible, limitando el texto al mínimo imprescindible, siendo lo más claro y conciso posible. Recuerda reflejar sobre todo las razones de las decisiones.

Reserva las primeras páginas del documento de requisitos para los gestores y directivos, documentando cada caso de uso y sus detalles técnicos al final del documento.

¿Y Tú, Qué Opinas?

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *