sharmaaditya570191's Blog

Lifecycle hooks, threading and notification system in the user story system in GSOC'20

sharmaaditya570191
Published: 08/03/2020

A whole new set of awesome features are here for our beloved users. Do not get worried by the heavy terms in the title. Sit back, relax and follow me to catch a glimpse of my implementation for giving you the best possible user experience. You will soon be able to write your own story, share with us how you use our products, relate to other users’ stories, vote them up and we’ll make sure we deliver cohesive solutions to you.

What did I do this week?

This week it was time to design a personalized notification system for our users to notify them about the latest features when we launch them. Only author and followers(users who have voted) of the launched story should receive the notification so that we do not disturb other users who might be busy writing their own amazing stories.

The admins update the status of a user story to “launched” via the back end Strapi panel when our team have successfully pushed a new feature to production.

Now Strapi lifecycle hooks come into action. The lifecycle hooks are functions that get triggered when the Strapi queries are called. They will get triggered automatically when we manage our content in the Admin Panel or when we develop custom code using queries.

I wrote a asynchronous afterUpdate hook in the user story model which checks if the status of a user story has changed to “Launched” after being updated. If the status has changed then it creates a new notification record on the server with a custom message, seen status, link to the story page and a list of users to whom the notification is to be shown. I did this by utilizing Strapi services which are a set of reusable functions. They are particularly useful to respect the DRY (don’t repeat yourself) programming concept and to simplify controllers logic. Every notification on the server is required to have a different and unique message.

On the client side I fetch the notifications for the particular authenticated user using GraphQL queries. When the user has seen the notifications then they are marked as seen on our Strapi server too. This is done using GraphQL mutations which update the status of a notification. I made sure that we do not hit our API multiple times to update the status of a notification. 

The next major feature of the week was to add threading in comments. This allows users to reply to a particular comment on a story in a thread. I created a separate model on the server for user story comment replies. Each comment reply belongs to one comment, a user can have multiple comment replies, each reply belongs to one user and one comment can have multiple replies. Such was the complexity of relations between the models schema. You can also see the number of replies and even add your own reply via the client side. 

All these extra efforts will make your user experience super smooth. The blazing fast React re-renders and updates on the client side will be a icing on my cake. :P

What is coming up next?

I will spend some time to polish and test the existing features.

I will also work on the user story privacy policy to allow admins to manage and update the policies from the admin panel. Users should receive notifications whenever the privacy policies are updated. The user can then choose to accept them or remove their account.

Did I get stuck anywhere?

I got stuck at multiple places be it writing hooks and custom controllers in Koa for my server or implementing mutations in an effective and optimized way on the client side.

However, I did not give up and kept reading more about the topics and technologies involved. This way I was able to learn a lot of new things during the week. Debugging and troubleshooting became super easy after I hit my learning goals and covered all basic concepts properly.

This ended the week with the second evaluation. I received a really nice feedback from my mentors. I expressed my sincere thanks to them today for always supporting, motivating and inspiring me to learn more.

View Blog Post

Boosting application security, voting and commenting in the user story system in GSOC'20

sharmaaditya570191
Published: 07/27/2020

This time I let the title reveal the much awaited features that are up and running by the time you read this. I am really excited to experience that adrenaline rush when I get a chance to vote in the real elections and choose our leaders of tomorrow. For now I can fulfill my desire by contributing in selecting the best and most wanted user story of the season. Follow me to understand how I solved the mystery of votes and relations.

What did I do this week?

Recall that complex bug where Strapi could not find the schema for our user story model and kept flashing that weird error on my terminal despite repeated attempts. This time I dived deep inside to catch a glimpse of the internals of Strapi and finally solve that.

The fields of the newly established relations in the user story model were overlapping with each other because Strapi does not drop or migrate the database when a model is deleted or updated. They do so because users may start their application with a production database and a model name may not match with one of the tables in the database. Crash! :/ This is a work in progress and Strapi is improving it. I solved it by choosing a different one sided relation type of one-to-many and renamed it to followers.

Now I added client side logic for the voting system so that a user cannot vote more than once. Clicking on the like button for the second time removes the vote of the user and so on. Pushing all this to production gave me a sigh of relief. :)

After a deep breath I moved on to allow users to leave their valuable feedback and suggestions on user stories. Yes, comments. This way we can take into account the views of more users and design our next awesome feature accordingly.

Now it was time to step up the security as a lot of functionality was already in place. I wrote a custom controller in Koa which checks that the localStorage id matches with the id of the authenticated user and if the same user is the author of the story they are viewing. A positive response will allow the user to edit their story. I also modified the controller which creates a new story and now it can automatically assign the authenticated user to be the author of the story.

What is coming up next?

I will work on the notification system. It would be great to have three types of notifications — in app, push and email notifications.

These will notify the user story author and followers that their user story has been launched. Only organization admins can update the status of a story from the Strapi panel.

If time permits I will try to setup Cypress for testing our application.

Did I get stuck anywhere?

The React implementation to allow one time voting for each user was a bit tricky as there are a lot of state variables on our story page. However, I solved this by catching the previous state value by applying functional updates in my useState hooks to overcome the stale state problem which arises due to closures in React.

Writing controllers for my server in Koa was also new but I was able to learn the basics quickly as it is similar to Express.

This ended the week on a sweet note. Stay tuned and get ready to receive another set of notifications on your device. Do not worry. We will not throw those sales ads on you again. This time it will be about the launch of your own story. :P

View Blog Post

Making and inspecting model relations for the user story system in GSOC’20

sharmaaditya570191
Published: 07/20/2020

The world is full of relationships. Everything around us is connected to each other in some way or the other. Sometimes relations can be hard to figure out. Join me as I help you create a unique relation with our user story system and some of its brand new features.

This week started with full action and thrill as usual and we decided to modify our models to align with our product name. This means all existing models had to be renamed according to the user story theme on the server side. A rename operation seemed like a small and simple task but I soon realized that Strapi does not update the GraphQL schema if we rename a model. This is because existing tables are not deleted or dropped from our MongoDB database and instead new ones are created. This started breaking everything on the server side.

I rolled back and created new models for user story system and imported all data from our staging database. This time the shadow CRUD functionality generated a perfect new schema for my use case. Server was good to go.

The schema changed so the next task was to change all GraphQL queries and mutations on the client side and align them with the new user story models. The docs for the schema helped me to complete this with ease.

Next I created a new model for all the products at EOS and related it to the user story system model. This allows users to filter stories according to the product and enhances user experience by allowing them to navigate faster among hundreds of user stories. I worked on the filter feature on the client side to fetch all products and filter them according to their status and product selected by the user via a drop down.

I eagerly wanted to allow users to respond to some amazing user stories so I moved on to implement the voting feature. This allowed users to vote for any user story to express their interest. Wait. It just sounds easy but some major problems and bugs were waiting for me at the end of the week before I could push the voting system to production.

MissingSchemaError: Schema hasn’t been registered for model “user-story”

My terminal kept flashing this message as I tried to figure out the problem in my new user story vote models and relations. It is still a mystery though because the same relations work fine with my comments model. I told you relationships can be hard sometimes. :/

I will work on the voting system for user stories. This involves establishing proper relations between the user story and user models. The mystery will be solved soon.

Further I would try to think of a nice implementation for the user notification system to tell users that their wait for the next awesome feature is over. This would be implemented later this week. Users really want to make comments so lets give them that privilege first.

MongoDB relationships represent how various documents are logically related to each other. I faced a weird problem when I was establishing a one-to-many relation between my user story vote, users and user story models. MongoDB could not identify the schema for my user story model for some reason and kept throwing an error. The bug came to us at the end of the week and I am still trying to solve the mystery with my mentors. Moving forward we created a map of all our relations to get a nice picture of all relationships and find the conflicts and resolve them.

This ended the week with lots of rain which gave me some relief from the scorching heat. Stay tuned as I solve the mystery behind relationships and add new path breaking features to the user story system. The adventure is yet to begin. :)

View Blog Post

Comment queries and edit mutations in the feature request system in GSOC’20

sharmaaditya570191
Published: 07/13/2020

Sometimes we are not able to express all our thoughts and ideas in one go. A great idea may strike later or you may want to comment and give some suggestions and feedback to stories of other users. Come explore with me some exciting features that I added to our feature request system using Strapi , GraphQL and React this week.

What did I do this week?

A strange bug starts the week with some thrill and action. Our whole application breaks when a user logs in to the system and submits a new user story. Crash!

We were checking and dividing our user stories on our client side according to their current status. No status gets assigned by default to a new user story as that is an admin or root level permission feature. In Strapi I cannot assign a default status to a relation type field because relations between models can be of various types. I solved the bug on the client side by assigning every new user story a status of “Under Consideration” in my GraphQL mutation.

A user may want to check out their own stories at some point of time so I implemented a GraphQL query to fetch all user stories based on their user id. Users need to be authenticated to access their own stories. They can check their stories for status updates, votes, likes and comments from other users.

The next was the most awaited feature of allowing our beloved users to edit their own user stories. However, they cannot change the already added description. Content can just be added to the existing information. This is just to avoid trolls. :P

What is coming up next?

This week I will create a product model so that we can relate all our products at EOS Design System with a separate user story system. Users can filter their stories for different products.

I am also working on user comments system so that we can display all comments properly and further allow users to add more comments.

Did I get stuck anywhere?

Development without getting stuck is no fun. We learn fast from our mistakes. Initially I was happy to complete the edit story functionality and it worked well. Then my mentors could hack into the system easily. Security compromised. :P

They could edit stories of other users as well after writing into the famous localStorage . I solved the bug easily by implementing a function to verify and allow editing only if the user is the owner of the story.

This ended the week on a sweet note with quite some features added. Stay tuned for more fun and action. :)

View Blog Post

Unleash content with Strapi and GraphQL in the feature request system in GSOC’20

sharmaaditya570191
Published: 07/06/2020

You definitely received exactly what you wanted and you enjoyed using it. Now you just want to know how this actually works under the hood. Is it real magic? Did god just shaped it according to your needs and sent it down from heaven? Come with me and I’ll answer all your GraphQL queries.

What did I do this week?

It took me some time to realize that GraphQL is not another programming language. It is a specification or a technical standard. This mean it can have several implementations and variations. GraphQL.js is the JavaScript reference implementation. Legends like Strapi implemented a fully customizable GraphQL plugin which creates a new endpoint /graphql and the GraphiQL interface. The plugin adds a new layer to easily request the API using GraphQL, without breaking the existing endpoints.

GraphQL secures all queries by default and the plugin plays well with the users and permissions plugin. When we are making a query with GraphQL we are hitting the same controller’s actions as we were doing with the REST endpoints.

I utilized the introspection system of GraphQL to fetch all categories available to our user while making a new story.

I also used a mutation to create a new user story which takes in all data entered by the user as parameter. I pass all my GraphQL queries through a set of custom policies before they hit my custom authentication controllers in the customized Strapi back end. This completed the feature to create a new user story.

On the server side I created a new model for the comments on the stories which contains 3 fields. The first is a rich text field to write the comment and the remaining two are relation fields with user and feature requests models. This means I also had to add a relation field to the feature request model to connect it with my comments model.

The next big feature of the week was to add functionality to display all stories on the home page according to their current status. The shadow CRUD feature of Strapi GraphQL plugin automatically generates the type definition, queries, mutations and resolvers based on our models. The feature also lets us make complex query with many arguments such as limit, sort, start and where. This helped me to implement a GraphQL query to fetch the required details of all user stories and sort them according to the highest number of votes and most recently created stories. I used the query response to display the title, description and the no. of votes and comments for all stories on the home page.

All these features for the week helped me to catch up with GraphQL really fast. It was completely new to me and I was feeling stuck just a week before. Now by the end of the week I am happy that I am able to understand how it works so efficiently deep down the layers.

What is coming up next?

I will work on displaying all information about each user story on a separate page. This requires a query to fetch all story details by the story id. The date of publishing and author details will be available on this page as well.

The system needs an edit feature which may allow our beloved users to add information to their story. They will not be allowed to edit the existing description though.

Did I get stuck anywhere?

Sometimes rare bugs can be difficult to catch and you may feel stuck while trying to solve them. This week I came across something strange.

All my code and functionality was running successfully on my development environment. After getting merged, the Gitlab CI deployed it to our staging servers and the whole application crashed, both the client and server side.

I finally solved all bugs and got to learn that Strapi stores all the roles and permissions that we assign to our users in the database. In this case our development and staging servers are using different database. Simple :)

We just exported all our models data from the testing database to the one used by our staging server.

Another bug was to specify the exact cors origin which can access our server as I used withCredentials : true in my Axios configuration to store the cookies in the browser and send them back in future requests.

This ended the week with the first evaluations in which I received an awesome feedback from my mentors and passed with flying colors. I thanked them for all their support and guidance. Looking forward to a great journey ahead :)

View Blog Post