Jahangir Nabin
← All projects

Multi-Tenant Compliance SaaS at 400-Endpoint Scale

A vendor-risk and compliance platform: tenant isolation with EF Core global query filters, CQRS across 54 feature modules, multi-IdP SSO, and Stripe subscription billing.

Role:
Architect and top contributor (~45% of 3,240 commits); lead a 6-developer team
Period:
2025 – 2026, Brain Station 23
  • .NET 8
  • Next.js 15
  • React 19
  • PostgreSQL
  • EF Core
  • CQRS/MediatR
  • Stripe
  • SignalR
  • AWS ECS Fargate
413
REST endpoints
342
Command/query handlers
54
Feature modules

Context

TPSaaS helps companies manage vendor security risk: supplier onboarding, security assessments, evidence review, risk registers, audits, remediation, and certification. Every customer is a tenant with its own users, data, and subscription plan, so isolation failures are existential, not cosmetic.

Architecture

Frontend
Next.js 15 / React 19
Role-aware dashboards
SignalR notifications
API
ASP.NET Core (.NET 8)
413 REST endpoints
CQRS, 342 handlers
54 feature modules
Cross-cutting
Multi-IdP OIDC SSO
Multi-layer RBAC
Tenant middleware
Audit logging
Data & Infra
PostgreSQL + EF Core
ElastiCache Redis
Hangfire jobs
AWS ECS Fargate

Key decisions

Tenancy enforced in the data layer. Tenant scoping lives in EF Core global query filters plus middleware that resolves the tenant before any handler runs. Developers cannot forget a WHERE TenantId = …: the filter applies unless explicitly and visibly disabled, which code review treats as a red flag.

CQRS kept honest at scale. 342 handlers across 54 modules stay navigable because each module owns its commands, queries, and validation. No shared god-services. New features follow a template, which is what makes a 6-developer team productive in parallel without merge wars.

Identity is pluggable. Enterprise customers bring their own IdP: the platform speaks OIDC to Azure AD, Okta, Auth0, and others, layered under a role model that separates platform administrators from tenant roles.

Billing with webhooks, not polling. Stripe subscriptions (including enterprise plans and quotas) sync through idempotent webhook processing; BitSight security ratings integrate with encrypted tokens and full API audit logging.

Results

The platform runs on AWS ECS Fargate with RDS PostgreSQL, S3, Secrets Manager, and ElastiCache across development, UAT, and production environments; 13 Hangfire recurring jobs handle assessment reminders, syncs, and digests. In-app SignalR notifications pair with SES email delivery including bounce tracking. I also wrote the pandas + psycopg2 ETL that seeded the question bank: tiered fuzzy matching that maps business-owner questions to conditional vendor follow-ups from questionnaire spreadsheets.

What I'd do differently

Introduce integration-test coverage per module earlier. The CQRS template made features fast to add; test scaffolding lagged behind it, and backfilling coverage is slower than growing it alongside.