Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ out/
### VS Code ###
.vscode/

docker-compose/.env
docker-compose/.env
docker-compose/.env.local
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package life.mosu.mosuserver.application.admin;

import java.util.List;
import life.mosu.mosuserver.domain.admin.ApplicationQueryRepositoryImpl;
import life.mosu.mosuserver.domain.admin.StudentQueryRepositoryImpl;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationExcelDto;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationFilter;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationListResponse;
import life.mosu.mosuserver.presentation.admin.dto.SchoolLunchResponse;
import life.mosu.mosuserver.presentation.admin.dto.StudentExcelDto;
import life.mosu.mosuserver.presentation.admin.dto.StudentFilter;
import life.mosu.mosuserver.presentation.admin.dto.StudentListResponse;
Expand All @@ -17,6 +22,7 @@
public class AdminService {

private final StudentQueryRepositoryImpl studentQueryRepository;
private final ApplicationQueryRepositoryImpl applicationQueryRepository;

public Page<StudentListResponse> getStudents(StudentFilter filter, Pageable pageable) {
return studentQueryRepository.searchAllStudents(filter, pageable);
Expand All @@ -25,4 +31,18 @@ public Page<StudentListResponse> getStudents(StudentFilter filter, Pageable page
public List<StudentExcelDto> getStudentExcelData() {
return studentQueryRepository.searchAllStudentsForExcel();
}

public List<SchoolLunchResponse> getLunchCounts() {
return applicationQueryRepository.searchAllSchoolLunches();
}

public Page<ApplicationListResponse> getApplications(ApplicationFilter filter,
Pageable pageable) {
return applicationQueryRepository.searchAllApplications(filter, pageable);
}

public List<ApplicationExcelDto> getApplicationExcelData() {
return applicationQueryRepository.searchAllApplicationsForExcel();
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package life.mosu.mosuserver.application.application;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
Expand All @@ -9,6 +10,9 @@
import life.mosu.mosuserver.domain.application.ApplicationJpaRepository;
import life.mosu.mosuserver.domain.application.ApplicationSchoolJpaRepository;
import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaEntity;
import life.mosu.mosuserver.domain.school.AddressJpaVO;
import life.mosu.mosuserver.domain.school.SchoolJpaEntity;
import life.mosu.mosuserver.domain.school.SchoolJpaRepository;
import life.mosu.mosuserver.global.exception.CustomRuntimeException;
import life.mosu.mosuserver.global.exception.ErrorCode;
import life.mosu.mosuserver.global.util.FileRequest;
Expand All @@ -29,12 +33,13 @@ public class ApplicationService {
private final ApplicationJpaRepository applicationJpaRepository;
private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository;
private final AdmissionTicketImageJpaRepository admissionTicketImageJpaRepository;
private final SchoolJpaRepository schoolJpaRepository;

// 신청
@Transactional
public ApplicationResponse apply(Long userId, ApplicationRequest request) {
Set<ApplicationSchoolRequest> schools = request.schools();
List<ApplicationSchoolJpaEntity> schoolEntities = new java.util.ArrayList<>(List.of());
List<ApplicationSchoolJpaEntity> schoolEntities = new ArrayList<>();

Set<Long> schoolIds = schools.stream()
.map(ApplicationSchoolRequest::schoolId)
Expand All @@ -45,16 +50,23 @@ public ApplicationResponse apply(Long userId, ApplicationRequest request) {
}

ApplicationJpaEntity application = request.toEntity(userId);

ApplicationJpaEntity applicationJpaEntity = applicationJpaRepository.save(application);
Long applicationId = applicationJpaEntity.getId();

admissionTicketImageJpaRepository.save(
createAdmissionTicketImageIfPresent(request.admissionTicket(), applicationId));

schools.forEach(applicationSchoolRequest -> {
SchoolJpaEntity school = schoolJpaRepository.findById(
applicationSchoolRequest.schoolId())
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND));

AddressJpaVO address = school.getAddress();
ApplicationSchoolJpaEntity applicationSchoolJpaEntity = applicationSchoolRequest.toEntity(
userId, applicationId);
schoolEntities.add(applicationSchoolJpaRepository.save(applicationSchoolJpaEntity));
userId, applicationId, address);
ApplicationSchoolJpaEntity saved = applicationSchoolJpaRepository.save(
applicationSchoolJpaEntity);
schoolEntities.add(saved);
});

return ApplicationResponse.of(applicationId, schoolEntities);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package life.mosu.mosuserver.application.applicationschool;

import java.time.Duration;
import java.util.Set;
import java.util.stream.Collectors;
import life.mosu.mosuserver.domain.application.AdmissionTicketImageJpaEntity;
import life.mosu.mosuserver.domain.application.AdmissionTicketImageJpaRepository;
import life.mosu.mosuserver.domain.application.ApplicationJpaEntity;
import life.mosu.mosuserver.domain.application.ApplicationJpaRepository;
import life.mosu.mosuserver.domain.application.ApplicationSchoolJpaRepository;
import life.mosu.mosuserver.domain.application.Subject;
import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaEntity;
import life.mosu.mosuserver.domain.profile.ProfileJpaEntity;
import life.mosu.mosuserver.domain.profile.ProfileJpaRepository;
Expand All @@ -23,7 +26,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

@Service
@RequiredArgsConstructor
Expand All @@ -41,7 +43,6 @@ public class ApplicationSchoolService {

@Transactional
public ApplicationSchoolResponse updateSubjects(
@RequestParam Long userId,
Long applicationSchoolId,
SubjectUpdateRequest request
) {
Expand All @@ -56,7 +57,6 @@ public ApplicationSchoolResponse updateSubjects(

@Transactional
public void cancelApplicationSchool(
@RequestParam Long userId,
Long applicationSchoolId,
RefundRequest request
) {
Expand Down Expand Up @@ -104,12 +104,16 @@ public AdmissionTicketResponse getAdmissionTicket(Long userId, Long applicationS
AdmissionTicketImageJpaEntity admissionTicketImage = admissionTicketImageJpaRepository.findByApplicationId(
application.getId());

Set<String> subjectNames = applicationSchool.getSubjects().stream()
.map(Subject::getSubjectName)
.collect(Collectors.toSet());

return AdmissionTicketResponse.of(
getAdmissionTicketImageUrl(admissionTicketImage),
profile.getUserName(),
profile.getBirth(),
applicationSchool.getExaminationNumber(),
applicationSchool.getSubjects(),
subjectNames,
applicationSchool.getSchoolName()
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package life.mosu.mosuserver.domain.admin;

import java.util.List;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationExcelDto;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationFilter;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationListResponse;
import life.mosu.mosuserver.presentation.admin.dto.SchoolLunchResponse;
Comment on lines +4 to +7
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Architecture concern: Domain layer importing presentation DTOs.

The domain layer is importing DTOs from the presentation layer (lines 4-7), which violates the typical layered architecture where domain should not depend on presentation. This creates a reverse dependency that makes the domain layer less reusable and harder to test.

Consider moving these DTOs to a shared package or creating separate domain-specific DTOs:

- import life.mosu.mosuserver.presentation.admin.dto.ApplicationExcelDto;
- import life.mosu.mosuserver.presentation.admin.dto.ApplicationFilter;
- import life.mosu.mosuserver.presentation.admin.dto.ApplicationListResponse;
- import life.mosu.mosuserver.presentation.admin.dto.SchoolLunchResponse;
+ import life.mosu.mosuserver.domain.admin.dto.ApplicationExcelDto;
+ import life.mosu.mosuserver.domain.admin.dto.ApplicationFilter;
+ import life.mosu.mosuserver.domain.admin.dto.ApplicationListResponse;
+ import life.mosu.mosuserver.domain.admin.dto.SchoolLunchResponse;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import life.mosu.mosuserver.presentation.admin.dto.ApplicationExcelDto;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationFilter;
import life.mosu.mosuserver.presentation.admin.dto.ApplicationListResponse;
import life.mosu.mosuserver.presentation.admin.dto.SchoolLunchResponse;
import life.mosu.mosuserver.domain.admin.dto.ApplicationExcelDto;
import life.mosu.mosuserver.domain.admin.dto.ApplicationFilter;
import life.mosu.mosuserver.domain.admin.dto.ApplicationListResponse;
import life.mosu.mosuserver.domain.admin.dto.SchoolLunchResponse;
🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/domain/admin/ApplicationQueryRepository.java
around lines 4 to 7, the domain layer is importing DTO classes from the
presentation layer, which breaks the layered architecture by creating a reverse
dependency. To fix this, refactor by moving these DTO classes to a shared or
common package accessible by both domain and presentation layers, or create new
domain-specific DTOs within the domain layer itself, then update the imports
accordingly to remove any direct dependency on the presentation layer.

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

public interface ApplicationQueryRepository {

Page<ApplicationListResponse> searchAllApplications(ApplicationFilter filter,
Pageable pageable);

List<ApplicationExcelDto> searchAllApplicationsForExcel();

List<SchoolLunchResponse> searchAllSchoolLunches();
}
Loading