diff --git a/.gitignore b/.gitignore
index cd38e2e7b..7f9709787 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,5 +5,6 @@ target
logs
attachments
*.patch
+.env
diff --git a/compose.yaml b/compose.yaml
new file mode 100644
index 000000000..d52c3716b
--- /dev/null
+++ b/compose.yaml
@@ -0,0 +1,14 @@
+
+services:
+ postgres-db:
+ image: postgres
+ container_name: postgres-db
+ ports:
+ - "5432:5432"
+ environment:
+ POSTGRES_USER: jira
+ POSTGRES_PASSWORD: JiraRush
+ PGDATA: /var/lib/postgresql/data/pgdata
+ volumes:
+ - ./pgdata:/var/lib/postgresql/data
+ restart: unless-stopped
\ No newline at end of file
diff --git a/config/nginx.conf b/config/nginx.conf
index 82b9e234d..024e03cf5 100644
--- a/config/nginx.conf
+++ b/config/nginx.conf
@@ -1,4 +1,4 @@
-# https://losst.ru/ustanovka-nginx-ubuntu-16-04
+
# https://pai-bx.com/wiki/nginx/2332-useful-redirects-in-nginx/#1
# sudo iptables -A INPUT ! -s 127.0.0.1 -p tcp -m tcp --dport 8080 -j DROP
server {
diff --git a/pom.xml b/pom.xml
index f6c152c68..753fe8cdb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,12 +97,15 @@
org.projectlombok
lombok
true
+ 1.18.30
+
org.mapstruct
mapstruct
${mapstruct.version}
+
org.springframework.boot
spring-boot-configuration-processor
@@ -142,10 +145,37 @@
junit-platform-launcher
test
+
+
+ me.paulschwarz
+ spring-dotenv
+ 4.0.0
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.6.0.Beta1
+
+
+
+
+
org.springframework.boot
spring-boot-maven-plugin
diff --git a/resources/static/fontawesome/css/all.css b/resources/static/fontawesome/css/all.css
index af5980828..6a347647c 100644
--- a/resources/static/fontawesome/css/all.css
+++ b/resources/static/fontawesome/css/all.css
@@ -8603,9 +8603,7 @@ readers do not read off random characters that represent icons */
content: "\f3e8";
}
-.fa-vk:before {
- content: "\f189";
-}
+
.fa-untappd:before {
content: "\f405";
@@ -9955,9 +9953,7 @@ readers do not read off random characters that represent icons */
content: "\f3bc";
}
-.fa-yandex:before {
- content: "\f413";
-}
+
.fa-readme:before {
content: "\f4d5";
@@ -10183,9 +10179,7 @@ readers do not read off random characters that represent icons */
content: "\f7c6";
}
-.fa-yandex-international:before {
- content: "\f414";
-}
+
.fa-cc-amex:before {
content: "\f1f3";
diff --git a/resources/view/login.html b/resources/view/login.html
index 8765ca8ff..d49ce5691 100644
--- a/resources/view/login.html
+++ b/resources/view/login.html
@@ -48,14 +48,6 @@ Sign in
type="button">
-
-
-
-
-
-
diff --git a/resources/view/unauth/register.html b/resources/view/unauth/register.html
index 2ba955045..52a892bd3 100644
--- a/resources/view/unauth/register.html
+++ b/resources/view/unauth/register.html
@@ -77,14 +77,6 @@ Registration
type="button">
-
-
-
-
-
-
diff --git a/src/main/java/com/javarush/jira/bugtracking/attachment/AttachmentController.java b/src/main/java/com/javarush/jira/bugtracking/attachment/AttachmentController.java
index 2ddd79591..1cc1f7b5f 100644
--- a/src/main/java/com/javarush/jira/bugtracking/attachment/AttachmentController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/attachment/AttachmentController.java
@@ -2,6 +2,7 @@
import com.javarush.jira.bugtracking.ObjectType;
import com.javarush.jira.login.AuthUser;
+import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
@@ -27,6 +28,10 @@ public class AttachmentController {
@Transactional
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ @Operation(
+ summary = "Завантажити файл вкладення",
+ description = "Додає нове вкладення до об'єкта певного типу (наприклад, задачі чи проєкту) та зберігає його у файловій системі"
+ )
public ResponseEntity upload(@RequestPart MultipartFile file, @RequestParam ObjectType type,
@RequestParam Long objectId, @AuthenticationPrincipal AuthUser authUser) {
log.debug("upload file {} to folder {}", file.getOriginalFilename(), type.toString().toLowerCase());
@@ -41,6 +46,10 @@ public ResponseEntity upload(@RequestPart MultipartFile file, @Reque
@DeleteMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Видалити файл вкладення",
+ description = "Видаляє вкладення з бази даних та фізично з файлової системи за ID"
+ )
public void delete(@PathVariable Long id) {
log.debug("delete file id = {}", id);
Attachment attachment = repository.getExisted(id);
@@ -49,6 +58,10 @@ public void delete(@PathVariable Long id) {
}
@GetMapping(value = "/download/{id}", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+ @Operation(
+ summary = "Завантажити файл вкладення",
+ description = "Повертає файл вкладення як ресурс для завантаження за його ID"
+ )
public ResponseEntity download(@PathVariable long id) {
log.debug("download file id = {}", id);
Attachment attachment = repository.getExisted(id);
@@ -59,12 +72,20 @@ public ResponseEntity download(@PathVariable long id) {
}
@GetMapping("/for-object")
+ @Operation(
+ summary = "Отримати всі вкладення для об'єкта",
+ description = "Повертає список усіх вкладень, прикріплених до вказаного об'єкта певного типу (за objectId та типом)"
+ )
public List getAllForObject(@RequestParam long objectId, @RequestParam ObjectType type) {
log.info("get all attachment by objectId = {}", objectId);
return repository.getAllForObject(objectId, type);
}
@GetMapping
+ @Operation(
+ summary = "Отримати всі вкладення",
+ description = "Повертає повний список всіх вкладень, збережених у системі"
+ )
public List getAll() {
log.info("get all attachment");
return repository.findAll();
diff --git a/src/main/java/com/javarush/jira/bugtracking/attachment/FileUtil.java b/src/main/java/com/javarush/jira/bugtracking/attachment/FileUtil.java
index 6cffbe175..dd9f42664 100644
--- a/src/main/java/com/javarush/jira/bugtracking/attachment/FileUtil.java
+++ b/src/main/java/com/javarush/jira/bugtracking/attachment/FileUtil.java
@@ -25,14 +25,15 @@ public static void upload(MultipartFile multipartFile, String directoryPath, Str
throw new IllegalRequestDataException("Select a file to upload.");
}
- File dir = new File(directoryPath);
- if (dir.exists() || dir.mkdirs()) {
- File file = new File(directoryPath + fileName);
- try (OutputStream outStream = new FileOutputStream(file)) {
- outStream.write(multipartFile.getBytes());
- } catch (IOException ex) {
- throw new IllegalRequestDataException("Failed to upload file" + multipartFile.getOriginalFilename());
- }
+ try {
+ Path dirPath = Paths.get(directoryPath);
+ Files.createDirectories(dirPath);
+
+ Path filePath = dirPath.resolve(fileName);
+ Files.write(filePath, multipartFile.getBytes());
+
+ } catch (IOException ex) {
+ throw new IllegalRequestDataException("Failed to upload file " + multipartFile.getOriginalFilename());
}
}
diff --git a/src/main/java/com/javarush/jira/bugtracking/project/ProjectController.java b/src/main/java/com/javarush/jira/bugtracking/project/ProjectController.java
index 5ebd02ee3..4dc4cf1d6 100644
--- a/src/main/java/com/javarush/jira/bugtracking/project/ProjectController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/project/ProjectController.java
@@ -2,6 +2,7 @@
import com.javarush.jira.bugtracking.Handlers;
import com.javarush.jira.bugtracking.project.to.ProjectTo;
+import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
@@ -22,16 +23,29 @@ public class ProjectController {
private final Handlers.ProjectHandler handler;
@GetMapping("/projects")
+ @Operation(
+ summary = "Отримати список усіх проєктів",
+ description = "Повертає список усіх проєктів у порядку від найновіших до найстаріших"
+ )
+
public List getAll() {
return handler.getAllTos(ProjectRepository.NEWEST_FIRST);
}
@GetMapping("/projects/{id}")
+ @Operation(
+ summary = "Отримати проєкт за ID",
+ description = "Повертає повну інформацію про проєкт із зазначеним ID"
+ )
public ProjectTo getById(@PathVariable Long id) {
return handler.getTo(id);
}
@PostMapping(path = "/mngr/projects", consumes = MediaType.APPLICATION_JSON_VALUE)
+ @Operation(
+ summary = "Створити новий проєкт",
+ description = "Створює новий проєкт на основі переданих даних"
+ )
public ResponseEntity create(@Valid @RequestBody ProjectTo projectTo) {
Project created = handler.createWithBelong(projectTo, PROJECT, "project_author");
return createdResponse(REST_URL + "/projects", created);
@@ -39,12 +53,20 @@ public ResponseEntity create(@Valid @RequestBody ProjectTo projectTo) {
@PutMapping("/mngr/projects/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Оновити проєкт",
+ description = "Оновлює існуючий проєкт за його ID"
+ )
public void update(@Valid @RequestBody ProjectTo projectTo, @PathVariable Long id) {
handler.updateFromTo(projectTo, id);
}
@PatchMapping("/mngr/projects/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Увімкнути/вимкнути проєкт",
+ description = "Змінює статус активності проєкту: enabled = true/false"
+ )
public void enable(@PathVariable long id, @RequestParam boolean enabled) {
handler.enable(id, enabled);
}
diff --git a/src/main/java/com/javarush/jira/bugtracking/report/ReportRestController.java b/src/main/java/com/javarush/jira/bugtracking/report/ReportRestController.java
index a2b221d95..40cfa9c62 100644
--- a/src/main/java/com/javarush/jira/bugtracking/report/ReportRestController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/report/ReportRestController.java
@@ -1,5 +1,6 @@
package com.javarush.jira.bugtracking.report;
+import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
@@ -20,6 +21,10 @@ public class ReportRestController {
private final ReportRepository reportRepository;
@GetMapping
+ @Operation(
+ summary = "Отримати звіт по задачах спринту",
+ description = "Повертає список зведеної інформації про задачі у межах вказаного спринту, включаючи кількість, статуси та інші ключові метрики"
+ )
public List getTaskSummaries(@PathVariable long sprintId) {
log.info("get task summaries for sprint with id={}", sprintId);
return reportRepository.getTaskSummaries(sprintId);
diff --git a/src/main/java/com/javarush/jira/bugtracking/sprint/SprintController.java b/src/main/java/com/javarush/jira/bugtracking/sprint/SprintController.java
index 67611735f..c55ca2f8b 100644
--- a/src/main/java/com/javarush/jira/bugtracking/sprint/SprintController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/sprint/SprintController.java
@@ -3,6 +3,7 @@
import com.javarush.jira.bugtracking.Handlers;
import com.javarush.jira.bugtracking.project.ProjectRepository;
import com.javarush.jira.bugtracking.sprint.to.SprintTo;
+import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
@@ -32,11 +33,19 @@ public class SprintController {
private final Handlers.SprintHandler handler;
@GetMapping("/sprints/{id}")
+ @Operation(
+ summary = "Отримати спринт за ID",
+ description = "Повертає повну інформацію про спринт із зазначеним ID"
+ )
public SprintTo get(@PathVariable long id) {
return handler.getTo(id);
}
@GetMapping("/sprints/by-project")
+ @Operation(
+ summary = "Отримати спринти за проєктом",
+ description = "Повертає список усіх спринтів для проєкту. Якщо enabled=true, то тільки активні"
+ )
public List getAllByProject(@RequestParam long projectId, @RequestParam @Nullable Boolean enabled) {
log.info("get all for project {} and enabled {}", projectId, enabled);
checkProjectExists(projectId);
@@ -52,6 +61,10 @@ private void checkProjectExists(long id) {
}
@GetMapping("/sprints/by-project-and-status")
+ @Operation(
+ summary = "Отримати спринти за статусом",
+ description = "Повертає спринти проєкту з певним статусом (наприклад: active, done)"
+ )
public List getAllByProjectAndStatus(@RequestParam long projectId, @NotBlank @RequestParam String statusCode) {
log.info("get all {} sprints for project with id={}", statusCode, projectId);
checkProjectExists(projectId);
@@ -60,6 +73,10 @@ public List getAllByProjectAndStatus(@RequestParam long projectId, @NotB
@PostMapping(path = "/mngr/sprints", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
+ @Operation(
+ summary = "Створити спринт",
+ description = "Створює новий спринт у вказаному проєкті"
+ )
public ResponseEntity createWithLocation(@Valid @RequestBody SprintTo sprintTo) {
Sprint created = handler.createWithBelong(sprintTo, SPRINT, "sprint_author");
return createdResponse(REST_URL + "/sprints", created);
@@ -67,6 +84,10 @@ public ResponseEntity createWithLocation(@Valid @RequestBody SprintTo sp
@PutMapping(path = "/mngr/sprints/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Оновити спринт",
+ description = "Оновлює існуючий спринт за його ID"
+ )
public void update(@Validated @RequestBody SprintTo sprintTo, @PathVariable long id) {
handler.updateFromTo(sprintTo, id);
}
@@ -74,6 +95,10 @@ public void update(@Validated @RequestBody SprintTo sprintTo, @PathVariable long
@Transactional
@PatchMapping("/mngr/sprints/{id}/change-status")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Змінити статус спринта",
+ description = "Змінює статус спринта (наприклад, з active на done)"
+ )
public void changeStatusCode(@PathVariable long id, @RequestParam String statusCode) {
log.info("change statusCode of sprint {}", id);
Sprint sprint = handler.getRepository().getExisted(id);
@@ -82,6 +107,10 @@ public void changeStatusCode(@PathVariable long id, @RequestParam String statusC
@PatchMapping("/mngr/sprints/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Активувати/деактивувати спринт",
+ description = "Вмикає або вимикає спринт (enabled = true/false)"
+ )
public void enable(@PathVariable long id, @RequestParam boolean enabled) {
handler.enable(id, enabled);
}
diff --git a/src/main/java/com/javarush/jira/bugtracking/task/TaskController.java b/src/main/java/com/javarush/jira/bugtracking/task/TaskController.java
index b53f7ff37..ce248628f 100644
--- a/src/main/java/com/javarush/jira/bugtracking/task/TaskController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/task/TaskController.java
@@ -10,6 +10,7 @@
import com.javarush.jira.bugtracking.tree.ITreeNode;
import com.javarush.jira.common.util.Util;
import com.javarush.jira.login.AuthUser;
+import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Nullable;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
@@ -42,12 +43,20 @@ public class TaskController {
@GetMapping("/{id}")
+ @Operation(
+ summary = "Отримати задачу за ID",
+ description = "Повертає повну інформацію про задачу з вказаним ID"
+ )
public TaskToFull get(@PathVariable long id) {
log.info("get task by id={}", id);
return taskService.get(id);
}
@GetMapping("/by-sprint")
+ @Operation(
+ summary = "Отримати задачі по спринту",
+ description = "Повертає всі задачі, що належать до вказаного спринту"
+ )
public List getAllBySprint(@RequestParam long sprintId) {
log.info("get all for sprint {}", sprintId);
return sortTasksAsTree(handler.getMapper().toToList(handler.getRepository().findAllBySprintId(sprintId)));
@@ -70,6 +79,10 @@ private List sortTasksAsTree(List tasks) {
}
@GetMapping("/by-project")
+ @Operation(
+ summary = "Отримати задачі по проєкту",
+ description = "Повертає всі задачі, що належать до вказаного проєкту"
+ )
public List getAllByProject(@RequestParam long projectId) {
log.info("get all for project {}", projectId);
return handler.getMapper().toToList(handler.getRepository().findAllByProjectId(projectId));
@@ -77,24 +90,40 @@ public List getAllByProject(@RequestParam long projectId) {
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
+ @Operation(
+ summary = "Створити нову задачу",
+ description = "Створює нову задачу на основі переданих даних"
+ )
public ResponseEntity createWithLocation(@Valid @RequestBody TaskToExt taskTo) {
return createdResponse(REST_URL, taskService.create(taskTo));
}
@PutMapping(path = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Оновити задачу",
+ description = "Оновлює існуючу задачу за її ID"
+ )
public void update(@Valid @RequestBody TaskToExt taskTo, @PathVariable long id) {
taskService.update(taskTo, id);
}
@PatchMapping("/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Активувати/деактивувати задачу",
+ description = "Встановлює статус 'enabled' для задачі"
+ )
public void enable(@PathVariable long id, @RequestParam boolean enabled) {
handler.enable(id, enabled);
}
@PatchMapping("/{id}/change-status")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Змінити статус задачі",
+ description = "Змінює статус задачі за допомогою коду статусу"
+ )
public void changeTaskStatus(@PathVariable long id, @NotBlank @RequestParam String statusCode) {
log.info("change task(id={}) status to {}", id, statusCode);
taskService.changeStatus(id, statusCode);
@@ -102,12 +131,20 @@ public void changeTaskStatus(@PathVariable long id, @NotBlank @RequestParam Stri
@PatchMapping("/{id}/change-sprint")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Змінити спринт задачі",
+ description = "Прив'язує або відв'язує задачу від конкретного спринту"
+ )
public void changeTaskSprint(@PathVariable long id, @Nullable @RequestParam Long sprintId) {
log.info("change task(id={}) sprint to {}", id, sprintId);
taskService.changeSprint(id, sprintId);
}
@GetMapping("/assignments/by-sprint")
+ @Operation(
+ summary = "Отримати призначення задач по спринту",
+ description = "Повертає список користувацьких призначень для задач у заданому спринті"
+ )
public List getTaskAssignmentsBySprint(@RequestParam long sprintId) {
log.info("get task assignments for user {} for sprint {}", AuthUser.authId(), sprintId);
return userBelongRepository.findActiveTaskAssignmentsForUserBySprint(AuthUser.authId(), sprintId);
@@ -115,6 +152,10 @@ public List getTaskAssignmentsBySprint(@RequestParam long sprintId)
@PatchMapping("/{id}/assign")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Призначити користувача до задачі",
+ description = "Призначає поточного користувача до задачі з вказаним типом ролі"
+ )
public void assign(@PathVariable long id, @NotBlank @RequestParam String userType) {
log.info("assign user {} as {} to task {}", AuthUser.authId(), userType, id);
taskService.assign(id, userType, AuthUser.authId());
@@ -122,12 +163,20 @@ public void assign(@PathVariable long id, @NotBlank @RequestParam String userTyp
@PatchMapping("/{id}/unassign")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Видалити призначення користувача",
+ description = "Видаляє призначення користувача з задачі"
+ )
public void unAssign(@PathVariable long id, @NotBlank @RequestParam String userType) {
log.info("unassign user {} as {} from task {}", AuthUser.authId(), userType, id);
taskService.unAssign(id, userType, AuthUser.authId());
}
@GetMapping("/{id}/comments")
+ @Operation(
+ summary = "Отримати коментарі до задачі",
+ description = "Повертає список коментарів, пов'язаних із задачою"
+ )
public List getComments(@PathVariable long id) {
log.info("get comments for task with id={}", id);
return activityHandler.getMapper().toToList(activityHandler.getRepository().findAllComments(id));
@@ -135,18 +184,30 @@ public List getComments(@PathVariable long id) {
@PostMapping(value = "/activities", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.CREATED)
+ @Operation(
+ summary = "Створити активність",
+ description = "Додає нову активність або коментар до задачі"
+ )
public Activity create(@Valid @RequestBody ActivityTo activityTo) {
return activityService.create(activityTo);
}
@PutMapping(path = "/activities/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Оновити активність",
+ description = "Оновлює існуючу активність (наприклад, коментар)"
+ )
public void update(@Valid @RequestBody ActivityTo activityTo, @PathVariable long id) {
activityService.update(activityTo, id);
}
@DeleteMapping("/activities/{id}")
@ResponseStatus(HttpStatus.NO_CONTENT)
+ @Operation(
+ summary = "Видалити активність",
+ description = "Видаляє активність або коментар за ID"
+ )
public void delete(@PathVariable long id) {
activityService.delete(id);
}
diff --git a/src/main/java/com/javarush/jira/bugtracking/tree/TreeRestController.java b/src/main/java/com/javarush/jira/bugtracking/tree/TreeRestController.java
index a3a7da4ec..ea4ba98cf 100644
--- a/src/main/java/com/javarush/jira/bugtracking/tree/TreeRestController.java
+++ b/src/main/java/com/javarush/jira/bugtracking/tree/TreeRestController.java
@@ -9,6 +9,7 @@
import com.javarush.jira.bugtracking.task.TaskRepository;
import com.javarush.jira.bugtracking.task.mapper.TaskMapper;
import com.javarush.jira.common.util.Util;
+import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
@@ -44,12 +45,20 @@ private static List toTree(List list, Function mappe
}
@GetMapping("/projects")
+ @Operation(
+ summary = "Отримати дерево проєктів",
+ description = "Повертає всі проєкти у вигляді ієрархічного дерева NodeTo"
+ )
public List getProjects() {
log.info("get projects tree");
return toTree(projectMapper.toToList(projectRepository.getAll()), mapper::fromProject);
}
@GetMapping("/projects/{projectId}/sprints")
+ @Operation(
+ summary = "Отримати спринти проєкту та беклог",
+ description = "Повертає список спринтів проєкту у вигляді дерева, включаючи окремий вузол 'Backlog'"
+ )
public List getSprintsAndBacklog(@PathVariable long projectId) {
log.info("get project {} sprints", projectId);
List sprintTos = new ArrayList<>(sprintMapper.toToList(sprintRepository.getAllByProject(projectId)));
@@ -58,12 +67,20 @@ public List getSprintsAndBacklog(@PathVariable long projectId) {
}
@GetMapping("/sprints/{sprintId}/tasks")
+ @Operation(
+ summary = "Отримати задачі для спринту",
+ description = "Повертає задачі, прикріплені до певного спринту, у вигляді дерева"
+ )
public List getSprintTasks(@PathVariable long sprintId) {
log.info("get sprint {} tasks", sprintId);
return toTree(taskMapper.toToList(taskRepository.findAllBySprintId(sprintId)), mapper::fromTask);
}
@GetMapping("/projects/{projectId}/backlog/tasks")
+ @Operation(
+ summary = "Отримати задачі беклогу проєкту",
+ description = "Повертає задачі проєкту, які ще не додані до жодного спринту, у вигляді дерева"
+ )
public List getBacklogTasks(@PathVariable long projectId) {
log.info("get project {} backlog tasks", projectId);
return toTree(taskMapper.toToList(taskRepository.findAllByProjectIdAndSprintIsNull(projectId)), mapper::fromTask);
diff --git a/src/main/java/com/javarush/jira/login/internal/sociallogin/handler/VkOAuth2UserDataHandler.java b/src/main/java/com/javarush/jira/login/internal/sociallogin/handler/VkOAuth2UserDataHandler.java
deleted file mode 100644
index e8e05be05..000000000
--- a/src/main/java/com/javarush/jira/login/internal/sociallogin/handler/VkOAuth2UserDataHandler.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.javarush.jira.login.internal.sociallogin.handler;
-
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-import java.util.Map;
-
-@Component("vk")
-public class VkOAuth2UserDataHandler implements OAuth2UserDataHandler {
- @Override
- public String getFirstName(OAuth2UserData oAuth2UserData) {
- return getAttribute(oAuth2UserData, "first_name");
- }
-
- @Override
- public String getLastName(OAuth2UserData oAuth2UserData) {
- return getAttribute(oAuth2UserData, "last_name");
- }
-
- @Override
- public String getEmail(OAuth2UserData oAuth2UserData) {
- return oAuth2UserData.getData("email");
- }
-
- private String getAttribute(OAuth2UserData oAuth2UserData, String name) {
- List