Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions aics-api/src/main/resources/db/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,18 @@ VALUES
('박민수', 'minsu@kyonggi.ac.kr', '정약용', '논문', '2029-02-28', 3, NULL, NULL, '202512347', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('정수진', 'sujin@kyonggi.ac.kr', '김이박', '논문', '2030-02-28', 4, 5, NULL, '202512349', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('최동욱', 'dongwook@kyonggi.ac.kr', '이교수', '자격증', '2027-08-31', NULL, NULL, 2, '202512348', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

-- schedule
INSERT INTO schedule (submission_type, title, content, start_date, end_date, created_at, updated_at)
VALUES ('SUBMITTED', '신청 접수', '학부생 졸업 논문 신청을 접수합니다.', '2025-02-24 09:00:00', '2025-03-10 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('MIDTHESIS', '중간 보고서', '중간 논문 제출 및 심사 기간입니다.', '2025-04-01 09:00:00', '2025-04-12 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('FINALTHESIS', '최종 보고서', '최종 논문 제출 및 심사 기간입니다.', '2025-05-20 09:00:00', '2025-06-05 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('CERTIFICATE', '제안서', '취득한 자격증 제출 및 심사 기간입니다.', '2025-03-15 09:00:00', '2025-03-29 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('APPROVED', '최종 통과', '최종 승인 기간입니다.', '2025-06-10 09:00:00', '2025-06-14 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('OTHER', '기타 일정 안내', '기타 일정 입니다.', '2025-03-01 09:00:00', '2025-12-31 18:00:00',
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
17 changes: 17 additions & 0 deletions aics-api/src/main/resources/db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,21 @@ CREATE TABLE graduation_user
ON DELETE CASCADE,
CONSTRAINT fk_graduation_user_certificate FOREIGN KEY (certificate_id) REFERENCES "certificate" (id)
ON DELETE CASCADE,
);

-- schedule
CREATE TABLE schedule
(
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
submission_type VARCHAR(20) NOT NULL UNIQUE
CONSTRAINT schedule_submission_type_check
CHECK ((submission_type)::TEXT = ANY
(ARRAY ['SUBMITTED', 'MIDTHESIS', 'FINALTHESIS', 'CERTIFICATE', 'APPROVED', 'OTHER'])),
title VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
start_date TIMESTAMP(6) NOT NULL,
end_date TIMESTAMP(6) NOT NULL,
created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
deleted_at TIMESTAMP(6) DEFAULT NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package kgu.developers.domain.schedule.application.command;


import kgu.developers.domain.schedule.domain.Schedule;
import kgu.developers.domain.schedule.domain.ScheduleRepository;
import kgu.developers.domain.schedule.domain.SubmissionType;
import kgu.developers.domain.schedule.exception.DuplicateScheduleTypeException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
@RequiredArgsConstructor
public class ScheduleService {
private final ScheduleRepository scheduleRepository;

public Long createSchedule(SubmissionType submissionType, String title, String content , LocalDateTime startDate, LocalDateTime endDate) {
scheduleRepository.findBySubmissionType(submissionType).ifPresent(existing -> {
throw new DuplicateScheduleTypeException();
});
Schedule schedule = Schedule.create(submissionType,title,content,startDate,endDate);

return scheduleRepository.save(schedule).getId();
}
@Transactional
public void updateSchedule(Schedule schedule, SubmissionType submissionType , String title, LocalDateTime startDate, LocalDateTime endDate) {
schedule.updateSubmissionType(submissionType);
schedule.updateTitle(title);
schedule.updateStartDate(startDate);
schedule.updateEndDate(endDate);

scheduleRepository.save(schedule);
}
@Transactional
public void updateScheduleContent(Schedule schedule, String content) {
schedule.updateContent(content);
scheduleRepository.save(schedule);
}
public void deleteSchedule(Long id) {
scheduleRepository.deleteById(id);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package kgu.developers.domain.schedule.application.query;

import kgu.developers.domain.schedule.domain.Schedule;
import kgu.developers.domain.schedule.domain.ScheduleRepository;
import kgu.developers.domain.schedule.domain.SubmissionType;
import kgu.developers.domain.schedule.exception.ScheduleNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@RequiredArgsConstructor
public class ScheduleQueryService {
private final ScheduleRepository scheduleRepository;

public List<Schedule> getAllScheduleManagements() {
return scheduleRepository.findAll();
}

public Schedule getScheduleManagement(Long id) {
return scheduleRepository
.findById(id)
.orElseThrow(ScheduleNotFoundException::new);
}
public Schedule getBySubmissionType(SubmissionType submissionType) {
return scheduleRepository.findBySubmissionType(submissionType)
.orElseThrow(ScheduleNotFoundException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package kgu.developers.domain.schedule.domain;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Schedule {

private Long id;
private SubmissionType submissionType;
private String title;
private String content;
private LocalDateTime startDate;
private LocalDateTime endDate;

private LocalDateTime createdAt;
private LocalDateTime updatedAt;
private LocalDateTime deletedAt;


public static Schedule create(SubmissionType submissionType, String title,String content, LocalDateTime startDate, LocalDateTime endDate) {
return Schedule.builder()
.submissionType(submissionType)
.title(title)
.content(content)
.startDate(startDate)
.endDate(endDate)
.build();
}
public ScheduleStatus determineStatusAt(LocalDateTime referenceTime) {
if (referenceTime.isBefore(startDate)) {
return ScheduleStatus.PENDING;
}
if (referenceTime.isAfter(endDate)) {
return ScheduleStatus.CLOSED;
}
return ScheduleStatus.IN_PROGRESS;
}
public void updateSubmissionType(SubmissionType submissionType) {
this.submissionType = submissionType;
}
public void updateTitle(String title) {
this.title = title;
}
public void updateContent(String content) {this.content = content;}
public void updateStartDate(LocalDateTime startDate) {
this.startDate = startDate;
}
public void updateEndDate(LocalDateTime endDate) {
this.endDate = endDate;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kgu.developers.domain.schedule.domain;

import java.util.List;
import java.util.Optional;

public interface ScheduleRepository {
Schedule save(Schedule schedule);
void deleteById(Long id);
Optional<Schedule> findById(Long id);
List<Schedule> findAll();
Optional<Schedule> findBySubmissionType(SubmissionType submissionType);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package kgu.developers.domain.schedule.domain;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum ScheduleStatus {
PENDING("대기"),
IN_PROGRESS("진행 중"),
CLOSED("마감")
;
private final String label;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package kgu.developers.domain.schedule.domain;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum SubmissionType {
SUBMITTED("신청접수"),
MIDTHESIS("중간논문"),
FINALTHESIS("최종논문"),
CERTIFICATE("자격증"),
APPROVED("최종 통과"),
OTHER("기타")
;
private final String label;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kgu.developers.domain.schedule.exception;

import kgu.developers.common.exception.CustomException;

import static kgu.developers.domain.schedule.exception.ScheduleDomainExceptionCode.DUPLICATE_SCHEDULE_TYPE;

public class DuplicateScheduleTypeException extends CustomException {
public DuplicateScheduleTypeException() {super(DUPLICATE_SCHEDULE_TYPE);}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package kgu.developers.domain.schedule.exception;

import kgu.developers.common.exception.ExceptionCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.NOT_FOUND;

@Getter
@AllArgsConstructor
public enum ScheduleDomainExceptionCode implements ExceptionCode {
DUPLICATE_SCHEDULE_TYPE(BAD_REQUEST, "동일 제출 유형의 일정이 이미 존재합 니다."),
SCHEDULE_MANAGEMENT_NOT_FOUND(NOT_FOUND,"해당 일정을 찾을 수 없습니다.");

private final HttpStatus status;
private final String message;

@Override
public String getCode() {return this.name();}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kgu.developers.domain.schedule.exception;

import kgu.developers.common.exception.CustomException;

import static kgu.developers.domain.schedule.exception.ScheduleDomainExceptionCode.SCHEDULE_MANAGEMENT_NOT_FOUND;

public class ScheduleNotFoundException extends CustomException {
public ScheduleNotFoundException() {super(SCHEDULE_MANAGEMENT_NOT_FOUND);}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package kgu.developers.domain.schedule.infrastructure.entity;

import jakarta.persistence.*;
import kgu.developers.common.domain.BaseTimeEntity;
import kgu.developers.domain.schedule.domain.Schedule;
import kgu.developers.domain.schedule.domain.SubmissionType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

import static jakarta.persistence.EnumType.STRING;
import static jakarta.persistence.GenerationType.IDENTITY;
import static lombok.AccessLevel.PROTECTED;

@Entity
@Getter
@Builder
@Table(name = "schedule", uniqueConstraints = @UniqueConstraint(columnNames = "submission_type"))
@NoArgsConstructor
@AllArgsConstructor(access = PROTECTED)
public class ScheduleJpaEntity extends BaseTimeEntity {

@Id
@GeneratedValue(strategy = IDENTITY)
private Long id;

@Column(name = "submission_type",nullable = false)
@Enumerated(STRING)
private SubmissionType submissionType;

@Column(nullable = false)
private String title;

@Column(nullable = false, columnDefinition = "text")
private String content;

@Column(nullable = false)
private LocalDateTime startDate;

@Column(nullable = false)
private LocalDateTime endDate;

public static ScheduleJpaEntity toEntity(final Schedule schedule) {
if (schedule == null) {
return null;
}

return ScheduleJpaEntity.builder()
.id(schedule.getId())
.submissionType(schedule.getSubmissionType())
.title(schedule.getTitle())
.content(schedule.getContent())
.startDate(schedule.getStartDate())
.endDate(schedule.getEndDate())
.build();
}
public Schedule toDomain(){
return Schedule.builder()
.id(id)
.submissionType(submissionType)
.title(title)
.startDate(startDate)
.content(content)
.endDate(endDate)
.createdAt(getCreatedAt())
.updatedAt(getUpdatedAt())
.deletedAt(getDeletedAt())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package kgu.developers.domain.schedule.infrastructure.repository;

import kgu.developers.domain.schedule.domain.SubmissionType;
import kgu.developers.domain.schedule.infrastructure.entity.ScheduleJpaEntity;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface JpaScheduleRepository extends JpaRepository<ScheduleJpaEntity, Long> {
Optional<ScheduleJpaEntity> findBySubmissionType(SubmissionType submissionType);

}
Loading