Цей проєкт буде відрізнятися від усіх попередніх, які ти вже зробив протягом курсу навчання. Його головна відмінність — те, що це відносно великий проєкт, який вже існує.

Його не потрібно писати з нуля: треба лише вносити зміни в код і нічого в ньому не зламати, додавати ще не написаний функціонал, налаштовувати інфраструктуру. Саме з таким видом завдань ти, здебільшого, стикатимешся на роботі.

Це половина всієї роботи програміста — читання та розбір чужого коду.

На роботі ти будеш весь час витрачати на 3 речі:

  • Розбір та читання чужого коду — 50% часу.
  • Уявити, як твоє завдання описати у вигляді коду-рішення — 25% часу.
  • Додавання твшого коду в існуючу логіку проєкту — 25% часу.

Коли я починаю знайомитися з новим проєктом, я намагаюся дотримуватися такої послідовності:

  1. Дізнаюся, яку завдання вирішує (або вирішуватиме в майбутньому) проєкт.
  2. Дивлюсь, які залежності є в проєкту.
  3. Дивлюся на структуру БД.
  4. Дивлюсь на структуру Entity.
  5. Дивлюся API та/або інші контролери.
  6. Аналізую, яке завдання у кожного сервісу.

Тільки після знайомства з цим списком можна дивитися «а що, власне кажучи, я маю зробити». Давай за цим планом і рухатимемося.

Основне завдання

Назва проєкту JiraRush.

GitHub проєкту

Думаю, з назви можна здогадатися, що це дошка завдань, як Jira або Trello. Проєкт потрібен для відстеження будь-якої активності. Це може бути як ведення проєкту, так і перелік покупок від дружини для чоловіка. Клонуй проєкт собі, і давай дивитися, що в ньому є.

Якщо не знайомий з Jira, ось коротке ознайомче відео за темою

Технології

  • Spring Boot
  • Spring JPA
  • Hibernate
  • PostgreSQL
  • Liquibase (система управління версіями БД, в основному, її структурою)
  • Spring Security
  • Spring MVC
  • Thymeleaf
  • jQuery
  • Swagger (документування API)
  • Caffeine (кеш)
  • Lombok
  • Mapstruct (мапери для перетворення між entity & DTO)
  • Spring Test
  • JUnit
  • Docker [1], [2]

Структура БД

Як запустити програму:

  1. Клонувати собі на машину проєкт.
  2. Запустити локально сервер БД (PostgreSQL). Рекомендую це робити через docker.

    Зробимо 2 контейнери з БД. Перший — для запуску програми (профіль prod), другий — для білда та тестів (профіль test). Відповідні команди:

                docker run -p 5432:5432 --name postgres-db -e POSTGRES_USER=jira -e POSTGRES_PASSWORD=JiraRush -e 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 =jira-test -e PGDATA=/var/lib/postgresql/data/pgdata -v ./pgdata-test:/var/lib/postgresql/data -d postgres
  3. Сбилдить mvn clean install
  4. Запустити Spring Boot програму (JiraRushApplication) з профілем prod

Під час білда програми станеться наповнення тестової БД. Під час запуску програми відбудеться наповнення БД до роботи. Якщо точніше — накотиться структура та словники. Щоб «подивитися» як працює програма потрібно виконати скрипт data.sql з resources/data4dev.

Тепер можемо подивитися структуру БД:

activity — таблиця активностей, в якій зберігаються дії користувачів щодо інших сутностей. Наприклад, «користувач написав коментар», «користувач змінив статус завдання» …

attachment — таблиця для зберігання інформації про прикріплені файли.

contact — словник «користувач – тип контакту – значення контакту».

mail_case — таблиця куди зберігаються дані, якщо не вдалося відправити лист (email).

profile — профіль користувача. Налаштування зберігаються у полі mail_notifications у вигляді бітових прапорів.

project — Проєкти. Найбільша логічна одиниця дошки завдань. Наприклад, якщо компанія має мікросервіси, де кожен мікросервіс веде команда, тоді для такого мікросервісу буде створено проєкт.

reference — таблиця різних сутностей за типами. ref_type відповідає Enum com.javarush.jira.ref.RefType. Колонка aux — значення для обчислення бітових прапорців.

task — завдання. Найбільш базовий логічний структурний елемент дошки завдань JiraRush.

task_tag — словник зв'язків «завдання-тег». В одному завдання може бути нуль або більше тегів.

user_belong — зв'язок користувача з сутностями типу «завдання», «спринт», «проект». user_role – словник зв'язків «користувач – роль». Один користувач може мати кілька ролей.

users список зареєстрованих користувачів. Колонки endpoint та startpoint відповідають за те, чи активний цей користувач, чи був активним, але зараз ні. У полі password на початку пароля у вигляді «{…}» зберігається метод шифрування (Spring Security, пам'ятаєш?).

Структура Entity

Цей пункт я залишу на самостійне ознайомлення

Дивимося API та/або інші контролери

До проєкту підключено Swagger, який відповідає за документування API. Щоб подивитися, при запущеному додатку зайди на http://localhost:8080/swagger-ui/index.html

Тут можна подивитися, які є контролери, які методи у цих контролерів, які очікуються дані на вхід, типи методів тощо. Також можна надсилати запит самому. Не зайвим буде авторизуватися від різних користувачів (тестові дані написані на UI-і) і дивитися, які права потрібні для виконання якогось методу.

Який сервіс за що відповідає

З цим пунктом тобі також доведеться знайомитися самостійно. Натомість розглянемо вже реалізований функціонал. Дивитися будемо від користувача за участю ADMIN, тому що він має найширші повноваження. Але тобі потрібно буде подивитися і від MANAGER, і від DEV.

  • Дерево проєктів. Є перелік проєктів. Адмін або Менеджер (дивись Enum Role) може займатися додаванням нових проєктів та підпроєктів. Проєкт має беклог (список завдань (таск), які потрібно зробити), і спринти. Також проєкт може мати підпроєкт. Завдання може ставитися до спринту безпосередньо, або через епік (велика група завдань). Дивись http://localhost:8080/view/tree
  • Дошка завдань (дешборд). Дивитись дешборд можна за яким проєктом. За проєктом буде показано активний (або останній) спринт. Завдання зі спринту розбиті за колонками. Кольори виділені ті, на які потрібно звернути увагу. Зміна статусів завдань здійснюється через натискання правою кнопкою миші (райт-клік) на завдання. Дивись http://localhost:8080/ui/dashboard
  •  : мінімальний набір статистик з завершених спринтів з можливістю вибору проекту та спринту. Дивись http://localhost:8080/ui/reports
  • Список користувачів. Список усіх зареєстрованих користувачів з можливістю пошуку, сортування, додавання, редагування та видалення. Сторінка http://localhost:8080/view/admin/users
  • Посилання — функціонал налаштування JiraRush (які поля доступні якомусь виду сутностей. Наприклад, які соцмережі показувати в контакті користувача, або які є пріоритети завдання). Дивись http://localhost:8080/ui/admin/references
  • Редагування профілю користувача (свого профілю).
  • Реєстрація нового користувача через email + password.
  • Реєстрація нового користувача через соціальні мережі (Google, GitLab, GitHub).
  • Надсилання листів на пошту при скиданні пароля.
  • Надсилання листів на пошту для її підтвердження.
  • Створення нового завдання в беклозі (з можливістю прикріплювати файли як вкладення).

Ще якась інформація про проєкт "з вуст в уста"

Структура проєкту зроблена на зразок проєкту Spring Modulith. Тобто є пакети internal, до яких не може звертатися код ззовні пакета верхнього рівня.

Це зроблено з "запасом на майбутнє", щоб можна було легко поділити сервер на мікросервіси. Принаймні, така була задумка архітектора, а реалізація може відрізнятися (так, так буває в реальних проєктах майже завжди). Статичні файли для фронту надсилаються через nginx сервер. Принаймні так має бути на "проді", але при локальному запуску все простіше.

PostgreSQL. Ти не писатимеш нативні запити. Потрібно використовувати запити на JPQL. З нового для тебе буде лише підключення до PostgreSQL, щоб дивитися структуру таблиці та їх дані. Рекомендую використовувати вкладку database IDEA.

Liquibase — це відкрита незалежна від БД бібліотека для відстеження, керування та застосування змін схеми бази даних. У проєкті він використовується для автоматичного виконання скрипту ініціалізації бази даних та заповнення її тестовими даними. Якщо ти змінюєш структуру таблиць, потрібно видалити 2 службові таблиці Liquibase (databasechangelog та databasechangeloglock). Після цього при наступному запуску програми Liquibase виконає заново скрипт ініціалізації БД. Тобі ніякі налаштування робити не потрібно, все працює з коробки.

Swagger — дозволяє через UI візуально дивитися, які методи є в контролерах програми та виконувати до них тестові запити. Завдань щодо Swagger не буде. Він доданий для зручності роботи над проєктом.

Caffeine cache — це високопродуктивна бібліотека кеша для Java. Рекомендую подивитися, як він підключається. Завдання на використання не буде.

Твої завдання на вибір

Почни з легких завдань і тільки потім приступай до інших. Постарайся виконати якнайбільше завдань.

  1. Розібратися зі структурою проєкту (onboarding).
  2. Видалити соціальні мережі: vk, yandex. Easy task
  3. Винести чутливу інформацію до окремого проперті файлу:
    • логін
    • пароль БД
    • ідентифікатори для OAuth реєстрації/авторизації
    • налаштування пошти
    Значення цих проперті повинні зчитуватися при старті сервера зі змінних оточення машини. Easy task
  4. Переробити тести так, щоб під час тестів використовувалася in memory БД (H2), а не PostgreSQL. Для цього потрібно визначити 2 біна, і вибірка якої використовувати повинна визначатися активним профілем Spring. H2 не підтримує всі фічі, які є у PostgreSQL, тому тобі доведеться трохи спростити скрипти з тестовими даними.
  5. Написати тести для всіх публічних методів контролера ProfileRestController. Хоча методів лише 2, але тестових методів має бути більше, оскільки необхідно перевірити success and unsuccess path.
  6. Зробити рефакторинг методу com.javarush.jira.bugtracking.attachment.FileUtil#upload, щоб він використовував сучасний підхід для роботи з файловою системою. Easy task
  7. Додати новий функціонал: додавання тегів до завдання (REST API + реалізація на сервісі). Фронт робити необов'язково. Таблиця task_tag вже створена.
  8. Додати підрахунок часу: скільки завдання перебувало у роботі та тестуванні. Написати 2 методи на рівні сервісу, які параметром приймають завдання та повертають витрачений час:
    • Скільки завдання перебувало в роботі (ready_for_review мінус in_progress).
    • Скільки завдання перебувало на тестуванні (done мінус ready_for_review) .
    Для написання цього завдання, потрібно додати в кінець скрипту ініціалізації бази даних changelog.sql 3 записи до таблиці ACTIVITY
     insert into ACTIVITY ( ID, AUTHOR_ID, TASK_ID, UPDATED, STATUS_CODE ) values ... 
    Зі статусами:
    • час початку роботи над завданням — in_progress
    • час закінчення розробки — ready_for_review
    • час закінчення тестування — done
  9. Написати Dockerfile для основного сервера
  10. Написати docker-compose файл для запуску контейнера сервера разом з БД та nginx. Для nginx використовуй конфіг-файл config/nginx.conf. За потреби файл конфіга можна редагувати. Hard task
  11. Додати локалізацію мінімум двома мовами для шаблонів листів (mails) та стартовою сторінки index.html.
  12. Переробити механізм розпізнавання «свій-чужий» між фронтом і беком з JSESSIONID на JWT. Extra-hard task

При здачі проєкту в README.md напиши, які пункти завдання ти виконав.