diff --git a/README.md b/README.md
index 7cc01a7..6b3bae1 100644
--- a/README.md
+++ b/README.md
@@ -8,22 +8,58 @@ Step 1: CD to the project root directory `cart_api`
Step 2: Run `./mvnw spring-boot:run` command
-## Lesson Overview (6 Mar 2023, Mon)
+## Lesson Overview (9 Mar 2023, Fri)
Lesson Coverage:
-- Use of `@OneToOne` and `@JoinColumn` annotation
-- Start implementing new set of APIs
-
-## New APIs
-
-|URL|Status|Response|
-|-|-|-|
-|GET /carts|200|A list of records in cart table|
-||404|When no records are found in cart table|
-|POST /carts/add/{productId}?quantity=1|200|
If `productId` does not exist, create a new record with `quantity` set to 1.
When `quantity` is provided, set the quantity of the specified `productId` to the specified value.
When `quantity` is not provided, increment the quantity of the specified `productId` by 1.
|
-||400|When the specified `productId` does not exist in the product table.
-|POST /carts/decrement/{productId}|200|If the specified `productId` exist and the quantity is 1, delete the record from cart table.
If the specified `productId` exist and the quantity is greater than 1, decrement the quantity by 1.
|
-||400|When the specified `productId` does not exist in the `cart` table|
-|POST /carts/clear|200|If there are records in the cart table, delete all records in the cart table|
-||304|If there are no records in the cart table, do nothing.|
+1. Move complex logics in `/carts` to a `@Service` class
+2. Adding `User` entity
+3. Use of `UserID` header as a mock authentication header
+
+> Firebase SDK has a major shift and no longer support `signInWithEmailAndPassword` from the backend `Firebase Admin SDK` using Java.
+
+## 1. Move complex logics to @Service class
+
+Refer to the `add` and `decrement` methods in [CartService.java](./cart_api/src/main/java/sg/edu/ntu/cart_api/service/CartService.java) where complex logics is moved into.
+
+Refer to [CartController.java](./cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java) where the code mainly focuses on handling http request and response (status).
+
+A custom exception called [NotFoundException.java](./cart_api/src/main/java/sg/edu/ntu/cart_api/exception/NotFoundException.java) is created to help us identify scenario where the `productId` is not found.
+
+## 2. Adding the `User` Entity
+
+Let's refer to our ERD again while creating our `User` Entity class.
+
+
+
+The SQL Statements required to generate the `user` table:
+
+```sql
+create table user (
+ id int not null auto_increment,
+ email varchar(255) not null,
+ created_at timestamp not null default current_timestamp,
+ primary key (id)
+);
+
+alter table cart add column user_id int;
+alter table cart add constraint fk_cart_user foreign key (user_id) references user(id);
+```
+
+If you need to check all foreign keys in the DB, use the following command:
+
+```sql
+SELECT TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_SCHEMA = 'cartdb';
+```
+
+## 3. Using `@RequestHeader` to capture value from HTTP Header
+
+```java
+public ResponseEntity> findAll(@RequestHeader("user-id") int userId)
+```
+
+See [CartController.java](./cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java) for full details.
+
+We should also implement this for every methods in `CartController.java`. This will eventually affect `CartService.java` as well. All request to `/carts` must contains a `user-id` header.
+
+End
\ No newline at end of file
diff --git a/assets/erd.png b/assets/erd.png
new file mode 100644
index 0000000..3288370
Binary files /dev/null and b/assets/erd.png differ
diff --git a/cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java b/cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java
index 882af3f..7e62183 100644
--- a/cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java
+++ b/cart_api/src/main/java/sg/edu/ntu/cart_api/controller/CartController.java
@@ -8,6 +8,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@@ -34,16 +35,16 @@ public class CartController {
CartService service;
@RequestMapping(method=RequestMethod.GET)
- public ResponseEntity> findAll(){
- List cartItems = (List)repo.findAll();
+ public ResponseEntity> findAll(@RequestHeader("user-id") int userId){
+ List cartItems = (List)repo.findByUserId(userId);
if(cartItems.size() > 0) return ResponseEntity.ok().body(cartItems);
return ResponseEntity.notFound().build();
}
@RequestMapping(value="/add/{productId}", method=RequestMethod.POST)
- public ResponseEntity add(@PathVariable int productId, @RequestParam Optional quantity){
+ public ResponseEntity add(@PathVariable int productId, @RequestParam Optional quantity, @RequestHeader("user-id") int userId){
try{
- service.add(productId, quantity);
+ service.add(productId, quantity, userId);
return ResponseEntity.ok().build(); // When no exception is thrown means operation is successful.
}catch(NotFoundException nfe){
nfe.printStackTrace();
@@ -56,10 +57,10 @@ public ResponseEntity add(@PathVariable int productId, @RequestParam Optional {
- Optional findByProductId(int productId);
+ Optional findByProductIdAndUserId(int productId, int userId);
+
+ List findByUserId(int userId);
}
diff --git a/cart_api/src/main/java/sg/edu/ntu/cart_api/service/CartService.java b/cart_api/src/main/java/sg/edu/ntu/cart_api/service/CartService.java
index fa81f22..f4d22e2 100644
--- a/cart_api/src/main/java/sg/edu/ntu/cart_api/service/CartService.java
+++ b/cart_api/src/main/java/sg/edu/ntu/cart_api/service/CartService.java
@@ -19,8 +19,8 @@ public class CartService {
@Autowired
ProductRepository productRepo;
- public void add(int productId, Optional quantity) throws NotFoundException {
- Optional optionalCartItem = repo.findByProductId(productId);
+ public void add(int productId, Optional quantity, int userId) throws NotFoundException {
+ Optional optionalCartItem = repo.findByProductIdAndUserId(productId, userId);
if(optionalCartItem.isPresent()){
@@ -39,6 +39,7 @@ public void add(int productId, Optional quantity) throws NotFoundExcept
Cart cartItem = new Cart();
cartItem.setProduct(product);
cartItem.setQuantity(quantity.orElseGet(() -> 1));
+ cartItem.setUserId(userId);
repo.save(cartItem);
}else{
throw new NotFoundException("Product ID not found");
@@ -46,8 +47,8 @@ public void add(int productId, Optional quantity) throws NotFoundExcept
}
}
- public void decrement(int productId) throws NotFoundException{
- Optional optionalCartItem = repo.findByProductId(productId);
+ public void decrement(int productId, int userId) throws NotFoundException{
+ Optional optionalCartItem = repo.findByProductIdAndUserId(productId, userId);
if(optionalCartItem.isPresent()){
int currentQuantity = 0;