Skip to content
Closed

Yerak #127

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
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ dependencies {
// 메일 서버 연결 라이브러리
implementation 'org.springframework.boot:spring-boot-starter-mail'

// Jwt
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
implementation 'io.jsonwebtoken:jjwt-impl:0.11.5'
implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

@SpringBootApplication
@EnableScheduling // SchedulerService를 위한 Annotation
@EnableAsync // 비동기 처리 허용
public class DevkorProjectApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.example.Devkor_project.controller;

import com.example.Devkor_project.dto.PrivacyDto;
import com.example.Devkor_project.dto.PrivacyUpdateDto;
import com.example.Devkor_project.dto.ResponseDto;
import com.example.Devkor_project.service.PrivacyService;
import com.example.Devkor_project.configuration.VersionProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;

import java.security.Principal;
import java.util.List;

@RestController
@RequestMapping("/api/privacy")
@RequiredArgsConstructor
@Tag(name = "Privacy 개인일정", description = "개인일정(privacy) 관련 API입니다.")
public class PrivacyController {

private final PrivacyService privacyService;
private final VersionProvider versionProvider;

@GetMapping
@Operation(summary = "해당 사용자의 모든 개인일정 조회")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public List<PrivacyDto> getAllPrivacy(Principal principal) {
return privacyService.getAllPrivacy(principal);
}

@GetMapping("/timetable/{timetableId}")
@Operation(summary = "특정 시간표의 개인일정 조회")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
@Parameter(in = ParameterIn.PATH, name = "timetableId", description = "조회할 시간표 ID")
public List<PrivacyDto> getPrivacyByTimetable(@PathVariable ("timetableId")Long timetableId, Principal principal) {
return privacyService.getPrivacyByTimetable(timetableId, principal);
}


// @PostMapping
// @Operation(summary = "개인일정 생성")
// @Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
// public PrivacyDto createPrivacy(@Valid @RequestBody PrivacyDto privacyDto, Principal principal) {
// return privacyService.createPrivacy(privacyDto, principal);
// }

@PostMapping
@Operation(summary = "개인일정 생성(요일이름 반드시 한글자로 할것!!! ex. 월, 수, 토)")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> createPrivacy(@Valid @RequestBody PrivacyDto privacyDto, Principal principal) {
PrivacyDto createdPrivacy = privacyService.createPrivacy(privacyDto, principal);

return ResponseEntity.status(HttpStatus.OK)
.body(ResponseDto.Success.builder()
.message("개인일정이 성공적으로 생성되었습니다.")
.data(createdPrivacy)
.version(versionProvider.getVersion())
.build()
);
}

@PutMapping("/{privacyId}")
@Operation(summary = "개인일정 수정 (이름 & 장소만 변경 가능)")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
@Parameter(in = ParameterIn.PATH, name = "privacyId", description = "수정할 개인일정 ID")
public ResponseEntity<ResponseDto.Success> updatePrivacy(@PathVariable ("privacyId")Long privacyId, @Valid @RequestBody PrivacyUpdateDto privacyUpdateDto, Principal principal) {
return privacyService.updatePrivacy(privacyId, privacyUpdateDto, principal);
}

@DeleteMapping("/{privacyId}")
@Operation(summary = "개인일정 삭제")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> deletePrivacy(@PathVariable ("privacyId")Long privacyId, Principal principal) {
privacyService.deletePrivacy(privacyId, principal);
return ResponseEntity.status(HttpStatus.OK)
.body(ResponseDto.Success.builder()
.message("개인 일정이 성공적으로 삭제되었습니다.")
.version("v1.2.1-alpha")
.build());

}

// @PostMapping("/{timetableId}/privacy")
// @Operation(summary = "특정 시간표에 개인일정 추가(아래 timetable쪽에 똑같은 api있어서 삭제)")
// @Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
// public PrivacyDto addPrivacyToTimetable(@PathVariable Long timetableId, @Valid @RequestBody PrivacyDto privacyDto, Principal principal) {
// return privacyService.addPrivacyToTimetable(timetableId, privacyDto, principal);
// }

// @DeleteMapping("/{timetableId}/privacy/{privacyId}")
// @Operation(summary = "특정 시간표에서 개인일정 삭제(아래 timetable쪽에 똑같은 api있어서 삭제)")
// @Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
// public void removePrivacyFromTimetable(@PathVariable Long timetableId, @PathVariable Long privacyId, Principal principal) {
// privacyService.removePrivacyFromTimetable(timetableId, privacyId, principal);
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.example.Devkor_project.controller;

import com.example.Devkor_project.dto.*;
import com.example.Devkor_project.entity.Timetable;
import com.example.Devkor_project.service.TimetableService;
import com.example.Devkor_project.configuration.VersionProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.security.Principal;

@RestController
@RequestMapping("/api/timetables")
@RequiredArgsConstructor
@Tag(name = "Timetable 시간표", description = "시간표(timetable) 관련 API입니다.")
public class TimetableController {

private final TimetableService timetableService;
private final VersionProvider versionProvider;

/** 🟢 로그인된 사용자 시간표 생성 */
@PostMapping
@Operation(summary = "시간표 생성")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> createTimetable(
@Valid @RequestBody TimetableDto timetableDto,
Principal principal
) {
Timetable timetable = timetableService.createTimetableForProfile(timetableDto, principal);

return ResponseEntity.status(HttpStatus.OK)
.body(ResponseDto.Success.builder()
.message("시간표가 성공적으로 생성되었습니다.")
.data(timetable)
.version(versionProvider.getVersion())
.build());
}

/** 🟢 강의 추가 */
@PostMapping("/{timetableId}/course/{courseId}")
@Operation(summary = "시간표에 강의 추가")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<?> addCourseToTimetable(@PathVariable("timetableId") Long timetableId, @PathVariable("courseId") Long courseId, Principal principal) {
return timetableService.addCourseToTimetable(timetableId, courseId, principal);
}

/** 🟢 강의 제거 */
@DeleteMapping("/{timetableId}/course/{courseId}")
@Operation(summary = "시간표에서 강의 제거")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<?> removeCourseFromTimetable(@PathVariable("timetableId") Long timetableId, @PathVariable ("courseId")Long courseId, Principal principal) {
return timetableService.removeCourseFromTimetable(timetableId, courseId, principal);
}

/** 🟢 개인 일정 추가 */
@PostMapping("/{timetableId}/privacy/{privacyId}")
@Operation(summary = "시간표에 개인 일정 추가(이렇게 추후에 추가해도 되고, privacy 애초에 POST할때 시간표 id지정해서 넣어주는 것도 가능")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> addPrivacyToTimetable(@PathVariable("timetableId") Long timetableId, @PathVariable("privacyId") Long privacyId, Principal principal) {
return timetableService.addPrivacyToTimetable(timetableId, privacyId, principal);
}

// /** 🟢 로그인된 사용자의 모든 시간표 조회 */
// @GetMapping
// @Operation(summary = "로그인된 사용자의 정보와 시간표들 조회(너무 복잡. 잘안쓰일듯)")
// @Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
//
// public ResponseEntity<ResponseDto.Success> getAllTimetablesForUser(Principal principal) {
// return timetableService.getAllTimetablesForUser(principal);
// }

/** 🟢 로그인된 사용자의 시간표 이름과 ID 조회 */
@GetMapping("/names-and-ids")
@Operation(summary = "로그인된 사용자의 시간표 이름과 ID 조회(이게 목록 불러오기임)")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> getTimetableNamesAndIds(Principal principal) {
return timetableService.getTimetableNamesAndIds(principal);
}

/** 🟢 특정 시간표 조회 */
@GetMapping("/{timetableId}")
@Operation(summary = "특정 시간표 조회")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> getTimetableById(@PathVariable("timetableId") Long timetableId, Principal principal) {
return timetableService.getTimetableByIdWithDetails(timetableId, principal);
}

/** 🟢 시간표에서 개인 일정 제거 */
@DeleteMapping("/{timetableId}/privacy/{privacyId}")
@Operation(summary = "시간표에서 개인 일정 제거")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
public ResponseEntity<ResponseDto.Success> removePrivacyFromTimetable(
@PathVariable ("timetableId")Long timetableId,
@PathVariable ("privacyId")Long privacyId,
Principal principal
) {
return timetableService.removePrivacyFromTimetable(timetableId, privacyId, principal);
}

/** 🟢 시간표 이름 변경 */
@PutMapping("/{timetableId}")
@Operation(summary = "시간표 이름 변경")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
@Parameter(in = ParameterIn.PATH, name = "timetableId", description = "이름을 변경할 시간표 ID")
public ResponseEntity<ResponseDto.Success> updateTimetableName(
@PathVariable ("timetableId") Long timetableId,
@RequestBody TimetableDto timetableDto,
Principal principal
) {
return timetableService.updateTimetableName(timetableId, timetableDto, principal);
}

/** 🟢 시간표 삭제 */
@DeleteMapping("/{timetableId}")
@Operation(summary = "시간표 삭제")
@Parameter(in = ParameterIn.HEADER, name = "Authorization", description = "Bearer {access token}")
@Parameter(in = ParameterIn.PATH, name = "timetableId", description = "삭제할 시간표 ID")
public ResponseEntity<ResponseDto.Success> deleteTimetable(@PathVariable ("timetableId") Long timetableId, Principal principal) {
return timetableService.deleteTimetable(timetableId, principal);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.Devkor_project.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(description = "시간표에 강의를 추가하기 위한 요청 DTO")
public class CourseAssignmentDto {

@NotNull(message = "courseId는 null일 수 없습니다.")
@Schema(description = "추가할 강의 ID")
private Long courseId;
}
20 changes: 20 additions & 0 deletions src/main/java/com/example/Devkor_project/dto/CourseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -877,4 +877,24 @@ public static CourseDto.UPDATED_ExpiredDetail UPDATED_entityToExpiredDetail(
.isBookmark(isBookmark)
.build();
}
@AllArgsConstructor
@NoArgsConstructor
@Getter
@ToString
@Builder
public static class Basic { // ✅ 내부 static 클래스로 선언되어 있어야 함
private Long course_id;
private String course_code;
private String name;
private String professor;
}

public static CourseDto.Basic fromCourse(Course course) {
return CourseDto.Basic.builder()
.course_id(course.getCourse_id())
.course_code(course.getCourse_code())
.name(course.getName())
.professor(course.getProfessor())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.example.Devkor_project.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.*;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Schema(description = "시간표에 개인 일정을 추가하기 위한 요청 DTO")
public class PrivacyAssignmentDto {

@NotNull(message = "[privacyId] cannot be null.")
@Schema(description = "추가할 개인 일정 ID")
private Long privacyId;
}
63 changes: 63 additions & 0 deletions src/main/java/com/example/Devkor_project/dto/PrivacyDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.example.Devkor_project.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import com.example.Devkor_project.entity.Privacy;
import lombok.*;

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

@Getter
@Builder
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PrivacyDto {

@Schema(description = "Privacy ID")
private Long id;

// @NotNull(message = "[timetableId] cannot be null... 널이어도 되나? 되는듯")

@Schema(description = "Timetable IDs") // Timetable과 연결된 ID
private List<Long> timetableIds;

@NotBlank(message = "[name] cannot be blank.")
@Schema(description = "개인 일정 이름")
private String name;

@NotBlank(message = "[day] cannot be blank.")
@Schema(description = "요일 (e.g., 월, 화, 수)")
private String day;

@NotNull(message = "[startTime] cannot be null.")
@Schema(description = "시작 시간")
private LocalTime startTime;

@NotNull(message = "[finishTime] cannot be null.")
@Schema(description = "종료 시간")
private LocalTime finishTime;

@Schema(description = "장소")
private String location;

@Schema(description = "생성 시간")
private LocalDateTime createdAt;

@Schema(description = "수정 시간")
private LocalDateTime updatedAt;

public static PrivacyDto fromPrivacy(Privacy privacy) {
return PrivacyDto.builder()
.id(privacy.getId())
.name(privacy.getName())
.day(privacy.getDay())
.startTime(privacy.getStartTime())
.finishTime(privacy.getFinishTime())
.location(privacy.getLocation())
.build();
}
}
Loading
Loading