Skip to content

Latest commit

 

History

History
102 lines (67 loc) · 3.86 KB

File metadata and controls

102 lines (67 loc) · 3.86 KB

Docs Summary

This page is deliberately short. It is here so you can refresh the project quickly before a conversation.

What Is This Project?

Evently is a modular monolith for event management. It keeps business modules isolated, lets each module own its own data, and uses integration events, inbox/outbox processing, and a saga to coordinate cross-module workflows.

What Makes It A Modular Monolith Instead Of Just A Normal Monolith?

  • the code is split into bounded-context-style modules
  • modules do not share business internals directly
  • modules do not read each other's tables
  • communication happens through explicit contracts and messages
  • each module has its own domain, application, infrastructure, and presentation layers

What Are The Modules?

  • Users: profiles, roles, permissions, Keycloak identity mapping
  • Events: categories, events, ticket types, cancellation coordination
  • Ticketing: carts, orders, payments, tickets
  • Attendance: check-in and attendance statistics

Why Are There Local Copies Of Users, Events, And Tickets In Different Modules?

Because modules are not supposed to reach into each other's storage. They consume integration events and store the data they need locally.

Examples:

  • User becomes Customer in Ticketing
  • User becomes Attendee in Attendance
  • Event is replicated into Ticketing and Attendance
  • TicketIssuedIntegrationEvent creates an attendance-side ticket copy

How Do Modules Communicate?

Mostly through RabbitMQ and MassTransit.

Typical flow:

  1. local command changes state
  2. aggregate raises domain event
  3. domain event goes to outbox
  4. outbox job processes it
  5. handler publishes integration event
  6. receiving module stores it in inbox
  7. inbox job processes it
  8. integration handler sends a local command

Why Are Inbox And Outbox Useful?

  • they make message processing retryable
  • they reduce the risk of losing cross-module events
  • they support eventual consistency
  • they help with idempotency
  • they preserve module boundaries

What Is The Saga Doing?

The cancellation saga coordinates event cancellation.

It waits for two independent things to finish in Ticketing:

  • payment refunds
  • ticket archiving

When both are done, it publishes cancellation completion.

Where Is MongoDB Used?

Mostly for the Attendance module's EventStatistics projection. Most other reads still use Dapper over PostgreSQL.

How Does Authentication Work?

  • Keycloak issues tokens and acts as the identity provider
  • the Users module stores local user data and permissions
  • claims transformation enriches the principal with the local user ID and permission claims
  • endpoints authorize against permission codes

Why Not Microservices?

This design gets many of the boundary and consistency benefits of microservices without paying the full deployment and operational cost. It is a good middle ground for teams that want clear business separation but do not need separate deployment units yet.

What Is Production-Like And What Is Educational?

Strong architectural ideas:

  • module boundaries
  • inbox/outbox
  • integration events
  • permission flow
  • saga coordination

Clearly simplified areas:

  • payment gateway is fake
  • notification sending is not implemented
  • local Keycloak setup depends on persisted dev state

In short

Evently is a modular monolith built with .NET. The important idea is that each module owns its own business logic and persistence model, even though the whole solution runs together. When one module needs another module to react, it publishes integration events through RabbitMQ. Incoming messages are persisted in inbox tables, outgoing domain events are persisted in outbox tables, and Quartz processes both asynchronously. The most interesting workflow is event cancellation, where a saga waits for ticket archiving and payment refunds before marking the cancellation complete.