diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/controller/ProcessController.java b/nect-api/src/main/java/com/nect/api/domain/team/process/controller/ProcessController.java new file mode 100644 index 0000000..79a9ffd --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/controller/ProcessController.java @@ -0,0 +1,28 @@ +package com.nect.api.domain.team.process.controller; + +import com.nect.api.domain.team.process.dto.req.ProcessCreateReqDto; +import com.nect.api.domain.team.process.dto.res.ProcessCreateResDto; +import com.nect.api.global.response.ApiResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/projects/{projectId}/processes") +@RequiredArgsConstructor +public class ProcessController { + + // TODO : private final ProcessService processService + + // 새 프로세스 생성 + @PostMapping + public ApiResponse createProcess( + @PathVariable Long projectId, + @RequestBody ProcessCreateReqDto request + ) { + // TODO : Long processId = processService.createProcess(projectId, request); + + Long processId = 1L; // 임시 + return ApiResponse.ok(new ProcessCreateResDto(processId)); + } + +} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessCreateReqDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessCreateReqDto.java new file mode 100644 index 0000000..34668c3 --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessCreateReqDto.java @@ -0,0 +1,48 @@ +package com.nect.api.domain.team.process.dto.req; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.nect.core.entity.team.process.enums.ProcessStatus; + +import java.time.LocalDate; +import java.util.List; + +public record ProcessCreateReqDto( + // TODO : @Valid 나중에 필수값 확정되면 사용하기 + + @JsonProperty("process_title") + String processTitle, + + @JsonProperty("process_content") + String processContent, + + @JsonProperty("process_status") + ProcessStatus processStatus, + + @JsonProperty("assignee_ids") + List assigneeIds, + + @JsonProperty("field_ids") + List fieldIds, + + @JsonProperty("start_date") + LocalDate startDate, + + @JsonProperty("dead_line") + LocalDate deadLine, + + @JsonProperty("mentions") + List mentions, + + @JsonProperty("file_ids") + List fileIds, + + @JsonProperty("links") + List links, + + @JsonProperty("task_items") + List taskItems + + +// TODO : 일단은 null -> 프로세스 생성할 때 초기 피드백도 같이 등록할 수 있으면 사용 +// List feedbacks +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessTaskItemReqDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessTaskItemReqDto.java new file mode 100644 index 0000000..195fdfa --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/req/ProcessTaskItemReqDto.java @@ -0,0 +1,13 @@ +package com.nect.api.domain.team.process.dto.req; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record ProcessTaskItemReqDto( + String content, + + @JsonProperty("is_done") + Boolean isDone, + + @JsonProperty("sort_order") + Integer sortOrder +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/AssigneeResDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/AssigneeResDto.java new file mode 100644 index 0000000..cd531fd --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/AssigneeResDto.java @@ -0,0 +1,14 @@ +package com.nect.api.domain.team.process.dto.res; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record AssigneeResDto( + @JsonProperty("user_id") + Long userId, + + @JsonProperty("user_name") + String userName, + + @JsonProperty("user_image") + String userImage +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/FieldGroupResDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/FieldGroupResDto.java new file mode 100644 index 0000000..a77a986 --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/FieldGroupResDto.java @@ -0,0 +1,15 @@ +package com.nect.api.domain.team.process.dto.res; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public record FieldGroupResDto( + @JsonProperty("field_id") + Long fieldId, + + @JsonProperty("field_name") + String fieldName, + + List processes +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCardResDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCardResDto.java new file mode 100644 index 0000000..335119d --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCardResDto.java @@ -0,0 +1,37 @@ +package com.nect.api.domain.team.process.dto.res; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.time.LocalDate; +import java.util.List; + +public record ProcessCardResDto( + @JsonProperty("process_id") + Long processId, + + @JsonProperty("process_status") + String processStatus, + + // 파트(담당 분야) + String field, + + String title, + + @JsonProperty("complete_check_list") + Integer completeCheckList, + + @JsonProperty("whole_check_list") + Integer wholeCheckList, + + @JsonProperty("start_date") + LocalDate startDate, + + @JsonProperty("dead_line") + LocalDate deadLine, + + @JsonProperty("left_day") + Integer leftDay, + + @JsonProperty("assignee") + List assignee +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCreateResDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCreateResDto.java new file mode 100644 index 0000000..6167ca4 --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessCreateResDto.java @@ -0,0 +1,8 @@ +package com.nect.api.domain.team.process.dto.res; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public record ProcessCreateResDto( + @JsonProperty("process_id") + Long processId +) {} diff --git a/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessWeekResDto.java b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessWeekResDto.java new file mode 100644 index 0000000..b4d9445 --- /dev/null +++ b/nect-api/src/main/java/com/nect/api/domain/team/process/dto/res/ProcessWeekResDto.java @@ -0,0 +1,16 @@ +package com.nect.api.domain.team.process.dto.res; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; + +public record ProcessWeekResDto( + @JsonProperty("start_date") + String startDate, + + @JsonProperty("project_purpose") + List projectPurpose, + + @JsonProperty("by_field") + List byField +) {} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/Project.java b/nect-core/src/main/java/com/nect/core/entity/team/Project.java new file mode 100644 index 0000000..8a806e2 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/Project.java @@ -0,0 +1,69 @@ +package com.nect.core.entity.team; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.enums.ProjectStatus; +import com.nect.core.entity.team.enums.RecruitmentStatus; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "project") +public class Project extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "title", length = 50, nullable = false) + private String title; + + @Column(name = "description", length = 100) + private String description; + + @Column(name = "information", columnDefinition = "TEXT") + private String information; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private ProjectStatus status; + + @Column(name = "notice_text", columnDefinition = "TEXT") + private String noticeText; + + // 정규 회의 + @Column(name = "regular_meeting_text", columnDefinition = "TEXT") + private String regularMeetingText; + + // 모집 상태 + @Enumerated(EnumType.STRING) + @Column(name = "recruitment_status", nullable = false) + private RecruitmentStatus recruitmentStatus; + + @Column(name = "ended_at") + private LocalDateTime endedAt; + + + @Builder + protected Project(String title, + String description, + String information, + ProjectStatus status, + String noticeText, + String regularMeetingText) { + this.title = title; + this.description = description; + this.information = information; + this.status = (status == null) ? ProjectStatus.ACTIVE : status; + this.noticeText = noticeText; + this.regularMeetingText = regularMeetingText; + } + + public void end() { + this.status = ProjectStatus.ENDED; + this.recruitmentStatus = RecruitmentStatus.CLOSED; + this.endedAt = LocalDateTime.now(); + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/ProjectUser.java b/nect-core/src/main/java/com/nect/core/entity/team/ProjectUser.java new file mode 100644 index 0000000..53ee3d6 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/ProjectUser.java @@ -0,0 +1,67 @@ +package com.nect.core.entity.team; + +import com.nect.core.entity.team.enums.ProjectMemberStatus; +import com.nect.core.entity.team.enums.ProjectMemberType; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +@Table( + name = "project_user", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_project_user_project_user", + columnNames = {"project_id", "user_id"} + ) + } +) +public class ProjectUser { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // TODO: User 엔티티 연결되면 연관관계로 변경 + // @ManyToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "user_id", nullable = false) + // private User user; + + @Column(name = "user_id", nullable = false) + private Long userId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private Project project; + + @Enumerated(EnumType.STRING) + @Column(name = "member_type", nullable = false) + private ProjectMemberType memberType; + + @Enumerated(EnumType.STRING) + @Column(name = "member_status", nullable = false) + private ProjectMemberStatus memberStatus; + + @Builder + private ProjectUser(Project project, Long userId, ProjectMemberType memberType, ProjectMemberStatus memberStatus) { + this.project = project; + this.userId = userId; + this.memberType = (memberType != null) ? memberType : ProjectMemberType.MEMBER; + this.memberStatus = (memberStatus != null) ? memberStatus : ProjectMemberStatus.PENDING; + } + + void setProject(Project project) { + this.project = project; + } + + public void activate() { + this.memberStatus = ProjectMemberStatus.ACTIVE; + } + + public void kick() { + this.memberStatus = ProjectMemberStatus.KICKED; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/SharedDocument.java b/nect-core/src/main/java/com/nect/core/entity/team/SharedDocument.java new file mode 100644 index 0000000..fec0cac --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/SharedDocument.java @@ -0,0 +1,78 @@ +package com.nect.core.entity.team; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.enums.FileExt; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "shared_document") +public class SharedDocument extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "created_by", nullable = false) +// private User createdBy; + + @Column(name = "is_pinned", nullable = false) + private boolean isPinned; + + @Column(name = "title", length = 200, nullable = false) + private String title; + + @Column(name = "description", columnDefinition = "TEXT") + private String description; + + @Column(name = "file_name", length = 200, nullable = false) + private String fileName; + + @Enumerated(EnumType.STRING) + @Column(name = "file_ext", length = 10, nullable = false) + private FileExt fileExt; + + @Column(name = "file_url", nullable = false, columnDefinition = "TEXT") + private String fileUrl; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + // TODO : 매개변수 User createdBy 추가 + @Builder + private SharedDocument( + boolean isPinned, + String title, + String description, + String fileName, + FileExt fileExt, + String fileUrl) { +// this.createdBy = createdBy; + this.isPinned = isPinned; + this.title = title; + this.description = description; + this.fileName = fileName; + this.fileExt = fileExt; + this.fileUrl = fileUrl; + } + + public void pin() { + this.isPinned = true; + } + + public void unpin() { + this.isPinned = false; + } + + public void softDelete() { + this.deletedAt = LocalDateTime.now(); + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/enums/FileExt.java b/nect-core/src/main/java/com/nect/core/entity/team/enums/FileExt.java new file mode 100644 index 0000000..e7b2dae --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/enums/FileExt.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.enums; + +public enum FileExt { + JPG, JPEG, PNG, PDF, ZIP +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberStatus.java b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberStatus.java new file mode 100644 index 0000000..31656f5 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberStatus.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.enums; + +public enum ProjectMemberStatus { + INVITED, PENDING, ACTIVE, KICKED +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberType.java b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberType.java new file mode 100644 index 0000000..5f91373 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectMemberType.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.enums; + +public enum ProjectMemberType { + LEADER, MEMBER; +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectStatus.java b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectStatus.java new file mode 100644 index 0000000..98b84d2 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/enums/ProjectStatus.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.enums; + +public enum ProjectStatus { + ACTIVE, ENDED +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/enums/RecruitmentStatus.java b/nect-core/src/main/java/com/nect/core/entity/team/enums/RecruitmentStatus.java new file mode 100644 index 0000000..ef0e2b5 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/enums/RecruitmentStatus.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.enums; + +public enum RecruitmentStatus { + UPCOMING, OPEN, CLOSED +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/Link.java b/nect-core/src/main/java/com/nect/core/entity/team/process/Link.java new file mode 100644 index 0000000..1e7fba4 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/Link.java @@ -0,0 +1,35 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "link") +public class Link extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="process_id", nullable=false) + private Process process; + + @Column(name = "url", nullable = false, columnDefinition = "TEXT") + private String url; + + @Builder + public Link(Process process, String url) { + this.process = process; + this.url = url; + } + + void setProcess(Process process) { + this.process = process; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/Process.java b/nect-core/src/main/java/com/nect/core/entity/team/process/Process.java new file mode 100644 index 0000000..2cfc4df --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/Process.java @@ -0,0 +1,142 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.Project; +import com.nect.core.entity.team.process.enums.ProcessStatus; +import com.nect.core.entity.team.SharedDocument; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "process") +public class Process extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // 프로젝트 1 : N 프로세스(카드) + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private Project project; + + // TODO + // 작성자(created_by) +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "created_by", nullable = false) +// private User createdBy; + + // TODO + // 파트(분야/레인) - Field FK +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "field_id", nullable = false) +// private Field field; + + @Column(name = "title", length = 50, nullable = false) + private String title; + + @Lob + @Column(name = "content") + private String content; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private ProcessStatus status; + + @Column(name = "start_at") + private LocalDate startAt; + + @Column(name = "end_at") + private LocalDate endAt; + + @Column(name = "status_order", nullable = false) + private Integer statusOrder = 0; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + @OneToMany(mappedBy = "process", cascade = CascadeType.ALL, orphanRemoval = true) + private final List taskItems = new ArrayList<>(); + + @OneToMany(mappedBy = "process", cascade = CascadeType.ALL, orphanRemoval = true) + private final List links = new ArrayList<>(); + + @OneToMany(mappedBy = "process", cascade = CascadeType.ALL, orphanRemoval = true) + private final List processUsers = new ArrayList<>(); + + @OneToMany(mappedBy = "process", cascade = CascadeType.ALL, orphanRemoval = true) + private final List sharedDocuments = new ArrayList<>(); + + @OneToMany(mappedBy = "process", cascade = CascadeType.ALL, orphanRemoval = true) + private final List processFields = new ArrayList<>(); + + + // TODO : User createdBy, Field field 매개변수 추가하기 + @Builder + private Process(Project project, String title, String content) { + this.project = project; +// this.createdBy = createdBy; +// this.field = field; + this.title = title; + this.content = content; + this.status = ProcessStatus.PLANNING; + this.statusOrder = 0; + } + + public void attachDocument(SharedDocument doc) { + ProcessSharedDocument psd = ProcessSharedDocument.builder() + .process(this) + .document(doc) + .build(); + this.sharedDocuments.add(psd); + } + + public void addTaskItem(ProcessTaskItem item) { + item.setProcess(this); + this.taskItems.add(item); + } + + public void addLink(Link link) { + link.setProcess(this); + this.links.add(link); + } + + public void addProcessUser(ProcessUser pu) { + pu.setProcess(this); + this.processUsers.add(pu); + } + + // TODO : Field 엔티티 생성되면 주석 풀기 +// public void addField(Field field) { +// ProcessField pf = ProcessField.builder() +// .process(this) +// .field(field) +// .build(); +// this.processFields.add(pf); +// } + + public void updateStatus(ProcessStatus status) { + if (status != null) this.status = status; + } + + public void updatePeriod(LocalDate startAt, LocalDate endAt) { + this.startAt = startAt; + this.endAt = endAt; + } + + public void updateContent(String content) { + this.content = content; + } + + public void softDelete() { + this.deletedAt = LocalDateTime.now(); + } +} + + diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessFeedback.java b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessFeedback.java new file mode 100644 index 0000000..c538662 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessFeedback.java @@ -0,0 +1,63 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.process.enums.ProcessFeedbackStatus; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "process_feedback") +public class ProcessFeedback extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="process_id", nullable=false) + private Process process; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "created_by", nullable = false) +// private User createdBy; + + @Column(name = "content", nullable = false, columnDefinition = "TEXT") + private String content; + + @Enumerated(EnumType.STRING) + @Column(name = "status", nullable = false) + private ProcessFeedbackStatus status; + + @Column(name = "resolved_at") + private LocalDateTime resolvedAt; + + // TODO : User createdBy 추가하기 + @Builder + private ProcessFeedback(Process process, String content) { + this.process = process; +// this.createdBy = createdBy; + this.content = content; + this.status = ProcessFeedbackStatus.OPEN; + } + + void setProcess(Process process) { + this.process = process; + } + + public void resolve() { + this.status = ProcessFeedbackStatus.RESOLVED; + this.resolvedAt = LocalDateTime.now(); + } + + public void reopen() { + this.status = ProcessFeedbackStatus.OPEN; + this.resolvedAt = null; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessField.java b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessField.java new file mode 100644 index 0000000..5309d1f --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessField.java @@ -0,0 +1,49 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "process_field", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_process_field_process_field", + columnNames = {"process_id", "field_id"} + ) + } +) +public class ProcessField extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "process_id", nullable = false) + private Process process; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "field_id", nullable = false) +// private Field field; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + // TODO : Field 추가 + @Builder + public ProcessField(Process process) { + this.process = process; +// this.field = field; + } + + void setProcess(Process process) { this.process = process; } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessSharedDocument.java b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessSharedDocument.java new file mode 100644 index 0000000..5e4cea4 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessSharedDocument.java @@ -0,0 +1,52 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.SharedDocument; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "process_shared_document", + uniqueConstraints = { + @UniqueConstraint(name = "uk_process_document", columnNames = {"process_id", "document_id"}) + } +) +public class ProcessSharedDocument extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "process_id", nullable = false) + private Process process; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "document_id", nullable = false) + private SharedDocument document; + + @Column(name = "attached_at", nullable = false) + private LocalDateTime attachedAt; + + @Builder + public ProcessSharedDocument(Process process, SharedDocument document, LocalDateTime attachedAt) { + this.process = process; + this.document = document; + this.attachedAt = (attachedAt == null ? LocalDateTime.now() : attachedAt); + } + + void setProcess(Process process) { + this.process = process; + } + + void setDocument(SharedDocument document) { + this.document = document; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessTaskItem.java b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessTaskItem.java new file mode 100644 index 0000000..821d338 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessTaskItem.java @@ -0,0 +1,50 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "process_task_item") +public class ProcessTaskItem extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="process_id", nullable=false) + private Process process; + + @Column(name = "content",nullable = false) + private String content; + + @Column(name = "is_done") + private boolean isDone; + + @Column(name = "done_at") + private LocalDate doneAt; + + @Column(name = "sort_order") + private Integer sortOrder = 0; + + @Builder + public ProcessTaskItem(Process process, String content, boolean isDone, Integer sortOrder) { + this.process = process; + this.content = content; + this.isDone = isDone; + this.sortOrder = (sortOrder != null) ? sortOrder : 0; + this.doneAt = isDone ? LocalDate.now() : null; + } + + + void setProcess(Process process) { + this.process = process; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessUser.java b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessUser.java new file mode 100644 index 0000000..9c45f16 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/ProcessUser.java @@ -0,0 +1,72 @@ +package com.nect.core.entity.team.process; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.process.enums.AssignmentRole; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "process_user", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_process_user_process_member", + columnNames = {"process_id", "member_id"} + ) + } +) +public class ProcessUser extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // 하나의 프로세스에 여러 유저 배정, 관찰 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "process_id", nullable = false) + private Process process; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User user; + + @Enumerated(EnumType.STRING) + @Column(name = "assignment_role", nullable = false) + private AssignmentRole assignmentRole; + + @Column(name = "assigned_at") + private LocalDateTime assignedAt; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + // TODO : user 추가 + @Builder + public ProcessUser(Process process, AssignmentRole assignmentRole, LocalDateTime assignedAt) { + this.process = process; +// this.user = user; + this.assignmentRole = assignmentRole; + this.assignedAt = (assignedAt != null) ? assignedAt : LocalDateTime.now(); + this.deletedAt = null; + } + + public void delete() { + this.deletedAt = LocalDateTime.now(); + } + + void setProcess(Process process) { + this.process = process; + } + +// void setMember(User user) { +// this.user = user; +// } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/enums/AssignmentRole.java b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/AssignmentRole.java new file mode 100644 index 0000000..4ce5a5d --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/AssignmentRole.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.process.enums; + +public enum AssignmentRole { + ASSIGNEE, WATCHER +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessFeedbackStatus.java b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessFeedbackStatus.java new file mode 100644 index 0000000..a846f04 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessFeedbackStatus.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.process.enums; + +public enum ProcessFeedbackStatus { + OPEN, RESOLVED +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessStatus.java b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessStatus.java new file mode 100644 index 0000000..e519eb7 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/process/enums/ProcessStatus.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.process.enums; + +public enum ProcessStatus { + BACKLOG, PLANNING, IN_PROGRESS, DONE +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/Post.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/Post.java new file mode 100644 index 0000000..f335180 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/Post.java @@ -0,0 +1,53 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.Project; +import com.nect.core.entity.team.workspace.enums.PostType; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "post") +public class Post extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User author; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "project_id", nullable = false) + private Project project; + + @Enumerated(EnumType.STRING) + @Column(name = "post_type", nullable = false) + private PostType postType; + + @Column(name = "title", length = 100, nullable = false) + private String title; + + @Column(name = "content", nullable = false, columnDefinition = "TEXT") + private String content; + + @Column(name = "is_pinned", nullable = false) + private Boolean isPinned; + + @Column(name = "like_count", nullable = false) + private Long likeCount = 0L; + + @Column(name = "comment_count", nullable = false) + private Long commentCount = 0L; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostAttachment.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostAttachment.java new file mode 100644 index 0000000..0b8fecb --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostAttachment.java @@ -0,0 +1,39 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.SharedDocument; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "post_attachment", + uniqueConstraints = { + @UniqueConstraint(name = "uk_post_attachment_post_document", columnNames = {"post_id", "document_id"}) + } +) +public class PostAttachment extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "document_id", nullable = false) + private SharedDocument document; + + void setPost(Post post) { + this.post = post; + } + + void setDocument(SharedDocument document) { + this.document = document; + } +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostComment.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostComment.java new file mode 100644 index 0000000..af7b8d3 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostComment.java @@ -0,0 +1,65 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "post_comment") +public class PostComment extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; + +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User author; + + /** + * 부모 댓글 (대댓글용) + * - NULL 이면 일반 댓글 + * - 값이 있으면 해당 댓글의 대댓글 + */ + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_comment_id") + private PostComment parentComment; + + @Column(name = "like_count", nullable = false) + private Long likeCount = 0L; + + @Column(name = "comment_count", nullable = false) + private Long commentCount = 0L; + + @Column(name = "content", nullable = false, columnDefinition = "TEXT") + private String content; + + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + + void setPost(Post post) { + this.post = post; + } + +// void setAuthor(User author) { +// this.author = author; +// } + + void setParentComment(PostComment parentComment) { + this.parentComment = parentComment; + } + + public void softDelete() { + this.deletedAt = LocalDateTime.now(); + } + +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostCommentLike.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostCommentLike.java new file mode 100644 index 0000000..6038f4c --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostCommentLike.java @@ -0,0 +1,40 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "post_comment_like", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_post_comment_like_comment_member", + columnNames = {"post_comment_id", "member_id"} + ) + } +) +public class PostCommentLike extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // 어떤 댓글에 좋아요인지 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_comment_id", nullable = false) + private PostComment comment; + + // TODO +// // 누가 좋아요 했는지 +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User user; + + void setComment(PostComment comment) { this.comment = comment; } +// void setMember(User user) { this.user = user; } + +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostLike.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostLike.java new file mode 100644 index 0000000..4bfb183 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/PostLike.java @@ -0,0 +1,40 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table( + name = "post_comment_like", + uniqueConstraints = { + @UniqueConstraint( + name = "uk_post_comment_like_comment_member", + columnNames = {"post_id", "member_id"} + ) + } +) +public class PostLike extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // 어떤 게시글에 좋아요인지 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "post_id", nullable = false) + private Post post; + + // TODO +// // 누가 좋아요 했는지 +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User user; + + void setPost(Post post) { this.post = post; } +// void setMember(User member) { this.member = member; } + +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/ProjectHistory.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/ProjectHistory.java new file mode 100644 index 0000000..900c7c1 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/ProjectHistory.java @@ -0,0 +1,39 @@ +package com.nect.core.entity.team.workspace; + +import com.nect.core.entity.BaseEntity; +import com.nect.core.entity.team.Project; +import com.nect.core.entity.team.workspace.enums.ActionType; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.catalina.User; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "project_history") +public class ProjectHistory extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "user_id", nullable = false) +// private User user; + + // TODO +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "project_id", nullable = false) +// private Project project; + + @Enumerated(EnumType.STRING) + @Column(name = "action_type", nullable = false) + private ActionType actionType; + + @Column(name = "content", nullable = false) + private String content; + + +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/ActionType.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/ActionType.java new file mode 100644 index 0000000..dcd6340 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/ActionType.java @@ -0,0 +1,12 @@ +package com.nect.core.entity.team.workspace.enums; + +public enum ActionType { + // 프로세스(TASK) + PROCESS_CREATE, PROCESS_UPDATE, PROCESS_MOVE_STATUS, PROCESS_ASSIGN, + // 문서 + DOCUMENT_UPLOAD, DOCUMENT_DELETE, + // 게시글 + POST_CREATE, COMMENT_CREATE, POST_DELETE, + // 멤버 + MEMBER_INVITE, MEMBER_KICK +} diff --git a/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/PostType.java b/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/PostType.java new file mode 100644 index 0000000..df6f890 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/entity/team/workspace/enums/PostType.java @@ -0,0 +1,5 @@ +package com.nect.core.entity.team.workspace.enums; + +public enum PostType { + NOTICE, FREE +} diff --git a/nect-core/src/main/java/com/nect/core/repository/team/ProjectRepository.java b/nect-core/src/main/java/com/nect/core/repository/team/ProjectRepository.java new file mode 100644 index 0000000..c00e782 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/repository/team/ProjectRepository.java @@ -0,0 +1,7 @@ +package com.nect.core.repository.team; + +import com.nect.core.entity.team.Project; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProjectRepository extends JpaRepository { +} \ No newline at end of file diff --git a/nect-core/src/main/java/com/nect/core/repository/team/SharedDocumentRepository.java b/nect-core/src/main/java/com/nect/core/repository/team/SharedDocumentRepository.java new file mode 100644 index 0000000..a5f536e --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/repository/team/SharedDocumentRepository.java @@ -0,0 +1,7 @@ +package com.nect.core.repository.team; + +import com.nect.core.entity.team.SharedDocument; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SharedDocumentRepository extends JpaRepository { +} diff --git a/nect-core/src/main/java/com/nect/core/repository/team/process/ProcessRepository.java b/nect-core/src/main/java/com/nect/core/repository/team/process/ProcessRepository.java new file mode 100644 index 0000000..e9c96d4 --- /dev/null +++ b/nect-core/src/main/java/com/nect/core/repository/team/process/ProcessRepository.java @@ -0,0 +1,7 @@ +package com.nect.core.repository.team.process; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ProcessRepository extends JpaRepository { +} +