Skip to content

Backend for Messenger Application Jellyfish Messenger Application

Notifications You must be signed in to change notification settings

0x00405A00/jellyfish-backend-ddd

Repository files navigation

Jellyfish Mobile Application

Intro

The project focuses on recreating the Jellyfish Backend, a critical component of the Messaging Application Jellyfish designed for Android and iOS platforms. The backend is meticulously developed following the principles of domain-driven design and clean architecture. Communication within the system is orchestrated using the Meditr library, emphasizing command-query separation (CQS) for improved code clarity and separation of concerns.

While the current deployment operates as a monolith, the architecture is inherently flexible. It can swiftly adapt to a microservices paradigm with the incorporation of tools such as API gateways (e.g., Ocelot, YARP), command-query responsibility segregation (CQRS), and background database synchronization processes. The latter employs optimistic locking with row versioning to ensure consistency between read and write databases.

In anticipation of future enhancements, the architecture envisions the implementation of asynchronous communication through AMQP over RabbitMQ. This will empower the system to efficiently handle events through queues, laying the groundwork for robust publish/subscribe behaviors.

Technology Stack

Backend Web-Frontend Mobile Application
C#/NET 7 C#/NET 7 C#/NET 7
ASP NET Blazor Server .NET MAUI
MySql 8.0.35 Razor Components
SignalR Mudblazor UI Components (https://mudblazor.com/)
Docker
EF Core

Testing

  • Unit Testing Approach:

    • Unit testing is a fundamental practice applied in this project to verify the correctness and functionality of methods and process flows. While it is acknowledged that not every method is individually tested, a balanced approach is adopted. The principle is to avoid over-engineering and over-testing, finding a middle ground that ensures critical processes and methods are thoroughly tested.
    • The unit testing behavior adheres to the standard arrange, act, assertion methodology, which is a common and effective approach in software testing. This methodology provides a structured framework for setting up the test conditions, executing the specific action, and validating the expected outcomes.
  • End-to-End Testing with Postman:

    • End-to-end testing is conducted using Postman, leveraging the imported generated Swagger API documentation. Postman serves as a powerful tool for comprehensive API testing, allowing for the verification of the entire system's functionality. The integration of Swagger API documentation enhances the efficiency of the testing process by providing a clear and interactive interface for exploring and validating API endpoints.

Documentation

  • Extensive Documentation:
    • The project places a strong emphasis on comprehensive documentation to facilitate ease of use and understanding for all stakeholders. Currently, the documentation includes:
      • Entity-Relationship Diagram (EER) Documentation:
        • A detailed EER documentation has been prepared to provide insights into the data model and relationships within the system. This documentation serves as a valuable resource for developers, aiding in a clear understanding of the underlying database structure.
      • Swagger Documentation:
        • The project leverages Swagger Documentation to ensure detailed and interactive API documentation. Swagger provides an intuitive and user-friendly interface for exploring and understanding the available API endpoints, parameters, and responses. This documentation is essential for developers, enabling seamless integration and interaction with the provided APIs.

Deployment

Legacy over binary or with docker container.

Project Motivation and Objectives

  • Testing NET MAUI on Multiple Mobile Platforms:
    • The primary motivation behind initiating this project is to rigorously test NET MAUI on various mobile platforms. This involves comprehensive testing and optimization to ensure seamless performance and compatibility across the specified platforms, contributing valuable insights to the NET MAUI community.
  • Empowering Users to Host Their Own Messaging Infrastructure:
    • One of the key objectives of this project is to empower users by providing them with the opportunity to host their messaging infrastructure independently. This aims to democratize the accessibility of messaging services, allowing users to take control of their communication environment.
  • Optimal Resource Utilization:
    • A noteworthy side effect of this initiative is the focus on enabling messaging infrastructure hosting with minimal hardware resources. Specifically, the project targets efficient utilization, allowing users to run the infrastructure on accessible hardware like Raspberry Pi. This emphasis on resource efficiency aligns with the project's commitment to accessibility and sustainability.

Security and Future Features

  • End-to-End Encryption and Privacy Protection:
    • Ensuring the security of user data is paramount. The upcoming steps before the release of the first production version will include the meticulous implementation of end-to-end encryption. This will provide a robust layer of protection for sensitive user information. Additionally, the adoption of the forgettable payload pattern will further enhance privacy by minimizing data retention, aligning with privacy best practices.
  • AI Support Bots:
    • Embracing the future of user interaction, there are plans to integrate artificial intelligence (AI) support bots into the system. Consideration is given to leveraging advanced AI technologies such as Google Llama or ChatGPT. These AI-driven bots will enhance user engagement, streamline support processes, and contribute to an intelligent and responsive user experience.
  • Blockchain Infrastructure:
    • Exploring cutting-edge technologies, there is a forward-looking vision to investigate the feasibility of hosting the system's infrastructure on the blockchain. The benefits of blockchain technology, including enhanced security, decentralization, and transparency, will be assessed. This forward-thinking approach aims to future-proof the system and align it with emerging trends in secure and decentralized architectures.

To Do

Backend:

  • Docker.compose for JellyfishBackend, PostgreSql
  • RateLimiter for specific actions
  • IModelBinder+IModelBinderProvider for HttpQuery and HttpBody to resolve and validate data that is inside of 'ApiDataTransferObject'
  • CRUD + Search Filter (Transition from http request (json) to dto filter model to linq expression to sql)
  • Linq Expressions to sql: override/create operators in value objects and Domain models and translate them to linq expressions
  • Cache Functionality (currently IMemoryCache)
  • Password Reset Endpoint: Enable password reset via the "Edit User" feature; domain logic change: UpdateUser, updateuser command+handler update.
  • Password encrytion in database with best practise encryption method
  • Auth/Authorization: Match Jwt Data (Claims etc.) with the database
    • Trigger events if token claims do not match roles from the database or if IP location (Geo IP for IPv4+v6 or User-Agent different from token creation) is vastly different. Notify users via email.
  • File Upload / User Profile Pictures / Attachments from Jellyfish Messages or Media / Storing Strategy: Avoid storing in the database for performance reasons. Implement caching strategy, build up cache during backend start. Conduct virus checks using content and an external AI service (Azure= link, AWS) to detect uploads of violent media/pornography.
    • Chain Of Responsibility for virus and inadmissible/violent content (abstraction implemented)
  • Domain: Implement Chat Business Logic checks.
  • GDPR: Module for GDPR to make all GDPR actions available (reporting, deletion etc.)
  • Implementation of Presentation/Infrastructure/Application of Domain Entity Chat/Message/Userfriendship requests: Utilize SignalR to notify target users, etc. -> Event Handler
  • Forgettable Payload -> GDPR (German: DSGVO).
  • End-to-End encryption for Jellyfish users. Sequence: Users that will interact to each other will share the Public Keys. When a message will be created by User-A, the message will be encrypted with the public key of User-B. The message will send to backend and will be stored (encrypted) in the database. User-B received the message over signalr or polls all unacknowleged messages from backend (polling by reconnect, when the connection is gone e.g. lost connection to radio cell). User-B acknowledge the message to backend (received rake will be shown in User-A's App). User-B decrypt the message with the private key.
    • Delete messages that are successfully delivered to target
  • SSL Encryption for Backend.
  • Swagger Documentation
  • Rewrite some default ASP.NET Core response messages with a filter: e.g., HTTP error 422 or unauthorized response -> rewrite to JSONAPI error response ----------> Presentation.Extension.JsonApiResultExtension.
  • FluentValidation: Prepare Validators with response handling for JSONAPI error response due to validation errors. CommandHandlerValidators already implemented: ValidationPipelineBehavior; only the validation rule needs definition in constructors of each CommandValidation.
  • Chat Bounding Context implementations:
    • POST: /api/v1/chat, Create chat (only with friends, Domain-Logic requirements defined the rule that a chat needs at least one message to exists)
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain (removed completion state because of New Business rule)
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/chat/{chatId}, Gets the chat
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/chat/{chatId}, Update chat informations such as description, name
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/chat/{chatId}, Delete chat
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/chat/{chatId}/picture/{messageId}, Sets the chat picture
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/chat/{chatId}/member/{userId}, Add user to chat (new member)
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/chat/{chatId}/member/{userId}, Remove member from chat
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/chat/{chatId}/admin/{userId}, Assign admin action
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/chat/{chatId}/admin/{userId}, Revoke admin action
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/chat/{chatId}/message, Message create action
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/chat/{chatId}/message/{messageId}, Message update action
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/chat/{chatId}/message/{messageId}, Message delete action
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
  • User Bounding Context implementations:
    • POST: /api/v1/user/register, Register user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/password/reset/request, Creates a password reset requests
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/password/change/{id?}, Change password endpoint for admin UI
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/password/reset/{base64Token}, Resets password with user received password reset url (link from mail)
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/activation/{base64Token}, Activate user with them received activation url (link from mail)
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/user/user-types, Get all available user types
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/user/messenger/{guid}, Get messenger profile from user (less information than default user profile)
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/friend/request, Create friendship request
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/user/friend/request, Remove friendship request
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/user/friend/request, Get friendship requests
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/friend/request/accept, Accept friendship request
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/user/friend, Get Friends
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/user/friend, Remove friend
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/user/{id}/profile-picture, Add profile picture
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/user/{id}/profile-picture, Remove profile picture
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PATCH: /api/v1/user/{id}/role, Assign role to user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/user/{id}/role, Revoke role from user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • POST: /api/v1/user/, Create a user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • GET: /api/v1/user/{id}, Get a user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • PUT: /api/v1/user/{id}, Update a user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)
    • DELETE: /api/v1/user/{id}, Delete a user
      • Presentation
        • Implementation
        • Test (Grey Box Test)
      • Infrastructure
        • Implementation
        • Test (Grey Box Test)
      • Application
        • Command/Query
        • Validation (Fluentvalidation)
        • Handler
        • EventHandling
      • Domain
        • Implementation
        • Test (Unit-Test)

Web-Frontend:

  • Check all http request to backend and catch all state above all errors, so http codes 4xx and 5xx
  • Icons: MudBlazor Icons.
  • NavBar:
    • Features
    • Privacy
    • Help Section:
      • NavBar as Sidebar with Help points
      • Body with Search for Help points
      • Popular Articles
        • Android and iOS Help tabs under Help points
    • Blog:
      • Latest information about Jellyfish
    • Download:
      • Link to App stores
  • Footer:
    • Jellyfish Icon
    • Copyright
    • Terms of Use and Privacy Policy
    • Social Media Icons with Channels

Features (from Web-Frontend):

  • Snackbar for notifications (any action like edit user, get notification of service x/y, etc.) => https://mudblazor.com/components/snackbar#5ac08464-80c3-4c34-8cac-24f0947275e7
  • SignIn Page with Password recovery function
  • Impressum
  • GDPR:
    • Cookie Disclaimer
  • Dashboard.razor:
    • Charts:
      • Outgoing mails
      • Registered users compared to the previous month
      • Chart background slightly gray
  • _Host.cshtml: Default Messages changing
  • App.razor:
    • PageNotFound Page
  • Signup.razor (Login + Register):
    • Component arrangement
    • Success page after registration
  • Users.razor:
    • CRUD+Search (Search maybe with elastic search)
    • Password Reset Action separately
    • View User Profile Picture (MudBlazor Image)
    • Upload User Profile Picture (MudBlazor FileUpload)
    • User Edit/Delete Audit Log (all events in a separate table)
    • View users' friends/friendship requests in-outcoming
  • Health.razor:
    • Prettify the healthcheck view (currently default healthcheck view as presentation)
  • Blog:
    • CRUD Posts
    • Embedded Media
    • Blog: Load Posts vertically with MudBlazor vertical Progressbar (animated)
    • Blog: Posts look at with Timeline with left and right order
  • Authentication: Timer in the Background that will be visible in UI when the token is only 5 minutes valid anymore, then the activation tracking will start. When the user triggers actions in UI, the token will be refreshed in the backend automatically.
  • Session store: Store the last visited URL
  • Own profil
    • View
    • Edit/Manage

Mobile App:

  • Remove old DTO and Model structure andold namespaces
  • Rewrite to new structure
  • Message/user cache in SQLite, adapt to new structure
  • Add new WebApiClient and SignalRClient (WebAPI client from WebFrontend into shared, new SignalR client (typed client) into shared for reusability)
  • Msg-interceptor: Maintain the invoker chain for message/notification procedures (main messaging functionality)
  • Rewrite target endpoint URLs to backend to new backend structure
  • Chat: Messaging (UI+App backend)
  • Chat+Friendlist: See profile
  • Chat: Messaging (send attachments)
  • Standalone characteristics opposite to WhatsApp etc.:
  1. Mark messages as not able to screenshot: These messages a blured by Screenshot creation. Same by profile picture.
  2. Group calenders: Planing private activities together in a Groupchat calender.
  3. Caring about shareing: Mark messages as not shareable, to make no care about not permitted share :)
  4. Ability to host the messaging infrastructue by your own. No dependency to others!
  5. Against violence: Todays private chats like Telegramm are abused by people for violence and adult content. So jellyfish brings the ability to avoid the share for such content. Machine Learning algorithm evaluate the Media that will be shared over the messenger. When violent content is recognized the message sent will be avoid. ** Requires Azure AI Vision or similar ML-Algorithm **
  6. Location share with live track: unnessesary if in groups or private chats, your movements will be streamed live to the chat members when the spectator Mode is on (only availble in live track map).
  7. Oblivion: The right to forget is a cornerstone of todays GDPR. By removing the Account all data (also chat messages that are shared with friends) will be removed. Of course the media too. Im aware that a deletion of Media that is sent to chat members is not the today practice but every human has the right that his created data can be forgotten.
  8. Polls/Votes: In example to WhatsApp: Votes will be also available in jellyfish.

General:

  • DNS Preconf, Windows hosts-file equal names like Docker
  • License definition
  • Terms of use
  • Donation
  • Manual for installation and execution

Stay tuned đź‘Ť.

Admin Panel Alpha 0.1

Alt text

Dashboard

Alt text

User Management (Users.razor) w/ Pagination and Search

Alt text Alt text

User Management (Users.razor) - Add/Edit

Alt text

User Management (Users.razor) - Delete

Alt text

VIDEO: Preview Transitioning Filter from Http Request to Linq Expression and finally to MySql Query via ORM (dynamically) / THUMBNAIL PNG BELOW (HREF)

Preview Transitioning

Enhanced Entity Relation Diagram

Alt text Alt text

Codemetrical analysis after adding MobileApp to solution

Alt text

Continious Integration workflow with Github Action

Alt text

Testing from Core (Use cases & Domain)

Alt text