An advanced online bookstore built with Java Spring Boot, where users can browse and order books, interact with an AI chatbot, and admins can manage the entire platform through a dedicated panel.
Check out the deployed frontend here: https://ai-book-store-jyd2.vercel.app/
The full project is on my YouTube channel: Youtube
β οΈ Note: This is the frontend-only version and is not connected to the backend API yet. Some features like login, ordering, and chatbot may not function properly.
-
Register and log in securely
-
Browse and search books
-
Place and view orders
-
Contact us and send Messages
-
AI-powered chatbot for:
- Book information
- Recommendations
- talk about everything
- Manage all books (Add / Edit / Delete)
- View and manage user accounts
- Monitor and manage orders
- Answers questions about books and categories
- Recommends books based on user interests
- Backend: Java, Spring Boot, Spring Security, Spring Data JPA
- Database: MySQL or PostgreSQL
- Frontend: NextJs
- AI Integration: gemma3/googleAi
- Authentication: JWT / Spring Security
- Deployment: Docker / Heroku / VPS
Swagger UI is available at the following URL after running the application:
http://localhost:8080/swagger-ui/index.html#/
You can use it to explore and test the available REST endpoints of this project.
-
Clone the repository:
git clone https://github.com/yourusername/bookstore.git cd bookstore -
Configure your environment:
- Set database connection and credentials in
application.properties - Configure AI chatbot API (if needed)
- Set database connection and credentials in
-
Run the project:
./mvnw spring-boot:run
- Add payment gateway integration
- Implement wishlists and reviews
- Improve chatbot with machine learning
- Add internationalization (i18n) support
This document describes the testing structure and coverage for the project, including unit tests, integration tests, and testing tools.
We follow a layered testing approach:
- Unit Tests: Focus on individual classes or methods (e.g., services, controllers).
- Integration Tests: Validate how different layers interact (e.g., controller + service + repository).
- End-to-End Tests (Optional): Simulate real user scenarios through the whole application.
- JUnit 5 β For writing and executing unit tests.
- Mockito β For mocking dependencies in unit tests.
- Spring Boot Test β For integration tests with a real Spring context.
- Testcontainers (optional) β For testing with real databases like PostgreSQL or MySQL.
src/
βββ main/
β βββ java/
β βββ com/example/project/...
βββ test/
β βββ java/
β βββ com/example/project/
β βββ controller/ # Controller layer tests
β βββ service/ # Service layer unit tests
β βββ repository/ # Integration tests for repositories
β βββ utils/ # Utility/helper tests
BookServiceTest: Test book creation, update, deletion, and fetching.OrderControllerTest: Validate admin order status update API.AccountControllerTest: Test account retrieval and update for a user.AIChatControllerTest: Simulate AI responses and test streaming behavior.ContactServiceTest: Test contact message storage and retrieval.
With Maven:
./mvnw testWith Gradle:
./gradlew testI hope you have good experience with this project but for better experience i wrote this documentations
should downlod it on your desktop Download
to run your llm model localy on your desktop
ollama run gemma3This section includes administrative endpoints for managing books, orders, and users.
Base Path: /api/admin/book
| Method | Endpoint | Description |
|---|---|---|
| GET | /getAllBooks |
Retrieves a list of all books |
| POST | /addBook |
Adds a new book β Requires BookRequest in the request body |
| PUT | /updateBook/{bookId} |
Updates an existing book identified by bookId β Requires BookRequest in the request body |
| DELETE | /deleteBook/{bookId} |
Deletes a specific book identified by bookId |
| DELETE | /deleteAll |
Deletes all books |
Base Path: /api/admin/order
| Method | Endpoint | Description |
|---|---|---|
| GET | /getAllOrders |
Retrieves a list of all orders |
| PUT | /updateStatus/{orderId} |
Updates the status of an order identified by orderId β Requires OrderStatusResponse (containing orderStatus) in the request body |
Base Path: /api/admin/user
| Method | Endpoint | Description |
|---|---|---|
| GET | /getAllUsers |
Retrieves a list of all users |
| PUT | /updateStatus/{userId} |
Updates the active status of a user β Requires status query parameter (true or false) |
| PUT | /updateRole/{userId} |
Updates the role of a user β Requires UserRoleResponse (containing role) in the request body |
This section outlines the public API endpoints for accessing book information.
Base Path: /api/book
| Method | Endpoint | Description |
|---|---|---|
| GET | /Books |
Retrieves a paginated list of all books |
Query Parameters for /Books:
pageNumber(int, default: 0): The page number to retrieveperPage(int, default: 12): The number of books per page
| Method | Endpoint | Description |
|---|---|---|
| GET | /getByCategory |
Retrieves a list of books belonging to a specified category |
Query Parameter:
category(String): The name of the category
| Method | Endpoint | Description |
|---|---|---|
| GET | /getById |
Retrieves a specific book by its ID |
Query Parameter:
id(int): The ID of the book
| Method | Endpoint | Description |
|---|---|---|
| GET | /findBestSeller |
Retrieves a list of best-selling books, limited by the specified count |
Query Parameter:
books(int): The maximum number of best-selling books to return
This section outlines the API endpoints for managing user account details.
Base Path: /api/account
| Method | Endpoint | Description |
|---|---|---|
| GET | /getAccount |
Retrieves the account details for a user specified by email |
Query Parameter:
email(String): The email address of the user
Response: UserDTO object containing account details
| Method | Endpoint | Description |
|---|---|---|
| PUT | /setAccount |
Updates the account details for a user specified by email |
Query Parameter:
email(String): The email address of the user whose account is to be updated
Request Body: UserDTO object containing the new account details
Response: A string message indicating the outcome of the update
This section outlines the API endpoint for interacting with the AI chatbot.
Base Path: /api/ai
| Method | Endpoint | Description |
|---|---|---|
| GET | /ask-bot |
Sends a message to the AI chatbot and receives a streamed response |
Query Parameter:
message(String): The message/question to send to the chatbot
Produces: MediaType.TEXT_EVENT_STREAM_VALUE (Server-Sent Events)
Response: A Flux<String> representing the stream of responses from the chatbot
This section outlines the API endpoints for managing contact messages.
Base Path: /api/contact
Adds a new contact message.
- Request Body:
ContactDTOobject containing the message details. - Response:
ContactResponseobject.
Retrieves a list of contact messages for a user specified by email.
- Query Parameter:
email(String): The email address of the user.
- Response: A list of
ContactDTOobjects.
This document outlines the structure of various Data Transfer Objects (DTOs) used in the application.
Description: Represents the data transfer object for contact information.
Properties:
id(String): The unique identifier of the contact.fullName(String): The full name of the contact.email(String): The email address of the contact.subject(String): The subject of the contact message.message(String): The content of the contact message.status(ContactStatus): Enum representing the status of the contact.createdAt(LocalDateTime): The date and time when the contact was created.
Description: Represents the data transfer object for creating or detailing an order.
Properties:
items(List): A list of items included in the order.email(String): The email address associated with the order.subtotal(double): The subtotal amount for the order.tax(double): The tax amount for the order.total(double): The total amount for the order.
Description: Represents the data transfer object for responding with order details.
Properties:
id(Integer): The unique identifier of the order.items(List): A list of items included in the order.email(String): The email address associated with the order.subtotal(double): The subtotal amount for the order.tax(double): The tax amount for the order.total(double): The total amount for the order.status(OrderStatus): Enum representing the current status of the order.date(LocalDate): The date the order was placed or last updated.
Description: Represents the data transfer object for user information.
Properties:
name(String): The name of the user.phone(Long): The phone number of the user.email(String): The email address of the user.address(String): The street address of the user.city(String): The city of the user.state(String): The state or region of the user.zipCode(Integer): The postal or zip code of the user.country(String): The country of the user.
This document outlines the structure and purpose of classes involved in JSON Web Token (JWT) generation, validation, and management.
Description: A service class responsible for handling JSON Web Token (JWT) operations such as generation, validation, and extraction of claims.
Key Public Methods:
String extractUsername(String token): Extracts the username (subject) from a given JWT.String generateToken(UserDetails userDetails): Generates a new JWT for the provided user details.boolean isTokenValid(String token, UserDetails userDetails): Validates a given JWT against the user details, checking if the username matches and the token is not expired.
Configuration:
secretKey: The secret key used for signing and verifying tokens, loaded from application properties (${application.security.jwt.secret-key}).jwtExpiration: The expiration time for JWTs in milliseconds, loaded from application properties (${application.security.jwt.expiration}).
Description: An entity class representing a JWT stored in the database, typically used for managing token lifecycle, such as revocation.
Properties:
id(Integer): The unique identifier for the token record.token(String): The actual JWT string.tokenType(TokenType): The type of the token (e.g., BEARER).revoked(Boolean): A flag indicating whether the token has been revoked.user(User): The user associated with this token, creating a many-to-one relationship with the User entity.
Description: A JPA repository interface for Token entities, providing database operations.
Key Methods:
List<Token> findAllValidTokensByUser(Integer userId): Finds all tokens for a given user ID that have not been revoked. This is a custom query.Optional<Token> findByToken(String token): Finds a token entity by its token string.
Description: An enumeration representing the types of tokens.
Values:
BEARER: Indicates a bearer token type.
This document outlines the API endpoints, Data Transfer Objects (DTOs), and services involved in user authentication and session management.
Description: This controller handles user registration and login requests.
Base Path: /api/auth
Endpoints:
- POST /register: Registers a new user.
- Request Body:
RegisterRequest - Response:
AuthenticationResponsecontaining an access token.
- Request Body:
- POST /login: Authenticates an existing user.
- Request Body:
AuthenticationRequest - Response:
AuthenticationResponsecontaining an access token and an admin status flag.
- Request Body:
Cross-Origin Resource Sharing (CORS): Configured to allow requests from http://localhost:3000.
Description: A Data Transfer Object (DTO) representing the request payload for user login.
Properties:
email(String): The email address of the user.password(String): The password of the user.
Description: A DTO representing the response payload after successful authentication (login or register).
Properties:
token(String): The JWT access token, labeled as"access_token"in the JSON response.isAdmin(boolean): A flag indicating if the authenticated user has admin privileges.
Description: This service class contains the business logic for user registration and login.
Key Public Methods:
AuthenticationResponse register(RegisterRequest registerRequest): Handles new user registration. Checks if the email is already in use, creates a new user with theUSERrole, encodes the password, saves the user, generates a JWT token, revokes any existing tokens for the user, and saves the new token. Throws anIllegalArgumentExceptionif the email already exists.AuthenticationResponse login(AuthenticationRequest authenticationRequest): Authenticates a user using Spring Security'sAuthenticationManager. If authentication is successful, checks if the user is anADMIN, generates a new JWT token, revokes all previous valid tokens for that user, and saves the new token to the repository. Returns anAuthenticationResponsewith the token and anisAdminflag if applicable. ThrowsUsernameNotFoundExceptionif the user is not found.
Key Private Methods:
void revokeAllUserTokens(User user): Revokes all existing valid tokens for a given user by setting theirrevokedstatus totrue.void saveUserToken(String token, User user): Saves a new JWT token for a user withTokenType.BEARERandrevokedstatus asfalse.
Description: Implements Spring Security's LogoutHandler to manage user logout by revoking the JWT token.
Key Public Methods:
void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication): Handles the logout process. Extracts the JWT from the"Authorization"header of the request. If a validBearertoken is found, retrieves the token fromTokenRepo, sets itsrevokedstatus totrue, and saves the updated token.
Description: A DTO representing the request payload for user registration.
Properties:
fullName(String): The full name of the user.email(String): The email address of the user.password(String): The password of the user.
This document outlines the purpose and methods of various mapper components responsible for converting between Data Transfer Objects (DTOs) and entity objects.
Interface: ContactMapper.java
Implementation: ContactMapperImpl.java
Purpose: Handles conversions between ContactDTO objects and Contact entity objects.
Methods:
Contact contactDtoToContact(ContactDTO contactDto, User user): Converts aContactDTOand aUserobject into aContactentity.- Implementation sets
statustoPENDINGandcreatedAtto the current time by default.
- Implementation sets
List<ContactDTO> contactToContactDTOList(List<Contact> contactList): Converts a list ofContactentities into a list ofContactDTOobjects.ContactDTO contactToContactDTO(Contact contact): (Private utility method in implementation) Converts a singleContactentity to aContactDTO.
Interface: OrderMapper.java
Implementation: OrderMapperImpl.java (Marked as @Component)
Purpose: Facilitates conversions between order-related DTOs (OrderDTO, OrderResponse) and entities (Order, OrderItem), as well as to detail view objects (OrderDetails, OrderItemDetails).
Methods:
Order OrderDTOToOrder(OrderDTO orderDTO): Converts anOrderDTOto anOrderentity.- Implementation sets
statustoPROCESSING,datato the currentLocalDateTime,createdAtto the currentLocalDate, and generates a partialorderNumberusing UUID.
- Implementation sets
List<OrderResponse> OrderToOrderResponse(List<Order> orders): Converts a list ofOrderentities to a list ofOrderResponseDTOs.OrderResponse OrderToOrderResponse(Order order): Converts a singleOrderentity to anOrderResponseDTO.- Implementation sets the
dateinOrderResponseto the currentLocalDate.
- Implementation sets the
OrderDetails OrderToOrderDetails(Order order): Converts anOrderentity to anOrderDetailsobject.List<OrderDetails> OrderToOrderDetailsList(List<Order> orders): Converts a list ofOrderentities to a list ofOrderDetailsobjects.List<OrderItemDetails> OrderItemToOrderItemDetails(List<OrderItem> items): Converts a list ofOrderItementities to a list ofOrderItemDetailsobjects.OrderItemDetails OrderItemToOrderItemDetails(OrderItem orderItem): Converts a singleOrderItementity to anOrderItemDetailsobject.
Interface: UserMapper.java
Implementation: UserMapperImpl.java (Marked as @Component)
Purpose: Responsible for conversions between UserDTO, UserResponse DTOs, and the User entity.
Methods:
UserDTO UserToUserDTO(User user): Converts aUserentity to aUserDTO.- Throws a
RuntimeExceptionif theuserobject is null.
- Throws a
User UserDtoToUser(UserDTO userDTO): Converts aUserDTOto aUserentity.UserResponse UserToUserResponse(User user): Converts aUserentity to aUserResponseDTO.List<UserResponse> UserToUserResponseList(List<User> users): Converts a list ofUserentities to a list ofUserResponseDTOs.
This document outlines the components of the notification system, including the entity, controller, repository, service, and status enum.
Description: An entity class representing a notification in the system.
Entity Name: _notifications
Properties:
id(Integer): The unique identifier for the notification.title(String): The title of the notification.message(String): The content of the notification message.type(NotificationStatus): The type of notification, represented by an enum.date(LocalDateTime): The date and time when the notification was created.isRead(boolean): A flag indicating whether the notification has been read.user(User): The user associated with this notification. Creates a many-to-one relationship with theUserentity and is ignored during JSON serialization (@JsonIgnore).
Description: This controller handles HTTP requests related to notifications.
Base Path: /api/notification
Endpoints:
- GET /getAll/{email}: Retrieves all notifications for a user specified by their email address.
- Path Variable:
email(String) - The email of the user. - Response: A list of
Notificationobjects with an HTTP 200 OK status.
- Path Variable:
- DELETE /deleteById/{id}: Deletes a specific notification by its ID for a given user's email.
- Path Variable:
id(int) - The ID of the notification to delete. - Query Parameter:
email(String) - The email of the user. - Response: The updated list of notifications for the user with an HTTP 202 Accepted status.
- Path Variable:
- GET /marksAllRead/{email}: Marks all notifications for a user (specified by email) as read.
- Path Variable:
email(String) - The email of the user. - Response: The updated list of notifications for the user with an HTTP 200 OK status.
- Path Variable:
Description: A JPA repository interface for Notification entities, providing database operations.
Key Methods:
List<Notification> findByEmail(@Param("email") String email): Finds all notifications associated with a user's email address (case-insensitive search on email) using a custom JPQL query.
Description: This service class contains the business logic for managing notifications.
Key Public Methods:
List<Notification> getAllNotificationsByEmail(String email): Retrieves all notifications for a given email by callingnotificationRepo.findByEmail(email).void createNotification(Notification notification): Saves a new notification to the database usingnotificationRepo.save(notification).List<Notification> deleteById(String email, int id): Deletes a notification by its ID for a specific email. Checks if the user has any notifications; if not, throws aRuntimeException. Filters the user's notifications by the providedidand deletes the matching one(s). Returns the updated list of notifications for the email.List<Notification> marksAllRead(String email): Marks all notifications for a given email as read by setting theirisReadproperty totrueand saving the changes. Returns the updated list of notifications for the email.
Description: An enumeration representing the different types or categories of notifications.
Values:
ORDERDELIVEREDPROMOTIONGIFTOTHER
This document outlines the components of the order management system, including entities, Data Transfer Objects (DTOs), controllers, repositories, services, and enums.
Description: Represents an order placed in the system.
Table Name: _orders
Properties:
id(Integer): The unique identifier for the order.data(LocalDateTime): The date and time when the order data was recorded.status(OrderStatus): The current status of the order (e.g., PROCESSING, SHIPPED).items(List): A list of items included in the order. Configured with a one-to-many relationship withOrderItem, using cascade all and orphan removal.email(String): The email of the user who placed the order, stored in theuser_emailcolumn.subTotal(double): The subtotal amount for the order.tax(double): The tax amount for the order.total(double): The total amount for the order.createdAt(LocalDate): The date when the order was created, automatically timestamped.orderNumber(String): A unique number identifying the order.
Description: Represents an individual item within an order.
Table Name: _order_items
Properties:
author(String): The author of the book in the order item.coverImage(String): The URL or path to the cover image of the book.id(Integer): The unique identifier for the order item, ignored during JSON serialization.price(double): The price of this item.quantity(int): The quantity of this item.title(String): The title of the book in the order item.
Description: A DTO used to provide detailed information about an order, often for display or administrative purposes.
Properties:
id(Integer): The order ID.orderNumber(String): The unique order number.customerEmail(String): The email of the customer.totalAmount(double): The total amount of the order.status(String): The current status of the order.createdAt(String): The creation date of the order.items(List): A list of detailed items in the order.
Description: A DTO providing specific details for an item within an order, often used within OrderDetails.
Properties:
bookId(Integer): The ID of the book (presumably,OrderItem.idis used here, but namedbookIdin this DTO).quantity(int): The quantity of the item.price(double): The price of the item.
Description: A DTO used to return a message string, typically after an order operation.
Properties:
massage(String): The message content, labeled as"Massage_Order"in JSON.
Description: A DTO for conveying order status information, likely used when updating or querying an order's status.
Properties:
orderStatus(String): The status of the order.
Description: Handles HTTP requests related to orders.
Base Path: /api/order
Endpoints:
- POST /addOrder/{email}: Adds a new order for the specified email.
- Path Variable:
email(String) - The email of the user placing the order. - Request Body:
OrderDTO- Contains the details of the order to be added. - Response:
OrderMassagewith an HTTP 201 Created status.
- Path Variable:
- GET /getAllOrders/{email}: Retrieves all orders for the specified email.
- Path Variable:
email(String) - The email of the user. - Response: A list of
OrderResponseobjects with an HTTP 200 OK status.
- Path Variable:
Description: A JPA repository interface for Order entities, providing database operations.
Key Methods:
List<Order> findByEmail(@Param("email") String email): Finds all orders associated with a user's email address (case-insensitive search on email) using a custom JPQL query.
Description: Contains the business logic for managing orders.
Key Public Methods:
OrderMassage addOrder(String email, OrderDTO order): Adds a new order for the given email andOrderDTO. Maps theOrderDTOto anOrderentity, sets the user's email, saves the order, creates a notification for the user, and returns anOrderMassage. Throws aRuntimeExceptionif the user is not found.List<OrderResponse> getAllOrders(String email): Retrieves all orders for a given email by fetching them from theorderRepoand mapping them to a list ofOrderResponseDTOs usingOrderMapper.
Description: An enumeration representing the possible statuses of an order.
Values:
DELIVEREDPROCESSINGPENDINGSHIPPEDCANCELLED
This project is licensed under the MIT License.
Feel free to fork and contribute to this project!
