website: scsp.sayn.work
github: https://github.com/sayan01/scsp
This semester in my college I had to build a web project as a part of one of my courses, and I decided to make a social network platform that works for its users, unlike the most of them. The idea was simple, provide a platform to your users, nothing more, nothing less. The software does not assume what you want to see, or what you dont. It doesnt give you 'recommendations' or automatically hide posts from people you follow because it thinks it is irrelevant. If you follow someone, you see their posts. Its that simple.
But how are we sorting the posts? By time? By likes? For this I resorted to one of the most unbiased platforms - reddit. I used its hotranking algorithm to mathematically determine which post is deserving by using its age, as well as the number of likes and dislikes it gained from other users to dynamically assign it a score to sort the posts. The comments are also sorted using an algorithm, but not one which uses time. It only takes into account the number of likes and dislikes a comment has.
The platform was built mostly in one week, and refactored in another week, so it doesn't look very special. Basic UI with minimal but good looks were the target, along with a fully responsive design. Both of which are accomplished by the project.
The project taught me multitudes of things, not just how to develop in ASP.NET CORE 6 (yeah it took me a while to understand that ASP and ASP.NET and ASP.NET CORE are three different things), but also how to host the application on digital ocean. How to operate reverse proxy (nginx), and also how to create an entire project in one week. It would be a lie if I said no sleep schedules were hurt during the making of this. This project also taught me how to make 2-3 all-nighters. Other things like how the MVC architecture works were also among the things learnt.
The thing I remember the most from those nights is trying to figure out how to implement a self-referencing many-to-many relationship in the database migrations (for the user-follows-user relationship). Painstaking as it was, this project gave me the experience of developing a full-flegded full-stack application in somewhat un-obsolete technologies. Although my design choices might not have been very ideal, it does the job and is somewhat structured into M-VM-V-C structure (models, viewmodels, views, controllers).
MVC
Models are the object-oriented abstractions of your database tables. Usually done using an ORM (object relational mapper) to map the O-O classes into database tables and queries. To do this, model classes are created and then the db-migrate is called to create migrations that take care of the database creation, table creation, etc. We need a source of truth though as there are two places where we can declare our database implementation, the model class, or the database itself. I took the code-first approach, that is, my model classes created the database and not the other way around.
ViewModels are also classes but they have nothing to do with the database. Good, cause we want to create our models once at the start and never have to hopefully touch them again if we have good design choices. The viewmodels however we will keep on making as we add new views. VM are just simple classes (POCO) and are used to store data we need to pass from controller to view. for this reason, each view should have its unique VM. It is a class that has multiple datafields, which can be primitives, or objects of our model class.
View are the html (or templating language like razor in asp) files that decide what is shown to the user. Views are the pages which the user can naviagate to. They are created according to the website structure and each action of each controller usually has a view to it. Views implement all the data passed by controller through the viewmodels. They can have some level of programming through the templating engine, but all computation should ideally be pre-done by controller before passing the data to the view.
Controller are the pure business logic codes. They also handle the routing mostly. Each controller has multiple actions. Like User/Create, User/Delete, User/Follow, User/Details, etc. Controllers are defined in their own files, and each controller defines methods for each of its actions, which resemble the routing requests. GET and POST requests are handled by controller, but also other API calls like PUT, DELETE,etc. the API stack to be used is up to the developer, be it REST or SOAP, or not API at all, by using total SSR (like this project). When a route is requested the methods of the controller perform the business logic and parse the data, after which the data is passed to the view using the viewmodel, where it is rendered. The view is displayed as HTML-CSS to the user.
Authentication
If I were to make a social network, you better believe I implemented actual authentication logic and not what our college teaches us. Naive approach would be to store username and password as plain text strings into the database and then check them during login. This is insecure for multitudes of reason. I shall not take time explaining why, as this is done very well by others online. Simply hashing the password is also not totally safe as same passwords will generate same hash, which reveals when two people have the same password. The password can then be guessed by finding what is common among those people. The approach I took is to salt the password with the username before hashing it. Thus the password hashes were unique for every username-password combinations, which is always guarenteed to be unique as username itself is guarenteed to be unique.
Hosting
A simple ubuntu server was created and on it dotnet runtime was installed, along with nginx for reverse proxy. The dotnet server was set to be auto run from the pre-built and self-contained .dll. nginx was configured to proxy traffic of port 80 (http) to the kestrel server running at port 5000. (I didn't care about trying to get SSL and TLS working, so http will have to do for now). Finally all of them were started using the default init system (systemd) and a restart job was created in case kestrel ever went down due to some server error. As it was a hurry-project, things like logging were not taken care of extensively, although in case of errors one can always ssh into the machine and read the journalctl for context. This phase of the project was not as nerve-wrecking as it can be as I am already familiar with linux systems as my daily driver is an arch linux I've configured and been using for years now. So things like systemd, cronjobs, and ssh came naturally to me. The network forwarding was the hardest of all, with things like DNS, A records, CNAME, it took me a long time to try to forward the subdomain to the IP with masking, to give up anyway at the end. Currently the forwarding does not mask the IP.
Thoughts?
Although most people say things like projects of college courses are a waste of time, I would argue otherwise. Although the teachers are not well-versed with modern technologies, we can self-learn and utilise industry tools and make a project that actually works and is useful and host it on the cloud, and not create a hacky fake application that just simulates workflow instead of augmenting it. College is a great learning space as our opportunities are endless but repurcussions low, giving us an open field to run on, but also grass to balance our falls. Projects like these should be utilised to their fullest for our own growth and learning how SDLC works.
I will end the blog with some technical details of the project, copied directly from the README of the github repository.
--------------------------------------------------------------------------------------------------------------------------
SCSP - Social Content Sharing Platform
Open source, community driven, audience-centric platform to share posts and communicate with peers on the internet without the fear of the 'algorithm'.
SCSP is a platform that lets user share their posts and follow other users. Users can like,dislike,comment on users' posts. Users recieve notification on comments on their posts. User can upload images to be posted inside the post. They can also upload image as their display picture, without which a default display picture is assigned which is made from their name provided by taking the initials.
Users can also message other users and the messages are stored in the data base as plain text (no encryption). The user credentials are not stored in plain text, they are salted and hashed before storing in the database.
User auth is performed using cookies on the server side. Multiple users can use the platform simultaneously.
The platform is mobile friendly and primarily built using bootstrap, along with some custom styles.
The posts on main page are ranked using hot-ranking algorithm so newer posts are shown at top. Posts with more like:dislike are shown above others.
hot-rank algorithm of posts
The comments on each posts are sorted only on merit and not age. The comments are ranked using the Wilson Score Confidence Sort Algorithm to predict the merit of a comment from the number of likes and dislikes available at the time. The algorithm gets better with more data.
confidence sort for comments
The formula used is talked in detail, along with a python implementation in this medium article by Amir Salihefendic: How Reddit ranking algorithms work
The intention of making this platform was to have a platform that respects the user's choices of what they want to see by implementing a community logic of post ranking, instead of an advertiser centric one. Although media like reddit and 4chan already do this, they primarily focus on communities as a whole, and people follow subreddits, instead of individual users. Furthermore those platforms advocate anonymity (which I agree with, in that use-case) which does not enhance the socialising outcome desired by SCSP. SCSP encourages people to use real names and a display picture to be explore-able and connect to people using the platform (like twitter). In doing so, an user does not need to worry about the platform moderating their free-speech or de-ranking their post. Posts of an user are shown to anyone and everyone who chooses to follow them, and are ranked fairly using their score and age as variables.
SCSP does not use any advertisement for its running. If it becomes unviable to keep it running, the hosting may be taken down but the project will always be present on VCS. Anyone can clone/download this repository and host their own version (it will have its own point-of-truth). This is useful for organizations or communities that wish to connect only within their group and not expose it to the internet. The server's IP can be distributed to the employees and they can use the platform as a totally disconnected network of its own. All functions still work.
Ser๐๐ฏ
ReplyDeleteThanks ❤️
Delete