Fix Summary β€” Backend Architecture Overview

Fixed: 2026-03-09

Last updated: March 10, 2026 Reading time: 3 minutes File size: 3.89 KB

Changes made

MISMATCH fixes

  • M1 β€” canDemoteOrganizer predicate corrected from > 2 to >= 2. The deployed rule allows demotion when 2 or more organizers remain (consistent with both RoleServiceTest cases: 2 organizers β†’ success, 1 organizer β†’ MinimumOrganizersException).

  • M2 β€” Replaced the role-gated security filter chain snippet (which falsely implied domain services enforce hasAnyRole("ORGANIZER", "ATTENDEE", ...)) with the actual model: domain services trust the API Gateway and expose public endpoints via permitAll. Added a note that JWT validation is the gateway’s responsibility. Documented all public endpoints in a table (event details, sessions, speakers, registration create/confirm, actuator, Swagger UI).

  • M3 β€” Updated the β€œUser Lifecycle” key-point line: roles are stored as Set<Role> on the User entity, not in a separate role_assignments table. Added a note to the Role Management section header clarifying that the RoleManagementService snippet is a design reference; the deployed RoleService uses UserRepository only.

  • M4 β€” Replaced the bespoke CircuitBreakerService snippet (count-based threshold of 5, timeout 60 000 ms, ConcurrentHashMap) with the actual Resilience4j YAML configuration: failureRateThreshold: 60%, waitDurationInOpenState: 10s, permittedNumberOfCallsInHalfOpenState: 5, named instance eventBridgePublisher.

UNDOCUMENTED additions

  • N1 β€” Added a prominent note at the top of the β€œRole-Based Security Configuration” subsection: domain services do not validate JWT signatures; that responsibility belongs to the API Gateway.

  • N2 β€” Added /swagger-ui/** and /v3/api-docs/** to the public-endpoints table (confirmed by SecurityConfigTest#should_allowAccess_when_swaggerUiAccessed).

  • N3 β€” Documented public GET /api/v1/events/**, GET /api/v1/events/{code}/sessions/**, and GET /api/v1/events/{code}/speakers/** endpoints in the new public-endpoints table.

  • N4 β€” Documented public POST /api/v1/events/{code}/registrations and POST /api/v1/events/{code}/registrations/confirm in the public-endpoints table.

  • N5 β€” Added β€œConflict Detection Severities” subsection after validateSpeakerInvitation: ROOM_OVERLAP β†’ ERROR (blocking), SPEAKER_DOUBLE_BOOKED β†’ ERROR (blocking), PREFERENCE_MISMATCH β†’ WARNING (non-blocking).

  • N6 β€” Added idempotency note to the Role Management section header: addRole/removeRole are idempotent; UserRoleChangedEvent is only published when the role set actually changes.

Skipped β€” needs manual decision

  • U1 β€” "Event date must be at least 30 days in the future" β€” no test was found in the searched directories. Either a missing test or an aspirational code snippet in the doc. Recommend: add a unit test for EventBusinessRules.validateEventCreation or remove the validation claim from the doc if the rule was never implemented.

  • U2 β€” "Only one event is allowed per quarter" β€” no test was found. Same risk as U1: may be aspirational. Recommend: add a test or remove from doc.

  • U3 β€” @Retryable(value = {TransientException.class, TemporaryUnavailableException.class}, ...) β€” Resilience4j retry values are consistent with the doc, but no unit test asserts retry behaviour for these exception types. If Spring-Retry (@Retryable) and Resilience4j retry coexist, document which layer handles which exception. Otherwise, add a test or clarify that only Resilience4j retry is used.

  • U4 β€” X-Correlation-ID header propagation via RequestCorrelationFilter β€” the error-response test confirms a correlation ID appears in responses, but no test verifies the filter reads an incoming X-Correlation-ID header and propagates it. Low-risk gap; consider adding a filter-level unit test.