Beginner 6 parts • ~2 hours

Building Your First SaaS Application

A comprehensive, hands-on tutorial that takes you from zero to a fully functional SaaS application with authentication, multi-tenancy, and subscription billing.

0% complete (0/6 steps)

Prerequisites

What You'll Learn

1

Set Up Your Development Environment

~15 minutes

Let's start by setting up your development environment and cloning the Agentifiq.Web.MVC project. This will give you a solid foundation to build upon.

Install Required Tools

Make sure you have the following installed:

# Check .NET version
dotnet --version
# Should output: 8.0.x

# Check if Git is installed
git --version

# Clone the starter project
git clone https://github.com/yourusername/Agentifiq.Web.MVC.git
cd Agentifiq.Web.MVC

Configure Your Database

Open appsettings.json and update the connection string to point to your database:

{
  "ConnectionStrings": {
    "PostgreSQL": "Host=localhost;Database=myapp;Username=postgres;Password=yourpassword"
  }
}

Run Migrations

# Apply database migrations
cd Business.DB.PostgreSQL
dotnet ef database update --startup-project ../Agentifiq.Web.MVC

Quick Check

Which command is used to apply database migrations?

2

Configure Authentication

~20 minutes

Authentication is a critical part of any SaaS application. Agentifiq.Web.MVC comes with a complete authentication system including email/password login, OAuth providers, and two-factor authentication.

Understanding the Authentication Flow

The authentication system uses ASP.NET Core Identity with custom extensions for multi-tenancy support. Here's how it works:

  1. User registers with email and password
  2. Email confirmation is sent
  3. Upon login, tenant context is established
  4. 2FA is prompted if enabled

Configure Email Settings

For email confirmation and password reset to work, configure your SMTP settings:

{
  "GmailSmtp": {
    "SmtpServer": "smtp.gmail.com",
    "SmtpPort": 587,
    "SmtpUsername": "your-email@gmail.com",
    "SmtpPassword": "your-app-password",
    "SenderEmail": "noreply@yourdomain.com",
    "SenderName": "Your App Name"
  }
}
Tip: For Gmail, you'll need to create an App Password if you have 2FA enabled.

Add Google OAuth (Optional)

To enable "Sign in with Google", add your OAuth credentials:

{
  "Authentication": {
    "Google": {
      "ClientId": "your-google-client-id",
      "ClientSecret": "your-google-client-secret"
    }
  }
}
3

Implement Multi-Tenancy

~25 minutes

Multi-tenancy allows your application to serve multiple organizations (tenants) from a single deployment. Each tenant's data is isolated and invisible to other tenants.

Understanding Tenant Context

Agentifiq.Web.MVC uses a shared database with tenant discriminator approach. Every entity that needs tenant isolation inherits from TenantEntity:

public class Product : TenantEntity
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    // TenantId is inherited from TenantEntity
}

How Tenant Resolution Works

The tenant context is established through middleware:

// TenantContextMiddleware resolves tenant from:
// 1. User claims (after login)
// 2. Subdomain (optional)
// 3. Custom header (for API access)

app.UseMiddleware<TenantResolutionMiddleware>();
app.UseMiddleware<TenantContextMiddleware>();

Creating Tenant-Scoped Entities

When creating new entities that need tenant isolation:

// In your service
public async Task<Product> CreateProductAsync(CreateProductDto dto)
{
    var product = new Product
    {
        Name = dto.Name,
        Price = dto.Price,
        TenantId = _tenantContext.TenantId // Automatically set
    };

    await _repository.AddAsync(product);
    return product;
}
Important: Always use global query filters to prevent accidental cross-tenant data access.
4

Set Up Subscription Billing

~30 minutes

Monetize your SaaS with subscription billing powered by Stripe. Agentifiq.Web.MVC includes a complete payment system with trials, upgrades, and webhook handling.

Configure Stripe

Add your Stripe API keys to the configuration:

{
  "Stripe": {
    "SecretKey": "sk_test_xxxxx",
    "PublishableKey": "pk_test_xxxxx",
    "WebhookSecret": "whsec_xxxxx"
  }
}

Create Products in Stripe Dashboard

Create your subscription products in Stripe's dashboard, then sync them to your database using the admin panel.

Handle Subscription Events

The webhook handler processes Stripe events automatically:

// WebhookEventHandler.cs handles:
// - customer.subscription.created
// - customer.subscription.updated
// - customer.subscription.deleted
// - invoice.payment_succeeded
// - invoice.payment_failed
5

Build a Modern UI with HTMX

~20 minutes

Create interactive, SPA-like user interfaces without complex JavaScript frameworks using HTMX.

HTMX SPA Navigation

All navigation uses HTMX for seamless page transitions:

<a href="/Dashboard/Billing"
   hx-get="/Dashboard/Billing"
   hx-target="#main-content"
   hx-push-url="true"
   hx-indicator="#loading">
    Billing
</a>

Modal Forms

Load modals dynamically with HTMX:

<button hx-get="/Admin/Users/Create"
        hx-target="#modal-container"
        class="btn-primary">
    Create User
</button>

Try It: HTMX Basics

Edit the code below and click "Run" to see how HTMX triggers work:

6

Deploy to Production

~20 minutes

Your SaaS application is ready! Let's deploy it to production.

Deployment Checklist

  • Update appsettings.Production.json with production values
  • Configure production database connection
  • Set up SSL certificate
  • Configure Stripe webhook endpoint
  • Set up email service
  • Configure logging and monitoring

Deploy to Azure (Example)

# Build for production
dotnet publish -c Release -o ./publish

# Deploy to Azure App Service
az webapp deploy --resource-group mygroup \
                 --name myapp \
                 --src-path ./publish
Congratulations! You've built and deployed your first SaaS application with Agentifiq.Web.MVC!

What's Next?

Continue learning with these related tutorials: