Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] Lesson 저장 로직 구현 #17

Closed
wants to merge 15 commits into from
7 changes: 7 additions & 0 deletions doochul/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-webflux'
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

implementation 'com.google.firebase:firebase-admin:9.2.0'

runtimeOnly 'mysql:mysql-connector-java'
runtimeOnly 'com.h2database:h2'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
31 changes: 31 additions & 0 deletions doochul/src/main/java/org/doochul/application/LessonService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.doochul.application;

import lombok.RequiredArgsConstructor;
import org.doochul.domain.lesson.Lesson;
import org.doochul.domain.lesson.LessonRepository;
import org.doochul.domain.membership.MemberShip;
import org.doochul.domain.membership.MemberShipRepository;
import org.doochul.domain.product.Product;
import org.doochul.domain.product.ProductRepository;
import org.doochul.domain.user.User;
import org.doochul.domain.user.UserRepository;
import org.doochul.ui.dto.LessonRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class LessonService {

private final LessonRepository lessonRepository;
private final MemberShipRepository memberShipRepository;
private final UserRepository userRepository;

@Transactional
public Long save(final Long userId, final Long membershipId, final LessonRequest lessonRequest) {
final User user = userRepository.findById(userId).orElseThrow();
final MemberShip memberShip = memberShipRepository.findById(membershipId).orElseThrow();

return lessonRepository.save(Lesson.of(user, memberShip.getProduct().getTeacher(),memberShip, lessonRequest.startedAt(), lessonRequest.endedAt(), lessonRequest.record())).getId();
}
}
20 changes: 20 additions & 0 deletions doochul/src/main/java/org/doochul/application/ProductService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.doochul.application;

import java.util.List;
import lombok.RequiredArgsConstructor;
import org.doochul.domain.product.Product;
import org.doochul.domain.product.ProductRepository;
import org.doochul.ui.dto.ProductResponse;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class ProductService {

private final ProductRepository productRepository;

public List<ProductResponse> findMemberShipsById(Long userId) {
List<Product> products = productRepository.findByUserId(userId);
Comment on lines +16 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파라미터랑 products에 final 키워드 붙혀주세요

return ProductResponse.fromList(products);
}
}
25 changes: 25 additions & 0 deletions doochul/src/main/java/org/doochul/application/RedisService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.doochul.application;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;

@Service
public class RedisService {

private final RedisTemplate<String, String> redisTemplate;

public RedisService(final RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}

public void delete(final String key) {
redisTemplate.delete(key);
}


public boolean setNX(final String key, final String value, final Duration duration) {
return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value, duration));
}
}
22 changes: 22 additions & 0 deletions doochul/src/main/java/org/doochul/config/AppConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.doochul.config;

import java.time.Clock;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
public class AppConfig {

@Bean
public Clock clock() {
return Clock.systemDefaultZone();
}

@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(2);
return scheduler;
}
}
26 changes: 26 additions & 0 deletions doochul/src/main/java/org/doochul/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.doochul.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}

@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
10 changes: 10 additions & 0 deletions doochul/src/main/java/org/doochul/config/SchedulingConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.doochul.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

@Configuration
@EnableScheduling
public class SchedulingConfig {

}
29 changes: 29 additions & 0 deletions doochul/src/main/java/org/doochul/domain/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.doochul.domain;

import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.PreUpdate;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
@MappedSuperclass
public abstract class BaseEntity {

@Column(updatable = false, nullable = false)
private LocalDateTime createdAt;

@Column(nullable = false)
private LocalDateTime updatedAt;

public BaseEntity() {
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}

@PreUpdate
public void update() {
this.updatedAt = LocalDateTime.now();
}
}
59 changes: 59 additions & 0 deletions doochul/src/main/java/org/doochul/domain/lesson/Lesson.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.doochul.domain.lesson;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;

import java.time.LocalDateTime;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.doochul.domain.BaseEntity;
import org.doochul.domain.membership.MemberShip;
import org.doochul.domain.user.User;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Lesson extends BaseEntity {

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

@ManyToOne
@JoinColumn(name = "membership_id")
private MemberShip memberShip;

@ManyToOne
@JoinColumn(name = "user_id")
private User user;

@ManyToOne
@JoinColumn(name = "teacher_id")
private User teacher;

private LocalDateTime startedAt;

private LocalDateTime endedAt;

private String record;

private Lesson(Long id, User user, User teacher, MemberShip memberShip, LocalDateTime startedAt, LocalDateTime endedAt, String record) {
this.id = id;
this.user = user;
this.teacher = teacher;
this.memberShip = memberShip;
this.startedAt = startedAt;
this.endedAt = endedAt;
this.record = record;
}

public static Lesson of(User user, User teacher, MemberShip memberShip, LocalDateTime startedAt, LocalDateTime endedAt, String record) {
return new Lesson(null, user, teacher,memberShip, startedAt, endedAt, record);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.doochul.domain.lesson;

import org.doochul.domain.product.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;

@Repository
public interface LessonRepository extends JpaRepository<Lesson, Long> {
default Lesson getById(final Long id) {
return findById(id).orElseThrow(() -> new IllegalArgumentException("해당 수업이 없습니다."));
}
List<Lesson> findByStartedAtBefore(final LocalDateTime currentServerTime);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.doochul.domain.membership;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.doochul.domain.BaseEntity;
import org.doochul.domain.product.Product;
import org.doochul.domain.user.User;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MemberShip extends BaseEntity {

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

@ManyToOne
@JoinColumn(name = "user_id")
private User student;

@ManyToOne
@JoinColumn(name = "product_id")
private Product product;

private Integer remainingCount;

public void decreasedCount() {
validateMinRemainingCount();
remainingCount -= 1;
}

public boolean isCountZero() {
return remainingCount == 0;
}

private void validateMinRemainingCount() {
if (remainingCount < 1) {
throw new IllegalArgumentException("안돼");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.doochul.domain.membership;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MemberShipRepository extends JpaRepository<MemberShip, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.doochul.domain.membership;

public enum MemberShipType {
LOL, TFT
}
36 changes: 36 additions & 0 deletions doochul/src/main/java/org/doochul/domain/product/Product.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.doochul.domain.product;

import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.doochul.domain.BaseEntity;
import org.doochul.domain.user.User;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Product extends BaseEntity {

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

private String name;

@Enumerated(EnumType.STRING)
private ProductType type;

@ManyToOne
@JoinColumn(name = "teacher_id")
private User teacher;

private Integer count;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.doochul.domain.product;

import java.util.List;

import org.doochul.domain.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findAll();
List<Product> findByUserId(Long userId);
Comment on lines +11 to +12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

둘다 없애도될거같아요!
findByUserId는 UserRepository에서 가져오고 findAll은 정의되있어서요..

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.doochul.domain.product;

public enum ProductType {
LOL, TFT
}
5 changes: 5 additions & 0 deletions doochul/src/main/java/org/doochul/domain/user/Gender.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.doochul.domain.user;

public enum Gender {
MEN, WOMEN
}
5 changes: 5 additions & 0 deletions doochul/src/main/java/org/doochul/domain/user/Identity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.doochul.domain.user;

public enum Identity {
GENERAL, TEACHER
}
Loading