Feat: создана сущность Issue и вспомогательные, приступаю к миграциям БД.

This commit is contained in:
Dmitry Sheyko 2023-01-18 21:52:25 +03:00
parent 32f427a6a2
commit b5ff193b49
19 changed files with 627 additions and 0 deletions

View File

@ -0,0 +1,5 @@
package dev.struchkov.bot.gitlab.context.domain;
public enum IssueState {
OPENED, CLOSED
}

View File

@ -0,0 +1,6 @@
package dev.struchkov.bot.gitlab.context.domain;
public enum IssueType {
ISSUE,
INCIDENT
}

View File

@ -0,0 +1,5 @@
package dev.struchkov.bot.gitlab.context.domain;
public enum MilestoneState {
ACTIVE, CLOSED
}

View File

@ -0,0 +1,181 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import dev.struchkov.bot.gitlab.context.domain.IssueState;
import dev.struchkov.bot.gitlab.context.domain.IssueType;
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
/**
* Сущность Issue.
*
* @author Dmitry Sheyko [17.01.2023]
*/
// При запросе issue учесть что пагинация по умолчанию - 20 объектов
@Getter
@Setter
@Entity
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
@Table(name = "issue")
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Issue {
@Id
@Column(name = "id")
@EqualsAndHashCode.Include
private Long id;
@Column(name = "iid")
private Long twoId;
@Column(name = "project_id")
private Long projectId;
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@Enumerated(value = EnumType.STRING)
@Column(name = "state")
private IssueState state;
@Column(name = "created_date")
private LocalDateTime createdDate;
@Column(name = "updated_date")
private LocalDateTime updatedDate;
@Column(name = "closed_at")
private LocalDateTime closeDate;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "closed_by_id")
private Person closedBy;
@ElementCollection
@CollectionTable(name = "issue_label", joinColumns = @JoinColumn(name = "label_id"))
@Column(name = "labels")
private Set<String> labels = new HashSet<>();
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "milestone_id")
private Milestone milestone;
@Column(name = "assignees")
@OneToMany(
fetch = FetchType.LAZY,
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
)
@JoinTable(
name = "issue_assignees",
joinColumns = @JoinColumn(name = "issue_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
)
private Set<Person> assignees = new HashSet<>();
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "author_id")
private Person author;
@Enumerated(value = EnumType.STRING)
@Column(name = "type")
private IssueType type; // ОБразец приходящего значения "INCIDENT"
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "assignee")
private Person assignee;
@Column(name = "user_notes_count") //Количество комментов пользователя
private Integer userNotesCount;
@Column(name = "merge_requests_count")
private Integer mergeRequestsCount;
@Column(name = "upvotes") // Количество лайков
private Integer upVotes;
@Column(name = "downvotes") // Количество дизлайков
private Integer downVotes;
@Column(name = "due_date")
private LocalDateTime dueDate;
@Column(name = "confidential") // Конфиденцальное или нет
private Boolean confidential;
@Column(name = "discussion_locked")
private Integer discussionLocked; //TODO выяснить тип поляя.
@Column(name = "issue_type")
private String issueType; //TODO выяснить зачем дублирует поле type Образец приходящего значения "incident"
@Column(name = "web_url")
private String webUrl;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "timeEstimate", column = @Column(name = "time_estimate")),
@AttributeOverride(name = "totalTimeSpent", column = @Column(name = "total_time_spent")),
@AttributeOverride(name = "humanTimeEstimate", column = @Column(name = "human_time_estimate")),
@AttributeOverride(name = "humanTotalTimeSpent", column = @Column(name = "human_total_time_spent"))
})
private TimeStats timeStats;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "count", column = @Column(name = "count")),
@AttributeOverride(name = "completedCount", column = @Column(name = "completed_count"))
})
private TaskCompletionStatus taskCompletionStatus;
@Column(name = "blocking_issues_count")
private Integer blockingIssuesCount;
@Column(name = "has_tasks")
private Boolean hasTasks;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "self", column = @Column(name = "self")),
@AttributeOverride(name = "notes", column = @Column(name = "notes")),
@AttributeOverride(name = "awardEmoji", column = @Column(name = "award_emoji")),
@AttributeOverride(name = "project", column = @Column(name = "project")),
@AttributeOverride(name = "closedAsDuplicateOf", column = @Column(name = "closed_as_duplicate_of"))
})
private Links links;
@Embedded
@AttributeOverrides({
@AttributeOverride(name = "shortReference", column = @Column(name = "short_reference")),
@AttributeOverride(name = "relativeReference", column = @Column(name = "relative_reference")),
@AttributeOverride(name = "fullReference", column = @Column(name = "full_reference"))
})
private References references;
/*Возможно надо заменить на енум "UNKNOWN", Critical - S1, High - S2, Medium - S3, Low - S4.
Но это поле доступно только для премиум акаунтов
*/
@Column(name = "severity")
private String severity;
@Column(name = "moved_to_id")
private Long movedToId;
@Column(name = "service_desk_reply_to")
private String serviceDescReplyTo; //TODO не понятен тип поля
@Column(name = "epic_issue_id")
private Long epicId; // "epic_issue_id" Поле доснтупное только для премиум акаунтов
}

View File

@ -0,0 +1,23 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Embeddable;
/**
* Сущность Issue.
*
* @author Dmitry Sheyko [17.01.2023]
*/
@Embeddable
@Getter
@Setter
public class Links {
private String self;
private String notes;
private String awardEmoji;
private String project;
private String closedAsDuplicateOf;
}

View File

@ -0,0 +1,64 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import dev.struchkov.bot.gitlab.context.domain.MilestoneState;
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
import java.time.LocalDateTime;
/**
* Сущность Milestone.
*
* @author Dmitry Sheyko 17.01.2023
*/
@Entity
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "milestone")
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
public class Milestone {
@Id
@EqualsAndHashCode.Include
private Long id;
@Column(name = "iid")
private Long twoId;
@Column(name = "project_id")
private Long projectId;
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@Enumerated(value = EnumType.STRING)
@Column(name = "state")
private MilestoneState state;
@Column(name = "created_date")
private LocalDateTime createdDate;
@Column(name = "updated_date")
private LocalDateTime updatedDate;
@Column(name = "start_date")
private LocalDateTime startDate; //установленное создателем время начала
@Column(name = "due_date")
private LocalDateTime dueDate; //установленное создателем время окончания
@Column(name = "expired")
private Boolean expired;
@Column(name = "web_url")
private String webUrl;
}

View File

@ -0,0 +1,21 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Embeddable;
/**
* Сущность References.
*
* @author Dmitry Sheyko [17.01.2023]
*/
@Embeddable
@Getter
@Setter
public class References {
private String shortReference;
private String relativeReference;
private String fullReference;
}

View File

@ -0,0 +1,20 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Embeddable;
/**
* Сущность TaskCompletionStatus.
*
* @author Dmitry Sheyko [17.01.2023]
*/
@Embeddable
@Getter
@Setter
public class TaskCompletionStatus {
private Integer count;
private Integer completedCount;
}

View File

@ -0,0 +1,23 @@
package dev.struchkov.bot.gitlab.context.domain.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Embeddable;
/**
* Сущность TimeStats.
*
* @author Dmitry Sheyko [17.01.2023]
*/
@Embeddable
@Getter
@Setter
public class TimeStats {
private Integer timeEstimate;
private Integer totalTimeSpent; // количество секунд затраченых на работы, пример 37800"
private String humanTimeEstimate;
private String humanTotalTimeSpent; // Время строкой, пример "10h 30m"
}

View File

@ -0,0 +1,10 @@
package dev.struchkov.bot.gitlab.core.service.parser;
import dev.struchkov.bot.gitlab.context.domain.IssueState;
import java.util.Set;
public class IssueRequestParser {
private static final Set<IssueState> OLD_STATUSES = Set.of(
IssueState.OPENED, IssueState.CLOSED);
}

View File

@ -0,0 +1,108 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class IssueJson {
private Long id;
@JsonProperty("iid")
private Long twoId;
@JsonProperty("project_id")
private Long projectId;
private String title;
private String description;
private IssueStateJson state;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime createdDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("updated_at")
private LocalDateTime updatedDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("closed_at")
private LocalDateTime closedDate;
@JsonProperty("closed_by")
private PersonJson closedBy;
private Set<String> labels;
private MilestoneJson milestone;
private Set<PersonJson> assignees;
private PersonJson author;
private IssueTypeJson type;
private PersonJson assignee;
@JsonProperty("user_notes_count")
private Integer userNotesCount;
@JsonProperty("merge_requests_count")
private Integer mergeRequestsCount;
@JsonProperty("upvotes")
private Integer upVotes;
@JsonProperty("downvotes")
private Integer downVotes;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("due_date")
private LocalDateTime dueDate;
private Boolean confidential;
@JsonProperty("discussion_locked")
private Integer discussionLocked; //TODO выяснить тип поля
@JsonProperty("issue_type")
private String issueType; //TODO выяснить зачем дублирует поле type
@JsonProperty("web_url")
private String webUrl;
@JsonProperty("time_stats")
private TimeStatsJson timeStats;
@JsonProperty("task_completion_status")
private TaskCompletionStatusJson taskCompletionStatus;
@JsonProperty("blocking_issues_count")
private Integer blockingIssuesCount;
@JsonProperty("has_tasks")
private Boolean hasTasks;
@JsonProperty("_links")
private LinksJson links;
private ReferencesJson references;
private String severity; //TODO заменить на енум "UNKNOWN", Critical - S1, High - S2, Medium - S3, Low - S4,
@JsonProperty("moved_to_id")
private Long movedToId;
@JsonProperty("service_desk_reply_to")
private Long serviceDescReplyTo; //TODO не понятен тип поля
@JsonProperty("epic_issue_id")
private Long epicId; // "epic_issue_id" Поле доступное только для премиум акаунтов
}

View File

@ -0,0 +1,15 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
public enum IssueStateJson {
@JsonProperty("opened")
OPENED,
@JsonProperty("closed")
CLOSED
}

View File

@ -0,0 +1,6 @@
package dev.struchkov.bot.gitlab.sdk.domain;
public enum IssueTypeJson {
ISSUE,
INCIDENT
}

View File

@ -0,0 +1,21 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class LinksJson {
private String self;
private String notes;
@JsonProperty("award_emoji")
private String awardEmoji;
private String project;
@JsonProperty("closed_as_duplicate_of")
private String closedAsDuplicateOf;
}

View File

@ -0,0 +1,52 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;
import java.time.LocalDateTime;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class MilestoneJson {
private Long id;
@JsonProperty("iid")
private Long twoId;
@JsonProperty("project_id")
private Long projectId;
private String title;
private String description;
private MilestoneStateJson state;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("created_at")
private LocalDateTime createdDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("updated_at")
private LocalDateTime updatedDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("start_date")
private LocalDateTime startDate;
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
@JsonProperty("due_date")
private LocalDateTime dueDate;
private boolean expired;
@JsonProperty("web_url")
private String webUrl;
}

View File

@ -0,0 +1,15 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
public enum MilestoneStateJson {
@JsonProperty("active")
ACTIVE,
@JsonProperty("closed")
CLOSED
}

View File

@ -0,0 +1,20 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class ReferencesJson {
@JsonProperty("short")
private String shortReference;
@JsonProperty("relative")
private String relativeReference;
@JsonProperty("full")
private String fullReference;
}

View File

@ -0,0 +1,17 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class TaskCompletionStatusJson {
@JsonProperty("count")
private Integer count;
@JsonProperty("completed_count")
private Integer completedCount;
}

View File

@ -0,0 +1,15 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import lombok.Data;
/**
* @author Dmitry Sheyko [17.01.2023]
*/
@Data
public class TimeStatsJson {
private Integer timeEstimate;
private Integer totalTimeSpent; // количество секунд затраченых на работы, пример 37800"
private String humanTimeEstimate;
private String humanTotalTimeSpent; // Время строкой, пример "10h 30m"
}