Skip to content

Enterprise SaaS framework (FastAPI + Next.js) — Hybrid DDD Core + governed modules

License

Notifications You must be signed in to change notification settings

anthonykewl20/efncore

Repository files navigation

efncore

The Enterprise SaaS Framework Kernel — Production-grade multi-tenancy, events, jobs, and observability for building SaaS products.

CI/CD Security License: RSEL v1.0


🎯 What is efncore?

efncore is a production-grade framework for building multi-tenant SaaS products. Like WordPress for enterprise SaaS, it provides:

  • 🏗️ Domain-Driven Design architecture that scales with your team
  • 🏢 Built-in multi-tenancy with tenant isolation at all layers
  • Event-driven architecture with transactional outbox
  • 🔄 Background jobs with retry logic and scheduling
  • 📊 OpenTelemetry observability from day one
  • 🔌 Module system for extensible features
  • 🎨 Frontend shell included (Next.js 16)

For SaaS Founders: Ship months faster with production-grade patterns. For Developers: FastAPI + Next.js with TypeScript everywhere. For AI Agents: CLAUDE.md with explicit architecture documentation.


⚡ Quick Start (5 minutes)

Get efncore running locally with Docker Compose.

Prerequisites

  • Docker & Docker Compose
  • Git

One-Command Setup

git clone https://github.com/anthonykewl20/efncore.git
cd efncore
docker compose up -d

Access Your SaaS

Service URL Credentials
Frontend http://localhost:3001 -
Backend API http://localhost:8001 -
API Docs http://localhost:8001/docs -
Debug Context http://localhost:8001/debug/context -
Keycloak http://localhost:8080 admin/admin

Verify It's Working

# Check health status
curl http://localhost:8001/health

# Check request context (tenant isolation)
curl -H "X-Tenant-Id: 123e4567-e89b-12d3-a456-426614174000" \
     http://localhost:8001/debug/context

← Full Setup Guide


✨ Why efncore?

For SaaS Founders

Challenge efncore Solution
Building multi-tenancy from scratch Tenant isolation built-in (DB, cache, events)
Handling background jobs reliably Transactional outbox + RabbitMQ workers
Scaling read load Automatic replica routing (ADR-014)
Observability after the fact OpenTelemetry tracing from day one
Hiring developers Standard DDD patterns, clear documentation

For Developers

# Tenant-scoped requests (automatic)
from efncore.kernel.request_context import RequestContextDep

@router.get("/users")
async def list_users(ctx: RequestContextDep):
    # ctx.tenant_id automatically filters queries
    users = await user_service.list(ctx.tenant_id)
    return users
# Read from replicas automatically
# Write to primary explicitly
async with get_db_session(prefer_replica=True) as session:
    user = await session.get(User, id)  # Routes to replica

async with get_write_db_session() as session:
    session.add(new_user)  # Always goes to primary
    await session.commit()

For AI Agents

efncore includes CLAUDE.md — explicit architecture documentation for AI assistants:

  • File placement rules (non-negotiable)
  • API patterns and conventions
  • Testing workflows and patterns
  • Configuration system reference

✨ Core Features

🏢 Multi-Tenancy

  • Tenant isolation at database, cache, and event layers
  • Request context middleware automatically scopes all operations
  • Tenant-scoped Redis keys prevent data leakage
  • Row-level security with tenant governance
  • Tenant onboarding flows built-in

⚡ Event-Driven Architecture

  • Transactional outbox pattern prevents event loss
  • RabbitMQ integration with at-least-once delivery
  • Event handlers with idempotency and replay
  • Dead-letter queues for failed events
  • Module-to-core communication via events

🔄 Background Jobs

  • Arq-based job queue with Redis backend
  • Retry logic with exponential backoff
  • Scheduled jobs and cron-like workflows
  • Tenant-isolated job execution
  • Job observability with tracing

📊 Observability

  • OpenTelemetry tracing (OTLP) with W3C trace context
  • Structured logging with tenant/user context
  • Performance guardrails (query timeouts, backpressure)
  • Slow query logging with automatic detection
  • Health checks for all dependencies

🔌 Module System

  • Dynamic module loading from directory
  • Strict contracts (HTTP APIs + domain events)
  • Module governance (allowlist, version checks)
  • UI extension points for frontend modules
  • Kill switch for emergency disabling

🛡️ Security

  • OIDC authentication (Keycloak integration)
  • Role-based access control (RBAC)
  • Audit logging for compliance (SOC 2, HIPAA)
  • PII redaction in logs and events
  • Rate limiting and load shedding

🏗️ Architecture Overview

efncore follows Domain-Driven Design (DDD) with bounded contexts:

graph TB
    subgraph "Frontend (Next.js)"
        A[app/] --> B[core/templates/]
        A --> C[modules/]
        A --> D[platform/]
    end

    subgraph "Backend (FastAPI)"
        E[app/main.py] --> F[core/contexts/]
        E --> G[modules/]
        E --> H[efncore/kernel/]
    end

    subgraph "Kernel Services"
        H --> I[request_context/]
        H --> J[data/]
        H --> K[eventing/]
        H --> L[jobs/]
        H --> M[cache/]
    end

    A -->|HTTP/REST| E
    K -->|RabbitMQ| N[Workers]
    J -->|PostgreSQL| O[(Primary)]
    J -->|Read Replicas| O
    M -->|Redis| P[(Cache)]
Loading

Repository Structure

efncore/
├── backend/                 # FastAPI application
│   ├── src/
│   │   ├── app/            # Composition root
│   │   ├── core/           # Non-removable bounded contexts
│   │   │   ├── tenancy/    # Tenant lifecycle
│   │   │   ├── iam/         # Users, auth, RBAC
│   │   │   ├── audit/       # Audit logging
│   │   │   └── billing/     # Subscriptions, entitlements
│   │   ├── modules/        # Installable features
│   │   └── efncore/        # Platform kernel
│   │       ├── kernel/
│   │       │   ├── request_context/  # Tenant/user metadata
│   │       │   ├── data/             # Read/write splitting
│   │       │   ├── eventing/         # Outbox, events
│   │       │   ├── jobs/             # Background jobs
│   │       │   └── cache/            # Redis caching
│   │       ├── http/         # Middleware, errors
│   │       └── config/       # Centralized settings
│   ├── tests/               # Unit, integration, E2E
│   └── worker/              # Background job worker
│
├── frontend/                # Next.js application
│   ├── src/
│   │   ├── app/            # App Router
│   │   ├── core/           # Shell/core UI
│   │   ├── modules/        # Module UI
│   │   └── platform/       # Theme, UI kit
│   └── e2e/                # Playwright E2E tests
│
├── docs/                    # Architecture & dev docs
│   ├── architecture/        # ADRs, system context
│   ├── development/         # Roadmap, workstreams
│   └── dev-docs/           # Developer guides
│
└── CLAUDE.md                # AI agent documentation

Key Principles:

  • 📁 No utils/, common/, or shared/ directories
  • 🚫 No business logic in HTTP routers
  • 🔒 All requests tenant-scoped
  • 📡 Modules communicate via HTTP APIs or events

📚 Documentation

Getting Started

Guide Description
Quick Start Get running in 5 minutes
Configuration Guide All 100+ environment variables
Debugging Guide Troubleshooting common issues
Request Context Tenant/user propagation

Architecture

Document Description
System Context C4 system-level architecture
ADR Index Architecture decision records
Deployment Production deployment guide
Performance Scaling and optimization

Development

Document Description
File Governance Where code belongs (NON-NEGOTIABLE)
Module Development Building modules
Eventing Guide Event handlers and outbox
Jobs Guide Background job patterns

🧪 Testing

efncore uses Shin et al methodologies (mutation testing, sad path first):

# Backend tests
cd backend
pytest                          # All tests
pytest -m unit                  # Unit tests only
pytest -m integration           # Integration tests (requires DB)
pytest -m smoke                 # Health checks against running services

# Frontend tests
cd frontend
npm test                        # Unit tests (Vitest)
npm run test:e2e                # E2E tests (Playwright)
npm run test:coverage           # With coverage

Test Philosophy:

  • ✅ Sad path before happy path
  • ✅ Tenant isolation tests
  • ✅ Mutation testing for critical modules
  • ✅ Cross-module integration tests

🚀 Deployment

Development (Docker Compose)

docker compose up -d

Production

See Deployment Guide for:

  • Kubernetes manifests
  • Environment variable reference
  • Database migrations
  • PgBouncer for read replicas
  • OpenTelemetry collector setup

Current Deployment: Single VPS with Dokploy (Phase 0) Migration Path: VPS → Split DB → Multi-region (same codebase)


🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Areas for Contribution:

  • 🐛 Bug fixes
  • 🔌 New modules
  • 📖 Documentation improvements
  • ✅ Test coverage
  • ⚡ Performance optimizations

Good First Issues: GitHub Issues


💬 Community


🗺️ Roadmap

Phase Status Description
Phase 0 ✅ Complete Single VPS deployment (cost optimization)
Phase 1 ✅ Complete Core multi-tenancy + read replicas
Phase 2 🚧 In Progress Module marketplace + governance UI
Phase 3 📋 Planned AI agent SDK for module development
Phase 4 📋 Planned Multi-region high availability

Full Roadmap


📊 Performance

efncore is built for scale:

  • Throughput: 10,000+ req/sec per instance
  • Database: Read replicas with automatic routing
  • Caching: Tenant-scoped Redis with TTL governance
  • Backpressure: Load shedding when overloaded
  • Query Timeouts: 50% of request timeout threshold
  • Slow Queries: Auto-logged when exceeding 1 second

Performance Guide


🛠️ Tech Stack

Backend:

Frontend:

Observability:


📄 License

RANEX FRAMEWORKS SOURCE-AVAILABLE EVALUATION LICENSE (RSEL) v1.0

See LICENSE for details.


🙏 Acknowledgments

efncore stands on the shoulders of giants:

  • WordPress — Plugin architecture inspiration
  • Stripe — API design patterns
  • Shopify — Multi-tenancy patterns
  • FastAPI — Backend framework
  • Next.js — Frontend framework

📖 Citation

If you use efncore in your research or production, please cite:

@software{efncore,
  title = {efncore: Enterprise SaaS Framework Kernel},
  author = {Anthony Kewl},
  year = {2024},
  url = {https://github.com/anthonykewl20/efncore}
}

⭐ Star us on GitHub — it helps more people discover efncore!

← Back to Docs | Quick Start →