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).
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 Variable | Mode | What Loads | Use Case |
|---|---|---|---|
| (empty / unset) | Monolith | All modules register | Development, small deployments |
| MODULE_NAME=Gateway | Gateway role | YARP proxy only, no business controllers | Edge routing when ServiceDiscovery is configured |
| MODULE_NAME=Identity | Composite server role | Identity + Entitlements services, Auth/signup controllers | Auth and self-service signup host |
| MODULE_NAME=Entitlements | Server role | Entitlements services and controllers | Platform billing and feature control |
| MODULE_NAME=Compliance | Server role | Compliance services and controllers | Compliance API host |
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
| Layer | Technology | Version | Purpose |
|---|---|---|---|
| Backend Framework | .NET | 10 | Core runtime and SDK |
| API Style | ASP.NET Core Web API | 10 | REST controllers with Swagger |
| CQRS | AstraFlow mediator | 12+ | Command/Query separation |
| Validation | FluentValidation | 11+ | Request validation pipeline |
| ORM | Entity Framework Core | 10 | Multi-database O/R mapping |
| Caching | IMemoryCache + Redis | — | L1/L2 cache layers |
| Real-time | SignalR | 10 | WebSocket hubs for live data |
| Background Jobs | Hangfire | 1.8+ | Recurring and fire-and-forget jobs |
| Frontend Framework | Next.js | 16 (App Router) | Server/Client hybrid rendering |
| UI Library | Shadcn/ui + Radix | — | Accessible component primitives |
| State Management | TanStack Query + Zustand | v5 / v5 | Server state + client state |
| Styling | Tailwind CSS + CSS Modules | 4 | Utility-first with scoped styles |
| Localization | Custom 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.
| Order | Registration | Size | Purpose |
|---|---|---|---|
| 1 | AddInfrastructureServices | 11KB | Serilog, API versioning, controllers, JSON options |
| 2 | AddCorsConfiguration | 5KB | Dev vs Production CORS policies |
| 3 | AddRateLimitingConfiguration | 13KB | DDoS prevention, per-IP, login rate limits |
| 4 | AddSwaggerConfiguration | 8KB | OpenAPI documentation |
| 5 | AddScripeObservability | 8KB | OpenTelemetry tracing + metrics |
| 6 | AddCoreInfrastructure | 11KB | ICurrentUser, Audit, Cache, DI container |
| 7 | AddBlobStorage | 2KB | Local / Azure / S3 / MinIO storage |
| 8 | AddIdentityModule | Module | Identity-specific services |
| 9 | AddCoreApplication | 2KB | AstraFlow mediator + Behaviors + Domain Events |
| 10 | AddHealthCheckConfiguration | 2KB | Health endpoints |
| 11 | AddBackgroundJobsConfiguration | 9KB | Hangfire + recurring jobs |
| 12 | AddSignalRConfiguration | 2KB | Real-time WebSocket hubs |
| 13 | AddGatewayConfiguration | 4KB | YARP reverse proxy (Gateway mode only) |
Environment Profiles
| Environment | Config File | Features |
|---|---|---|
| Development | appsettings.Development.json | Swagger enabled, verbose logging, UserSecrets |
| Production | appsettings.json | HSTS, minimal logging, no Swagger |
| Oracle | appsettings.Oracle.example.json | Oracle provider configuration |
| PostgreSQL | appsettings.PostgreSQL.example.json | PostgreSQL provider configuration |
Priority (highest wins):
1. UserSecrets (Development only)
2. Environment Variables (prefix: SCRIPE_)
3. appsettings.Secrets.json (optional)
4. appsettings.json (base)