Overview

Introduction to the SCRIPE Enterprise Platform architecture, capabilities, and technology stack.

SCRIPE is a production-ready enterprise platform built with a Modular Monolith architecture. It provides everything you need to build scalable business applications authentication, authorization, multi-tenancy, audit logging, real-time events, and a comprehensive admin panel all out of the box. The platform runs as a single binary that can be deployed as a monolith or decomposed into microservices without code changes.

  • Modular Monolith

    Isolated modules with clean boundaries develop, test, and deploy independently. Same binary, flexible deployment.

  • CQRS + SCRIPE mediator

    Command/Query separation with a 4-behavior pipeline: validation, feature gating, caching, and performance monitoring.

  • Enterprise Security

    Unified Policy-Based Access Control (PBAC) engine uniting Role-Based (RBAC), Group-Based (GBAC), and Attribute-Based (ABAC) Access Control. Includes 2FA, Field-Level Restrictions, Rate Limiting, Session Management, and immutable Audit Trails.

  • Multi-Tenancy

    Row-level tenant isolation with EF Core global query filters. Per-tenant settings, branding, and data scoping.

  • Flexible Database

    Switch between SQL Server, PostgreSQL, or Oracle. Run all modules in a single shared database (Single mode) or give each module its own database (Multi mode) — controlled by a single config toggle.

  • Flexible Deployment

    Deploy as monolith, microservices, or hybrid via a single MODULE_NAME environment variable.

  • Enterprise SSO & Identity Provider

    Native OIDC/OAuth2 Identity Provider enabling true Single Sign-On across your ecosystem. Act as a primary IDP (like Keycloak) managing external client applications seamlessly.

Architecture Topology

SCRIPE operates in three deployment modes controlled entirely by a single environment variable. The same compiled binary can run as a monolith (all modules), a microservice (single module), or an API gateway (YARP proxy).

System Architecture
Client (Next.js 16)
API Gateway (YARP)
Host Layer — Program.cs
10 Middleware Pipeline
18 REST Controllers
AstraFlow mediator CQRS + 3 Behaviors
Domain Layer — 15 Entities
Infrastructure — Multi-DB + Cache

Deployment Modes

The MODULE_NAME environment variable determines which modules load at startup. When empty, all modules register (monolith mode). When set to a module name, only that module loads (microservice mode). When set to 'Gateway', YARP reverse proxy activates.

Environment VariableModeWhat LoadsUse Case
(empty / unset)MonolithAll modules registerDevelopment, small deployments
MODULE_NAME=GatewayGateway roleYARP proxy only, no business controllersEdge routing when ServiceDiscovery is configured
MODULE_NAME=IdentityComposite server roleIdentity + Entitlements services, Auth/signup controllersAuth and self-service signup host
MODULE_NAME=EntitlementsServer roleEntitlements services and controllersPlatform billing and feature control
MODULE_NAME=ComplianceServer roleCompliance services and controllersCompliance API host
Program.cs — Deployment DetectionC#
var moduleName = Environment.GetEnvironmentVariable("MODULE_NAME") ?? "";
var isMonolith = string.IsNullOrEmpty(moduleName);
var isGateway = moduleName.Equals("Gateway", StringComparison.OrdinalIgnoreCase);

// MODULE_NAME is resolved as a server role.
// Identity/Auth roles intentionally load Identity + Entitlements for signup.
// Gateway loads no business modules and only maps YARP when ServiceDiscovery exists.

Technology Stack

LayerTechnologyVersionPurpose
Backend Framework.NET10Core runtime and SDK
API StyleASP.NET Core Web API10REST controllers with Swagger
CQRSAstraFlow mediator12+Command/Query separation
ValidationFluentValidation11+Request validation pipeline
ORMEntity Framework Core10Multi-database O/R mapping
CachingIMemoryCache + Redis—L1/L2 cache layers
Real-timeSignalR10WebSocket hubs for live data
Background JobsHangfire1.8+Recurring and fire-and-forget jobs
Frontend FrameworkNext.js16 (App Router)Server/Client hybrid rendering
UI LibraryShadcn/ui + Radix—Accessible component primitives
State ManagementTanStack Query + Zustandv5 / v5Server state + client state
StylingTailwind CSS + CSS Modules4Utility-first with scoped styles
LocalizationCustom LanguageProvider—7-language RTL/LTR support

Service Registration Order

The order of service registration in Program.cs is architecturally significant. Changing the order can cause runtime failures. Core infrastructure must register before modules, and SCRIPE mediator needs module assembly markers collected first.

OrderRegistrationSizePurpose
1AddInfrastructureServices11KBSerilog, API versioning, controllers, JSON options
2AddCorsConfiguration5KBDev vs Production CORS policies
3AddRateLimitingConfiguration13KBDDoS prevention, per-IP, login rate limits
4AddSwaggerConfiguration8KBOpenAPI documentation
5AddScripeObservability8KBOpenTelemetry tracing + metrics
6AddCoreInfrastructure11KBICurrentUser, Audit, Cache, DI container
7AddBlobStorage2KBLocal / Azure / S3 / MinIO storage
8AddIdentityModuleModuleIdentity-specific services
9AddCoreApplication2KBAstraFlow mediator + Behaviors + Domain Events
10AddHealthCheckConfiguration2KBHealth endpoints
11AddBackgroundJobsConfiguration9KBHangfire + recurring jobs
12AddSignalRConfiguration2KBReal-time WebSocket hubs
13AddGatewayConfiguration4KBYARP reverse proxy (Gateway mode only)

Environment Profiles

EnvironmentConfig FileFeatures
Developmentappsettings.Development.jsonSwagger enabled, verbose logging, UserSecrets
Productionappsettings.jsonHSTS, minimal logging, no Swagger
Oracleappsettings.Oracle.example.jsonOracle provider configuration
PostgreSQLappsettings.PostgreSQL.example.jsonPostgreSQL provider configuration
Secrets Provider Chain (highest wins)Text
Priority (highest wins):
  1. UserSecrets          (Development only)
  2. Environment Variables (prefix: SCRIPE_)
  3. appsettings.Secrets.json (optional)
  4. appsettings.json         (base)