SkillAgentSearch skills...

Visage

The project is an app to manage events for OSS community events promoting inclusiveness and diversity

Install / Use

/learn @HackerspaceMumbai/Visage
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center"> <h1>Visage</h1> Meetups done right </div> <hr1> <p align="center"> <!-- <a href="https://github.com/HackerspaceMumbai/Visage/actions/workflows/ci.yml"> <img src="https://github.com/HackerspaceMumbai/Visage/actions/workflows/ci.yml/badge.svg" alt="CI Build Status"> </a> --> <a href="https://github.com/HackerspaceMumbai/Visage/releases"> <img src="https://img.shields.io/github/v/release/HackerspaceMumbai/Visage" alt="Latest Release"> </a> <a href="https://github.com/HackerspaceMumbai/Visage/issues"> <img src="https://img.shields.io/github/issues/HackerspaceMumbai/Visage" alt="Open Issues"> </a> <a href="https://github.com/HackerspaceMumbai/Visage/blob/main/LICENSE"> <img src="https://img.shields.io/github/license/HackerspaceMumbai/Visage" alt="License"> </a> <a href="https://github.com/HackerspaceMumbai/Visage"> <img src="https://img.shields.io/github/stars/HackerspaceMumbai/Visage" alt="GitHub Stars"> </a> </p>

The problem

We are the largest Open Source Software[OSS] community with its longest running(> 10 years) tech meetup in Bombay. Most of our events are houseful.

  1. We have to curate the registrants based on the theme and also to ensure we are inclusive, diverse, and have a good mix of attendees.
  2. We have to ensure that the attendees are checked-in to the event and also to the individual sessions. This is important for us to understand the attendee interest and also to ensure that we are able to provide the best experience to the attendees. Most importantly, we need to record the checkout time so as to comply with building/civic code.
  3. With DPDP (India's equivalent of GDPR) coming into effect, we have to ensure that the data we collected is secure, is not misused, and resides within the jurisdiction of India.

The solution

We will build a solution on the latest .NET version, that takes full advantage of AI and Azure services to solve the problem. The solution will have the following components:

  1. Aspire
  2. Microsoft .NET AI extensions
  3. Blazor Hybrid Web App
  4. Azure Open AI

For further reading on architecture, please check our website here

Prerequisites

Before running the Visage project, ensure you have the following installed:

  • .NET 10 SDK - Download here
  • Docker Desktop - Required for containerized SQL Server and services (Download)
  • Visual Studio 2025 or VS Code with C# Dev Kit
  • Aspire workload - Install via: dotnet workload install aspire

Running the Project

  1. Start Docker Desktop - Ensure Docker is running before launching the application
  2. Run the AppHost:
    cd Visage.AppHost
    dotnet run
    
  3. Access the Aspire Dashboard - Opens automatically at https://localhost:17044/
  4. Verify Health Status:
    • ✅ SQL Server resource shows "Healthy" (green)
    • ✅ Both registrationdb and eventingdb databases are listed
    • ✅ Registration and Eventing services show "Healthy"
    • ✅ Frontend web application is accessible

Note: The first run may take longer as Docker downloads SQL Server images. Subsequent runs are faster.

Database Management

Aspire automatically manages SQL Server - no manual installation required! Connection strings are injected automatically via Aspire's service discovery.

  • View database schema: Connect via connection string shown in Aspire dashboard
  • Run migrations: Automatic on service startup (or manually via dotnet ef database update)
  • Reset database: Stop AppHost → Delete Docker container → Restart AppHost

For detailed setup and troubleshooting, see Aspire SQL Server Quickstart.

Testing Guidelines

Since this is an Aspire based solution we are predominantly doing Integration testing using TUnit, Fluent Assertions, & Playwright. We will strive to have 100% test coverage. External connections are mocked via NSubstitute, and load testing by NBomber. We will also include security testing using OWASP ZAP and Stryker for chaos.

Below are the guidelines for writing and running tests:

Running Unit Tests

Unit testing is restricted for crucial Blazor Hybrid components using bunit. Unit testing is restricted for crucial Blazor Hybrid components using bunit.

Running Integration Tests

To run the integration tests, execute the following command:

dotnet test tests/Visage.Tests.Integration/Visage.Tests.Integration.csproj

Note: To keep dotnet test fast for local development, this repository defaults to running Smoke tests (home page validation) when running dotnet test without any filters. Use scripts/test-all.ps1 to run the broader test suite locally:

# Run default and non-auth tests
pwsh -File ./scripts/test-all.ps1

To run full validation (including RequiresAuth tests), either use pwsh -File ./scripts/test-all.ps1 -RunAuth (with Auth secrets set) or run a direct CLI filter:

dotnet test --filter "Category!=RequiresAuth&Category!=AspireHealth"
dotnet test --filter "Category=RequiresAuth" # requires secrets

Configurable Tests

Our tests are configurable to run on different endpoints for local workstations and CI/CD environments. Ensure you have the appropriate configuration set in your environment variables.

Writing New Tests

When writing new tests, follow these guidelines:

  • Use TUnit and FluentAssertions for unit and integration tests.
  • Use Playwright for end-to-end tests.
  • Ensure tests are clear, maintainable, and cover critical functionalities.
  • Document any new tests added to the suite.

For more detailed instructions and examples, refer to the test project files in the tests directory.

By following these guidelines, we can ensure that our codebase remains reliable, maintainable, and of high quality.

Project Architecture and Components

The Visage project is built using a modular architecture to ensure scalability, maintainability, and ease of development. Below is an overview of the project's architecture and its main components:

The following diagram illustrates how the components of Visage interact with each other and how data flows through the system

Detailed Diagram:


flowchart TD

        %% Define the user and their interactions
    User(["User"])
    %% Top layer: User Interfaces
    subgraph "User Interfaces" 
        direction TB
        WebClient["Blazor Hybrid Web Client"]:::client
        WebServer["Blazor Web (server-hosted)"]:::client
        MAUI[".NET MAUI Mobile/Desktop App"]:::client
        SharedUI["Shared UI Library"]:::client
    end

    %% Middle layer: AppHost
    AppHost["Visage.AppHost"]:::aspire

    %% Lower layer: Microservices
    subgraph "Microservices"
        direction TB
        Eventing["Visage.Services.Eventing"]:::aspire
        Registrations["Visage.Services.Registrations"]:::aspire
        Cloudinary["Cloudinary Image Signing (Node.js)"]:::aspire
    end

    %% Bottom layer: Data Stores
    subgraph "Data Stores"
        direction TB
        EventDB[(EventDB)]:::data
        RegistrantDB[(RegistrantDB)]:::data
    end

    %% Bottom layer: External Services
    subgraph "External Services"
        direction TB
        AzureAI["Azure AI Foundry"]:::azure
        AzureContainer["Azure Container Apps"]:::azure
        Insights["Azure Monitor & App Insights"]:::azure
        CloudinaryStorage["Cloudinary"]:::azure
    end

    %% Connections
    User -->|Interacts with| WebClient
    User -->|Interacts with| WebServer
    User -->|Interacts with| MAUI

    WebClient -->|"HTTPS/REST"| AppHost
    WebServer -->|"HTTPS/REST"| AppHost
    MAUI -->|"HTTPS/REST"| AppHost
    WebClient -->|"HTTPS/REST"| Cloudinary
    WebServer -->|"HTTPS/REST"| Cloudinary
    MAUI -->|"HTTPS/REST"| Cloudinary

    AppHost -->|"HTTP/REST"| Eventing
    AppHost -->|"HTTP/REST"| Registrations
    AppHost -->|"Node Hosting Extension"| Cloudinary

    Eventing -->|"EF Core"| EventDB
    Registrations -->|"EF Core"| RegistrantDB

    AppHost -->|"Azure SDK"| AzureAI
    Eventing -->|"Azure SDK"| AzureAI
    Registrations -->|"Azure SDK"| AzureAI

    AppHost ---|"Containerized"| AzureContainer
    Eventing ---|"Containerized"| AzureContainer
    Registrations ---|"Containerized"| AzureContainer
    Cloudinary ---|"Containerized"| AzureContainer

    AppHost -->|"Monitoring"| Insights
    Eventing -->|"Monitoring"| Insights
    Registrations -->|"Monitoring"| Insights
    Cloudinary -->|"Monitoring"| Insights

    Cloudinary -->|"Media Storage"| CloudinaryStorage

    %% Dependencies
    WebClient --> SharedUI
    WebServer --> SharedUI
    MAUI --> SharedUI

    %% Legend
    subgraph Legend
        direction TB
        F["Rectangles: Frontend"]:::client
        S["Rounded: Services"]:::aspire
        D["Cylinders: Databases"]:::data
        C["Cloud: External Services"]:::azure
    end

    %% Click Events
    click WebClient "https://github.com/hackerspacemumbai/visage/blob/main/Visage.FrontEnd/Visage.FrontEnd.Web.Client"
    click WebServer "https://github.com/hackerspacemumbai/visage/blob/main/Visage.FrontEnd/Visage.FrontEnd.Web"
    click MAUI "https://github.com/hackerspacemumbai/visage/blob/main/Visage.FrontEnd/Visage.FrontEnd"
    click SharedUI "https://github.com/hackerspacemumbai/visage/blob/main/Visage.FrontEnd/Visage.FrontEnd.Shared"
    click AppHost "https://github.com/hackerspacemumbai/visage/blob/main/Visage.AppHost"
    click Eventing "https://github.com/hackerspacemumbai/visage/blob/main/services/Visage.Services.Eventing"
    click Registrations "https://github.com/hackerspacemumbai/visage/blob/main/services

Related Skills

View on GitHub
GitHub Stars15
CategoryDevelopment
Updated2mo ago
Forks5

Languages

C#

Security Score

90/100

Audited on Feb 5, 2026

No findings