From 11b8f6aa820b733f68d4f12498274fa0e1555dae Mon Sep 17 00:00:00 2001 From: Anton Dzyk Date: Fri, 9 Jan 2026 17:17:29 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=B4=D0=BE=D0=B2=D0=BE=D0=B9?= =?UTF-8?q?=20=D0=B1=D0=B0=D0=B7=D1=8B,=20=D0=BF=D0=BE=D1=81=D0=BB=D0=B5?= =?UTF-8?q?=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=81=D1=85=D0=B5=D0=BC=D1=8B=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/schema-database.puml | 137 ++++++++++++++++++ docs/schema-db-2.puml | 120 +++++++++++++++ docs/schema-db.puml | 44 ++++++ .../controller/TaskController.java | 2 + .../repository/LMSContentRepository.java | 2 +- .../repository/TaskQueueRepository.java | 9 -- .../repository/entities/History.java | 31 ++++ .../repository/entities/LMSContent.java | 30 ++-- .../repository/entities/Task.java | 25 ++-- .../repository/entities/TaskQueue.java | 29 ---- .../infrastructure/runner/Runner.java | 2 + .../infrastructure/runner/RunnerImpl.java | 6 + .../service/task/TaskServiceImpl.java | 48 ++++-- .../oa2/lti/domain/model/task/TaskData.java | 2 + ...task_queue.xml => 2025-12-add_history.xml} | 28 ++-- .../1.0.0/2025-12-add_lms_content.xml | 22 ++- .../db/changelog/1.0.0/2025-12-add_task.xml | 14 +- .../db/changelog/changelog-master.xml | 2 +- 18 files changed, 457 insertions(+), 96 deletions(-) create mode 100644 docs/schema-database.puml create mode 100644 docs/schema-db-2.puml create mode 100644 docs/schema-db.puml delete mode 100644 src/main/java/ru/oa2/lti/application/infrastructure/repository/TaskQueueRepository.java create mode 100644 src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/History.java delete mode 100644 src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/TaskQueue.java rename src/main/resources/db/changelog/1.0.0/{2025-12-add_task_queue.xml => 2025-12-add_history.xml} (51%) diff --git a/docs/schema-database.puml b/docs/schema-database.puml new file mode 100644 index 0000000..d057734 --- /dev/null +++ b/docs/schema-database.puml @@ -0,0 +1,137 @@ +@startuml PostgreSQL Database Schema + +!define PRIMARY_KEY(x) <&key> x +!define FOREIGN_KEY(x) <&link-intact> x +!define COLUMN(x) x +!define INDEX(x) <&magnifying-glass> x + +scale 1024 width + +skinparam linetype ortho +skinparam roundcorner 10 +skinparam shadowing true + +skinparam entity { + BackgroundColor #FFFEF0 + BorderColor #2F4F4F + ArrowColor #2F4F4F + FontColor #333333 + FontSize 12 + AttributeFontSize 11 +} + +skinparam note { + BackgroundColor #FFFFCC + BorderColor #999999 +} + +package "External Tool schema" { + + entity "**history**" as history { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты .. + COLUMN(deployment_id) : uuid [NOT NULL] + COLUMN(content_uuid) : uuid [NOT NULL] + COLUMN(created) : timestamp [NOT NULL] + COLUMN(message) : varchar(2048) [NOT NULL] + ---- + .. Ограничения .. + <&check> pk_history (PRIMARY KEY) + } + + entity "**lms_content**" as lms_content { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты .. + COLUMN(deployment_id) : uuid [NOT NULL] + INDEX(content_uuid) : uuid [NOT NULL] + COLUMN(created) : timestamp [NOT NULL] + FOREIGN_KEY(task_id) : int8 [NOT NULL] + ---- + .. Ограничения .. + <&check> pk_lms_content (PRIMARY KEY) + <&link-intact> fk_lms_content_task (FOREIGN KEY) + ---- + .. Индексы .. + <&list> idx_content_uuid (content_uuid) + } + + entity "**task**" as task { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты (обязательные) .. + COLUMN(name) : varchar(250) [NOT NULL] + COLUMN(description) : text [NOT NULL] + ---- + .. Атрибуты (опциональные) .. + COLUMN(init_script) : text [NULL] + COLUMN(verification_script) : text [NULL] + COLUMN(delete_script) : text [NULL] + ---- + .. Ограничения .. + <&check> pk_task (PRIMARY KEY) + } + +} + +' === СВЯЗИ === +lms_content }o--|| task : " fk_lms_content_task\n (task_id → id) " + +' === ЛОГИЧЕСКИЕ СВЯЗИ (пунктиром) === +history ..> lms_content : " content_uuid, deployment_id " + +' === ПРИМЕЧАНИЯ === +note right of history + **Таблица истории** + ════════════════════ + Хранит историю изменений + и событий в системе. + + Назначение полей: + • deployment_id - ID развёртывания + • content_uuid - UUID контента + • created - время создания + • message - текст сообщения + + ✓ Все поля обязательные + ⚠ Нет явных FK связей +end note + +note left of task + **Таблица лабораторных работ** + ════════════════════ + Хранит определения задач + для системы обучения. + + Обязательные поля: + • name - название задачи + • description - описание + + Скрипты (опциональные): + • init_script - инициализация + • verification_script - проверка + • delete_script - очистка +end note + +note left of lms_content + **Связь контента LMS с Task** + ════════════════════ + Связь контента из LMS с + лабораторными работами в + External Tool + + Индексы: + • idx_content_uuid для + быстрого поиска по UUID + + Связи: + • task_id → task.id (N:1) + + ✓ Все поля обязательные +end note + +@enduml \ No newline at end of file diff --git a/docs/schema-db-2.puml b/docs/schema-db-2.puml new file mode 100644 index 0000000..058775c --- /dev/null +++ b/docs/schema-db-2.puml @@ -0,0 +1,120 @@ +@startuml PostgreSQL Database Schema + +!define PRIMARY_KEY(x) <&key> x +!define FOREIGN_KEY(x) <&link-intact> x +!define COLUMN(x) x +!define INDEX(x) <&magnifying-glass> x + +scale 1024 width + +skinparam linetype ortho +skinparam roundcorner 10 +skinparam shadowing true + +skinparam entity { + BackgroundColor #FFFEF0 + BorderColor #2F4F4F + ArrowColor #2F4F4F + FontColor #333333 + FontSize 12 + AttributeFontSize 11 +} + +skinparam note { + BackgroundColor #FFFFCC + BorderColor #999999 +} + +package "public schema" { + + entity "**history**" as history { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты .. + COLUMN(deployment_id) : uuid [NULL] + COLUMN(content_uuid) : uuid [NULL] + COLUMN(created) : timestamp [NULL] + COLUMN(message) : varchar(2048) [NULL] + ---- + .. Ограничения .. + <&check> pk_history (PRIMARY KEY) + } + + entity "**lms_content**" as lms_content { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты .. + COLUMN(deployment_id) : uuid [NULL] + INDEX(content_uuid) : uuid [NULL] + COLUMN(created) : timestamp [NULL] + FOREIGN_KEY(task_id) : int8 [NULL] + ---- + .. Ограничения .. + <&check> pk_lms_content (PRIMARY KEY) + <&link-intact> fk_lms_content_task (FOREIGN KEY) + ---- + .. Индексы .. + <&list> idx_content_uuid (content_uuid) + } + + entity "**task**" as task { + .. Первичный ключ .. + PRIMARY_KEY(id) : int8 <> + ---- + .. Атрибуты .. + COLUMN(data) : jsonb [NULL] + ---- + .. Ограничения .. + <&check> pk_task (PRIMARY KEY) + } + +} + +' === СВЯЗИ === +lms_content }o--|| task : " fk_lms_content_task\n (task_id → id) " + +' === ЛОГИЧЕСКИЕ СВЯЗИ (пунктиром) === +history ..> lms_content : " логическая связь\n по content_uuid " + +' === ПРИМЕЧАНИЯ === +note right of history + **Таблица истории** + ════════════════════ + Хранит историю изменений + и событий в системе. + + Назначение полей: + • deployment_id - ID развёртывания + • content_uuid - UUID контента + • message - текст сообщения + + ⚠ Нет явных FK связей +end note + +note bottom of task + **Таблица задач** + ════════════════════ + Хранит задачи в формате JSON. + + Поле data (jsonb): + Гибкая структура для хранения + произвольных данных задачи. +end note + +note left of lms_content + **Контент LMS** + ════════════════════ + Основная таблица контента + системы обучения. + + Индексы: + • idx_content_uuid для + быстрого поиска по UUID + + Связи: + • task_id → task.id (N:1) +end note + +@enduml \ No newline at end of file diff --git a/docs/schema-db.puml b/docs/schema-db.puml new file mode 100644 index 0000000..5b25991 --- /dev/null +++ b/docs/schema-db.puml @@ -0,0 +1,44 @@ +@startuml +!define table(x) entity x << (T,#FFAAAA) >> +!define pk(x) x +!define fk(x) x + +skinparam entity { + BackgroundColor #F5F5F5 + BorderColor #333333 +} + +table(history) { + pk(id) : int8 <> + -- + deployment_id : uuid + content_uuid : uuid + created : timestamp + message : varchar(2048) +} + +table(lms_content) { + pk(id) : int8 <> + -- + deployment_id : uuid + content_uuid : uuid <> + created : timestamp + fk(task_id) : int8 +} + +table(task) { + pk(id) : int8 <> + -- + data : jsonb +} + +lms_content }o--|| task : "task_id → id" + +note bottom of history + Нет явных FK связей, + но content_uuid может + логически связываться + с lms_content.content_uuid +end note + +@enduml \ No newline at end of file diff --git a/src/main/java/ru/oa2/lti/application/controller/TaskController.java b/src/main/java/ru/oa2/lti/application/controller/TaskController.java index 1210187..1362f07 100644 --- a/src/main/java/ru/oa2/lti/application/controller/TaskController.java +++ b/src/main/java/ru/oa2/lti/application/controller/TaskController.java @@ -52,11 +52,13 @@ public class TaskController { return "redirect:/error"; } + model.addAttribute("name", data.getName()); model.addAttribute("description", data.getDescription()); if (Objects.requireNonNull(payload).getCoach()) { model.addAttribute("initScript", data.getInitScript()); model.addAttribute("checkScript", data.getVerificationScript()); + model.addAttribute("deleteScript", data.getDeleteScript()); return "task-editor"; } diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/LMSContentRepository.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/LMSContentRepository.java index c309277..f8f70cd 100644 --- a/src/main/java/ru/oa2/lti/application/infrastructure/repository/LMSContentRepository.java +++ b/src/main/java/ru/oa2/lti/application/infrastructure/repository/LMSContentRepository.java @@ -10,5 +10,5 @@ import java.util.UUID; @Repository public interface LMSContentRepository extends JpaRepository { - Optional getLMSContentByContentId(UUID contentId); + Optional getLMSContentByContentUuid(UUID contentUuid); } diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/TaskQueueRepository.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/TaskQueueRepository.java deleted file mode 100644 index 2b9b572..0000000 --- a/src/main/java/ru/oa2/lti/application/infrastructure/repository/TaskQueueRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package ru.oa2.lti.application.infrastructure.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import ru.oa2.lti.application.infrastructure.repository.entities.TaskQueue; - -@Repository -public interface TaskQueueRepository extends JpaRepository { -} diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/History.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/History.java new file mode 100644 index 0000000..8a0fe48 --- /dev/null +++ b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/History.java @@ -0,0 +1,31 @@ +package ru.oa2.lti.application.infrastructure.repository.entities; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +import java.time.LocalDateTime; +import java.util.UUID; + +@Getter +@Setter +@Entity +@Table(name = "history") +public class History { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + long id; + + @Column(name = "deployment_id", nullable = false) + UUID deploymentId; + + @Column(name = "content_uuid", nullable = false) + UUID contentUuid; + + @Column(name = "created", nullable = false) + LocalDateTime created; + + @Column(name = "message", nullable = false, length = 2048) + String message; +} diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/LMSContent.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/LMSContent.java index cd3b7bb..ff9f663 100644 --- a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/LMSContent.java +++ b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/LMSContent.java @@ -2,28 +2,34 @@ package ru.oa2.lti.application.infrastructure.repository.entities; import jakarta.persistence.*; import lombok.Getter; +import lombok.Setter; -import java.util.Collection; +import java.time.LocalDateTime; import java.util.UUID; @Getter +@Setter @Entity -@Table(name = "lms_content") +@Table(name = "lms_content", +indexes = { + @Index(name = "idx_content_uuid", columnList = "content_uuid") +}) public class LMSContent { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) long id; - @Column(name = "content_key") - long contentKey; - - @Column(name = "content_uuid") - UUID contentId; - - @Column(name = "deployment_id") + @Column(name = "deployment_id", nullable = false) UUID deploymentId; - @OneToMany(mappedBy="id", fetch = FetchType.LAZY) - Collection tasks; + @Column(name = "content_uuid", nullable = false) + UUID contentUuid; + + @Column(name = "created", nullable = false) + LocalDateTime created; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "task_id", nullable = false, foreignKey = @ForeignKey(name = "fk_lms_content_task")) + Task task; } diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/Task.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/Task.java index 377d1ce..0920297 100644 --- a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/Task.java +++ b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/Task.java @@ -3,10 +3,6 @@ package ru.oa2.lti.application.infrastructure.repository.entities; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; -import ru.oa2.lti.domain.model.task.TaskData; -import ru.oa2.lti.domain.model.task.TaskType; @Getter @Setter @@ -15,14 +11,21 @@ import ru.oa2.lti.domain.model.task.TaskType; public class Task { @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) long id; - @Column(name = "task_type", length = 20) - @Enumerated(EnumType.STRING) - TaskType taskType; + @Column(name = "name", nullable = false, length = 250) + String name; - @JdbcTypeCode(SqlTypes.JSON) - @Column(name = "data", columnDefinition = "jsonb") - TaskData data; + @Column(name = "description", nullable = false, columnDefinition = "text") + String description; + + @Column(name = "init_script", columnDefinition = "text") + String initScript; + + @Column(name = "verification_script", columnDefinition = "text") + String verificationScript; + + @Column(name = "delete_script", columnDefinition = "text") + String deleteScript; } diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/TaskQueue.java b/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/TaskQueue.java deleted file mode 100644 index ceaac58..0000000 --- a/src/main/java/ru/oa2/lti/application/infrastructure/repository/entities/TaskQueue.java +++ /dev/null @@ -1,29 +0,0 @@ -package ru.oa2.lti.application.infrastructure.repository.entities; - -import jakarta.persistence.*; -import lombok.Getter; -import ru.oa2.lti.domain.model.task.TaskQueueStatus; - -@Getter -@Entity -@Table(name = "task_queue") -public class TaskQueue { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - Long id; - - @ManyToOne - @JoinColumn(name = "task_id", nullable = false) - Task taskId; - - @Column(name = "content", columnDefinition = "jsonb") - Object content; - - @Column(name = "status") - @Enumerated(EnumType.STRING) - TaskQueueStatus status; - - @Column(name = "finished") - Boolean finished; -} diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/runner/Runner.java b/src/main/java/ru/oa2/lti/application/infrastructure/runner/Runner.java index 9983e37..9972257 100644 --- a/src/main/java/ru/oa2/lti/application/infrastructure/runner/Runner.java +++ b/src/main/java/ru/oa2/lti/application/infrastructure/runner/Runner.java @@ -7,4 +7,6 @@ public interface Runner { boolean run(UUID userId, String script); boolean check(UUID userId, String script); + + boolean delete(UUID userId, String script); } diff --git a/src/main/java/ru/oa2/lti/application/infrastructure/runner/RunnerImpl.java b/src/main/java/ru/oa2/lti/application/infrastructure/runner/RunnerImpl.java index 0609b08..44fab8e 100644 --- a/src/main/java/ru/oa2/lti/application/infrastructure/runner/RunnerImpl.java +++ b/src/main/java/ru/oa2/lti/application/infrastructure/runner/RunnerImpl.java @@ -39,6 +39,12 @@ public class RunnerImpl implements Runner { } } + @Override + public boolean delete(UUID userId, String script) { + //TODO реализовать метод удаления сущностей + return false; + } + private boolean runScript(UUID userId, String script) throws Exception { var processBuilder = new ProcessBuilder(); diff --git a/src/main/java/ru/oa2/lti/application/service/task/TaskServiceImpl.java b/src/main/java/ru/oa2/lti/application/service/task/TaskServiceImpl.java index 245cbc0..40e6a4c 100644 --- a/src/main/java/ru/oa2/lti/application/service/task/TaskServiceImpl.java +++ b/src/main/java/ru/oa2/lti/application/service/task/TaskServiceImpl.java @@ -14,7 +14,6 @@ import ru.oa2.lti.domain.model.results.ResultResponse; import ru.oa2.lti.domain.model.task.RequestUpdateTask; import ru.oa2.lti.domain.model.task.TaskData; -import java.util.Collection; import java.util.UUID; @Slf4j @@ -42,23 +41,26 @@ public class TaskServiceImpl implements TaskService { @Override public TaskData getTask(UUID contextId) { - var content = lmsContentRepository.getLMSContentByContentId(contextId); + var content = lmsContentRepository.getLMSContentByContentUuid(contextId); if(content.isPresent()) { LMSContent lmsContent = content.get(); - Collection tasks = lmsContent.getTasks(); + Task task = lmsContent.getTask(); - //TODO добавить версию в Task и выбирать самую старшую и опубликованную - TaskData data = tasks.stream().findFirst().get().getData(); + if (task == null) { + return new TaskData("Not Page", "", "", "", ""); + } + + TaskData data = entityToTaskData(task); //TODO string -> exception? if (!runner.run(contextId, data.getInitScript())) { - return new TaskData("Init script FAILED", "", ""); + return new TaskData("Init script FAILED", "", "", "", ""); } return data; } else { - return new TaskData("Not Page", "", ""); + return new TaskData("Not Page", "", "", "", ""); } } @@ -78,18 +80,38 @@ public class TaskServiceImpl implements TaskService { public ResultResponse saveTask(RequestUpdateTask requestUpdateTask) { log.info("save"); - var result = lmsContentRepository.getLMSContentByContentId(requestUpdateTask.getContextId()); + var result = lmsContentRepository.getLMSContentByContentUuid(requestUpdateTask.getContextId()); //TODO доработать версионирование task-ов if (result.isPresent()) { - var content = result.get(); - var tasks = content.getTasks(); - var currentTask = tasks.stream().findFirst(); - currentTask.ifPresent(task -> task.setData(requestUpdateTask.getData())); - lmsContentRepository.save(content); + LMSContent content = result.get(); + Task task = content.getTask(); + + if (task != null) { + updateTaskFromData(task, requestUpdateTask.getData()); + lmsContentRepository.save(content); + } } //TODO обработка exception - failed / success return new ResultResponse("success"); } + + private TaskData entityToTaskData(Task task) { + return new TaskData( + task.getName(), + task.getDescription(), + task.getInitScript(), + task.getVerificationScript(), + task.getDeleteScript() + ); + } + + private void updateTaskFromData(Task task, TaskData data) { + task.setName(data.getName()); + task.setDescription(data.getDescription()); + task.setInitScript(data.getInitScript()); + task.setVerificationScript(data.getVerificationScript()); + task.setDeleteScript(data.getDeleteScript()); + } } diff --git a/src/main/java/ru/oa2/lti/domain/model/task/TaskData.java b/src/main/java/ru/oa2/lti/domain/model/task/TaskData.java index 7135db9..daeaf07 100644 --- a/src/main/java/ru/oa2/lti/domain/model/task/TaskData.java +++ b/src/main/java/ru/oa2/lti/domain/model/task/TaskData.java @@ -8,7 +8,9 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor public class TaskData { + String name; String description; String initScript; String verificationScript; + String deleteScript; } diff --git a/src/main/resources/db/changelog/1.0.0/2025-12-add_task_queue.xml b/src/main/resources/db/changelog/1.0.0/2025-12-add_history.xml similarity index 51% rename from src/main/resources/db/changelog/1.0.0/2025-12-add_task_queue.xml rename to src/main/resources/db/changelog/1.0.0/2025-12-add_history.xml index a87d55e..4cf23fe 100644 --- a/src/main/resources/db/changelog/1.0.0/2025-12-add_task_queue.xml +++ b/src/main/resources/db/changelog/1.0.0/2025-12-add_history.xml @@ -8,29 +8,29 @@ - + - + - + + + - + + + - + + + - + + + - - \ No newline at end of file diff --git a/src/main/resources/db/changelog/1.0.0/2025-12-add_lms_content.xml b/src/main/resources/db/changelog/1.0.0/2025-12-add_lms_content.xml index 70b82d7..a285b66 100644 --- a/src/main/resources/db/changelog/1.0.0/2025-12-add_lms_content.xml +++ b/src/main/resources/db/changelog/1.0.0/2025-12-add_lms_content.xml @@ -14,13 +14,21 @@ - + + + - + + + - + + + - + + + @@ -32,5 +40,11 @@ referencedColumnNames="id" onDelete="NO ACTION"/> + + + + \ No newline at end of file diff --git a/src/main/resources/db/changelog/1.0.0/2025-12-add_task.xml b/src/main/resources/db/changelog/1.0.0/2025-12-add_task.xml index efef0d5..dff1bd5 100644 --- a/src/main/resources/db/changelog/1.0.0/2025-12-add_task.xml +++ b/src/main/resources/db/changelog/1.0.0/2025-12-add_task.xml @@ -14,9 +14,19 @@ - + + + - + + + + + + + + + diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index 4bc73a2..0e5f394 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -10,6 +10,6 @@ - + \ No newline at end of file