Architecture Overview

Architecture! The Four Letter word, the bane of any developers existence, the great leveler, the mistake magnifier, and so on and so forth. The following will represent my personal views on software architecture and structure, this is just one of the myriad of opinions and implementations that are used.

The system is separated into multiple components each with their own responsibilities and implementations. The application has the following capabilities, Authentication, Authorization, Content Management Website, End User Website, Data Store.

Authentication(AuthN)

There are two distinct authentication sources, a Google Workspace login for the content management, and various social logins for end users. Both can be accomplished with https://www.keycloak.org/.

Authorization(AuthZ)

I have been intrigued by the idea of https://zanzibar.academy/. In my experience, most applications start with some sort of a flag based system. It's a simple implementation of checking if a particular role has been assigned to you. As the application evolves, more needs are discovered and the linear structure of AuthZ becomes a tree like structure with each role assigned permissions. But this too becomes too limiting and the structure becomes some sort of a monster web with custom logic strewn all over the place. To some degree, this is inevitable. But with understanding the inevitable end, we can somewhat protect ourselves with treating authorization as its own component and rely on abstractions instead of concrete implementations.

Content Management Website (CMS)

With the myriad of tools available today for content management and no-code or low-code api generation tools, there is little to no point in creating custom forms to fill out some database tables. One such tool is https://directus.io/ and it works wonderfully as a rapid prototyping tool for managing data in a relational database. Others include https://www.nocodb.com/, https://baserow.io/, and https://supabase.com/. These tools also include a generated api from the content being managed. The generated api can be consumed independently from end user generated content. The data in Scry that will be managed by our CMS is publicly accessible but privately managed. The content will include, question text, answer text, answer categorization and weight distribution. Other website related content such as titles and seo related metadata has an excellent home in the CMS. To provide the API we will serve the content from a separate directus instance operating in headless mode. This allows for flexibility in how we host the management system for example as an internal application accessible only by VPN.

End User Website

TLDR: The end user website will be created with https://nextjs.org/, because its easy and fully featured. There are several frameworks that I evaluated before settling on NextJS. https://nuxt.com/ is a simple https://vuejs.org/ framework that handles a lot of needs out of the box. My personal preference of how Vue handles html directives, prevented me from enjoying coding in Vue so after testing out some pages and data fetching, it was ruled out. Next I evaluated the latest version of https://angular.io/, having extensively worked with it in the past, I wanted to revisit it. Unfortunately for the large part all the little things that bothered me in the past remained. A difficult to understand and use routing schema, the verbose and repeated boilerplate, the confusing server access was too much to bear and I quickly gave up.

Data Store

For the database, I picked PostgreSQL. It was a simple choice due to the wide adoption and implementation of the database on various clouds. A relational database is the choice that I start with when requirements are unclear or the dataset is relatively small. Decomposing the application into several tools, allows for picking the right data store for the job. Perhaps in the future a more object or graph database will make more sense for the parts of the application that will store users surveys.

Hosting

Hosting each piece is made simpler with Kubernetes as the platform for managing resources. From local setup and testing how everything comes together, to hosting in development environments that reflect the production environment. Using cilium for networking and service mesh will allow for flexibility on the ingress to the application and secure communication with mTLS between services.

As the application requirements get more complex and I can certainly foresee a need to store Personal Identifiable Information(PII), the architecture has been put in place to create a highly secure setup. By segregating the different services we can lock down and treat some datastores as vaults. Having a service mesh running on the cluster, we can ensure secure communication and have fine grained control over connectivity between components. This is certainly not the simplest possible way to build an web application. There are plenty of easier and quicker approaches. In the long term, the complexity incurred is worth the price of admission.