diff --git a/.docker/appsettings.json b/.docker/appsettings.json
new file mode 100644
index 0000000..f6c57ef
--- /dev/null
+++ b/.docker/appsettings.json
@@ -0,0 +1,25 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "ConnectionStrings": {
+ "DefaultConnection": "Host=db:5432;Database=persistence;Username=postgres;Password=postgres;Persist Security Info=True"
+ },
+ "AllowedHosts": "*",
+ "NeedUseKeyCloak": false,
+ "KeyCloakAuthentication": {
+ "Audience": "account",
+ "Host": "http://192.168.0.10:8321/realms/Persistence"
+ },
+ "AuthUser": {
+ "username": "myuser",
+ "password": 12345,
+ "clientId": "webapi",
+ "grantType": "password",
+ "http://schemas.xmlsoap.org/ws/2005/05/identity /claims/nameidentifier": "7d9f3574-6574-4ca3-845a-0276eb4aa8f6"
+ },
+ "ClientUrl": "http://localhost:5000/"
+}
diff --git a/.docker/compose.yaml b/.docker/compose.yaml
new file mode 100644
index 0000000..646af62
--- /dev/null
+++ b/.docker/compose.yaml
@@ -0,0 +1,31 @@
+networks:
+ persistence:
+ external: false
+
+services:
+ db:
+ image: timescale/timescaledb:latest-pg16
+ container_name: some-timescaledb-16
+ restart: always
+ environment:
+ - POSTGRES_PASSWORD=postgres
+ networks:
+ - persistence
+ ports:
+ - "5462:5432"
+ volumes:
+ - ./db:/var/lib/postgresql/data
+
+ persistence:
+ image: git.ddrilling.ru/ddrilling/persistence:latest
+ container_name: persistence
+ restart: always
+ depends_on:
+ - db
+ networks:
+ - persistence
+ ports:
+ - "1111:8080"
+ volumes:
+ - ./appsettings.json:/app/appsettings.json
+
diff --git a/DD.Persistence.API/Controllers/ChangeLogController.cs b/DD.Persistence.API/Controllers/ChangeLogController.cs
index e4d1c09..f10ae1a 100644
--- a/DD.Persistence.API/Controllers/ChangeLogController.cs
+++ b/DD.Persistence.API/Controllers/ChangeLogController.cs
@@ -1,4 +1,4 @@
-using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using DD.Persistence.Models;
using DD.Persistence.Models.Requests;
@@ -174,4 +174,87 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
return Ok(result);
}
+
+ ///
+ /// Метод, который возвращает статистику по количеству изменений в разрезе дней
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("statistics")]
+ public async Task>> GetStatisticsCountAsync([FromQuery] ChangeLogRequest request, CancellationToken token)
+ {
+ var result = new List() {
+ new() { DateTime = DateTimeOffset.UtcNow.AddDays(-60), ChangesCount = 10},
+ new() { DateTime = DateTimeOffset.UtcNow.AddDays(-50), ChangesCount = 2},
+ new() { DateTime = DateTimeOffset.UtcNow.AddDays(-25), ChangesCount = 560},
+ new() { DateTime = DateTimeOffset.UtcNow.AddDays(-2), ChangesCount = 78},
+ new() { DateTime = DateTimeOffset.UtcNow.AddDays(-1), ChangesCount = 39},
+ };
+
+ return Ok(result);
+ }
+
+ ///
+ /// Метод, который возвращает историю изменений в разрезе дней
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("history")]
+ public async Task>> HistoryChangeLogAsync([FromQuery] ChangeLogRequest request, CancellationToken token)
+ {
+ var userId = Guid.CreateVersion7();
+ var changeLogItemCurrentId = Guid.CreateVersion7();
+ var changeLogItemCreation = DateTimeOffset.UtcNow;
+ var changeLogItems = new List()
+ {
+ new ChangeLogDto()
+ {
+ Id = changeLogItemCurrentId,
+ Creation = changeLogItemCreation,
+ IdAuthor = userId,
+ IdEditor = userId,
+ Obsolete = null,
+ Value = new ChangeLogValuesDto(){
+ Id = Guid.CreateVersion7(),
+ Value = new Dictionary() {
+ ["1"] = new { id = 1, caption = "Изменение 1 (c правкой)" },
+ ["2"] = new { id = 2, caption = "Изменение 2 (с правкой)" },
+ }
+ }
+ },
+ new ChangeLogDto()
+ {
+ Id = Guid.CreateVersion7(),
+ Creation = DateTimeOffset.UtcNow.AddDays(-10),
+ IdAuthor = userId,
+ IdEditor = userId,
+ IdNext = changeLogItemCurrentId,
+ Obsolete = DateTimeOffset.UtcNow.AddDays(-5),
+ Value = new ChangeLogValuesDto(){
+ Id = Guid.CreateVersion7(),
+ Value = new Dictionary() {
+ ["1"] = new { id = 1, caption = "Изменение 1" },
+ ["2"] = new { id = 2, caption = "Изменение 2" },
+ }
+ }
+ }
+ };
+ var result = new List() {
+ new() {
+ Comment = "Петров И. Ю. попросил внести изменения",
+ DateTime = changeLogItemCreation,
+ DiscriminatorId = Guid.CreateVersion7(),
+ User = new UserDto()
+ {
+ Id = userId,
+ DisplayName = "Иванов И. И"
+ },
+ ChangeLogItems = changeLogItems
+ },
+ };
+
+ return Ok(result);
+ }
}
diff --git a/DD.Persistence.Models/HistoryChangeLogDto.cs b/DD.Persistence.Models/HistoryChangeLogDto.cs
new file mode 100644
index 0000000..748310e
--- /dev/null
+++ b/DD.Persistence.Models/HistoryChangeLogDto.cs
@@ -0,0 +1,32 @@
+namespace DD.Persistence.Models;
+
+///
+/// Модель, необходимая для отображения истории по журналу изменений
+///
+public class HistoryChangeLogDto
+{
+ ///
+ /// Дата и время изменений
+ ///
+ public DateTimeOffset DateTime { get; set; }
+
+ ///
+ /// Пользователь, совершивший изменение данных
+ ///
+ public required UserDto User { get; set; }
+
+ ///
+ /// Проект, с которым связаны изменения
+ ///
+ public Guid DiscriminatorId { get; set; }
+
+ ///
+ /// Список изменений
+ ///
+ public required IEnumerable ChangeLogItems { get; set; }
+
+ ///
+ /// Комментарий к изменению
+ ///
+ public required string Comment { get; set; }
+}
diff --git a/DD.Persistence.Models/Requests/ChangeLogRequest.cs b/DD.Persistence.Models/Requests/ChangeLogRequest.cs
new file mode 100644
index 0000000..59396ff
--- /dev/null
+++ b/DD.Persistence.Models/Requests/ChangeLogRequest.cs
@@ -0,0 +1,17 @@
+namespace DD.Persistence.Models.Requests;
+
+///
+/// Запрос, используемый для получения данных по журналу операций
+///
+public class ChangeLogRequest
+{
+ ///
+ /// Дискриминатор задачи
+ ///
+ public Guid DiscriminatorId { get; set; }
+
+ ///
+ /// Пользователь
+ ///
+ public Guid UserId { get; set; }
+}
diff --git a/DD.Persistence.Models/StatisticsChangeLogDto.cs b/DD.Persistence.Models/StatisticsChangeLogDto.cs
new file mode 100644
index 0000000..f8ab537
--- /dev/null
+++ b/DD.Persistence.Models/StatisticsChangeLogDto.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DD.Persistence.Models;
+
+///
+/// Модель, необходимая для отображения статистики по журналу изменений
+///
+public class StatisticsChangeLogDto
+{
+ ///
+ /// Дата и время изменений
+ ///
+ public DateTimeOffset DateTime { get; set; }
+
+ ///
+ /// Количество изменений
+ ///
+ public int ChangesCount { get; set; }
+}
diff --git a/DD.Persistence.Models/UserDto.cs b/DD.Persistence.Models/UserDto.cs
new file mode 100644
index 0000000..682ccf8
--- /dev/null
+++ b/DD.Persistence.Models/UserDto.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DD.Persistence.Models;
+
+///
+/// Класс, описывающий пользователя
+///
+public class UserDto
+{
+ ///
+ /// Идентификатор пользователя
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Имя пользователя для отображения
+ ///
+ public required string DisplayName { get; set; }
+}
diff --git a/README.md b/README.md
index 130c2e5..30904ec 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,10 @@
-# Persistence
\ No newline at end of file
+# Persistence
+## Инструкция по развертыванию persistence в docker
+1. Необходимо скопировать себе локально папку **.docker**, которая находится внутри проекта **persistence**
+
+2. Авторизоваться в gitea-registry при помощи командры: `docker login -u пользователь -p пароль https://git.ddrilling.ru`
+
+3. Из папки **.docker** запустить команду:
+ `docker-compose up`
+
+4. При успешном старте persistence необходимо откорректировать ссылку в браузере: `[host]:[port]/swagger/index.html`
\ No newline at end of file