Este proyecto será diferente a todos los anteriores que ya has realizado durante el curso. Su principal diferencia es que es un proyecto funcional relativamente grande.

No es necesario escribirlo desde cero, pero sí es necesario realizar cambios en el código y no romper nada en él, agregar funcionalidad que aún no se ha escrito y configurar la infraestructura. Es este tipo de tarea la que encontrarás principalmente en el trabajo.

Esta es la mitad del trabajo completo de un programador: leer y analizar el código de otras personas.

En el trabajo pasarás todo dedica tu tiempo a 3 cosas:

  • Analizar y leer el código de otras personas: el 50 % del tiempo.
  • Imagina cómo describir tu tarea en forma de código de solución: el 25% del tiempo.
  • Agregar su código a la lógica del proyecto existente: el 25% del tiempo.

Cuando empiezo a familiarizarme con un nuevo proyecto, lo intento seguir la siguiente secuencia:

  1. Descubro qué problema resuelve (o resolverá en el futuro) el proyecto.
  2. Observo qué dependencias tiene el proyecto.
  3. Miro la estructura de la base de datos.
  4. Miro la estructura de la entidad.
  5. Miro la API y/u otros controladores.
  6. Entiendo qué tarea tiene cada servicio.

Solo después de familiarizarte con esta lista podrás ver “lo que, de hecho, tengo que hacer”. .” Sigamos este plan y avancemos.

Tarea principal

El nombre del proyecto es JiraRush.

GitHub del proyecto

Creo que puedes adivinar por el nombre que se trata de una especie de tablero de tareas como Jira o Trello. El proyecto es necesario para realizar un seguimiento de cualquier actividad. Puede ser la gestión de proyectos o una lista de compras de esposa a marido. Clone el proyecto usted mismo y veamos qué contiene.

Si no está familiarizado con Jira, aquí tiene una breve introducción vídeo sobre el tema

Tecnología

  • Spring Boot
  • Spring JPA
  • Hibernate
  • PostgreSQL
  • Liquibase (sistema de control de versiones de bases de datos, principalmente su estructura)
  • Spring Security
  • Spring MVC
  • Thymeleaf
  • jQuery
  • Swagger (documentación API)
  • Cafeína (caché )
  • Lombok
  • Mapstruct (mapeadores para convertir entre entidad y DTO)
  • Spring Test
  • JUnit
  • Docker [1], [2]

Estructura de la base de datos

Cómo ejecutar la aplicación:

  1. Clone el proyecto en su máquina.
  2. Inicie el servidor de la base de datos localmente (PostgreSQL). Recomiendo hacer esto a través de Docker.
  3. Creemos 2 contenedores con una base de datos. El primero es para iniciar la aplicación (perfil de producción), el segundo es para la compilación y las pruebas (perfil de prueba). Comandos relevantes:

     docker run -p 5432:5432 --name postgres-db -e POSTGRES_USER=jira -e POSTGRES_PASSWORD=JiraRush -e POSTGRES_DB=jira -e PGDATA=/var/lib/postgresql/data/pgdata -v ./pgdata:/var/lib/postgresql/data -d postgres docker run -p 5433:5432 --name postgres-db-test -e POSTGRES_USER=jira -e POSTGRES_PASSWORD=JiraRush -e POSTGRES_DB =jira-test -e PGDATA=/var/lib/postgresql/data/pgdata -v ./pgdata-test:/var/lib/postgresql/data -d postgres 
  4. Construir el aplicación: mvn clean install
  5. Ejecute una aplicación Spring Boot (JiraRushApplication) con el perfil prod

Durante La aplicación construirá la población de la base de datos de prueba. Durante el inicio de la aplicación habrá una población de bases de datos con las que trabajar. Más precisamente, se implementarán la estructura y los diccionarios. Para "ver" cómo funciona la aplicación, debe ejecutar el script data.sql desde resources/data4dev.

Ahora podemos ver la estructura de la base de datos:

actividad: una tabla de actividades que almacena las acciones del usuario con respecto a otras entidades. Por ejemplo, “el usuario escribió un comentario”, “el usuario cambió el estado de la tarea”...

adjunto – una tabla para almacenar información sobre los archivos adjuntos.

contacto – diccionario “usuario – tipo de contacto – valor del contacto”.

mail_case – tabla donde se guardan los datos si se envía un carta (correo electrónico) fallida.

perfil – perfil de usuario. La configuración se almacena en el campo mail_notifications en forma de indicadores de bits.

proyecto – Proyectos. La unidad lógica más grande de un tablero de tareas. Por ejemplo, si una empresa tiene microservicios, cada microservicio está dirigido por un equipo, entonces se creará un proyecto para dicho microservicio.

referencia – una tabla de diferentes entidades por tipo. ref_type corresponde a Enum com.javarush.jira.ref.RefType. Columna aux – valor para calcular indicadores de bits.

task – tareas. El elemento estructural lógico más básico del tablero de tareas de JiraRush.

task_tag es un diccionario de relaciones tarea-etiqueta. Una tarea puede tener cero o más etiquetas.

user_belong – conexión del usuario con entidades del tipo “tarea”, “sprint”, “proyecto”.

user_role – diccionario de conexiones de roles de usuario. Un usuario puede tener varios roles.

usuarios lista de usuarios registrados. Las columnas endpoint y startpoint son responsables de si este usuario está activo o si estuvo activo, pero ya no está activo. El campo contraseña al principio de la contraseña en el formato “{...}” almacena el método de cifrado (Spring Security, ¿recuerdas?).

Estructura de la entidad

Este punto lo dejo para que lo revises por tu cuenta

Estoy mirando la API y/u otros controladores

Swagger está conectado al proyecto, que es responsable de documentar la API. Para verlo, con la aplicación ejecutándose, vaya a http://localhost:8080/swagger-ui/index.html

Aquí puedes ver qué controladores hay, qué métodos tienen estos controladores, qué datos de entrada se esperan, tipos de métodos, etc. También puede enviar una solicitud usted mismo. Sería una buena idea iniciar sesión como usuarios diferentes (los datos de prueba se escriben en la interfaz de usuario) y ver qué derechos se necesitan para ejecutar qué método.

Qué servicio es responsable de qué

Con este punto tú también tendrás que averiguarlo por tu cuenta. En cambio, veamos la funcionalidad ya implementada. Lo veremos desde un usuario con rol ADMIN, ya que tiene las competencias más amplias. Pero necesitarás mirar tanto a MANAGER como a DEV.

  • Árbol de proyectos. Hay una lista de proyectos. El administrador o gerente (ver función enam) puede agregar nuevos proyectos y subproyectos. El proyecto tiene un trabajo pendiente (una lista de tareas (tareas) que deben realizarse) y sprints. Un proyecto también puede tener un subproyecto. Una tarea puede relacionarse directamente con un sprint o mediante una épica (un gran grupo de tareas). Consulte http://localhost:8080/view/tree
  • Tablero de tareas). Puede elegir para qué proyecto ver el panel. Se mostrará el sprint activo (o último) del proyecto. Las tareas de Sprint se dividen en columnas. Aquellos a los que debes prestar atención están resaltados en color. El cambio de estado de las tareas se realiza haciendo clic derecho en la tarea. Consulte http://localhost:8080/ui/dashboard
  • Informe de Sprint: un conjunto mínimo de estadísticas sobre sprints completados con la capacidad de seleccionar un proyecto y un sprint. Consulte http://localhost:8080/ui/reports
  • Lista de usuarios. Lista de todos los usuarios registrados con capacidad de buscar, ordenar, agregar, editar y eliminar. Página http://localhost:8080/view/admin/users
  • Enlaces: funcionalidad para configurar JiraRush (qué campos están disponibles para qué tipo de entidad. Por ejemplo, qué redes sociales mostrar en el contacto de un usuario o qué prioridades tiene una tarea). Consulte http://localhost:8080/ui/admin/references
  • Edición de un perfil de usuario (tu perfil).
  • Registro de un nuevo usuario mediante correo electrónico + contraseña.
  • Registro de un nuevo usuario a través de redes sociales (Google , GitLab, GitHub).
  • Enviar correos electrónicos cuando se restablece una contraseña.
  • Enviar correos electrónicos para confirmarla.
  • Crear una nueva tarea en el trabajo pendiente (con la posibilidad de adjuntar archivos como archivos adjuntos).

Más información sobre el proyecto “de boca en boca”

La estructura del proyecto es similar a la Spring Modulith. Es decir, hay paquetes internos a los que no se puede acceder mediante código desde fuera del paquete de nivel superior.

Esto se hace con una “reserva futura” para que el servidor pueda ser fácilmente dividido en microservicios. Al menos, esta fue la idea del arquitecto, pero la implementación puede diferir (sí, esto casi siempre sucede en proyectos reales).

Los archivos estáticos para el frente se distribuyen a través de nginx. servidor. Al menos este debería ser el caso en producción, pero cuando se ejecuta localmente, todo es más sencillo.

PostgreSQL. No escribirás consultas nativas. Deberá utilizar consultas JPQL. Lo único nuevo para usted será conectarse a PostgreSQL para ver la estructura de la tabla y sus datos. Recomiendo usar la pestaña IDEA de base de datos.

Liquibase es una biblioteca abierta e independiente de la base de datos para rastrear, administrar y aplicar cambios en el esquema de la base de datos. El proyecto lo utiliza para ejecutar automáticamente el script de inicialización de la base de datos y completarlo con datos de prueba. Si cambia la estructura de la tabla, debe eliminar 2 tablas de servicio de Liquibase (databasechangelog y databasechangeloglock). Después de esto, la próxima vez que inicie la aplicación, Liquibase volverá a ejecutar el script de inicialización de la base de datos. No necesita realizar ninguna configuración, todo funciona de inmediato.

Swagger: le permite ver visualmente a través de la interfaz de usuario qué métodos están en los controladores de la aplicación y realizar solicitudes de prueba para ellos. No habrá tareas Swagger. Se agrega para facilitar el trabajo en el proyecto.

Caffeine cache es una biblioteca de caché de alto rendimiento para Java. Recomiendo ver cómo se conecta. No habrá tareas para usar.

Tareas de su elección

Comience con tareas fáciles y solo luego continúe con el resto. Intente completar tantas tareas como sea posible.

  1. Comprender la estructura del proyecto (incorporación).
  2. Eliminar redes sociales: vk, yandex. Tarea fácil
  3. Coloque la información confidencial en un archivo de propiedades separado:
    • iniciar sesión
    • contraseña de base de datos
    • identificadores para registro/autorización de OAuth
    • configuración de correo
    Los valores de estas propiedades deben leerse de las variables de entorno de la máquina cuando se inicia el servidor. Tarea fácil
  4. Vuelva a trabajar las pruebas para que durante las pruebas se utilice la base de datos en memoria (H2) y no PostgreSQL. Para hacer esto, necesita definir 2 beans, y cuál usar debe estar determinado por el perfil Spring activo. H2 no admite todas las funciones que tiene PostgreSQL, por lo que tendrá que simplificar un poco sus scripts con datos de prueba.
  5. Escriba pruebas para todos los métodos públicos del controlador ProfileRestController. Aunque solo hay 2 métodos, debería haber más métodos de prueba, porque debe verificar la ruta de éxito y fracaso.
  6. Refactorice el método com.javarush.jira.bugtracking.attachment.FileUtil#upload para que utilice un enfoque moderno para trabajar con el sistema de archivos. Tarea fácil
  7. Agregar nueva funcionalidad: agregar etiquetas a una tarea (API REST + implementación en el servicio). El frente es opcional. La tabla task_tag ya se ha creado.
  8. Agregue un recuento del tiempo que la tarea estuvo en operación y prueba. Escriba 2 métodos a nivel de servicio que acepten una tarea como parámetro y devuelvan el tiempo transcurrido:
    • Cuánto tiempo estuvo en progreso la tarea (ready_for_review menos in_progress).
    • Cuánto tiempo duró la tarea estaba bajo prueba (hecho menos ready_for_review).
    Para escribir esta tarea, necesita agregar changelog.sql 3 registros al ACTIVITY tabla al final del script de inicialización de la base de datos
     insertar en ACTIVITY ( ID, AUTHOR_ID, TASK_ID, UPDATED, STATUS_CODE ) valores... 
    Con estados :
    • hora de inicio del trabajo en la tarea – en_progreso
    • hora de finalización del desarrollo - ready_for_review
    • prueba hora de finalización: hecho
  9. Escribe un Dockerfile para el servidor principal
  10. Escribe un docker-compose para ejecutar el contenedor del servidor junto con la base de datos y nginx. Para nginx, utilice el archivo de configuración config/nginx.conf. Si es necesario, se puede editar el archivo de configuración. Tarea difícil
  11. Agregar localización en al menos dos idiomas para las plantillas de cartas (correos electrónicos) y la página de inicio index.html .
  12. Rehaga el mecanismo de reconocimiento de “amigo o enemigo” entre el frente y el reverso de JSESSIONID a JWT. Entre las dificultades, tendrá que rehacer el formulario envío desde el frente para agregar un encabezado de autenticación. Tarea muy difícil

Al enviar el proyecto en README.md escriba qué tareas completó.