Go to file
Jean-Philippe Brule 9772fec30e Add .env.example template and protect secrets from version control
Improves security by preventing accidental commit of sensitive credentials to the
repository. The .env file contains Langfuse API keys, database passwords, and encryption
keys that should never be exposed in version control.

## Security Improvements

**Added .env to .gitignore:**
- Prevents .env file with real secrets from being committed
- Protects Langfuse API keys (public/secret)
- Protects database credentials
- Protects NextAuth secrets and encryption keys

**Created .env.example template:**
- Safe template file for new developers to copy
- Contains all required environment variables with placeholder values
- Includes helpful comments for key generation (openssl commands)
- Documents all configuration options

**Updated Claude settings:**
- Added git restore to allowed commands for workflow automation

## Setup Instructions for New Developers

1. Copy .env.example to .env: `cp .env.example .env`
2. Generate random secrets:
   - `openssl rand -base64 32` for NEXTAUTH_SECRET and SALT
   - `openssl rand -hex 32` for ENCRYPTION_KEY
3. Start Docker: `docker compose up -d`
4. Open Langfuse UI: http://localhost:3000
5. Create account, project, and copy API keys to .env
6. Restart API: `docker compose restart api`

## Files Changed

- .gitignore: Added .env to ignore list
- .env.example: New template file with placeholder values
- .claude/settings.local.json: Added git restore to allowed commands

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 12:29:39 -05:00
.claude Add .env.example template and protect secrets from version control 2025-11-08 12:29:39 -05:00
.gitea/workflows remove TestClient and update gitea workflow 2025-11-07 12:04:47 -05:00
docker/configs Add complete production deployment infrastructure with full observability 2025-11-08 11:03:25 -05:00
Svrnty.CQRS Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.Abstractions Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.DynamicQuery Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.DynamicQuery.Abstractions Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.DynamicQuery.MinimalApi Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.FluentValidation Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.Grpc Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.Grpc.Abstractions Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.Grpc.Generators Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.CQRS.MinimalApi Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Svrnty.Sample Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
.dockerignore Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
.DS_Store yes 2025-11-02 20:44:47 -05:00
.env Add complete production deployment infrastructure with full observability 2025-11-08 11:03:25 -05:00
.env.example Add .env.example template and protect secrets from version control 2025-11-08 12:29:39 -05:00
.gitattributes Add .gitignore and .gitattributes. 2021-02-01 23:31:05 -05:00
.gitignore Add .env.example template and protect secrets from version control 2025-11-08 12:29:39 -05:00
CLAUDE.md yes 2025-11-04 16:45:54 -05:00
DEPLOYMENT_README.md Add complete production deployment infrastructure with full observability 2025-11-08 11:03:25 -05:00
DEPLOYMENT_SUCCESS.md Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
docker-compose.yml Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
Dockerfile Add complete production deployment infrastructure with full observability 2025-11-08 11:03:25 -05:00
icon.png prepare for publishing 2025-11-07 12:02:33 -05:00
LICENSE Create LICENSE 2021-02-01 23:55:58 -05:00
QUICK_REFERENCE.md Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
README.md Add complete production deployment infrastructure with full observability 2025-11-08 11:03:25 -05:00
Svrnty.CQRS.sln mega cleanup :D 2025-11-03 16:00:13 -05:00
test-production-stack.sh Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00
TESTING_GUIDE.md Fix ARM64 Mac build issues: Enable HTTP-only production deployment 2025-11-08 12:07:50 -05:00

This project was originally initiated by Powered Software Inc. and was forked from the PoweredSoft.CQRS Repository

CQRS

Our implementation of query and command responsibility segregation (CQRS).

Getting Started

Install nuget package to your awesome project.

Package Name NuGet NuGet Install
Svrnty.CQRS NuGet dotnet add package Svrnty.CQRS
Svrnty.CQRS.MinimalApi NuGet dotnet add package Svrnty.CQRS.MinimalApi
Svrnty.CQRS.FluentValidation NuGet dotnet add package Svrnty.CQRS.FluentValidation
Svrnty.CQRS.DynamicQuery NuGet dotnet add package Svrnty.CQRS.DynamicQuery
Svrnty.CQRS.DynamicQuery.MinimalApi NuGet dotnet add package Svrnty.CQRS.DynamicQuery.MinimalApi
Svrnty.CQRS.Grpc NuGet dotnet add package Svrnty.CQRS.Grpc
Svrnty.CQRS.Grpc.Generators NuGet dotnet add package Svrnty.CQRS.Grpc.Generators

Abstractions Packages.

Package Name NuGet NuGet Install
Svrnty.CQRS.Abstractions NuGet dotnet add package Svrnty.CQRS.Abstractions
Svrnty.CQRS.DynamicQuery.Abstractions NuGet dotnet add package Svrnty.CQRS.DynamicQuery.Abstractions
Svrnty.CQRS.Grpc.Abstractions NuGet dotnet add package Svrnty.CQRS.Grpc.Abstractions
using Svrnty.CQRS;
using Svrnty.CQRS.FluentValidation;
using Svrnty.CQRS.Grpc;

var builder = WebApplication.CreateBuilder(args);

// Register your commands with validators
builder.Services.AddCommand<AddUserCommand, int, AddUserCommandHandler, AddUserCommandValidator>();
builder.Services.AddCommand<RemoveUserCommand, RemoveUserCommandHandler>();

// Register your queries
builder.Services.AddQuery<FetchUserQuery, User, FetchUserQueryHandler>();

// Configure CQRS with gRPC support
builder.Services.AddSvrntyCqrs(cqrs =>
{
    // Enable gRPC endpoints with reflection
    cqrs.AddGrpc(grpc =>
    {
        grpc.EnableReflection();
    });
});

var app = builder.Build();

// Map all configured CQRS endpoints
app.UseSvrntyCqrs();

app.Run();

Important: gRPC Requirements

The gRPC implementation uses Grpc.Tools with .proto files and source generators for automatic service implementation:

1. Install required packages:

dotnet add package Grpc.AspNetCore
dotnet add package Grpc.AspNetCore.Server.Reflection
dotnet add package Grpc.StatusProto  # For Rich Error Model validation

2. Add the source generator as an analyzer:

dotnet add package Svrnty.CQRS.Grpc.Generators

The source generator is automatically configured as an analyzer when installed via NuGet and will generate both the .proto files and gRPC service implementations at compile time.

3. Define your C# commands and queries:

public record AddUserCommand
{
    public required string Name { get; init; }
    public required string Email { get; init; }
    public int Age { get; init; }
}

public record RemoveUserCommand
{
    public int UserId { get; init; }
}

Notes:

  • The source generator automatically creates:
    • .proto files in the Protos/ directory from your C# commands and queries
    • CommandServiceImpl and QueryServiceImpl implementations
  • FluentValidation is automatically integrated with Google Rich Error Model for structured validation errors
  • Validation errors return google.rpc.Status with BadRequest containing FieldViolations
  • Use record types for commands/queries (immutable, value-based equality, more concise)
  • No need for protobuf-net attributes - just define your C# types

Sample of startup code for Minimal API (HTTP)

For HTTP scenarios (web browsers, public APIs), you can use the Minimal API approach:

using Svrnty.CQRS;
using Svrnty.CQRS.FluentValidation;
using Svrnty.CQRS.MinimalApi;

var builder = WebApplication.CreateBuilder(args);

// Register your commands with validators
builder.Services.AddCommand<CreatePersonCommand, CreatePersonCommandHandler, CreatePersonCommandValidator>();
builder.Services.AddCommand<EchoCommand, string, EchoCommandHandler, EchoCommandValidator>();

// Register your queries
builder.Services.AddQuery<PersonQuery, IQueryable<Person>, PersonQueryHandler>();

// Configure CQRS with Minimal API support
builder.Services.AddSvrntyCqrs(cqrs =>
{
    // Enable Minimal API endpoints
    cqrs.AddMinimalApi();
});

// Add Swagger (optional)
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// Map all configured CQRS endpoints (automatically creates POST /api/command/* and POST/GET /api/query/*)
app.UseSvrntyCqrs();

app.Run();

Notes:

  • FluentValidation is automatically integrated with RFC 7807 Problem Details for structured validation errors
  • Use record types for commands/queries (immutable, value-based equality, more concise)
  • Supports both POST and GET (for queries) endpoints
  • Automatically generates Swagger/OpenAPI documentation

Sample enabling both gRPC and HTTP

You can enable both gRPC and traditional HTTP endpoints simultaneously, allowing clients to choose their preferred protocol:

using Svrnty.CQRS;
using Svrnty.CQRS.FluentValidation;
using Svrnty.CQRS.Grpc;
using Svrnty.CQRS.MinimalApi;

var builder = WebApplication.CreateBuilder(args);

// Register your commands with validators
builder.Services.AddCommand<AddUserCommand, int, AddUserCommandHandler, AddUserCommandValidator>();
builder.Services.AddCommand<RemoveUserCommand, RemoveUserCommandHandler>();

// Register your queries
builder.Services.AddQuery<FetchUserQuery, User, FetchUserQueryHandler>();

// Configure CQRS with both gRPC and Minimal API support
builder.Services.AddSvrntyCqrs(cqrs =>
{
    // Enable gRPC endpoints with reflection
    cqrs.AddGrpc(grpc =>
    {
        grpc.EnableReflection();
    });

    // Enable Minimal API endpoints
    cqrs.AddMinimalApi();
});

// Add HTTP support with Swagger
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

// Map all configured CQRS endpoints (both gRPC and HTTP)
app.UseSvrntyCqrs();

app.Run();

Benefits:

  • Single codebase supports multiple protocols
  • gRPC for high-performance, low-latency scenarios (microservices, internal APIs)
  • HTTP for web browsers, legacy clients, and public APIs
  • Same commands, queries, and validation logic for both protocols
  • Swagger UI available for HTTP endpoints, gRPC reflection for gRPC clients

Fluent Validation

FluentValidation is optional but recommended for command and query validation. The Svrnty.CQRS.FluentValidation package provides extension methods to simplify validator registration.

The package exposes extension method overloads that accept the validator as a generic parameter:

dotnet add package Svrnty.CQRS.FluentValidation
using Svrnty.CQRS.FluentValidation; // Extension methods for validator registration

// Command with result - validator as last generic parameter
builder.Services.AddCommand<EchoCommand, string, EchoCommandHandler, EchoCommandValidator>();

// Command without result - validator included in generics
builder.Services.AddCommand<CreatePersonCommand, CreatePersonCommandHandler, CreatePersonCommandValidator>();

Benefits:

  • Single line registration - Handler and validator registered together
  • Type safety - Compiler ensures validator matches command type
  • Less boilerplate - No need for separate AddTransient<IValidator<T>>() calls
  • Cleaner code - Clear intent that validation is part of command pipeline

Without Svrnty.CQRS.FluentValidation

If you prefer not to use the FluentValidation package, you need to register commands and validators separately:

using FluentValidation;
using Svrnty.CQRS;

// Register command handler
builder.Services.AddCommand<EchoCommand, string, EchoCommandHandler>();

// Manually register validator
builder.Services.AddTransient<IValidator<EchoCommand>, EchoCommandValidator>();

2024-2025 Roadmap

Task Description Status
Support .NET 8 Ensure compatibility with .NET 8.
Support .NET 10 Upgrade to .NET 10 with C# 14 language support.
Update FluentValidation Upgrade FluentValidation to version 11.x for .NET 10 compatibility.
Add gRPC Support with source generators Implement gRPC endpoints with source generators and Google Rich Error Model for validation.
Create a demo project (Svrnty.CQRS.Grpc.Sample) Develop a comprehensive demo project showcasing gRPC and HTTP endpoints.
Create a website for the Framework Develop a website to host comprehensive documentation for the framework.