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

전남대 BE_박진화 6주차 과제(Step2) #280

Open
wants to merge 112 commits into
base: jinhwa-park
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 111 commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
316e185
Initial commit
wotjd243 Jun 23, 2024
8569d45
Initial commit
wotjd243 Jun 23, 2024
d5003d1
feat: set up the project
wotjd243 Jul 15, 2024
ba7709c
feat: migrate prev project codes
Jinhwa-Park Jul 16, 2024
6c1df36
feat: migrate prev project codes (#131)
Jinhwa-Park Jul 16, 2024
c9708c4
docs: delete unnecessary lines
Jinhwa-Park Jul 16, 2024
3efb237
docs: add README
Jinhwa-Park Jul 17, 2024
0d0c2a9
docs: modify typo
Jinhwa-Park Jul 17, 2024
f596fbf
rename: move prev codes to oldTestCodes directory
Jinhwa-Park Jul 17, 2024
319d6a2
feat: add codes about Category
Jinhwa-Park Jul 17, 2024
d50a1b7
feat: changed feature about set to update
Jinhwa-Park Jul 17, 2024
41a56e1
refactor: modify ProductController as modified Product entity
Jinhwa-Park Jul 17, 2024
8efe562
feat: add getEmailFromRequest method to JwtUtil
Jinhwa-Park Jul 17, 2024
2378e85
refactor: update controllers with clear return types and improve read…
Jinhwa-Park Jul 17, 2024
3c5036e
feat: add new fields(color, imageUrl, description) and update Catego…
Jinhwa-Park Jul 17, 2024
30200d0
feat: add path variable support for category deletion
Jinhwa-Park Jul 18, 2024
3d12d7b
feat: integrate category handling in ProductController
Jinhwa-Park Jul 18, 2024
e0e7fbe
feat: update Product entity to include category handling
Jinhwa-Park Jul 18, 2024
b6eca3e
feat: update ProductRequest, ProductResponse, ProductService to inclu…
Jinhwa-Park Jul 18, 2024
3f68385
feat: Add code to WishController to verify ProductId
Jinhwa-Park Jul 18, 2024
b5c7cbd
"remove: delete unnecessary product.html"
Jinhwa-Park Jul 18, 2024
b82b476
Merge branch 'jinhwa-park' into step1
Jinhwa-Park Jul 18, 2024
b9d1b08
docs: update README
Jinhwa-Park Jul 18, 2024
e6f9d4c
feat: make addOption page for admin
Jinhwa-Park Jul 18, 2024
4a990a1
refactor: change dependency injection from field to constructor
Jinhwa-Park Jul 18, 2024
f735135
feat: implement option features
Jinhwa-Park Jul 18, 2024
9db3978
feat: add option handle feature
Jinhwa-Park Jul 18, 2024
d781978
refactor: change dependency injection from field to constructor (JwtA…
Jinhwa-Park Jul 19, 2024
f55e846
feat: add option schema
Jinhwa-Park Jul 19, 2024
b74f7ad
feat: add redundancy option check feature
Jinhwa-Park Jul 19, 2024
37177da
feat: add properties
Jinhwa-Park Jul 19, 2024
78f78fa
refactor: change annotation from korean to english
Jinhwa-Park Jul 19, 2024
cd2982f
Revert "feat: add redundancy option check feature"
Jinhwa-Park Jul 19, 2024
4494483
Revert "Revert "feat: add redundancy option check feature""
Jinhwa-Park Jul 19, 2024
35c1d34
feat: add enforcing product have at least one option
Jinhwa-Park Jul 19, 2024
a72acdb
feat: add feat ProductController, OptionDTO, ProductRequest
Jinhwa-Park Jul 19, 2024
d10b7a0
docs: update README
Jinhwa-Park Jul 19, 2024
2c3afa5
docs: edit README indent
Jinhwa-Park Jul 19, 2024
ec2b9d5
feat: add getter and setter for quantity
Jinhwa-Park Jul 19, 2024
6e576f5
feat: add method for decrease quantity value
Jinhwa-Park Jul 19, 2024
1978094
docs: update README as include selectable options
Jinhwa-Park Jul 20, 2024
1eb1dd1
fix: make GlobalExceptionHandler handles proper error
Jinhwa-Park Jul 20, 2024
ae56b70
refactor: changes id variable to indicate clearly
Jinhwa-Park Jul 20, 2024
1737485
feat: Apply review feedback and add test code
Jinhwa-Park Jul 21, 2024
29c5d18
Merge branch 'step1' into step2
Jinhwa-Park Jul 21, 2024
8477326
feat: add builder, delete unnecessary import and annotations
Jinhwa-Park Jul 21, 2024
4e0459c
fix: modify as it works on test codes, change order, add option on data
Jinhwa-Park Jul 21, 2024
c8b4d09
feat: add CustomException, delete unnecessary annotations
Jinhwa-Park Jul 21, 2024
8d4dfbb
rename: modify OptionDTO to OptionRequest
Jinhwa-Park Jul 21, 2024
d47d8b0
refactor: Improve validation, error handling, entity retrieval
Jinhwa-Park Jul 21, 2024
0c75891
refactor: change to use CustomException
Jinhwa-Park Jul 21, 2024
a9d6536
refactor: change to use CustomException
Jinhwa-Park Jul 21, 2024
8e1b1a0
refactor: using SpringBootTest to WebMvcTest
Jinhwa-Park Jul 21, 2024
152c8ad
refactor: apply renamed OptionRequest
Jinhwa-Park Jul 21, 2024
44ae309
refactor: enhance validation
Jinhwa-Park Jul 21, 2024
3d9b0ed
feat: set up the project
wotjd243 Jul 22, 2024
aae0660
전남대_BE 박진화 4주차 과제 (1단계) (#219)
Jinhwa-Park Jul 22, 2024
5af08fe
fix: resolve conflicts
Jinhwa-Park Jul 22, 2024
289a9bd
전남대 BE_박진화 4주차 과제 (2단계) (#312)
Jinhwa-Park Jul 23, 2024
50f4da0
fix: resolve conflicts and update codes using builder
Jinhwa-Park Jul 23, 2024
965cd9a
feat: add InvalidQuantityException
Jinhwa-Park Jul 23, 2024
a9218d9
Merge branch 'jinhwa-park' into step3
Jinhwa-Park Jul 23, 2024
3d4dc9a
feat: update step0 as step3 in previous project spring-gift-enhancement
Jinhwa-Park Jul 23, 2024
d437145
전남대 BE_박진화 5주차 과제 (0단계 (#120)
Jinhwa-Park Jul 23, 2024
6575763
feat: make file structure
Jinhwa-Park Jul 24, 2024
cfb623e
feat: modify file names, add API-KEY
Jinhwa-Park Jul 24, 2024
8fa967d
feat: add @ConfigurationPropertiesScan
Jinhwa-Park Jul 25, 2024
c297314
feat: add Lombok
Jinhwa-Park Jul 25, 2024
e49417e
refactor: change code order
Jinhwa-Park Jul 25, 2024
75513b9
feat: add code about kakao
Jinhwa-Park Jul 25, 2024
7ce7418
feat: add regexp 가-힣
Jinhwa-Park Jul 25, 2024
63a6112
feat: implement kakao OAuth features
Jinhwa-Park Jul 25, 2024
52f6302
Merge branch 'jinhwa-park' of https://github.com/kakao-tech-campus-2n…
Jinhwa-Park Jul 25, 2024
804182a
feat: update as fit on step2
Jinhwa-Park Jul 25, 2024
afe1211
feat: add logger and complement AccessDeniedException
Jinhwa-Park Jul 26, 2024
6e5122e
feat: implement feature about Message
Jinhwa-Park Jul 26, 2024
6c4e300
feat: add method that return error's reason
Jinhwa-Park Jul 26, 2024
b9ba916
fix: fix wrong data type
Jinhwa-Park Jul 26, 2024
f47ba7b
feat: implement features about order
Jinhwa-Park Jul 26, 2024
c4b89d2
fix: initialization with constructor
Jinhwa-Park Jul 26, 2024
9880e6f
feat: implement feature that delete related wish list items when orde…
Jinhwa-Park Jul 26, 2024
0aa3867
refactor: remove unnecessary indent
Jinhwa-Park Jul 26, 2024
2e79d2c
feat: add method that help update id
Jinhwa-Park Jul 26, 2024
b8f4158
feat: modify parameter that fits on OrderRequest
Jinhwa-Park Jul 26, 2024
2501774
fix: fix JWT token validation and order placement logic
Jinhwa-Park Jul 27, 2024
dd9e329
docs: remove unnecessary indent or annotations
Jinhwa-Park Jul 27, 2024
6f74476
fix: fix everything I can do
Jinhwa-Park Jul 27, 2024
dd9cb6a
Merge branch 'step1' into step2
Jinhwa-Park Jul 27, 2024
32dea8a
fix: fix everything I can do, and merge with Hotfix branch
Jinhwa-Park Jul 27, 2024
f14fcd0
docs: Write API document
Jinhwa-Park Jul 28, 2024
f28b45d
전남대_BE 박진화 5주차 과제(Step1) (#215)
Jinhwa-Park Jul 28, 2024
5fd98b1
fix: conflict fix
Jinhwa-Park Jul 28, 2024
4bc5f59
feat: Merge previous project's codes
Jinhwa-Park Jul 29, 2024
7c187d2
feat: add swagger for API documentation
Jinhwa-Park Jul 30, 2024
4686e3b
전남대 BE_ 박진화 5주차 과제(Step2) (#323)
Jinhwa-Park Jul 30, 2024
c02d690
docs: add DS_Store as ignore type
Jinhwa-Park Jul 30, 2024
3705f2e
feat: add swagger
Jinhwa-Park Jul 30, 2024
0a45662
Merge branch 'jinhwa-park' into step3
Jinhwa-Park Jul 30, 2024
50d5533
refactor: change url usage
Jinhwa-Park Jul 31, 2024
d8663a2
fix: fix conflict and type.
Jinhwa-Park Jul 31, 2024
dc602f1
feat: update codes as previous project's step3
Jinhwa-Park Jul 31, 2024
1cb5c30
feat: update differences
Jinhwa-Park Jul 31, 2024
d6ac0e9
refactor: set codes like teamMates
Jinhwa-Park Aug 1, 2024
34e9860
refactor: set codes like teamMates
Jinhwa-Park Aug 1, 2024
647f5c4
feat: update codes that fits on teammate's API
Jinhwa-Park Aug 1, 2024
20b375e
fix: fix different implements
Jinhwa-Park Aug 2, 2024
3d15b3e
feat: modify codes
Jinhwa-Park Aug 2, 2024
f2e57f9
fix: OrderServiceTest fixed
Jinhwa-Park Aug 6, 2024
390beb4
feat: add or modify DTO files
Jinhwa-Park Aug 6, 2024
870f8f0
Merge branch 'jinhwa-park' of https://github.com/kakao-tech-campus-2n…
Jinhwa-Park Aug 6, 2024
2f6243f
Merge branch 'above' into step2
Jinhwa-Park Aug 6, 2024
cda28a8
fix: fix conflicts
Jinhwa-Park Aug 7, 2024
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
41 changes: 25 additions & 16 deletions src/main/java/gift/controller/MemberController.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package gift.controller;

import gift.dto.member.LoginResponse;
import gift.dto.member.MemberRequest;
import gift.dto.member.MemberResponse;
import gift.entity.Member;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import gift.service.MemberService;
import gift.util.JwtUtil;

import jakarta.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

import java.net.URI;
import java.util.Optional;

import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;

@RestController
@RequestMapping("/member")
@RequestMapping("/api/members")
@Tag(name = "Member Management System", description = "Operations related to member management")
public class MemberController {
private final MemberService memberService;
Expand All @@ -29,31 +33,36 @@ public MemberController(MemberService service, JwtUtil util) {
this.jwtUtil = util;
}

@PostMapping("/register")
@PostMapping(value ="/register")
@Operation(summary = "Register a new member", description = "Registers a new member to the system", tags = { "Member Management System" })
public ResponseEntity<Map<String, String>> register(
public ResponseEntity<MemberResponse> register(
@Parameter(description = "Member object to be registered", required = true)
@RequestBody Member member) {
memberService.save(member);
Map<String, String> response = new HashMap<>();
response.put("message", "success");
return ResponseEntity.ok(response);
@RequestBody MemberRequest memberRequest) {
Member member = new Member.Builder()
.email(memberRequest.getEmail())
.password(memberRequest.getPassword())
.name(memberRequest.getName())
.build();
member = memberService.save(member);
String token = jwtUtil.generateToken(member.getEmail());
MemberResponse memberResponse = new MemberResponse(member.getId(), member.getEmail(), member.getName(), token);

return ResponseEntity.created(URI.create("/api/members/" + member.getId())).body(memberResponse);
}

@PostMapping("/login")
@Operation(summary = "Login a member", description = "Logs in an existing member", tags = { "Member Management System" })
public ResponseEntity<Map<String, String>> login(
public ResponseEntity<LoginResponse> login(
@Parameter(description = "Login request containing email and password", required = true)
@RequestBody Member loginRequest) {
@RequestBody MemberRequest loginRequest) {
Optional<Member> memberOpt = memberService.findByEmail(loginRequest.getEmail());
if (memberOpt.isPresent() && memberOpt.get().getPassword().equals(loginRequest.getPassword())) {
String token = jwtUtil.generateToken(memberOpt.get().getEmail());
Map<String, String> response = new HashMap<>();
response.put("message", "success");
response.put("token", token);
LoginResponse response = new LoginResponse(token);

return ResponseEntity.ok(response);
}
return ResponseEntity.status(401).body(null);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

@GetMapping("/me")
Expand Down
44 changes: 31 additions & 13 deletions src/main/java/gift/controller/OptionController.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
package gift.controller;

import gift.dto.OptionRequest;
import gift.dto.option.DeleteOptionRequest;
import gift.dto.option.OptionRequest;
import gift.dto.option.OptionResponse;
import gift.dto.option.OptionUpdateResponse;
import gift.entity.Option;
import gift.exception.CustomException;
import gift.service.OptionService;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.web.util.UriComponentsBuilder;

@RestController
@RequestMapping("/api/products/{productId}/options")
Expand All @@ -25,45 +32,56 @@ public OptionController(OptionService optionService) {

@GetMapping
@Operation(summary = "Get options for a product", description = "Fetches all options for a specified product", tags = { "Product Option Management System" })
public ResponseEntity<List<Option>> getOptions(
public ResponseEntity<List<OptionResponse>> getOptions(
@Parameter(description = "ID of the product", required = true)
@PathVariable Long productId) {
List<Option> options = optionService.getOptionsByProductId(productId);
List<OptionResponse> options = optionService.getOptionsByProductId(productId);
return ResponseEntity.ok(options);
}

@PostMapping
@Operation(summary = "Add an option to a product", description = "Adds a new option to a specified product", tags = { "Product Option Management System" })
public ResponseEntity<Option> addOptionToProduct(
public ResponseEntity<OptionResponse> addOptionToProduct(
@Parameter(description = "ID of the product", required = true)
@PathVariable Long productId,
@Parameter(description = "Option details", required = true)
@Valid @RequestBody OptionRequest optionDTO) {
Option option = optionService.addOptionToProduct(productId, optionDTO);
return ResponseEntity.ok(option);
@Valid @RequestBody OptionRequest optionRequest,
UriComponentsBuilder uriBuilder) {
Option option = optionService.addOptionToProduct(productId, optionRequest);
OptionResponse response = new OptionResponse(option.getId(), option.getName(), option.getQuantity());
URI location = uriBuilder.path("/api/products/{productId}/options/{optionId}").buildAndExpand(productId, option.getId()).toUri();
return ResponseEntity.created(location).body(response);
}

@PutMapping("/{optionId}")
@Operation(summary = "Update an option for a product", description = "Updates an existing option of a specified product", tags = { "Product Option Management System" })
public ResponseEntity<Option> updateOption(
public ResponseEntity<OptionUpdateResponse> updateOption(
@Parameter(description = "ID of the option to be updated", required = true)
@PathVariable Long optionId,
@Parameter(description = "Updated option details", required = true)
@RequestBody OptionRequest optionRequest,
@Parameter(description = "ID of the product", required = true)
@PathVariable String productId) {
Option updatedOption = optionService.updateOption(optionId, optionRequest.getName(), optionRequest.getQuantity());
OptionUpdateResponse updatedOption = optionService.updateOption(optionId, optionRequest.getName(), optionRequest.getQuantity());
return ResponseEntity.ok(updatedOption);
}

@DeleteMapping("/{optionId}")
@Operation(summary = "Delete an option from a product", description = "Deletes an option from a specified product", tags = { "Product Option Management System" })
public ResponseEntity<Void> deleteOption(
public ResponseEntity<String> deleteOption(
@Parameter(description = "ID of the option to be deleted", required = true)
@PathVariable Long optionId,
@Parameter(description = "ID of the product", required = true)
@PathVariable String productId) {
optionService.deleteOption(optionId);
return ResponseEntity.noContent().build();
@RequestBody DeleteOptionRequest deleteOptionRequest) {
try {
optionService.deleteOption(optionId, DeleteOptionRequest.getEmail(), DeleteOptionRequest.getPassword());
return ResponseEntity.ok("Option successfully deleted.");
} catch (CustomException.EntityNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
} catch (CustomException.InvalidPasswordException e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred: " + e.getMessage());
}
}
}
34 changes: 32 additions & 2 deletions src/main/java/gift/controller/OrderController.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package gift.controller;

import gift.dto.OrderRequest;
import gift.dto.OrderResponse;
import gift.dto.order.OrderRequest;
import gift.dto.order.OrderResponse;
import gift.service.OrderService;
import gift.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
Expand All @@ -29,6 +31,34 @@ public OrderController(OrderService orderService, JwtUtil jwtUtil) {
this.orderService = orderService;
this.jwtUtil = jwtUtil;
}
@GetMapping
@Operation(summary = "Get all orders for the logged-in user", description = "Fetches all orders made by the logged-in user", tags = {"Order Management System"})
public ResponseEntity<Page<OrderResponse>> getOrders(
@Parameter(description = "Authorization token", required = true) @RequestHeader("Authorization") String authorizationHeader,
Pageable pageable) {
logger.info("Received request to fetch orders");

if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
logger.warn("Authorization header is missing or invalid");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

String token = authorizationHeader.substring("Bearer ".length());
if (!jwtUtil.validateToken(token) || jwtUtil.isTokenExpired(token)) {
logger.warn("Invalid or expired token");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

String email = jwtUtil.extractEmail(token);
if (email == null) {
logger.warn("Failed to extract email from token");
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}

Page<OrderResponse> orderResponses = orderService.getOrdersByEmail(email, pageable);

return ResponseEntity.ok(orderResponses);
}

@PostMapping
@Operation(summary = "Place an order", description = "Places a new order in the system", tags = { "Order Management System" })
Expand Down
Loading