352 Milestone‐3 Report - bounswe/bounswe2024group1 GitHub Wiki
Milestone 3 Report
1. Executive Summary
1.1 Summary of project and current status
1.1.1 Summary
The "Semantic Browse for Cuisines" project is designed to discover, share, bookmark, and comment on the recipes of the cuisines. In a world where the exploration of global cuisines plays a significant role in cultural exchange, our project stands as an inspiration for people who are seeking to expand their culinary knowledge and connections. Our project's goal is to create a user-friendly platform that not only makes it easier to find diverse recipes but also encourages a community of culinary enthusiasts excited to share their culinary experiences.
1.1.2 Status
We have implemented a significant portion of our Requirements. In the current stage of the project, guest users are able to search for the dishes, view dish pages and view recipes at the explore feed. Also sign up, log in/log out functionalities have been implemented so guest users are able to become registered users when they sign up once and login to the system. Registered users are able to search for dishes, view recipes on the 'explore' feed, see profile pages of themselves and others, follow other users and see their recipes in the 'following' feed, rate recipes, comment on the recipes, bookmark recipes, like others' comments to the recipes, create new recipes.
1.2 Basic Functionality
1.3 URLs
Deliverable | Status |
---|---|
Github Repository | Completed ✔️ |
Release Tag | Completed ✔️ |
Deployed Application | Completed ✔️ |
APK for Mobile Application | Completed ✔️ |
API Documentation | Completed ✔️ |
Requirements | Completed ✔️ |
Class Diagrams | Completed ✔️ |
Use Case Diagrams | Completed ✔️ |
Sequence Diagrams | Completed ✔️ |
Activity Diagrams | Completed ✔️ |
Project Plan | Completed ✔️ |
Responsibility Assignment Matrix | Completed ✔️ |
1.3 Instructions to Build & Deploy
1.4 Information to Test the Application
Information on the basic functionality of our application can be found in our wiki here
1.5 Challenges, Strategies, and Reflections
1.5.1. Frontend
For the frontend, we had several challenges such as proper error handling, API incompatibility, missing validation checks, and onboarding of developers into the project.
For the error handling, our challenge was handling the various types of errors that can happen (i.e. network errors, api errors, internal server errors, parsing errors) and convert the error into a common format which would allow us to show it to the user. We decided to build our custom fetcher that validates and handles errors in a safe manner and returns the errors in a unified structure. We further added unit tests to ensure that edge cases are validated and that this critical part of the project is validated continuously.
For API incompatibility, our biggest challenge was when backend and frontend disagreed on the API contract. Sometimes the API specification had missing items, so we had to add them or adjust them on the API spec. We created a new WhatsApp group to quickly fix these disagreements. This group consisted of the members that worked on the API integration part of the implementation on the backend and frontend teams.
For validation checks, a big challenge was correctly rendering UI depending on the authentication state of the application. Some authentication required buttons like “Follow” “Bookmark” must only be shown when authenticated. We resolved this by reviewing this several times and cross-checking with the UI design.
Finally, we had challenges with onboarding developers in the frontend team. For this, we organized a meeting (Frontend Meeting 3) where the lead introduced the codebase and the repository was set up in each member’s machine. We also talked about good practices in general in Web development.
1.5.2. Mobile
Our mobile project aimed to create a social media app that allows users to search for dishes from Wikidata, add their own recipes, comment on and like other people's dishes, follow other users, and view a feed with trending recipes and recipes from the users they follow. This project presented several challenges, particularly in integrating data from Wikidata to ensure accurate and efficient retrieval of dish information. This aspect required meticulous attention to detail and thorough testing. Additionally, implementing the user functionalities, such as adding recipes, commenting, liking, and following other users, involved complex UI/UX design and front-end development, demanding significant time and effort.
One of the most challenging features was the feed, which consisted of two parts: trending recipes and recipes from followed users. Developing the algorithms to ensure the content was relevant and engaging for users required careful consideration and significant development work. Balancing these technical requirements while ensuring a seamless user experience was demanding and required constant iteration and testing.
However, the most significant challenge We faced was miscommunication within the team. A team member who was supposed to share the workload with us did not meet their responsibilities, leading to an uneven distribution of tasks and increased workload for me. This miscommunication resulted in delays and ultimately prevented us from completing the app within the planned timeframe. Reflecting on this experience, We learned the crucial importance of effective communication and accountability in a team setting. Regular check-ins and clear assignment of responsibilities are essential to ensure everyone is on the same page and contributing equally. The challenges faced during this project have strengthened my project management skills and underscored the need for adaptability and resilience when unexpected issues arise. Moving forward, We will apply these lessons to enhance communication, ensure fair workload distribution, and improve overall project execution in future endeavors.
1.5.3. DevOps
For devops, the challenges we faced were mostly with usage of CI which is Github Actions. After the addition of CI to our workflow, we had cases where team members forgot to check CI before merging their code into the develop
branch. We also had problems with commit hooks, they were not working correctly in some cases and were not as strict as the CI which led to commits passing pre-commit
checks but failing CI. We went through several iterations of the CI and the pre-commit
hook to fix these issues.
1.5.4. Backend
-
During the implementation of our project, which involved adding recipes and fetching data from Wikidata for various cuisines and dishes, we encountered several significant challenges.
-
One of the primary issues was handling the complex mappings in Spring JPA. Given the extensive and often nested relationships between entities such as ingredients, recipes,cuisines,comments,rates and upvotes, ensuring accurate and efficient mappings was crucial.
-
We used annotations like @ManyToOne, @OneToMany, and @ManyToMany to define these relationships, but this introduced complexities, especially when dealing with bidirectional mappings. It was vital to avoid infinite recursion issues that could arise from cyclic dependencies due to @Data annotation and default toString methods which come along with @Data annotation. So, we handled by defining our custom toString methods.
-
Edge cases presented another layer of difficulty. For instance, some dishes had incomplete data in Wikidata, necessitating robust error handling and default value assignment to ensure the system's stability. Additionally, fetching data from Wikidata involved dealing with asynchronous calls and potential delays, which we mitigated by implementing timeouts and fallback mechanisms.
-
Defining Data Transfer Objects (DTOs) was essential for ensuring that our application's data flow was both secure and efficient. DTOs helped us to avoid exposing entity classes directly, thus reducing the risk of unintentional data manipulation. We designed DTOs to capture only the necessary fields required for our application's operations, ensuring minimal data transfer and enhancing performance.Also, we designed our DTOs according to our API Spec.
-
Overall, while the project posed significant challenges in terms of entity mapping, edge case handling, recursion management, and DTO definition, our strategic use of Spring JPA's features, robust error handling mechanisms, and careful design of data structures allowed us to develop a reliable and efficient system for managing recipes,cuisine,dish and all related-mapped data.
2. Contributions
2.1 Mehmet Efe Akça
Github Links
Most Important PRs
Most Important Issues
- Handling and showing API errors as toasts
- Filling in missing items in API spec
- Implementing Recipe Creation Page
My Personal Page
API work
As I've worked mostly in the frontend part of the project (with minor contributions to the backend and mobile), I can talk about the API integration I've done on the frontend.
For the frontend, I've researched OpenAPI code generation tools and decided to use @openapi-codegen/cli
to generate API client code for the frontend. This tool allows us to write our own fetcher and context functions and provides TypeScript types for request bodies, schemas, and responses. Our API calls are also fully type-checked which provides another layer of safety in the frontend.
I've written thorough unit tests for the API fetcher code that validates error handling and rendering edge cases. These are detailed in a section below.
Since all API calling code is autogenerated, I will include examples of some API endpoints that I've used in my code. These examples are taken from the Swagger API spec.
Unit Tests
I've written 35 unit tests in total in the frontend. I have written unit tests for the API fetcher, for most of the input components, and for a couple of the route components.
For the API fetcher, I've written tests for the following cases:
- API Fetcher (6)
- on error (3)
- should forward an API error
- should handle an error HTTP status code
- should handle a rejection when fetching
- on success (2)
- should return the data
- should accept 201 Created status
- fetch call (1)
- should call fetch with the right arguments
- on error (3)
- renderErrors (5)
- should not throw
- should render general errors
- should render multiple errors
- should render form errors when there are general errors
- should render form errors
- getFieldErrors (2)
- should not return general errors
- should return field errors
- setFormErrors (5)
- should set general errors
- should set field errors
- should set general errors when there are field errors
- should set serverError to unknown error when no errors are available
- should not set the serverError when only field errors are present
A sample test case is as follows:
it("should handle an error HTTP status code", () => {
// fetchMock is a global mock for the fetch function
fetchMock.mockResolvedValueOnce(
createResponse(500, {
status: 500,
errors: [
{
message: "Internal server error",
},
],
}),
);
expect(
semanticBrowseFetch({
url: "/api/v1/hello",
method: "GET",
body: {},
}),
).to.rejects.toMatchObject({
status: 500,
payload: {
status: 500,
errors: [
{
message: "Internal server error",
},
],
},
});
});
This test case tests the behavior of the API fetcher when encountering an error. It checks if the fetcher rejects the promise with the correct error object. The other test cases are similar in nature.
For the input components, I've written tests for the following cases:
- BookmarkButton
- should render the bookmark button correctly
- when not bookmarked
- should trigger bookmark and refetch on click when successful
- should trigger bookmark and return to unbookmarked on error
- when bookmarked
- should trigger unbookmark and refetch on click when bookmarked
- should trigger unbookmark and still show bookmarked on error
- FilterCheckbox
- label renders text with label
- clicking on the label triggers onChange
- RatingInput
- renders correct number of stars based on currentRating
- updates tempRating on mouse enter and resets on mouse leave
- calls setRating with correct value on click
- SearchBar
- searching something goes to /search
- SearchFilterPopover
- does not call set functions when closed without confirming
- calls set functions with correct values when confirmed
For the routes, I've written tests for the following cases:
-
home route
- welcome test is shown
-
login route
- log in button goes to /login
- login calls service
Other significant work
Most of my work was implementing components and pages in the frontend. I've implemented the following components and pages:
- BookmarkButton
- FilterCheckbox
- RatingInput
- SearchBar
- SearchFilterPopover
- Recipe Page
- Dish Page
- Recipe Creation Page
- Profile Page
In terms of devops, I've set up an S3 Mock in our Docker Compose for the backend to use but unfortunately, there was not enough time to implement file uploading.
I've also reviewed all the PRs I was asked for a review on.
I've closed a total of 19 issues since the second milestone.
I've merged a total of 26 PRs since the second milestone.
Challenges faced
During implementation, I realized that manually implementing API calls was error-prone and time-consuming. This is why I've researched and found a tool that generates API client code from OpenAPI specs. The challenge here was finding the correct tool and configuring it to work with our project. Many tools either didn't have the featureset we needed or were not well-documented. I ended up finding one that fits our use case and had to adjust the API spec slightly to work with that tool. This tool saved us a lot of time and effort in the long run and sped up implementation massively by making API calls a breeze.
Another challenge was the lack of a proper error handling mechanism in the frontend. I've implemented a toast system that shows errors to the user in a non-intrusive way. This was a challenge because we had to decide on the best way to show errors in components that are nested inside like the BookmarkButton or the FollowButton. These components make API calls which can fail, but due to the nature of the components, they can't show their own error message in the area allocated to them. This is why I implemented a toast system that shows errors globally. It also handles and shows authentication errors like token expiration or when an action requires authentication (like upvoting a comment). This led to a smooth and efficient error handling mechanism in the frontend.
2.2. Ufuk Altunbulak
I have implemented the code that is responsible for adding a comment to recipe pages.
2.3. Nazire Ata
Most important issues I worked on:
- #146 - Implement Recipe Card UI
- #289 - Implement AddComments Component UI
- #314 - Implement Unit Test for Bookmarkers
My most important pull requests:
Description of Bookmarkers.test.tsx:
This is the first and only unit test I ever wrote, and it has 2 simple tests in it. The first test is to see if an error state is displayed when there is an error, and the second one basically tests if the Bookmarkers component will pop up on click. I had a hard time understanding how vi.mock works, but with the help of Efe, I managed to write these simple tests. I believe it was good practice for future projects.
Descriptions of third-party APIs and the API functions
To get the bookmarkers of a recipe with id 1, the API call looks like:
GET /api/v1/recipes/1/bookmarks and it returns a response with content type application/json in the form:
I worked on the frontend part of this project under Mehmet Efe’s leadership, and I implemented many components that can be found on my Personal Efforts page.
My biggest challenge in this project was that I had never written anything related to frontend before, so I had to spend a lot of time learning how React works. I did not give up and wanted to learn more, so I took on some tasks. It was really hard at the beginning, I would have to look at Mehmet Efe’s code for other pages and compare it to the online tutorials I found, even for the simplest task. Fortunately, in time, I got more used to creating components and linking pages and took on more tasks as I got better at it. So, it is fair to say that my biggest challenge was being inexperienced, but I managed to deal with it by simply not giving up and trying to learn as much as I could.
2.4. Enes Başer
Most Important Three Issue:
-
Issue 125 - Create entity classes and configure mappings https://github.com/bounswe/bounswe2024group1/issues/125
-
Issue 128 - Implement storage mechanism for fetched wikidata response. https://github.com/bounswe/bounswe2024group1/issues/128
-
Issue 133 - Resolve JWT and Security Filter Chain Functionality https://github.com/bounswe/bounswe2024group1/issues/133
Most Important Three PR :
- https://github.com/bounswe/bounswe2024group1/pull/145
- https://github.com/bounswe/bounswe2024group1/pull/158
- https://github.com/bounswe/bounswe2024group1/pull/297 (Stackoverflow error fix due to mapped entities)
Wiki Doc. For Personal Effort :
Third Party External & Internal APIs :
-
We have used Wikidata API to send SPARQL queries to retrieve cuisine,dish,foodType of that dishes and ingredients info from Wikidata. Also we have used Apache Sparql Service Library to send query in order to avoid possible encoding errors in query string. Reference 🔗 : https://jena.apache.org/documentation/query/
-
SPARQL Service and Wikidata API Usage Sample Images :
-
We have used Java Stream API instead of handling objects with for loops which is very common and readable way of handling Lists or Sets.(Stream, filter map etc.)
-
Sample Images for Stream API and its usage :
- Mapping Dish object to DishResponseDto.
- DishResponseDto class
Unit Test :
- JUnit 5 Test for Authentication Controller. Here is the code snippets for AuthenticationController mock test.
Other Significant Works
- I have been lead in backend team and implemented mapping logic for storage , folder structure (service,controller,respository …)
- Implemented all endpoints and services except two of them (GET & POST /upvotes)
- Implemented response object in proper format according to API Spec. so frontend team can handle fetched json response.
- Fixing bugs and misconfigs for other team members’ works.
- Reviewed pull request for backend tasks.
- Allocate tasks over backend team.
- Overall, had 36 PR that have been merged.
Challenges
- Finalizing mapping structure and bidirectional mappings was the one of the hardest part of the backend side because of that fact that especially in bidirectional mappings stackoverflow errors occurred and spent on much time to resolve its reason and came up with solution. (Removing Data annotation and handle ToString method with custom implementation.)
- Implementing endpoints considering especially for rating and upvoting. Because these entities related and mapped to many entities and should be tested with with caution.
- It was challenging to help other team members and solve their bugs because they need to grasp some concepts to resolve bugs and fix them. Formatting response type should exactly match with the expectation of frontend team so formatting needs to be rearranged many times.
- Rearranging SPARQL Query String to fetch more data from Wikidata API
2.5. Çağatay Çolak
Task | Related Issue |
---|---|
Implement POST upvote API | #285 |
Implement DELETE upvote API | #284 |
Implement POST comments API | #177 |
I have worked with the backend team and wrote the apis related with the comments and upvote features. Here is my personal effort page.
The main difficulty that I faced was the framework we worked on, as I have no experience with Spring Boot. However, since I know the fundamentals of backend and web development, I easily adapted to the framework and was able to start writing some endpoints.
2.6. Aslı Gök
The most important issues: #150, #147.
I was in the frontend team with Efe and Nazire, tried to learn the basics of frontend development and worked on some pages.
The main difficulty I have encountered during the course was that I had no experience in most topics regarding the implementation, so learning them in a very limited time and implementing simultaneously were so challenging which I couldn't manage well. At least I have tried with the help of my teammates, so I am happy for that. My other contributions can be seen under my personal effort page
2.7. Boray Kasap
The most important issues I worked on are #118, #175 and #233. My most important pull requests are #188 #189 and #253.
I worked with the backend team. I wrote most of the unit tests and added github actions to frontend. You can find detailed description of my efforts here.
The biggest challenge for me was lack of experience in backend development. First, I spent some time understanding how different components of Spring framework relate to each other. Watched some YouTube tutorials in that regard and tried to figure out how everything worked altogether in harmony from our existing codebase. Then I asked for help from Enes and Atakan. They helped me out a lot and I could contribute to some parts. Another challenge was adding GitHub Actions to the frontend part of our project. I was inexperienced in that also. Efe’s feedbacks made my job much easier. Apparently, helpful teammates are such a blessing.
2.8. Yiğit Memceroktay
My Top 3 most important issues
Task | Related Issue |
---|---|
Implement The Design For The Bookmarks Page | #209 |
Implement Navigation UI | #284 |
Implement Recipe Creation Page | #212 |
My Top 3 most important pull requests
Task | Related Issue |
---|---|
Implement The Design For The Bookmarks Page | #299 |
Implement The Navigation System For the Mobile Project | #300 |
Implement The Search Functionality For the Mobile Project | #304 |
I mostly worked on the mobile side of the project. I implemented the design of the feed page, bookmarks page, profile page and connected with some of the pages with the backend as much as my time allowed it. I also implemented the search functionality for the mobile part.
One of the biggest challenges I faced during the mobile project was dealing with miscommunication with a team member who was supposed to work alongside me. This individual did not meet their responsibilities, which led to a significant increase in my workload. As a result, I found myself having to take on much more than initially planned. This experience was quite stressful and required me to manage my time and resources more effectively to ensure the project was completed on time However, the project could not be completed on time. Reflecting on this situation, I learned the importance of clear communication and accountability within a team. It highlighted the need for regular check-ins and updates to ensure everyone is on track and aware of their tasks.
Worked with Mehmet Efe Akça mostly during the project
You can chech my work in more detail here
2.9. Yüksel Eren Şen
2.10. Atakan Yaşar
Most important issues |
---|
#126 |
#271 |
#313 |
Most important pull requests |
---|
#245 |
#259 |
#312 |
Implemented APIs | Sample Requests and Responses | Related Pull Request |
---|---|---|
GET /recipes/{recipeId}/bookmarks | #178 | #187 |
POST /recipes/{recipeId}/bookmarks | #179 | #186 |
DELETE /recipes/{recipeId}/bookmarks | #180 | #259 |
GET /dishes/{dishId} | #294 | #295 |
PUT /users/{userId} | #302 | #303 |
Implemented Unit Tests | Related Issue | Related Pull Request |
---|---|---|
Dish Controller Unit Test | #311 | #312 |
Solved Bugs | Related Issue | Related Pull Request |
---|---|---|
Missing Field GET recipe API | #243 | #251 |
Missing Fields in Response GET /users/me | #250 | #265 |
Refactor of Recipe Entity | #271 | #272, #282 |
Make Dishes Nullable | #287 | #288 |
Critical Bugs Appeared on Deployment | #313 | #317 |
Devops | Related Issue | Related Pull Request |
---|---|---|
CI/CD for backend | #119 | #132, #310 |
Meeting Notes |
---|
Backend Meeting Note 6 - 11.05.2024 |
Backend Meeting Note 5 - 10.05.2024 |
Backend Meeting Note 4 - 07.05.2024 |
Backend Meeting Note 3 - 06.05.2024 |
Teamwork
- Worked with Enes for planning of backend implementations.
- Helped and reviewed Boray's and Ufuk's contributions.
- Communicated with Efe for solving production bugs.
Lessons Learned
- Avoid cyclic dependencies for both backend services and entity mappings, which may cause infinite recursion. We should have designed them more carefully.
- Override toString method for safety in case of cyclic dependency.
- Do not forget OnCascade and text limit annotations.
- Avoid duplication of DTOs. There may be a lot of them at the end, which may cause complexity while solving bugs.
- Don't postpone unit test.
Honor Code Statements
MEHMET EFE AKÇA
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, MEHMET EFE AKÇA , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
NAZIRE ATA
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, NAZIRE ATA , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
ENES BASER
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, ENES BASER , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
BORAY KASAP
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, BORAY KASAP , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
CAGATAY COLAK
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, CAGATAY COLAK , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
ATAKAN YASAR
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, ATAKAN YASAR , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
ASLI GÖK
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, ASLI GÖK , declare that:
-
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
-
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
-
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.
YİĞİT MEMCEROKTAY
Related to the submission of all the project deliverables for the project of the CMPE 352 course, during the 2024 Spring semester, reported in this report, I, NAZIRE ATA , declare that:
I am a student in the Computer Engineering program at Boğaziçi University and am registered for the CMPE 352 course during the 2024 Spring semester.
All the material that I am submitting related to my project (including but not limited to the project repository, the final project report, and supplementary documents) have been exclusively prepared by myself.
I have prepared this material individually without the assistance of anyone else with the exception of permitted peer assistance which I have explicitly disclosed in this report.