feat: update codes
This commit is contained in:
@@ -5,16 +5,38 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.CorsConfigurationSource;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsConfigurationSource corsConfigurationSource() {
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
config.setAllowedOrigins(List.of(
|
||||||
|
"http://localhost:5173",
|
||||||
|
"http://localhost:3000"
|
||||||
|
));
|
||||||
|
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
|
||||||
|
config.setAllowedHeaders(List.of("*"));
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SecurityFilterChain securityFilterChain(
|
public SecurityFilterChain securityFilterChain(
|
||||||
HttpSecurity http
|
HttpSecurity http
|
||||||
) throws Exception {
|
) throws Exception {
|
||||||
|
|
||||||
http
|
http
|
||||||
|
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
|
||||||
.csrf(AbstractHttpConfigurer::disable)
|
.csrf(AbstractHttpConfigurer::disable)
|
||||||
.authorizeHttpRequests(auth -> auth
|
.authorizeHttpRequests(auth -> auth
|
||||||
.anyRequest().permitAll()
|
.anyRequest().permitAll()
|
||||||
|
|||||||
@@ -1,6 +1,25 @@
|
|||||||
package aplp.backend.lms.course.application.dtos;
|
package aplp.backend.lms.course.application.dtos;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
public record CourseReqDto(
|
public record CourseReqDto(
|
||||||
|
@NotBlank(message = "Course code is required")
|
||||||
|
@Size(max = 50, message = "Course code must not exceed 50 characters")
|
||||||
|
String courseCode,
|
||||||
|
|
||||||
|
@NotBlank(message = "Title is required")
|
||||||
|
@Size(max = 200, message = "Title must not exceed 200 characters")
|
||||||
String title,
|
String title,
|
||||||
String description
|
|
||||||
|
@Size(max = 255, message = "Slug must not exceed 255 characters")
|
||||||
|
String slug,
|
||||||
|
|
||||||
|
@Size(max = 1000, message = "Description must not exceed 1000 characters")
|
||||||
|
String description,
|
||||||
|
|
||||||
|
@Size(max = 500, message = "Image URL must not exceed 500 characters")
|
||||||
|
String image,
|
||||||
|
|
||||||
|
Boolean isPublished
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
@@ -2,16 +2,30 @@ package aplp.backend.lms.course.application.dtos;
|
|||||||
|
|
||||||
import aplp.backend.lms.course.domain.entities.Course;
|
import aplp.backend.lms.course.domain.entities.Course;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
public record CourseResDto(
|
public record CourseResDto(
|
||||||
Long id,
|
Long id,
|
||||||
|
String courseCode,
|
||||||
String title,
|
String title,
|
||||||
String description
|
String slug,
|
||||||
|
String description,
|
||||||
|
String image,
|
||||||
|
boolean isPublished,
|
||||||
|
LocalDateTime createdAt,
|
||||||
|
LocalDateTime updatedAt
|
||||||
) {
|
) {
|
||||||
public static CourseResDto from(Course course) {
|
public static CourseResDto from(Course course) {
|
||||||
return new CourseResDto(
|
return new CourseResDto(
|
||||||
course.getId(),
|
course.getId(),
|
||||||
|
course.getCourseCode(),
|
||||||
course.getTitle(),
|
course.getTitle(),
|
||||||
course.getDescription()
|
course.getSlug(),
|
||||||
|
course.getDescription(),
|
||||||
|
course.getImage(),
|
||||||
|
course.isPublished(),
|
||||||
|
course.getCreatedAt(),
|
||||||
|
course.getUpdatedAt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,14 +5,8 @@ import jakarta.persistence.*;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
|
||||||
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
|
||||||
|
|
||||||
import java.time.Instant;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "courses")
|
@Table(name = "courses")
|
||||||
@EntityListeners(AuditingEntityListener.class)
|
@EntityListeners(AuditingEntityListener.class)
|
||||||
@@ -21,9 +15,21 @@ import java.time.Instant;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class Course extends BaseEntity {
|
public class Course extends BaseEntity {
|
||||||
|
|
||||||
|
@Column(name = "course_code", nullable = false, length = 50, unique = true)
|
||||||
|
private String courseCode;
|
||||||
|
|
||||||
@Column(nullable = false, length = 200)
|
@Column(nullable = false, length = 200)
|
||||||
private String title;
|
private String title;
|
||||||
|
|
||||||
|
@Column(nullable = false, unique = true, length = 255)
|
||||||
|
private String slug;
|
||||||
|
|
||||||
@Column(length = 1000)
|
@Column(length = 1000)
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@Column(length = 500)
|
||||||
|
private String image;
|
||||||
|
|
||||||
|
@Column(name = "is_published", nullable = false)
|
||||||
|
private boolean isPublished;
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,27 @@
|
|||||||
package aplp.backend.lms.lesson.application.dtos;
|
package aplp.backend.lms.lesson.application.dtos;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
public record LessonReqDto(
|
public record LessonReqDto(
|
||||||
@NotBlank(message = "Lesson code is required")
|
@NotNull(message = "Course ID is required")
|
||||||
@Size(max = 50, message = "Lesson code must not exceed 50 characters")
|
Long courseId,
|
||||||
String lessonCode,
|
|
||||||
|
|
||||||
@NotBlank(message = "Lesson name is required")
|
@NotBlank(message = "Title is required")
|
||||||
@Size(max = 200, message = "Lesson name must not exceed 200 characters")
|
@Size(max = 200, message = "Title must not exceed 200 characters")
|
||||||
String lessonName,
|
String title,
|
||||||
|
|
||||||
|
@Size(max = 255, message = "Slug must not exceed 255 characters")
|
||||||
|
String slug,
|
||||||
|
|
||||||
@Size(max = 1000, message = "Description must not exceed 1000 characters")
|
@Size(max = 1000, message = "Description must not exceed 1000 characters")
|
||||||
String description
|
String description,
|
||||||
|
|
||||||
|
@NotNull(message = "Position is required")
|
||||||
|
@Min(value = 1, message = "Position must be at least 1")
|
||||||
|
Integer position,
|
||||||
|
|
||||||
|
Boolean isPublished
|
||||||
) {}
|
) {}
|
||||||
|
|||||||
@@ -6,18 +6,24 @@ import java.time.LocalDateTime;
|
|||||||
|
|
||||||
public record LessonResDto(
|
public record LessonResDto(
|
||||||
Long id,
|
Long id,
|
||||||
String lessonCode,
|
Long courseId,
|
||||||
String lessonName,
|
String title,
|
||||||
|
String slug,
|
||||||
String description,
|
String description,
|
||||||
|
int position,
|
||||||
|
boolean isPublished,
|
||||||
LocalDateTime createdAt,
|
LocalDateTime createdAt,
|
||||||
LocalDateTime updatedAt
|
LocalDateTime updatedAt
|
||||||
) {
|
) {
|
||||||
public static LessonResDto from(Lesson lesson) {
|
public static LessonResDto from(Lesson lesson) {
|
||||||
return new LessonResDto(
|
return new LessonResDto(
|
||||||
lesson.getId(),
|
lesson.getId(),
|
||||||
lesson.getLessonCode(),
|
lesson.getCourse().getId(),
|
||||||
lesson.getLessonName(),
|
lesson.getTitle(),
|
||||||
|
lesson.getSlug(),
|
||||||
lesson.getDescription(),
|
lesson.getDescription(),
|
||||||
|
lesson.getPosition(),
|
||||||
|
lesson.isPublished(),
|
||||||
lesson.getCreatedAt(),
|
lesson.getCreatedAt(),
|
||||||
lesson.getUpdatedAt()
|
lesson.getUpdatedAt()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,31 @@
|
|||||||
package aplp.backend.lms.lesson.application.mappers;
|
package aplp.backend.lms.lesson.application.mappers;
|
||||||
|
|
||||||
|
import aplp.backend.lms.course.domain.entities.Course;
|
||||||
import aplp.backend.lms.lesson.application.dtos.LessonReqDto;
|
import aplp.backend.lms.lesson.application.dtos.LessonReqDto;
|
||||||
import aplp.backend.lms.lesson.application.dtos.LessonResDto;
|
import aplp.backend.lms.lesson.application.dtos.LessonResDto;
|
||||||
import aplp.backend.lms.lesson.domain.entities.Lesson;
|
import aplp.backend.lms.lesson.domain.entities.Lesson;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
import org.mapstruct.MappingTarget;
|
import org.mapstruct.MappingTarget;
|
||||||
|
|
||||||
@Mapper(componentModel = "spring")
|
@Mapper(componentModel = "spring")
|
||||||
public interface LessonMapper {
|
public interface LessonMapper {
|
||||||
|
|
||||||
|
@Mapping(source = "course.id", target = "courseId")
|
||||||
LessonResDto toResponse(Lesson lesson);
|
LessonResDto toResponse(Lesson lesson);
|
||||||
|
|
||||||
|
@Mapping(source = "courseId", target = "course")
|
||||||
Lesson toEntity(LessonReqDto request);
|
Lesson toEntity(LessonReqDto request);
|
||||||
|
|
||||||
void updateEntity(
|
void updateEntity(
|
||||||
LessonReqDto request,
|
LessonReqDto request,
|
||||||
@MappingTarget Lesson lesson
|
@MappingTarget Lesson lesson
|
||||||
);
|
);
|
||||||
|
|
||||||
|
default Course mapCourse(Long courseId) {
|
||||||
|
if (courseId == null) return null;
|
||||||
|
Course course = new Course();
|
||||||
|
course.setId(courseId);
|
||||||
|
return course;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
package aplp.backend.lms.lesson.domain.entities;
|
package aplp.backend.lms.lesson.domain.entities;
|
||||||
|
|
||||||
import aplp.backend.core.common.entity.BaseEntity;
|
import aplp.backend.core.common.entity.BaseEntity;
|
||||||
import jakarta.persistence.Column;
|
import aplp.backend.lms.course.domain.entities.Course;
|
||||||
import jakarta.persistence.Entity;
|
import jakarta.persistence.*;
|
||||||
import jakarta.persistence.Table;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
@@ -15,12 +14,22 @@ import lombok.Setter;
|
|||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class Lesson extends BaseEntity {
|
public class Lesson extends BaseEntity {
|
||||||
|
|
||||||
@Column(name = "lesson_code", nullable = false, length = 50, unique = true)
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
private String lessonCode;
|
@JoinColumn(name = "course_id", nullable = false)
|
||||||
|
private Course course;
|
||||||
|
|
||||||
@Column(name = "lesson_name", nullable = false, length = 200)
|
@Column(nullable = false, length = 200)
|
||||||
private String lessonName;
|
private String title;
|
||||||
|
|
||||||
|
@Column(nullable = false, unique = true, length = 255)
|
||||||
|
private String slug;
|
||||||
|
|
||||||
@Column(length = 1000)
|
@Column(length = 1000)
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private int position;
|
||||||
|
|
||||||
|
@Column(name = "is_published", nullable = false)
|
||||||
|
private boolean isPublished;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ public interface LessonRepository {
|
|||||||
|
|
||||||
List<Lesson> findAll();
|
List<Lesson> findAll();
|
||||||
|
|
||||||
|
List<Lesson> findByCourseId(Long courseId);
|
||||||
|
|
||||||
Lesson save(Lesson lesson);
|
Lesson save(Lesson lesson);
|
||||||
|
|
||||||
void deleteById(Long id);
|
void deleteById(Long id);
|
||||||
|
|||||||
+3
@@ -4,6 +4,9 @@ import aplp.backend.lms.lesson.domain.entities.Lesson;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
public interface LessonJpaRepository extends JpaRepository<Lesson, Long> {
|
public interface LessonJpaRepository extends JpaRepository<Lesson, Long> {
|
||||||
|
List<Lesson> findByCourseIdOrderByPositionAsc(Long courseId);
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -23,6 +23,11 @@ public class LessonRepositoryImpl implements LessonRepository {
|
|||||||
return repository.findAll();
|
return repository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Lesson> findByCourseId(Long courseId) {
|
||||||
|
return repository.findByCourseIdOrderByPositionAsc(courseId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Lesson save(Lesson lesson) {
|
public Lesson save(Lesson lesson) {
|
||||||
return repository.save(lesson);
|
return repository.save(lesson);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ spring:
|
|||||||
name: lms
|
name: lms
|
||||||
|
|
||||||
datasource:
|
datasource:
|
||||||
url: jdbc:postgresql://192.168.2.100:5432/aplp
|
url: jdbc:postgresql://pgsql.koda.id.vn:5432/aplp
|
||||||
username: postgres
|
username: postgres
|
||||||
password: Pa55w0rd
|
password: Pa55w0rd
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user