Skip to content

Latest commit

 

History

History
216 lines (156 loc) · 6.36 KB

File metadata and controls

216 lines (156 loc) · 6.36 KB

Module Guide

This chapter is the practical map of the four modules: what each one owns, which endpoints it exposes, which messages it publishes or consumes, and what makes it special.

Users

Responsibility

The Users module is the system's internal identity and authorization source.

It owns:

  • local user profiles
  • the mapping between a Keycloak identity and the local user record
  • roles
  • permissions

It does not replace Keycloak as the identity provider. Instead, it complements Keycloak with application-specific data and authorization rules.

Main Endpoints

Endpoint Purpose
POST users/register register a user in Keycloak and create the local user
GET users/{id}/profile get a user profile
GET users/my-profile get the current authenticated user's profile
PUT users/{id}/profile update profile data

Published Integration Events

  • UserRegisteredIntegrationEvent
  • UserProfileUpdatedIntegrationEvent

Consumed Messages

  • GetUserPermissionsRequest via MassTransit request/response

Special Notes

  • New users are created with the Member role.
  • Permissions are derived from role-to-permission mappings stored in the module's own schema.
  • This module is the source of truth for authorization data used by other modules.

Events

Responsibility

The Events module is the authoritative source for the event catalog.

It owns:

  • categories
  • events
  • ticket types
  • event publication lifecycle
  • event cancellation coordination

Main Endpoints

Endpoint Purpose
POST categories create a category
GET categories list categories
GET categories/{id} get a category
PUT categories/{id} update a category
DELETE categories/{id}/archive archive a category
POST events create an event
GET events list events
GET events/{id} get an event
GET events/search search published events
PUT events/{id}/publish publish an event
PUT events/{id}/reschedule reschedule an event
DELETE events/{id}/cancel cancel an event
POST ticket-types create a ticket type
GET ticket-types list ticket types for an event
GET ticket-types/{id} get a ticket type
PUT ticket-types/{id}/price change ticket price

Published Integration Events

  • EventPublishedIntegrationEvent
  • EventRescheduledIntegrationEvent
  • EventCanceledIntegrationEvent
  • TicketTypePriceChangedIntegrationEvent
  • EventCancellationStartedIntegrationEvent
  • EventCancellationCompletedIntegrationEvent

Consumed Messages

  • EventPaymentsRefundedIntegrationEvent
  • EventTicketsArchivedIntegrationEvent

Special Notes

  • An event can only be published if it has at least one ticket type.
  • The module uses a MassTransit saga state machine to coordinate cancellation across modules.
  • The saga state is stored in Redis when available, with an in-memory fallback.

Ticketing

Responsibility

The Ticketing module owns the commercial workflow.

It manages:

  • customers
  • carts
  • orders
  • payments
  • local event and ticket-type copies needed for selling
  • issued tickets

Main Endpoints

Endpoint Purpose
PUT carts/add add a ticket type to the current cart
PUT carts/remove remove a ticket type from the current cart
DELETE carts clear the cart
GET carts get the current cart
POST orders create an order from the current cart
GET orders list the current user's orders
GET orders/{id} get order details
GET tickets/{id} get ticket details
GET tickets/code/{code} get a ticket by code
GET tickets/order/{orderId} list tickets for an order

Published Integration Events

  • OrderCreatedIntegrationEvent
  • TicketIssuedIntegrationEvent
  • TicketArchivedIntegrationEvent
  • TicketTypeSoldOutIntegrationEvent
  • EventPaymentsRefundedIntegrationEvent
  • EventTicketsArchivedIntegrationEvent

Consumed Integration Events

  • UserRegisteredIntegrationEvent
  • UserProfileUpdatedIntegrationEvent
  • EventPublishedIntegrationEvent
  • EventCancellationStartedIntegrationEvent
  • TicketTypePriceChangedIntegrationEvent

Special Notes

  • Customer is a local projection of a user, not a direct dependency on the Users module.
  • Checkout uses pessimistic locking when reserving ticket-type inventory.
  • Payment charging is intentionally faked in the sample.
  • Ticket issuance happens after order creation through domain-event handlers.

Attendance

Responsibility

The Attendance module owns check-in and attendance reporting.

It manages:

  • attendees
  • local event copies used for attendance operations
  • local ticket copies used for check-in
  • event statistics projections

Main Endpoints

Endpoint Purpose
PUT attendees/check-in check a ticket in for an attendee
GET event-statistics/{eventId} get attendance statistics for an event

Consumed Integration Events

  • UserRegisteredIntegrationEvent
  • UserProfileUpdatedIntegrationEvent
  • EventPublishedIntegrationEvent
  • TicketIssuedIntegrationEvent

Published Integration Events

There are no major cross-module business integrations currently emitted from Attendance.

Special Notes

  • Attendance maintains a MongoDB projection for event statistics.
  • A bad check-in attempt does not silently fail. It raises domain events that update statistics.
  • The module tracks duplicate and invalid check-in attempts, not just successful ones.

Which Module Owns What

Business Concept Owning Module
user profile Users
roles and permissions Users
event category Events
event catalog Events
ticket type definition and price Events
cart Ticketing
order Ticketing
payment Ticketing
issued ticket for selling Ticketing
attendee check-in state Attendance
attendance statistics Attendance

What To Notice As You Read The Code

When you move through the module code, pay special attention to these repeated patterns:

  • endpoints call MediatR
  • commands update aggregates and save through a module-specific unit of work
  • aggregates raise domain events
  • domain events are processed later through the outbox
  • integration events enter through inbox consumers and presentation handlers

Once you recognize that rhythm, the repository becomes much easier to navigate.