books/backend/Books.Api/EventFlow/Extensions/ReadModelRegistrationExtensions.cs
Nicolaj Hartmann 926085eeab Add OpenID Connect + API Key authentication
Backend:
- Cookie + OIDC + API Key authentication schemes
- ApiKeyAuthenticationHandler with SHA-256 validation and 24h cache
- AuthController with login/logout/profile endpoints
- API Key domain model (EventFlow aggregate, events, commands)
- ApiKeyReadModel and repository for key validation
- Database migration 002_ApiKeys.sql
- CORS configuration for frontend

Frontend:
- authService.ts for login/logout/profile API calls
- authStore.ts (Zustand) for user context state
- ProtectedRoute component for route guards
- Header updated with user display and logout
- GraphQL client with credentials: include

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 11:49:29 +01:00

33 lines
1.2 KiB
C#

using Books.Api.EventFlow.ReadModels;
using Books.Api.EventFlow.Repositories;
using EventFlow;
using EventFlow.Extensions;
using EventFlow.PostgreSql.Extensions;
using EventFlow.Sql.ReadModels;
using ReadModelSqlGenerator = Books.Api.EventFlow.Customs.ReadModelSqlGenerator;
namespace Books.Api.EventFlow.Extensions;
public static class ReadModelRegistrationExtensions
{
public static IEventFlowOptions AddReadModels(this IEventFlowOptions options)
{
return options
.UsePostgreSqlReadModel<CompanyReadModel, CompanyReadModelLocator>()
.UsePostgreSqlReadModel<ApiKeyReadModel, ApiKeyReadModelLocator>()
.RegisterServices(sr => sr.AddSingleton<IReadModelSqlGenerator>(new ReadModelSqlGenerator()));
}
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
// Register locators
services.AddTransient<CompanyReadModelLocator>();
services.AddTransient<ApiKeyReadModelLocator>();
// Register repositories
services.AddScoped<ICompanyRepository, CompanyRepository>();
services.AddScoped<IApiKeyRepository, ApiKeyRepository>();
return services;
}
}