This app aims to manage a simple cash register. Also list the products and offers. The app has user management and authorization. The app has a report system to list the sales and generate pdf receipts. The app has a logging system to log the actions of the system. The app has an authentication service to authenticate the users and authorize the other services. The app has an interface for other services to manage users and
- Listing Products
- Listing Offers
- Creating Sales
- Listing Sales
- Generate Reports of Sales
- User Management and Authorization
The project developed around the Java Spring framework. And, PostgreSQL is the database solution of the project.
- Java 17
- PostgreSQL
- Spring Boot
- Spring Security (for authentication and authorization)
- Spring Data JPA (for database operations)
- Eureka (for service discovery)
- Docker
- itextpdf html2pdf (for generating pdf reports)
- Feign (for calling other services)
- Log4j2 (for logging)
- Docker has to be installed on your machine.
- After running the docker compose command, the database must be created by executing
db_structure_public_scheme.sql
file. - Create a text file named
db_credential.txt
in the root directory of the project. Write the database password for postgres user directly. - Create a text file named
jwt_secret.txt
in the root directory of the project. Write the secret key for JWT directly.
Run the following command in the root directory of the project.
docker build . -f BuilderDockerfile
docker compose build
docker compose up
Check postman documentation for more details.
All the success responses are in AppSuccessResponse format that includes status, message and data fields.
Response format:
{
"status": 200,
"message": "Success",
"data": { }
}
{
"status": 200,
"message": "Success",
"data": [
{ },
{ }
]
}
- POST /api/v1/auth/login
- Authentication: no authentication
- Request Body: LoginRequest
- Response Body: LoginResponse: contains the JWT token
- GET /api/v1/auth/user
- Authentication: authenticated
- Request Body: no request body
- Response Body: UserDTO: the authenticated user
- GET /api/v1/user
- Authentication: ADMIN only
- Request Body: no request body
- Response Body: List: list of users
- GET /api/v1/user/{userId}
- Authentication: ADMIN only
- Request Body: no request body
- Response Body: UserDTO: the user
- POST /api/v1/user
- Authentication: ADMIN only
- Request Body: UserCreateRequest
- Response Body: UserDTO: the created user
- PATCH /api/v1/user/{userId}
- Authentication: ADMIN only
- Request Body: UserUpdateRequest
- Response Body: UserDTO: the updated user
- DELETE /api/v1/user/{userId}
- Authentication: ADMIN only
- Request Body: no request body
- Response Body: no request body: success or error response
- GET /api/v1/user/role
- Authentication: ADMIN only
- Request Body: no request body
- Response Body: List: list of roles
- GET /api/v1/user/role/{roleId}
- Authentication: ADMIN only
- Request Body: no request body
- Response Body: UserRoleDTO: the role
- GET /api/v1/product
- Authentication: no authentication
- Request Body: no request body
- Response Body: List: list of products
- GET /api/v1/product/{id}
- Authentication: no authentication
- Request Body: no request body
- Response Body: ProductDTO: the product
- POST /api/v1/sale
- Authentication: CASHIER only
- Request Body: SaleCreateRequest
- Response Body: SaleDTO: the created sale
- POST /api/v1/sale/preview
- Authentication: CASHIER only
- Request Body: SaleCreateRequest
- Response Body: SalePreviewDTO: the preview of the sale if it is valid
- GET /api/v1/offer
- Authentication: CASHIER only
- Request Body: no request body
- Response Body: List: list of offers
- GET /api/v1/offer/{id}
- Authentication: CASHIER only
- Request Body: no request body
- Response Body: OfferDTO: the offer
- GET /api/v1/payment-method
- Authentication: CASHIER only
- Request Body: no request body
- Response Body: List: list of payment methods
- GET /api/v1/payment-method/{id}
- Authentication: CASHIER only
- Request Body: no request body
- Response Body: PaymentMethodDTO: the payment method
- GET /api/v1/report
- Authentication: MANAGER only
- Request Body: no request body
- Request Param:
- p (required): Integer: page number
- s (required): Integer: page size
- orderBy (optional) String: the field to order by [id, receivedMoney, createdAt, cashier]
- orderByAsc (optional) Boolean: true for ascending, false for descending
- dateFilterAfter (optional) Long: timestamp in milliseconds
- dateFilterBefore (optional) Long: timestamp in milliseconds
- cashierFilter (optional) Long: the cashier id
- receivedMoneyFilterMin (optional) Double: received money filter min or equal
- receivedMoneyFilterMax (optional) Double: received money filter max or equal
- Response Body: List: list of reports
- GET /api/v1/report/{id}
- Authentication: MANAGER only
- Request Body: no request body
- Response Body: ReportDTO: the sale in json format
- GET /api/v1/report/{id}/receipt
- Authentication: MANAGER only
- Request Body: no request body
- Response Body: byte[] (file): the pdf receipt
- GET /api/v1/report/{id}/receipt-html
- Authentication: MANAGER only
- Request Body: no request body
- Response Body: byte[] (file): the html receipt
AppHttpError
class is used for error responses. The AppHttpError
class has a code
field for the error code and a
message
field for the error message. Example error response:
{
"status": 400,
"message": "<<Error explanation>>"
}
-
POST /api/v1/auth/user-management
- Request Body: UserCreateRequest
- Response Body: UserDTO: the created user
-
PATCH /api/v1/auth/user-management/{id}
- Request Body: UserUpdateRequest
- Response Body: UserDTO: the updated user
-
DELETE /api/v1/auth/user-management/{id}
- Request Body: no request body
- Response Body: no request body: success or error response
- GET /api/v1/auth/accessibility
- Request Body: no request body
- Response Body: no request body: success or error response
The log4j2 library is used for logging the actions of the system. The logs are stored in the home directory of the
container. log4j2.xml
file is used for configuration for all the modules.
The project has a AppSuccessResponse
class for the success responses. It has a data
field for the response data.
status
field for the response status code. message
field to response with a message, by default it is Success
.
GlobalExceptionHandler
class is used for handling exceptions over all the project. AppHttpError
class is used for
responding to the client in case of an error. The AppHttpError
class has a code
field for the error code and a
message
field for the error message. The AppHttpError
class is used in the GlobalExceptionHandler
class. All
defined exceptions are a AppHttpError
instance. The GlobalExceptionHandler
class is used for handling all the
exceptions and returning the AppHttpError
instance as a response.
Also, all the undefined exceptions are handled by the GlobalExceptionHandler
class. The GlobalExceptionHandler
class
returns a AppHttpError
instance with the error code 500
and the error message Internal Server Error
.
The project has an auth
service to manage the authentication and authorization of the users. The auth
service
generates a JWT tokens. The JWT token is used for the authorization on whole the project.
The auth
service has a /login
endpoint to authenticate the users. The /login
endpoint returns a JWT token in the
response body. The JWT token is used for the authorization of the other services.
The auth
service has a /user
endpoint to get the authenticated user. The /user
endpoint returns the authenticated
user information in the response body.
The auth
service has a /accessibility
endpoint to check the accessibility of the user. The /accessibility
endpoint
returns a success response if the user is authorized. Otherwise, it returns an error response. There is a Before Aspect
on all the controller methods in the project excluding the auth
service. This aspect sends a request to the auth
service to check the accessibility of the user to reach the endpoint via auth
service.
The log4j2 library is used for logging. The logs are stored in the home directory of the container. log4j2.xml
file is
used for configuration for all the modules.
All logs (including trace) are saved into the app.log
file in the home directory of the container. Info level logs are
saved to the general-info.log
file in the home directory of the container.
This application can generate pdf reports for the sales. The pdf reports are generated by the itextpdf.html2pdf
library with thymeleaf. When creating PDFs, first, it creates a PDF with many pages. Then, it calculates the total
height of the content and creates a new single page PDF with the total height. There is no caching for the PDF files.
The PDF files are generated on the fly.