Task A: Spring Initializr
This task involves creating the project with the initial set of four dependencies and setting up the application properties.
Step-by-step instructions:
- You have already created the project. The
pom.xmlyou provided is a correct starting point, as it includes only the four required dependencies. - Navigate to
src/main/resources/. - Open or create the
application.propertiesfile. - Paste the contents you provided from the lab environment into this file.
File: src/main/resources/application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/full-stack-ecommerce?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=ecommerceapp
spring.datasource.password=ecommerceapp
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=none
spring.data.rest.base-path=/api
# allow jackson parser to process comments in payload
spring.jackson.parser.allow-comments=true
# application logging level
logging.level.org.springframework=INFOKnowledge Transfer: The application.properties file is the central place for Spring Boot configuration. We are telling Spring how to connect to our MySQL database, what SQL dialect to use, and setting the base path for our REST API to /api. The setting spring.jpa.hibernate.ddl-auto=none is critical; it tells Hibernate (our JPA implementation) not to modify the database schema, as we are using a pre-existing one.
Task B: Git Repository
This is an ongoing task. You will commit your changes after completing each major step.
Step-by-step instructions for each commit:
- In your project’s root directory, add your changes to the staging area:
git add . - Commit the changes with a message reflecting the completed task:
git commit -m "C: Constructed package structure and added config" - Push your commit to GitLab:
git push
At the very end of the project, you will retrieve the repository URL and the branch history (git log --oneline) for submission.
Task C: Package Construction
Here, we will create the required package structure and configure the REST endpoints by adding the provided RestDataConfig class.
Step-by-step instructions:
- In your IDE, under your main package (e.g.,
src/main/java/edu/wgu/d288_backend), create these four packages:controllersdaoentitiesservices
- Create one more package:
config
- Inside the
configpackage, create a new Java class namedRestDataConfig.java. - Paste the provided code into this file. You must update the
packageandimportstatements to match your project’s package structure.
File: src/main/java/edu/wgu/d288_backend/config/RestDataConfig.java
package edu.wgu.d288_backend.config; // <-- Your package name
import edu.wgu.d288_backend.entities.*; // <-- Your package name
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
@Configuration
public class RestDataConfig implements RepositoryRestConfigurer {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
config.exposeIdsFor(Country.class);
config.exposeIdsFor(Customer.class);
config.exposeIdsFor(Division.class);
config.exposeIdsFor(Excursion.class);
config.exposeIdsFor(Vacation.class);
config.setDefaultPageSize(Integer.MAX_VALUE);
config.setMaxPageSize(Integer.MAX_VALUE);
}
}Knowledge Transfer: Spring Data REST automatically creates REST endpoints for your repositories. This configuration class customizes that behavior. Specifically, config.exposeIdsFor(...) tells Spring to include the entity’s primary key id field in the JSON response, which the front-end often needs.
Now, commit your work: git commit -m "C: Constructed package structure and added config"
Task D: Entities Package
We will create the Java classes (Entities) that map to the database tables shown in the ERD. We’ll use Lombok annotations to reduce boilerplate code like getters and setters.
Knowledge Transfer: An “Entity” is a special Java class that the Java Persistence API (JPA) can map to a database table. Annotations like @Entity, @Table, @Id, @Column, and relationship annotations (@ManyToOne, @OneToMany, etc.) are used to define this mapping. @CreationTimestamp and @UpdateTimestamp are convenient Hibernate annotations that automatically manage the create_date and last_update fields.
Create the following files inside the src/main/java/edu/wgu/d288_backend/entities/ package.
File: entities/StatusType.java
package edu.wgu.d288_backend.entities;
public enum StatusType {
pending,
ordered,
cancelled
}File: entities/Country.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.util.Date;
import java.util.Set;
@Entity
@Table(name="countries")
@Data
public class Country {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="country_id")
private Long id;
@Column(name="country")
private String country_name;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "country")
private Set<Division> divisions;
}File: entities/Division.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.util.Date;
import java.util.Set;
@Entity
@Table(name="divisions")
@Data
public class Division {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="division_id")
private Long id;
@Column(name="division")
private String division_name;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@ManyToOne
@JoinColumn(name="country_id")
private Country country;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "division")
private Set<Customer> customers;
}File: entities/Customer.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
@Entity
@Table(name="customers")
@Getter
@Setter
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="customer_id")
private Long id;
@Column(name="customer_first_name")
private String firstName;
@Column(name="customer_last_name")
private String lastName;
@Column(name="address")
private String address;
@Column(name="postal_code")
private String postal_code;
@Column(name="phone")
private String phone;
@Column(name="city")
private String city;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@ManyToOne
@JoinColumn(name = "division_id")
private Division division;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
private Set<Cart> carts = new HashSet<>();
public Customer() {}
public Customer(String firstName, String lastName, String address, String postal_code, String phone, String city, Division division) {
this.firstName = firstName;
this.lastName = lastName;
this.address = address;
this.postal_code = postal_code;
this.phone = phone;
this.city = city;
this.division = division;
}
public void addCart(Cart cart) {
if (cart != null) {
carts.add(cart);
cart.setCustomer(this);
}
}
}File: entities/Vacation.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
@Entity
@Table(name="vacations")
@Data
public class Vacation {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="vacation_id")
private Long id;
@Column(name="vacation_title")
private String vacation_title;
@Column(name="description")
private String description;
@Column(name="travel_fare_price")
private BigDecimal travel_fare_price;
@Column(name="image_url")
private String image_URL;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "vacation")
private Set<Excursion> excursions;
}File: entities/Excursion.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
@Entity
@Table(name="excursions")
@Data
public class Excursion {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="excursion_id")
private Long id;
@Column(name="excursion_title")
private String excursion_title;
@Column(name="excursion_price")
private BigDecimal excursion_price;
@Column(name="image_url")
private String image_URL;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@ManyToOne
@JoinColumn(name="vacation_id", nullable=false)
private Vacation vacation;
@ManyToMany(mappedBy = "excursions")
private Set<CartItem> cartItems;
}File: entities/Cart.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
@Entity
@Table(name="carts")
@Getter
@Setter
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="cart_id")
private Long id;
@Column(name="package_price")
private BigDecimal package_price;
@Column(name="party_size")
private int party_size;
@Enumerated(EnumType.STRING)
@Column(name="status")
private StatusType status;
@Column(name="order_tracking_number")
private String orderTrackingNumber;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@ManyToOne
@JoinColumn(name="customer_id")
private Customer customer;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "cart")
private Set<CartItem> cartItems = new HashSet<>();
public void add(CartItem item) {
if (item != null) {
cartItems.add(item);
item.setCart(this);
}
}
}File: entities/CartItem.java
package edu.wgu.d288_backend.entities;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import java.util.Date;
import java.util.Set;
import java.util.HashSet;
@Entity
@Table(name="cart_items")
@Getter
@Setter
public class CartItem {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="cart_item_id")
private Long id;
@Column(name="create_date")
@CreationTimestamp
private Date create_date;
@Column(name="last_update")
@UpdateTimestamp
private Date last_update;
@ManyToOne
@JoinColumn(name="vacation_id")
private Vacation vacation;
@ManyToOne
@JoinColumn(name = "cart_id")
private Cart cart;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name="excursion_cartitem",
joinColumns=@JoinColumn(name="cart_item_id"),
inverseJoinColumns=@JoinColumn(name="excursion_id"))
private Set<Excursion> excursions = new HashSet<>();
}Now, commit your changes: git commit -m "D: Created entity classes"
Task E: DAO (Repositories) Package
A repository provides an abstraction for data access. We define an interface that extends JpaRepository, and Spring Data JPA automatically provides the implementation for standard CRUD operations.
Knowledge Transfer:
JpaRepository<EntityType, PrimaryKeyType>: Extending this interface gives us methods likesave(),findById(),findAll(), etc., for free.@CrossOrigin("http://localhost:4200"): This annotation enables Cross-Origin Resource Sharing. It tells the browser that it is safe to allow requests from the Angular front-end (running onlocalhost:4200) to access this API endpoint. This is a security feature built into browsers.
Create the following interfaces inside the src/main/java/edu/wgu/d288_backend/dao/ package.
File: dao/CountryRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Country;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface CountryRepository extends JpaRepository<Country, Long> {
}File: dao/CustomerRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface CustomerRepository extends JpaRepository<Customer, Long> {
}File: dao/DivisionRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Division;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface DivisionRepository extends JpaRepository<Division, Long> {
}File: dao/ExcursionRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Excursion;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface ExcursionRepository extends JpaRepository<Excursion, Long> {
}File: dao/VacationRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Vacation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface VacationRepository extends JpaRepository<Vacation, Long> {
}File: dao/CartRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.Cart;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface CartRepository extends JpaRepository<Cart, Long> {
}File: dao/CartItemRepository.java
package edu.wgu.d288_backend.dao;
import edu.wgu.d288_backend.entities.CartItem;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.CrossOrigin;
@CrossOrigin("http://localhost:4200")
public interface CartItemRepository extends JpaRepository<CartItem, Long> {
}Now, commit your changes: git commit -m "E: Created repository interfaces"
Task F: Services Package
The service layer contains the application’s business logic. We will create the CheckoutService to handle the process of placing an order. This involves creating Data Transfer Objects (DTOs) for the purchase data and response.
Knowledge Transfer:
- DTO (Data Transfer Object):
PurchaseandPurchaseResponseare DTOs. They are simple classes used to carry data between the controller and the service, but they are not mapped to the database themselves. - Service Layer (
@Service): This is where business logic lives. It coordinates calls to different repositories to perform a complete operation, like placing an order. @Transactional: A crucial annotation that wraps a method in a database transaction. If any part of theplaceOrdermethod fails (e.g., an SQL error), all the database changes made within that method are automatically rolled back. This ensures data consistency.
Create the following files in the src/main/java/edu/wgu/d288_backend/services/ package.
File: services/Purchase.java
package edu.wgu.d288_backend.services;
import edu.wgu.d288_backend.entities.Cart;
import edu.wgu.d288_backend.entities.CartItem;
import edu.wgu.d288_backend.entities.Customer;
import lombok.Data;
import java.util.Set;
@Data
public class Purchase {
private Customer customer;
private Cart cart;
private Set<CartItem> cartItems;
}File: services/PurchaseResponse.java
package edu.wgu.d288_backend.services;
import lombok.Data;
import lombok.NonNull;
@Data
public class PurchaseResponse {
@NonNull
private String orderTrackingNumber;
}File: services/CheckoutService.java
package edu.wgu.d288_backend.services;
public interface CheckoutService {
PurchaseResponse placeOrder(Purchase purchase);
}File: services/CheckoutServiceImpl.java
package edu.wgu.d288_backend.services;
import edu.wgu.d288_backend.dao.CustomerRepository;
import edu.wgu.d288_backend.entities.Cart;
import edu.wgu.d288_backend.entities.CartItem;
import edu.wgu.d288_backend.entities.Customer;
import edu.wgu.d288_backend.entities.StatusType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Set;
import java.util.UUID;
@Service
public class CheckoutServiceImpl implements CheckoutService {
private final CustomerRepository customerRepository;
@Autowired
public CheckoutServiceImpl(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@Override
@Transactional
public PurchaseResponse placeOrder(Purchase purchase) {
Cart cart = purchase.getCart();
String orderTrackingNumber = generateOrderTrackingNumber();
cart.setOrderTrackingNumber(orderTrackingNumber);
cart.setStatus(StatusType.ordered);
Set<CartItem> cartItems = purchase.getCartItems();
cartItems.forEach(cart::add);
Customer customer = purchase.getCustomer();
customer.addCart(cart);
customerRepository.save(customer);
return new PurchaseResponse(orderTrackingNumber);
}
private String generateOrderTrackingNumber() {
return UUID.randomUUID().toString();
}
}Now, commit your changes: git commit -m "F: Created service layer for checkout"
Task G: Validation
To enforce the inputs required by the front-end, we will add validation. This requires a new dependency.
Step-by-step instructions:
-
Add the validation dependency: Open your
pom.xmlfile. Add the following dependency inside the<dependencies>section.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> -
Reload Maven: After adding the dependency, your IDE will prompt you to “Load Maven Changes” or “Import Changes”. Do this to download the necessary library.
-
Add validation annotations: Now, modify the
Purchase.javaDTO to include@NotNullannotations.
File: services/Purchase.java (Updated)
package edu.wgu.d288_backend.services;
import edu.wgu.d288_backend.entities.Cart;
import edu.wgu.d288_backend.entities.CartItem;
import edu.wgu.d288_backend.entities.Customer;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.Set;
@Data
public class Purchase {
@NotNull
private Customer customer;
@NotNull
private Cart cart;
@NotNull
private Set<CartItem> cartItems;
}Knowledge Transfer: The spring-boot-starter-validation dependency adds Hibernate Validator to our project. This allows us to use standard validation annotations (from jakarta.validation.constraints). @NotNull ensures that the annotated field must not be null. In the next step, we will use @Valid in our controller to tell Spring to enforce these rules on incoming requests. If validation fails, Spring automatically sends a 400 Bad Request response, protecting our business logic from incomplete data.
Now, commit your changes: git commit -m "G: Added validation dependency and annotations"
Task H: Controllers Package
The controller creates the public-facing API endpoint. It receives HTTP requests and delegates the work to the service layer.
Knowledge Transfer:
@RestController: Marks this class as a request handler and ensures the return values are automatically converted to JSON and written to the HTTP response.@RequestMapping("/api/checkout"): Maps all requests under this path to this controller.@PostMapping("/purchase"): Maps specifically HTTP POST requests for/api/checkout/purchaseto theplaceOrdermethod.@RequestBody: Deserializes the JSON from the request body into aPurchaseobject.@Valid: This annotation, placed next to@RequestBody, is what triggers the validation we set up in Task G.
Create the following file in the src/main/java/edu/wgu/d288_backend/controllers/ package.
File: controllers/CheckoutController.java
package edu.wgu.d288_backend.controllers;
import edu.wgu.d288_backend.services.CheckoutService;
import edu.wgu.d288_backend.services.Purchase;
import edu.wgu.d288_backend.services.PurchaseResponse;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
@CrossOrigin("http://localhost:4200")
@RestController
@RequestMapping("/api/checkout")
public class CheckoutController {
private final CheckoutService checkoutService;
public CheckoutController(CheckoutService checkoutService) {
this.checkoutService = checkoutService;
}
@PostMapping("/purchase")
public PurchaseResponse placeOrder(@Valid @RequestBody Purchase purchase) {
return checkoutService.placeOrder(purchase);
}
}Now, commit your changes: git commit -m "H: Created Checkout REST Controller"
Task I: Add Sample Customers
We’ll create a component to “bootstrap” our database with initial data. This will run once when the application starts up.
Knowledge Transfer:
CommandLineRunner: An interface that defines arunmethod. Spring Boot executes this method automatically after the application context is loaded. It’s a common pattern for running initialization code.@Component: This marks the class as a Spring bean, so Spring will manage its lifecycle and execute theCommandLineRunnerinterface.- We check if
customerRepository.count() == 0to satisfy the requirement that data is not overwritten on every application start. The code will only run if thecustomerstable is empty.
Step-by-step instructions:
- Create a new package named
bootstrap. - Inside the
src/main/java/edu/wgu/d288_backend/bootstrap/package, create the following class.
File: bootstrap/BootstrapData.java
package edu.wgu.d288_backend.bootstrap;
import edu.wgu.d288_backend.dao.CustomerRepository;
import edu.wgu.d288_backend.dao.DivisionRepository;
import edu.wgu.d288_backend.entities.Customer;
import edu.wgu.d288_backend.entities.Division;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class BootstrapData implements CommandLineRunner {
private final CustomerRepository customerRepository;
private final DivisionRepository divisionRepository;
public BootstrapData(CustomerRepository customerRepository, DivisionRepository divisionRepository) {
this.customerRepository = customerRepository;
this.divisionRepository = divisionRepository;
}
@Override
public void run(String... args) throws Exception {
if (customerRepository.count() == 0) {
Division division1 = divisionRepository.findById(2L).orElse(null);
Division division2 = divisionRepository.findById(3L).orElse(null);
Division division3 = divisionRepository.findById(4L).orElse(null);
Customer customer1 = new Customer("John", "Doe", "123 Main St", "12345", "555-1111", "Anytown", division1);
Customer customer2 = new Customer("Jane", "Smith", "456 Oak Ave", "67890", "555-2222", "Somecity", division2);
Customer customer3 = new Customer("Peter", "Jones", "789 Pine Ln", "13579", "555-3333", "Anotherplace", division3);
Customer customer4 = new Customer("Mary", "Williams", "321 Elm Rd", "24680", "555-4444", "Metropolis", division1);
Customer customer5 = new Customer("David", "Brown", "654 Birch Ct", "97531", "555-5555", "Villageton", division2);
customerRepository.save(customer1);
customerRepository.save(customer2);
customerRepository.save(customer3);
customerRepository.save(customer4);
customerRepository.save(customer5);
}
}
}Now, commit your changes: git commit -m "I: Added bootstrap to add 5 sample customers"
Task J: Run Application and Provide Screenshots
This is the final step where you test the full integration.
Step-by-step instructions:
- Run your Spring Boot application from your IDE.
- Run the provided Angular front-end application (e.g., with
ng serve). - Open
http://localhost:4200in your browser. - Open the Developer Tools (F12) and go to the “Network” tab.
- Use the application to select a vacation, add two excursions, and complete the checkout form.
- Click “Purchase”.
- Take the first screenshot: Show the browser window. It should include the front-end UI and the Network tab of the developer tools, showing a
purchaserequest with a200 OKstatus, proving there was no network error. - Open MySQL Workbench and connect to the
full-stack-ecommercedatabase. - Run queries to verify the data was saved.
-- Find the most recent cart that was fully ordered SELECT * FROM carts WHERE order_tracking_number IS NOT NULL ORDER BY last_update DESC LIMIT 1; -- Using the cart_id from the above query, find its items SELECT * FROM cart_items WHERE cart_id = [ID_FROM_PREVIOUS_QUERY]; -- Using a cart_item_id from the above query, find its excursions SELECT * FROM excursion_cartitem WHERE cart_item_id = [ID_FROM_PREVIOUS_QUERY]; - Take the second screenshot: Show the MySQL Workbench window with the results of these queries, confirming that the cart, cart items, and the links to their excursions were successfully persisted.
You have now completed all technical requirements for the project. The final step is to collect your GitLab URL and commit history for submission.