Technology
Frontend
Framework: React
Library: react-cookie (for using cookie),react-redux (for using redux), react-icons, react-router-dom (managing route),runtime-env-cra(inject runtime environment on production environment), framer-motion(make animation)
Backend
Framework: Flask
Library: elasticsearch, flask, flask_migrate, Flask-SQLAlchemy(using sql), Flask-Cors, gunicorn (building docker container), pandas, psycopg2 (postgresql), pytest, pyjwt (make jwt token), python-dotenv, requests, requests-futures
Deployment
Docker
Docker is used for building docker container to deploy on the kubenetes cluster
kubenetes
The Frontend and API was deployed on the kubenetes cluster
Azure
For deploying database and kubenetes cluster
Frontend Implementation
According to the use case diagram in the requirements
page, we are building the search, register, login, and privacy policy page by using react-router-dom and nginx (production) for managing route in react.
search
we build the google-like search-page in the home route. When the user click on the search form, the application will fetch the related API and show the result in the Resultlist components. The image below show the search page(before and after
searching) respectively
login and signup
the implementation details are shown
below
Privacy Notice
use privacy-notice route to manage show our privacy policy
Search Implementation
When the back-end API receives a search request, it parses the JSON object to retrieve the query and the filters. It then passes the request with parameters (query, filters) to the Controller which in turn sends it to the Model. The model stores
a SearchEngine object, which has a search() method. This object sends a GET search request to the ElasticSearch API with the query and the formatted filters. When it retrieves the response, it formats it as a Pandas DataFrame and sends it
to the model. Using parallel get requests to the X5GON api, the Model adds metadata to the search results. These results are then sent back to the Controller which translates it to JSON and sends it back to the API endpoint.
User Data/Login Implementation
User Login Implementation
We create a PostgreSQL to collect the user details. We made the following API endpoint: register, login, and user-detail for handling the user action related to login functionality
Related API implementation
Register - /register
- we collect the username, password, displayname, and email from the user. After that we are quering the database if the username and email has been taken. If those are not taken the new user will be generated with the following parameter userID,
username, password(hashed with salt), salt, displayname, public-id(the id expose to the frontend), timestamp
Login - /login
- we collect the username, password from the user. If that user does exist the API will make the json web token (JWT) using genJWT() with expired date
User Details - /user-detail
- we collect the JWT from the user. Then we check if the token is valid by using jwt_token() function. If the JWT is valid we are going to send user-details
Implementation on the frontend
Register
- we make a form to collect user input then fetch API
- Then redirect to login page after user is registered
- and warn the user if the username/email is taken by pop up our alert components
Login
- Normally, the user will not be login. User islogin and user detail are stored in the redux and backed-up in the localstorage
- User can login via login form
- If user is sucessfully login, the frontend will recieve JWT token from the api, which store in the cookies. After that, the frontend will fetch the api for retrieving user-detail which will update the user-detail and login status
- Later, the application will re-direct back to main page
User Data Implementation
We create a PostgreSQL to collect the search-history and click-history. We made the following API endpoint: search-history and click-history for handling the user action related to user data functionality
Related API implementation
Search History - /search-history
- This endpoint objective is to collect user data when user searching. We collect the user Query, Filter, TopDocumentID and PublicID from the user. If that user does exist, PublicID's value is null
Click History - /click-history
- This endpoint objective is to collect user data when user click on the url. We collect the username, password from the user. If that user does exist the API will make the json web token (JWT) using genJWT() with expired date
Implementation on the frontend
Search History
- After the user finish searching for the query. The application will make a temporary store query in the session storage "search_result". Then the react useEffect hook will check if the session storage "search_result" is not null. Then the
frontend will fetch api to collect search-history
Click History
- When the user click on the search result, collectClickHistory(), function that collect document_id document_pos and search_id, function will be triggered