Building a peer-to-peer social platform for conferences
Let’s Chat With is a social platform that facilitates direct peer-to-peer networking between attendees at both remote and in-person conferences.
It offers users an opportunity to meet other attendees and learn more about them in a moderated digital venue, create professional connections based on mutual interests, and communicate in real-time with in-app chat.
The platform allows organizers to generate a social space specific to each conference. Unique invitations to join Let’s Chat With for the conference are provided only to attendees, who then create profiles, begin viewing other attendees’ professional profiles, and select which attendees they would like to network with. If two attendees select each other, they are connected and can begin chatting in a secure environment.
The This Dot Labs team focused on helping refine the vision of the product on loose requirements and creating a timeline for feature development.
Our design team created high fidelity user interface components which the development team implemented.
- Refined product concept with key stakeholders by identifying market demands and potential customer interests and needs.
- Full feature design based on user interviews and accessibility requirements.
- Built a component based design system.
- Designed the architecture and implementation of the product with a focus on extensibility and ease of maintenance.
- Implemented an inter-module event system using NgRx, making global state changes predictable and debuggable.
- Angular: The application’s front end was developed using Angular.
- NgRx: We used NgRx for state management which allowed our team to implement complex integrations among different subdomains in the project.
- Storybook: The development process was enabled by Storybook, which was used to design and test individual components in isolation from the rest of the code, promoting development speed and simplicity.
- Amplify: The stack also includes Amplify for deploying our front end applications.
- GraphQL: We used GraphQL code generation tools to simplify the integration of the serverless functions and AWS AppSync with Angular.
- Jest & Cypress: We used Jest for unit testing and Cypress for integration testing. Both are modern and proven tools that enable developers to write cleaner tests faster.
- Serverless Framework: The application’s back end utilizes the Serverless Framework, deployed to AWS. The Serverless framework provides infrastructure as code, making the resource management deterministic and clear while also providing a great developer experience. One of our favorite features is plugin system that allowed us to utilize the serverless-offline plugin for offline developement, making each developer’s computer a complete development environment, which is typically not available for serverless applications.
- Nx Monorepo: Let’s Chat With utilizes Nx Monorepo technologies, reducing task execution times including those for running tests, linting, and building. It offers excellent ergonomics for library creation, and helps enforce architectural decisions by storing all of the project’s applications in a centralized repository.
- GitHub: We utilized GitHub for our git source control.
- GitHub Actions: We utilized GitHub Actions to build our CI/CD pipelines which include static code analysis, automated test runners, and deployment to infrastructure.
This Dot Labs is a development consultancy focused on providing staff augmentation, architectural guidance, and consulting to companies.
We help implement and teach modern web best practices with technologies such as React, Angular, Vue, Web Components, GraphQL, Node, and more.
Transition from Amplify to Serverless for Backend Management
One of the project’s major roadblocks in launch was using Amplify for the project’s entire stack. It caused a number of code merging problems by generating boilerplate files that are team-member dependent but required for deployment. Every time a developer made an infrastructure change to one of its environments, this would cause several files to change with complex and hard-to-read syntax that the team had difficulty resolving.
Similarly, the environment deployment was affected by the inability of the Amplify algorithms to successfully resolve some of the infrastructure conflicts visible in the code. Additionally, each time a developer needed to work in a new branch, they were forced to destroy their deployed environment and start from scratch. Even if a developer managed to keep their environments in sync, they still had to cope with slow deployment times that could take upwards of 10 minutes.
After team deliberation, we decided to migrate all the backend and AWS infrastructure to the Serverless Framework. The team completed the transition quickly, considering the application’s complexity and tight coupling with Amplify and AppSync.
The Serverless Framework solves the merging and environment problems by handling infrastructure as code in a readable syntax, removing Amplify’s magic file generation, and passing the task of configuration to the developer. Because the code to be merged is contained to a few files written by team members, the change significantly reduced merge conflicts.
Additionally, we were also able to eliminate the developer environments, moving the development process to the developer’s local machine. The trial and error cycles that took hours using Amplify were reduced to seconds. Even the deployment to the cloud environments was enhanced and now only takes fewer than 5 minutes.
Inter Subdomain Communication
Let’s Chat With comprises several subdomains with different degrees of complexity. Each subdomain organizes the application into isolated vertical slices of functionality. This means that our subdomains work independently and are agnostic about the existence or behavior of the rest. Regardless, in some scenarios, our isolated features need to react to events that originated in other subdomains and reconcile their internal state based on the emitted information. The chosen mechanism was to create an event-based architecture powered by NgRx actions, enabling the necessary inter-subdomain communication.
The below image shows this mechanism in practice. We have three different subdomains in this example: Connection, Report, and Chat. Those subdomains are independent and behave in isolation, but they also communicate indirectly by emitting events that the other subdomains can consume. The Connections subdomain listens to the event of a completed report and deletes a connection based on the event metadata. On the other hand, the Chat subdomain will create a new connection thread after a successful connection.
Shareability and Enforcing Architectural Decisions
When designing the project structure and architecture, the team rapidly discovered two main software elements: feature-centric logic, and business agnostic functionalities.
The business agnostic elements were highly reusable components, like modals and buttons, generic Angular directives, pipes, etc.
The more feature-centric business logic focused on everything that made the application work: featured components, state management tools, and server communication services.
The challenge was to enhance the shareability of the reusable parts and enforce the boundaries of the different subdomain logic.
The tool that helped the team the most to achieve those goals was Nx. With the Nx library creation system, the team isolated the most sharable code units into separate libraries. This effort made it easier to consume the libraries, and created very explicit dependencies in our code.
Nx also helped the team implement bounded contexts, code boundaries to isolate functionality to avoid domain scope pollution. We utilized Nx tags that we applied to our libraries to enforce vertical slices of our application and allowed us to enable linting rules to restrict cross domain depdenencies. This enhanced our testing strategy by avoiding unnecessary mocks due to scope pollution and enhancing the overall developer experience.
Building the Real Time Chat Feature
The Let’s Chat With chat system uses the power of AppSync and DynamoDB to provide a push-based event system to alert all participants in a conversation that a new message exists. The communication protocol is through a fast GraphQL subscription, and the result is a responsive UI with visual cues to alert the user of unread received messages. This allowed us to optimally leverage our GraphQL API rather than relying on third-party socket providers like Firebase or Pusher which kept our data in a single interface so developers did not have to be aware of multiple data provider services.