feat: 수강신청 프로젝트 생성
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.study.course_registration;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CourseRegistrationApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CourseRegistrationApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.study.course_registration.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
|
||||
|
||||
@Configuration
|
||||
@EnableJpaAuditing
|
||||
public class JpaConfig {
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.study.course_registration.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.study.course_registration.service.CourseRegistrationService;
|
||||
|
||||
import com.study.course_registration.dto.RequestDto;
|
||||
import com.study.course_registration.dto.ResponseDto;
|
||||
|
||||
@RestController
|
||||
@RequestMapping ("/api/v1")
|
||||
public class CourseRegistrationController {
|
||||
|
||||
private final CourseRegistrationService courseRegistrationService;
|
||||
|
||||
public CourseRegistrationController(CourseRegistrationService courseRegistrationService) {
|
||||
this.courseRegistrationService = courseRegistrationService;
|
||||
}
|
||||
|
||||
@PostMapping("/course-register")
|
||||
@Operation(summary = "Register a course",
|
||||
description = "Registers a new course with the provided details.")
|
||||
@ApiResponses({
|
||||
@ApiResponse (responseCode = "200", description = "Course registered successfully"),
|
||||
@ApiResponse (responseCode = "400", description = "Invalid request data")
|
||||
})
|
||||
public ResponseDto registerCourse(@Validated RequestDto requestDto) {
|
||||
return courseRegistrationService.registerCourse(requestDto);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.study.course_registration.dto;
|
||||
|
||||
public record RequestDto(
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.study.course_registration.dto;
|
||||
|
||||
public record ResponseDto(
|
||||
|
||||
) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@MappedSuperclass
|
||||
@EntityListeners (AuditingEntityListener.class)
|
||||
public class BaseCreateEntity {
|
||||
@CreatedDate
|
||||
private Instant createdAt;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import lombok.Getter;
|
||||
|
||||
@MappedSuperclass
|
||||
@Getter
|
||||
public class BaseDeleteEntity {
|
||||
private Instant deletedAt;
|
||||
|
||||
public void delete() {
|
||||
this.deletedAt = Instant.now();
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
this.deletedAt = null;
|
||||
}
|
||||
|
||||
public boolean isDeleted() {
|
||||
return this.deletedAt != null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@MappedSuperclass
|
||||
public class BaseEntity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.UUID)
|
||||
private String id;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
import org.springframework.data.annotation.LastModifiedDate;
|
||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
import jakarta.persistence.MappedSuperclass;
|
||||
|
||||
@MappedSuperclass
|
||||
@EntityListeners (AuditingEntityListener.class)
|
||||
public class BaseTimeZoneEntity extends BaseEntity {
|
||||
@CreatedDate
|
||||
private Instant createdAt;
|
||||
|
||||
@LastModifiedDate
|
||||
private Instant updatedAt;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Table(name = "lessons")
|
||||
public class Lesson extends BaseTimeZoneEntity {
|
||||
private String name;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private Subject subject;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
private Professor professor;
|
||||
|
||||
private Instant startTime;
|
||||
|
||||
private Instant endTime;
|
||||
|
||||
public Lesson(String name, Subject subject, Professor professor, Instant startTime, Instant endTime) {
|
||||
this.name = name;
|
||||
this.subject = subject;
|
||||
this.professor = professor;
|
||||
this.startTime = startTime;
|
||||
this.endTime = endTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Table(name = "professors")
|
||||
public class Professor extends BaseTimeZoneEntity {
|
||||
private String name;
|
||||
|
||||
public Professor(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Table(name = "subjects")
|
||||
public class Subject extends BaseTimeZoneEntity {
|
||||
private String name;
|
||||
|
||||
private String code;
|
||||
|
||||
private String description;
|
||||
|
||||
public Subject(String name, String code, String description) {
|
||||
this.name = name;
|
||||
this.code = code;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import com.study.course_registration.enums.UserRole;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@Table(name = "users")
|
||||
public class User extends BaseTimeZoneEntity {
|
||||
private String name;
|
||||
|
||||
private Long grade;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
private UserRole role;
|
||||
|
||||
public User(String name, Long grade, UserRole role) {
|
||||
this.name = name;
|
||||
this.grade = grade;
|
||||
this.role = role;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@Table(name = "user_lessons")
|
||||
public class UserLesson extends BaseCreateEntity {
|
||||
|
||||
@EmbeddedId
|
||||
private UserLessonId id;
|
||||
|
||||
@MapsId("userId")
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn (
|
||||
name = "user_id",
|
||||
foreignKey = @ForeignKey(name = "fk_user_lesson_user_id")
|
||||
)
|
||||
private User user;
|
||||
|
||||
@MapsId("lessonId")
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn (
|
||||
name = "lesson_id",
|
||||
foreignKey = @ForeignKey(name = "fk_user_lesson_lesson_id")
|
||||
)
|
||||
private Lesson lesson;
|
||||
|
||||
public UserLesson(User user, Lesson lesson) {
|
||||
this.user = user;
|
||||
this.lesson = lesson;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.study.course_registration.entity;
|
||||
|
||||
import jakarta.persistence.Embeddable;
|
||||
import java.io.Serializable;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Embeddable
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
public class UserLessonId implements Serializable {
|
||||
private String userId;
|
||||
private String lessonId;
|
||||
|
||||
public UserLessonId(String userId, String lessonId) {
|
||||
this.userId = userId;
|
||||
this.lessonId = lessonId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.study.course_registration.enums;
|
||||
|
||||
public enum UserRole {
|
||||
STUDENT, POSTGRADUATE
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.study.course_registration.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.study.course_registration.entity.Lesson;
|
||||
|
||||
public interface LessonRepository extends JpaRepository<Lesson, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.study.course_registration.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.study.course_registration.entity.Professor;
|
||||
|
||||
public interface ProfessorRepository extends JpaRepository<Professor, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.study.course_registration.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.study.course_registration.entity.Subject;
|
||||
|
||||
public interface SubjectRepository extends JpaRepository<Subject, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.study.course_registration.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.study.course_registration.entity.UserLesson;
|
||||
import com.study.course_registration.entity.UserLessonId;
|
||||
|
||||
public interface UserLessonRepository extends JpaRepository<UserLesson, UserLessonId> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.study.course_registration.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.study.course_registration.entity.User;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, String> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.study.course_registration.seeder;
|
||||
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.study.course_registration.entity.Lesson;
|
||||
import com.study.course_registration.entity.Professor;
|
||||
import com.study.course_registration.entity.Subject;
|
||||
import com.study.course_registration.entity.User;
|
||||
import com.study.course_registration.entity.UserLesson;
|
||||
import com.study.course_registration.enums.UserRole;
|
||||
import com.study.course_registration.repository.LessonRepository;
|
||||
import com.study.course_registration.repository.UserRepository;
|
||||
import com.study.course_registration.repository.SubjectRepository;
|
||||
import com.study.course_registration.repository.ProfessorRepository;
|
||||
import com.study.course_registration.repository.UserLessonRepository;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
|
||||
@Component
|
||||
@Profile ("local")
|
||||
public class DataSeeder implements CommandLineRunner {
|
||||
|
||||
private static final ZoneId KST = ZoneId.of("Asia/Seoul");
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final LessonRepository lessonRepository;
|
||||
private final SubjectRepository subjectRepository;
|
||||
private final ProfessorRepository professorRepository;
|
||||
private final UserLessonRepository userLessonRepository;
|
||||
|
||||
public DataSeeder(UserRepository userRepository, LessonRepository lessonRepository, SubjectRepository subjectRepository, ProfessorRepository professorRepository, UserLessonRepository userLessonRepository) {
|
||||
this.userRepository = userRepository;
|
||||
this.lessonRepository = lessonRepository;
|
||||
this.subjectRepository = subjectRepository;
|
||||
this.professorRepository = professorRepository;
|
||||
this.userLessonRepository = userLessonRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void run(String... args) throws Exception {
|
||||
if(userRepository.count() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Professor> professors = professorRepository.saveAll(List.of(
|
||||
new Professor("김영한"),
|
||||
new Professor("최태영"),
|
||||
new Professor("조재한")
|
||||
));
|
||||
|
||||
List<Subject> subjects = subjectRepository.saveAll(List.of(
|
||||
new Subject("자바 프로그래밍", "CS201", "자바 프로그래밍 기초"),
|
||||
new Subject("자료구조", "CS202", "자료구조 및 알고리즘"),
|
||||
new Subject("데이터베이스", "CS203", "데이터베이스 시스템")
|
||||
));
|
||||
|
||||
Instant base = Instant.now().truncatedTo(ChronoUnit.HOURS);
|
||||
List<Lesson> lessons = lessonRepository.saveAll(List.of(
|
||||
new Lesson("자바 프로그래밍", subjects.get(0), professors.get(0), kst(3, 2, 9), kst(3, 2, 11)),
|
||||
new Lesson("자료구조", subjects.get(1), professors.get(1), kst(3, 2, 13), kst(3, 2, 17)),
|
||||
new Lesson("데이터베이스", subjects.get(2), professors.get(2), kst(3, 3, 10), kst(3, 3, 14))
|
||||
));
|
||||
|
||||
List<User> users = userRepository.saveAll(List.of(
|
||||
new User("학생1", 1L, UserRole.STUDENT),
|
||||
new User("학생2", 2L, UserRole.STUDENT),
|
||||
new User("대학원생", 3L, UserRole.POSTGRADUATE)
|
||||
));
|
||||
|
||||
List<UserLesson> userLessons = userLessonRepository.saveAll(List.of(
|
||||
new UserLesson(users.get(0), lessons.get(0)),
|
||||
new UserLesson(users.get(0), lessons.get(1)),
|
||||
new UserLesson(users.get(1), lessons.get(1)),
|
||||
new UserLesson(users.get(2), lessons.get(2))
|
||||
));
|
||||
}
|
||||
|
||||
private Instant kst(int month, int day, int hour) {
|
||||
return ZonedDateTime.of(2026, month, day, hour, 0, 0, 0, KST).toInstant();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.study.course_registration.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.study.course_registration.dto.RequestDto;
|
||||
import com.study.course_registration.dto.ResponseDto;
|
||||
import com.study.course_registration.repository.LessonRepository;
|
||||
import com.study.course_registration.repository.UserLessonRepository;
|
||||
import com.study.course_registration.repository.UserRepository;
|
||||
import com.study.course_registration.repository.SubjectRepository;
|
||||
import com.study.course_registration.repository.ProfessorRepository;
|
||||
|
||||
@Service
|
||||
public class CourseRegistrationService {
|
||||
private final UserRepository userRepository;
|
||||
private final LessonRepository lessonRepository;
|
||||
private final SubjectRepository subjectRepository;
|
||||
private final ProfessorRepository professorRepository;
|
||||
private final UserLessonRepository userLessonRepository;
|
||||
|
||||
public CourseRegistrationService(UserRepository userRepository, LessonRepository lessonRepository, SubjectRepository subjectRepository, ProfessorRepository professorRepository, UserLessonRepository userLessonRepository) {
|
||||
this.userRepository = userRepository;
|
||||
this.lessonRepository = lessonRepository;
|
||||
this.subjectRepository = subjectRepository;
|
||||
this.professorRepository = professorRepository;
|
||||
this.userLessonRepository = userLessonRepository;
|
||||
}
|
||||
|
||||
public ResponseDto registerCourse(RequestDto requestDto) {
|
||||
|
||||
return new ResponseDto();
|
||||
}
|
||||
}
|
||||
// 저장 전 log
|
||||
// 검증 로직
|
||||
//
|
||||
@@ -0,0 +1,21 @@
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:h2:mem:course_db
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: create-drop
|
||||
show-sql: true
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.hibernate.SQL: debug
|
||||
@@ -0,0 +1,28 @@
|
||||
server:
|
||||
application:
|
||||
name: ${APP_NAME:course-registration}
|
||||
profiles:
|
||||
active: ${APP_PROFILE:local}
|
||||
|
||||
spring:
|
||||
jackson:
|
||||
time-zone: UTC
|
||||
h2:
|
||||
console:
|
||||
enabled: true
|
||||
path: /h2-console
|
||||
datasource:
|
||||
url: jdbc:h2:mem:course_db
|
||||
username: sa
|
||||
password:
|
||||
driver-class-name: org.h2.Driver
|
||||
jpa:
|
||||
hibernate:
|
||||
ddl-auto: create
|
||||
show-sql: true
|
||||
properties:
|
||||
hibernate:
|
||||
format_sql: true
|
||||
|
||||
logging.level:
|
||||
org.hibernate.SQL: debug
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.study.course_registration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class CourseRegistrationApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user