├── annotations ├── src │ └── main │ │ └── java │ │ └── com │ │ └── smalaca │ │ ├── domaindrivendesign │ │ ├── Policy.java │ │ ├── Saga.java │ │ ├── Factory.java │ │ ├── Specification.java │ │ ├── AggregateRoot.java │ │ ├── DomainEntity.java │ │ ├── DomainEvent.java │ │ ├── DomainService.java │ │ ├── ValueObject.java │ │ ├── ApplicationLayer.java │ │ └── DomainRepository.java │ │ └── architecture │ │ ├── cqrs │ │ ├── QueryOperation.java │ │ └── CommandOperation.java │ │ └── portsandadapters │ │ ├── DrivenPort.java │ │ ├── DrivingPort.java │ │ ├── DrivenAdapter.java │ │ └── DrivingAdapter.java └── pom.xml ├── payment-gateway ├── src │ ├── main │ │ ├── resources │ │ │ └── application.yml │ │ └── java │ │ │ └── com │ │ │ └── smalaca │ │ │ └── paymentgateway │ │ │ ├── api │ │ │ ├── PaymentResponse.java │ │ │ ├── PaymentRequest.java │ │ │ └── PaymentRestController.java │ │ │ └── PaymentGatewayApplication.java │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── paymentgateway │ │ └── api │ │ └── PaymentRestControllerTest.java └── sonar-project.properties ├── open-trainings ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── smalaca │ │ │ └── opentrainings │ │ │ ├── domain │ │ │ ├── offeracceptancesaga │ │ │ │ ├── OfferAcceptanceSagaStatus.java │ │ │ │ ├── OfferAcceptanceSagaDto.java │ │ │ │ ├── commands │ │ │ │ │ ├── OfferAcceptanceSagaCommand.java │ │ │ │ │ ├── BeginOfferAcceptanceCommand.java │ │ │ │ │ ├── RegisterPersonCommand.java │ │ │ │ │ ├── BookTrainingPlaceCommand.java │ │ │ │ │ ├── ReturnDiscountCodeCommand.java │ │ │ │ │ ├── ConfirmTrainingPriceCommand.java │ │ │ │ │ ├── UseDiscountCodeCommand.java │ │ │ │ │ └── RejectOfferCommand.java │ │ │ │ ├── OfferAcceptanceSagaRepository.java │ │ │ │ ├── OfferAcceptanceSagaEventRegistry.java │ │ │ │ └── events │ │ │ │ │ ├── OfferAcceptanceSagaEvent.java │ │ │ │ │ ├── DiscountCodeReturnedEvent.java │ │ │ │ │ ├── PersonRegisteredEvent.java │ │ │ │ │ ├── TrainingPriceNotChangedEvent.java │ │ │ │ │ ├── TrainingPlaceBookedEvent.java │ │ │ │ │ ├── AlreadyRegisteredPersonFoundEvent.java │ │ │ │ │ ├── NoAvailableTrainingPlacesLeftEvent.java │ │ │ │ │ ├── DiscountCodeAlreadyUsedEvent.java │ │ │ │ │ ├── TrainingPriceChangedEvent.java │ │ │ │ │ └── DiscountCodeUsedEvent.java │ │ │ ├── offer │ │ │ │ ├── events │ │ │ │ │ └── OfferEvent.java │ │ │ │ ├── AvailableOfferException.java │ │ │ │ ├── OfferRepository.java │ │ │ │ ├── NoAvailablePlacesException.java │ │ │ │ ├── OfferNumber.java │ │ │ │ ├── OfferStatus.java │ │ │ │ ├── InvalidOfferStatusException.java │ │ │ │ └── OfferNumberFactory.java │ │ │ ├── order │ │ │ │ ├── events │ │ │ │ │ ├── OrderEvent.java │ │ │ │ │ ├── OrderCancelledEvent.java │ │ │ │ │ ├── OrderTerminatedEvent.java │ │ │ │ │ ├── TrainingPurchasedEvent.java │ │ │ │ │ └── OrderRejectedEvent.java │ │ │ │ ├── OrderInFinalStateException.java │ │ │ │ ├── OrderStatus.java │ │ │ │ ├── OrderTerminationNotYetPermittedException.java │ │ │ │ ├── OrderRepository.java │ │ │ │ ├── OrderNumber.java │ │ │ │ └── OrderNumberFactory.java │ │ │ ├── clock │ │ │ │ └── Clock.java │ │ │ ├── paymentgateway │ │ │ │ ├── PaymentGateway.java │ │ │ │ └── PaymentResponse.java │ │ │ ├── paymentmethod │ │ │ │ ├── UnsupportedPaymentMethodException.java │ │ │ │ └── PaymentMethod.java │ │ │ ├── trainingoffercatalogue │ │ │ │ ├── TrainingOfferCatalogue.java │ │ │ │ └── TrainingDto.java │ │ │ ├── commandregistry │ │ │ │ └── CommandRegistry.java │ │ │ ├── eventregistry │ │ │ │ └── EventRegistry.java │ │ │ ├── commandid │ │ │ │ └── CommandId.java │ │ │ └── eventid │ │ │ │ └── EventId.java │ │ │ ├── application │ │ │ ├── order │ │ │ │ ├── ConfirmOrderCommand.java │ │ │ │ └── OrderApplicationServiceFactory.java │ │ │ └── offer │ │ │ │ └── OfferApplicationServiceFactory.java │ │ │ ├── infrastructure │ │ │ ├── api │ │ │ │ ├── eventpublisher │ │ │ │ │ └── kafka │ │ │ │ │ │ ├── order │ │ │ │ │ │ └── Topics.java │ │ │ │ │ │ └── offer │ │ │ │ │ │ └── Topics.java │ │ │ │ ├── rest │ │ │ │ │ └── offer │ │ │ │ │ │ └── AcceptOfferRestCommand.java │ │ │ │ └── eventlistener │ │ │ │ │ ├── offeracceptance │ │ │ │ │ └── OfferAcceptanceEventListenerFactory.java │ │ │ │ │ └── order │ │ │ │ │ └── OrderEventListener.java │ │ │ ├── outbox │ │ │ │ └── jpa │ │ │ │ │ ├── InvalidOutboxMessageException.java │ │ │ │ │ ├── SpringOutboxMessageCrudRepository.java │ │ │ │ │ ├── JpaOutboxMessageRepositoryFactory.java │ │ │ │ │ └── OutboxMessagePublisherFactory.java │ │ │ ├── paymentgateway │ │ │ │ ├── RestPaymentRequest.java │ │ │ │ └── PaymentGatewayRestClientFactory.java │ │ │ ├── repository │ │ │ │ └── jpa │ │ │ │ │ ├── offeracceptancesaga │ │ │ │ │ ├── InvalidOfferAcceptanceSagaEventException.java │ │ │ │ │ ├── SpringOfferAcceptanceSagaEventCrudRepository.java │ │ │ │ │ └── JpaOfferAcceptanceSagaRepositoryFactory.java │ │ │ │ │ ├── offer │ │ │ │ │ ├── OfferDoesNotExistException.java │ │ │ │ │ ├── SpringOfferCrudRepository.java │ │ │ │ │ └── JpaOfferRepository.java │ │ │ │ │ └── order │ │ │ │ │ ├── OrderDoesNotExistException.java │ │ │ │ │ ├── SpringOrderCrudRepository.java │ │ │ │ │ └── JpaOrderRepository.java │ │ │ ├── clock │ │ │ │ └── localdatetime │ │ │ │ │ └── LocalDateTimeClock.java │ │ │ └── trainingoffercatalogue │ │ │ │ ├── RestTrainingOfferDetailDto.java │ │ │ │ └── TrainingOfferCatalogueRestClientFactory.java │ │ │ ├── OpenTrainingsApplication.java │ │ │ └── query │ │ │ ├── offer │ │ │ ├── OfferViewRepository.java │ │ │ └── OfferView.java │ │ │ └── order │ │ │ └── OrderViewRepository.java │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── opentrainings │ │ ├── client │ │ └── opentrainings │ │ │ ├── order │ │ │ ├── RestConfirmOrderTestCommand.java │ │ │ └── RestOrderTestDto.java │ │ │ └── offer │ │ │ ├── RestOfferAcceptanceTestDto.java │ │ │ ├── RestAcceptOfferTestCommand.java │ │ │ └── RestOfferTestDto.java │ │ ├── domain │ │ ├── price │ │ │ └── PriceTest.java │ │ ├── order │ │ │ ├── DiscountCodeTest.java │ │ │ ├── OrderTestDto.java │ │ │ ├── OrderStatusTest.java │ │ │ ├── events │ │ │ │ └── OrderRejectedEventAssertion.java │ │ │ └── OrderNumberAssertion.java │ │ ├── offeracceptancesaga │ │ │ └── ConsumedEventTest.java │ │ └── offer │ │ │ ├── OfferTestDto.java │ │ │ └── OfferNumberAssertion.java │ │ ├── infrastructure │ │ ├── outbox │ │ │ └── jpa │ │ │ │ ├── OutboxMessageTest.java │ │ │ │ └── OutboxMessageTestListener.java │ │ └── clock │ │ │ └── localdatetime │ │ │ └── LocalDateTimeClockTest.java │ │ ├── architecture │ │ └── NoCyclesTest.java │ │ └── data │ │ └── Random.java └── sonar-project.properties ├── reviews ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── smalaca │ │ │ └── reviews │ │ │ ├── client │ │ │ └── reviews │ │ │ │ ├── proposal │ │ │ │ ├── CompleteReviewTestCommand.java │ │ │ │ └── RestProposalTestResponse.java │ │ │ │ └── ReviewsTestClient.java │ │ │ ├── domain │ │ │ └── proposal │ │ │ │ ├── GivenProposalFactory.java │ │ │ │ └── ProposalTestDto.java │ │ │ ├── architecture │ │ │ └── NoCyclesTest.java │ │ │ └── infrastructure │ │ │ └── clock │ │ │ └── localdatetime │ │ │ └── LocalDateTimeClockTest.java │ └── main │ │ ├── java │ │ └── com │ │ │ └── smalaca │ │ │ └── reviews │ │ │ ├── infrastructure │ │ │ ├── api │ │ │ │ └── rest │ │ │ │ │ └── proposal │ │ │ │ │ └── CompleteReviewCommand.java │ │ │ ├── repository │ │ │ │ └── jpa │ │ │ │ │ └── proposal │ │ │ │ │ ├── SpringProposalCrudRepository.java │ │ │ │ │ ├── ProposalDoesNotExistException.java │ │ │ │ │ └── JpaProposalRepository.java │ │ │ ├── clock │ │ │ │ └── localdatetime │ │ │ │ │ └── LocalDateTimeClock.java │ │ │ └── trainerscatalogue │ │ │ │ └── TrainersCatalogueRestClientFactory.java │ │ │ ├── domain │ │ │ ├── trainerscatalogue │ │ │ │ ├── Trainer.java │ │ │ │ └── TrainersCatalogue.java │ │ │ ├── clock │ │ │ │ └── Clock.java │ │ │ ├── commandid │ │ │ │ └── CommandId.java │ │ │ ├── proposal │ │ │ │ ├── ProposalStatus.java │ │ │ │ ├── ReviewerAssignmentPolicy.java │ │ │ │ ├── commands │ │ │ │ │ └── RegisterProposalCommand.java │ │ │ │ ├── UnsupportedProposalTransitionException.java │ │ │ │ ├── ProposalRepository.java │ │ │ │ ├── events │ │ │ │ │ ├── ProposalApprovedEvent.java │ │ │ │ │ ├── ProposalRejectedEvent.java │ │ │ │ │ └── ProposalAssignedEvent.java │ │ │ │ ├── NoAssignmentPolicy.java │ │ │ │ ├── ReviewerAssignmentPolicyFactory.java │ │ │ │ └── Assignment.java │ │ │ ├── eventid │ │ │ │ └── EventId.java │ │ │ └── eventregistry │ │ │ │ └── EventRegistry.java │ │ │ ├── ReviewsApplication.java │ │ │ └── query │ │ │ └── proposal │ │ │ ├── ProposalViewRepository.java │ │ │ └── ProposalQueryService.java │ │ └── resources │ │ └── application.yml └── sonar-project.properties ├── training-offer ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── smalaca │ │ │ │ └── trainingoffer │ │ │ │ ├── domain │ │ │ │ ├── trainingoffer │ │ │ │ │ ├── TrainingOfferStatus.java │ │ │ │ │ ├── events │ │ │ │ │ │ ├── TrainingOfferEvent.java │ │ │ │ │ │ ├── TrainingPriceNotChangedEvent.java │ │ │ │ │ │ ├── TrainingPlaceBookedEvent.java │ │ │ │ │ │ ├── NoAvailableTrainingPlacesLeftEvent.java │ │ │ │ │ │ └── TrainingPriceChangedEvent.java │ │ │ │ │ ├── RescheduledTrainingOffer.java │ │ │ │ │ ├── commands │ │ │ │ │ │ ├── BookTrainingPlaceCommand.java │ │ │ │ │ │ ├── ConfirmTrainingPriceCommand.java │ │ │ │ │ │ └── RescheduleTrainingOfferCommand.java │ │ │ │ │ ├── TrainingOfferRepository.java │ │ │ │ │ └── TrainingOfferDomainService.java │ │ │ │ ├── trainingofferdraft │ │ │ │ │ ├── TrainingOfferDraftAlreadyPublishedException.java │ │ │ │ │ ├── TrainingOfferDraftRepository.java │ │ │ │ │ └── commands │ │ │ │ │ │ └── CreateTrainingOfferDraftCommand.java │ │ │ │ ├── eventid │ │ │ │ │ └── EventId.java │ │ │ │ ├── eventregistry │ │ │ │ │ └── EventRegistry.java │ │ │ │ └── commandid │ │ │ │ │ └── CommandId.java │ │ │ │ ├── infrastructure │ │ │ │ ├── outbox │ │ │ │ │ └── jpa │ │ │ │ │ │ ├── InvalidOutboxMessageException.java │ │ │ │ │ │ ├── SpringOutboxMessageCrudRepository.java │ │ │ │ │ │ ├── JpaOutboxMessageRepositoryFactory.java │ │ │ │ │ │ └── OutboxMessagePublisherFactory.java │ │ │ │ ├── repository │ │ │ │ │ └── jpa │ │ │ │ │ │ ├── trainingoffer │ │ │ │ │ │ ├── SpringTrainingOfferCrudRepository.java │ │ │ │ │ │ └── TrainingOfferDoesNotExistException.java │ │ │ │ │ │ └── trainingofferdraft │ │ │ │ │ │ ├── SpringTrainingOfferDraftCrudRepository.java │ │ │ │ │ │ └── TrainingOfferDraftDoesNotExistException.java │ │ │ │ └── api │ │ │ │ │ ├── rest │ │ │ │ │ └── trainingoffer │ │ │ │ │ │ └── RescheduleTrainingOfferDto.java │ │ │ │ │ └── eventlistener │ │ │ │ │ └── spring │ │ │ │ │ └── TrainingOfferListener.java │ │ │ │ ├── query │ │ │ │ └── trainingofferdraft │ │ │ │ │ ├── TrainingOfferDraftViewRepository.java │ │ │ │ │ └── TrainingOfferDraftQueryService.java │ │ │ │ ├── TrainingOfferApplication.java │ │ │ │ └── application │ │ │ │ ├── trainingofferdraft │ │ │ │ └── TrainingOfferDraftApplicationServiceFactory.java │ │ │ │ └── trainingoffer │ │ │ │ └── TrainingOfferApplicationServiceFactory.java │ │ └── resources │ │ │ └── application.yml │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── trainingoffer │ │ ├── client │ │ └── trainingoffer │ │ │ ├── trainingoffer │ │ │ ├── RescheduleTrainingOfferTestDto.java │ │ │ └── RestTrainingOfferTestResponseAssertion.java │ │ │ ├── trainingofferdraft │ │ │ ├── CreateTrainingOfferDraftTestCommand.java │ │ │ └── RestTrainingOfferDraftTestDto.java │ │ │ └── TrainingOfferTestClient.java │ │ ├── domain │ │ ├── price │ │ │ └── PriceTest.java │ │ ├── trainingsessionperiod │ │ │ └── TrainingSessionPeriodTest.java │ │ └── trainingofferdraft │ │ │ └── GivenTrainingOfferDraftWithRepository.java │ │ └── infrastructure │ │ ├── outbox │ │ └── jpa │ │ │ └── OutboxMessageTest.java │ │ └── repository │ │ └── jpa │ │ └── trainingoffer │ │ └── SpringTrainingOfferCrudTestRepository.java └── sonar-project.properties ├── trainings-catalogue ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── smalaca │ │ │ │ └── trainingscatalogue │ │ │ │ ├── trainingprogram │ │ │ │ ├── TrainingProgramSummary.java │ │ │ │ ├── JpaTrainingProgramRepository.java │ │ │ │ └── TrainingProgramService.java │ │ │ │ ├── trainingoffer │ │ │ │ ├── TrainingOfferSummary.java │ │ │ │ ├── TrainingOfferDetail.java │ │ │ │ └── TrainingOfferService.java │ │ │ │ ├── TrainingsCatalogueApplication.java │ │ │ │ └── api │ │ │ │ └── kafka │ │ │ │ ├── TrainingOfferKafkaListener.java │ │ │ │ └── TrainingProgramKafkaListener.java │ │ └── resources │ │ │ └── application.yml │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── trainingscatalogue │ │ └── client │ │ └── trainingcatalogue │ │ ├── RestTrainingProgramSummaryTestDto.java │ │ ├── RestTrainingOfferSummaryTestDto.java │ │ ├── RestTrainingProgramTestDto.java │ │ ├── TrainingCatalogueTestClient.java │ │ └── RestTrainingOfferDetailTestDto.java └── sonar-project.properties ├── schema-registry ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── smalaca │ │ │ └── schemaregistry │ │ │ ├── reviews │ │ │ ├── events │ │ │ │ ├── ProposalApprovedEvent.java │ │ │ │ ├── ProposalRejectedEvent.java │ │ │ │ └── ProposalAssignedEvent.java │ │ │ └── commands │ │ │ │ └── RegisterProposalCommand.java │ │ │ ├── trainingoffer │ │ │ ├── events │ │ │ │ ├── TrainingPriceNotChangedEvent.java │ │ │ │ ├── TrainingPlaceBookedEvent.java │ │ │ │ ├── NoAvailableTrainingPlacesLeftEvent.java │ │ │ │ ├── TrainingPriceChangedEvent.java │ │ │ │ ├── TrainingOfferPublishedEvent.java │ │ │ │ └── TrainingOfferRescheduledEvent.java │ │ │ └── commands │ │ │ │ ├── BookTrainingPlaceCommand.java │ │ │ │ └── ConfirmTrainingPriceCommand.java │ │ │ ├── offeracceptancesaga │ │ │ ├── events │ │ │ │ ├── PersonRegisteredEvent.java │ │ │ │ ├── AlreadyRegisteredPersonFoundEvent.java │ │ │ │ ├── DiscountCodeReturnedEvent.java │ │ │ │ ├── DiscountCodeAlreadyUsedEvent.java │ │ │ │ └── DiscountCodeUsedEvent.java │ │ │ └── commands │ │ │ │ ├── ReturnDiscountCodeCommand.java │ │ │ │ ├── RegisterPersonCommand.java │ │ │ │ └── UseDiscountCodeCommand.java │ │ │ ├── trainingprogram │ │ │ └── events │ │ │ │ ├── TrainingProgramRejectedEvent.java │ │ │ │ ├── TrainingProgramProposalReleaseFailedEvent.java │ │ │ │ └── TrainingProgramReleasedEvent.java │ │ │ └── metadata │ │ │ ├── CommandId.java │ │ │ └── EventId.java │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── schemaregistry │ │ ├── reviews │ │ └── events │ │ │ ├── ProposalApprovedEventTest.java │ │ │ ├── ProposalRejectedEventTest.java │ │ │ └── ProposalAssignedEventTest.java │ │ ├── offeracceptancesaga │ │ └── events │ │ │ ├── PersonRegisteredEventTest.java │ │ │ └── AlreadyRegisteredPersonFoundEventTest.java │ │ ├── trainingoffer │ │ ├── events │ │ │ ├── TrainingPriceNotChangedEventTest.java │ │ │ └── TrainingPlaceBookedEventTest.java │ │ └── commands │ │ │ └── BookTrainingPlaceCommandTest.java │ │ └── trainingprogram │ │ └── events │ │ └── TrainingProgramRejectedEventTest.java └── sonar-project.properties ├── training-programs ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── smalaca │ │ │ │ └── trainingprograms │ │ │ │ ├── infrastructure │ │ │ │ ├── outbox │ │ │ │ │ └── jpa │ │ │ │ │ │ ├── InvalidOutboxMessageException.java │ │ │ │ │ │ ├── SpringOutboxMessageCrudRepository.java │ │ │ │ │ │ ├── JpaOutboxMessageRepositoryFactory.java │ │ │ │ │ │ ├── OutboxMessagePublisherFactory.java │ │ │ │ │ │ └── JpaOutboxMessageRepository.java │ │ │ │ ├── api │ │ │ │ │ └── eventpublisher │ │ │ │ │ │ └── kafka │ │ │ │ │ │ └── trainingprogram │ │ │ │ │ │ └── Topics.java │ │ │ │ └── repository │ │ │ │ │ └── jpa │ │ │ │ │ ├── trainingprogram │ │ │ │ │ ├── SpringTrainingProgramCrudRepository.java │ │ │ │ │ └── JpaTrainingProgramRepository.java │ │ │ │ │ └── trainingprogramproposal │ │ │ │ │ ├── SpringTrainingProgramProposalCrudRepository.java │ │ │ │ │ └── TrainingProgramProposalDoesNotExistException.java │ │ │ │ ├── domain │ │ │ │ ├── eventregistry │ │ │ │ │ └── EventRegistry.java │ │ │ │ ├── trainingprogramproposal │ │ │ │ │ ├── TrainingProgramProposalStatus.java │ │ │ │ │ ├── events │ │ │ │ │ │ ├── TrainingProgramProposalEvent.java │ │ │ │ │ │ ├── TrainingProgramRejectedEvent.java │ │ │ │ │ │ └── TrainingProgramProposalReleaseFailedEvent.java │ │ │ │ │ ├── TrainingProgramContent.java │ │ │ │ │ ├── commands │ │ │ │ │ │ └── CreateTrainingProgramProposalCommand.java │ │ │ │ │ ├── TrainingProgramProposalRepository.java │ │ │ │ │ ├── TrainingProgramProposalReviewSpecification.java │ │ │ │ │ ├── TrainingProgramProposalReviewSpecificationFactory.java │ │ │ │ │ └── TrainingProgramProposalFactory.java │ │ │ │ ├── trainingprogram │ │ │ │ │ └── TrainingProgramRepository.java │ │ │ │ ├── commandid │ │ │ │ │ └── CommandId.java │ │ │ │ └── eventid │ │ │ │ │ └── EventId.java │ │ │ │ ├── query │ │ │ │ └── trainingprogramproposal │ │ │ │ │ ├── TrainingProgramProposalViewRepository.java │ │ │ │ │ └── TrainingProgramProposalQueryService.java │ │ │ │ └── TrainingProgramsApplication.java │ │ └── resources │ │ │ └── application.yml │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── trainingprograms │ │ ├── client │ │ └── trainingprogram │ │ │ ├── trainingprogramproposal │ │ │ └── RestTrainingProgramProposalTestDto.java │ │ │ └── TrainingProgramTestClient.java │ │ ├── infrastructure │ │ └── outbox │ │ │ └── jpa │ │ │ └── OutboxMessageTest.java │ │ └── architecture │ │ └── NoCyclesTest.java └── sonar-project.properties ├── annotations-test └── src │ └── main │ └── java │ └── com │ └── smalaca │ └── test │ └── type │ ├── IntegrationTest.java │ ├── RepositoryTest.java │ ├── SpringBootIntegrationTest.java │ └── SystemTest.java ├── personal-data-management ├── src │ ├── main │ │ ├── resources │ │ │ └── application.yml │ │ └── java │ │ │ └── com │ │ │ └── smalaca │ │ │ └── personaldatamanagement │ │ │ └── PersonalDataManagementApplication.java │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── personaldatamanagement │ │ └── api │ │ └── EventIdAssertion.java └── sonar-project.properties ├── discount-management ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── smalaca │ │ │ │ └── discountmanagement │ │ │ │ └── DiscountManagementApplication.java │ │ └── resources │ │ │ └── application.yml │ └── test │ │ └── java │ │ └── com │ │ └── smalaca │ │ └── discountmanagement │ │ └── api │ │ └── EventIdAssertion.java └── sonar-project.properties ├── .gitignore ├── documentation └── architecture-decision-record │ └── template.md └── pom.xml /annotations/src/main/java/com/smalaca/domaindrivendesign/Policy.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface Policy { 4 | } -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/Saga.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface Saga { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/Factory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface Factory { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/Specification.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface Specification { 4 | } -------------------------------------------------------------------------------- /payment-gateway/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9010 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/cqrs/QueryOperation.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.cqrs; 2 | 3 | public @interface QueryOperation { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/AggregateRoot.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface AggregateRoot { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/DomainEntity.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface DomainEntity { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/DomainEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface DomainEvent { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/DomainService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface DomainService { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/ValueObject.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface ValueObject { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/cqrs/CommandOperation.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.cqrs; 2 | 3 | public @interface CommandOperation { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/ApplicationLayer.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface ApplicationLayer { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/domaindrivendesign/DomainRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.domaindrivendesign; 2 | 3 | public @interface DomainRepository { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/portsandadapters/DrivenPort.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.portsandadapters; 2 | 3 | public @interface DrivenPort { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/portsandadapters/DrivingPort.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.portsandadapters; 2 | 3 | public @interface DrivingPort { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/portsandadapters/DrivenAdapter.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.portsandadapters; 2 | 3 | public @interface DrivenAdapter { 4 | } 5 | -------------------------------------------------------------------------------- /annotations/src/main/java/com/smalaca/architecture/portsandadapters/DrivingAdapter.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.architecture.portsandadapters; 2 | 3 | public @interface DrivingAdapter { 4 | } 5 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/OfferAcceptanceSagaStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga; 2 | 3 | enum OfferAcceptanceSagaStatus { 4 | IN_PROGRESS, ACCEPTED, REJECTED 5 | } 6 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/application/order/ConfirmOrderCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.application.order; 2 | 3 | import java.util.UUID; 4 | 5 | public record ConfirmOrderCommand(UUID orderId, String paymentMethod) { 6 | } 7 | -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/client/reviews/proposal/CompleteReviewTestCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.client.reviews.proposal; 2 | 3 | import java.util.UUID; 4 | 5 | public record CompleteReviewTestCommand(UUID proposalId, UUID reviewerId) { 6 | } 7 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/api/rest/proposal/CompleteReviewCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.api.rest.proposal; 2 | 3 | import java.util.UUID; 4 | 5 | public record CompleteReviewCommand(UUID proposalId, UUID reviewerId) { 6 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/events/OfferEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | 5 | public interface OfferEvent { 6 | EventId eventId(); 7 | } 8 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/events/OrderEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | 5 | public interface OrderEvent { 6 | EventId eventId(); 7 | } 8 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/trainerscatalogue/Trainer.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.trainerscatalogue; 2 | 3 | import java.util.Set; 4 | import java.util.UUID; 5 | 6 | public record Trainer(UUID id, Set categoryIds, Set assignmentsIds) { 7 | } 8 | -------------------------------------------------------------------------------- /payment-gateway/src/main/java/com/smalaca/paymentgateway/api/PaymentResponse.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.paymentgateway.api; 2 | 3 | public record PaymentResponse(boolean isSuccessful) { 4 | public static PaymentResponse successful() { 5 | return new PaymentResponse(true); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/client/opentrainings/order/RestConfirmOrderTestCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.client.opentrainings.order; 2 | 3 | import java.util.UUID; 4 | 5 | public record RestConfirmOrderTestCommand(UUID orderId, String paymentMethod) { 6 | } 7 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/TrainingOfferStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | 5 | @ValueObject 6 | enum TrainingOfferStatus { 7 | PUBLISHED, RESCHEDULED 8 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/clock/Clock.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.clock; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | @DrivenPort 8 | public interface Clock { 9 | LocalDateTime now(); 10 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/commandid/CommandId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.commandid; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record CommandId(UUID commandId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 7 | 8 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/events/TrainingOfferEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.events; 2 | 3 | import com.smalaca.trainingoffer.domain.eventid.EventId; 4 | 5 | public interface TrainingOfferEvent { 6 | EventId eventId(); 7 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/api/eventpublisher/kafka/order/Topics.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.api.eventpublisher.kafka.order; 2 | 3 | record Topics(String trainingPurchased, String orderRejected, String orderTerminated, String orderCancelled) { 4 | } 5 | -------------------------------------------------------------------------------- /payment-gateway/src/main/java/com/smalaca/paymentgateway/api/PaymentRequest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.paymentgateway.api; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.UUID; 5 | 6 | public record PaymentRequest(UUID orderId, UUID participantId, String paymentMethod, BigDecimal amount, String currency) { 7 | } 8 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/clock/Clock.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.clock; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | @DrivenPort 8 | public interface Clock { 9 | LocalDateTime now(); 10 | } 11 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/OfferAcceptanceSagaDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga; 2 | 3 | import java.util.UUID; 4 | 5 | public record OfferAcceptanceSagaDto(UUID offerId, boolean isCompleted, String status, String rejectionReason) { 6 | } 7 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/ProposalStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | 5 | @ValueObject 6 | enum ProposalStatus { 7 | REGISTERED, 8 | QUEUED, 9 | ASSIGNED, 10 | APPROVED, 11 | REJECTED 12 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/client/opentrainings/offer/RestOfferAcceptanceTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.client.opentrainings.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public record RestOfferAcceptanceTestDto(UUID offerId, boolean isCompleted, String status, String rejectionReason) { 6 | } 7 | -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingprogram/TrainingProgramSummary.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingprogram; 2 | 3 | import java.util.UUID; 4 | 5 | public interface TrainingProgramSummary { 6 | UUID getTrainingProgramId(); 7 | UUID getAuthorId(); 8 | String getName(); 9 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/reviews/events/ProposalApprovedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record ProposalApprovedEvent(EventId eventId, UUID proposalId, UUID reviewerId) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/reviews/events/ProposalRejectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record ProposalRejectedEvent(EventId eventId, UUID proposalId, UUID reviewerId) { 8 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/test/java/com/smalaca/trainingscatalogue/client/trainingcatalogue/RestTrainingProgramSummaryTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.client.trainingcatalogue; 2 | 3 | import java.util.UUID; 4 | 5 | public record RestTrainingProgramSummaryTestDto(UUID trainingProgramId, UUID authorId, String name) { 6 | 7 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/paymentgateway/PaymentGateway.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.paymentgateway; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | @DrivenPort 6 | public interface PaymentGateway { 7 | PaymentResponse pay(PaymentRequest paymentRequest); 8 | } 9 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/client/opentrainings/offer/RestAcceptOfferTestCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.client.opentrainings.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public record RestAcceptOfferTestCommand(UUID offerId, String firstName, String lastName, String email, String discountCode) { 6 | } 7 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/reviews/events/ProposalAssignedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record ProposalAssignedEvent(EventId eventId, UUID proposalId, UUID assignedReviewerId) { 8 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/api/eventpublisher/kafka/offer/Topics.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.api.eventpublisher.kafka.offer; 2 | 3 | record Topics(String registerPerson, String useDiscountCode, String confirmTrainingPrice, String bookTrainingPlace, String returnDiscountCode) { 4 | } 5 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/OfferAcceptanceSagaCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | 5 | public interface OfferAcceptanceSagaCommand { 6 | CommandId commandId(); 7 | } 8 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/trainerscatalogue/TrainersCatalogue.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.trainerscatalogue; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | import java.util.List; 6 | 7 | @DrivenPort 8 | public interface TrainersCatalogue { 9 | List findAllTrainers(); 10 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/outbox/jpa/InvalidOutboxMessageException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.outbox.jpa; 2 | 3 | public class InvalidOutboxMessageException extends RuntimeException { 4 | InvalidOutboxMessageException(Exception exception) { 5 | super(exception); 6 | } 7 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/InvalidOutboxMessageException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | public class InvalidOutboxMessageException extends RuntimeException { 4 | InvalidOutboxMessageException(Exception exception) { 5 | super(exception); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingPriceNotChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record TrainingPriceNotChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId) { 8 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/InvalidOutboxMessageException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | public class InvalidOutboxMessageException extends RuntimeException { 4 | InvalidOutboxMessageException(Exception exception) { 5 | super(exception); 6 | } 7 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/events/PersonRegisteredEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record PersonRegisteredEvent(EventId eventId, UUID offerId, UUID participantId) { 8 | } 9 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/eventregistry/EventRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.eventregistry; 2 | 3 | import com.smalaca.trainingprograms.domain.trainingprogramproposal.events.TrainingProgramProposalEvent; 4 | 5 | public interface EventRegistry { 6 | void publish(TrainingProgramProposalEvent event); 7 | } 8 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/paymentgateway/RestPaymentRequest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.paymentgateway; 2 | 3 | import java.math.BigDecimal; 4 | import java.util.UUID; 5 | 6 | record RestPaymentRequest( 7 | UUID orderId, UUID participantId, String paymentMethod, BigDecimal amount, String currency) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingPlaceBookedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record TrainingPlaceBookedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) { 8 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/RescheduledTrainingOffer.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.domain.trainingoffer.events.TrainingOfferRescheduledEvent; 4 | 5 | public record RescheduledTrainingOffer(TrainingOffer trainingOffer, TrainingOfferRescheduledEvent event) { 6 | } 7 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramProposalStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | 5 | @ValueObject 6 | public enum TrainingProgramProposalStatus { 7 | PROPOSED, RELEASED, REJECTED, RELEASE_FAILED 8 | } 9 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/AvailableOfferException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public class AvailableOfferException extends RuntimeException { 6 | AvailableOfferException(UUID offerId) { 7 | super("Offer: " + offerId + " still available."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/ReviewerAssignmentPolicy.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import com.smalaca.domaindrivendesign.Policy; 4 | 5 | import java.util.Set; 6 | import java.util.UUID; 7 | 8 | @Policy 9 | public interface ReviewerAssignmentPolicy { 10 | Assignment assign(UUID authorId, Set categoriesIds); 11 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/query/trainingofferdraft/TrainingOfferDraftViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.query.trainingofferdraft; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.UUID; 6 | 7 | interface TrainingOfferDraftViewRepository extends CrudRepository { 8 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/api/eventpublisher/kafka/trainingprogram/Topics.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.api.eventpublisher.kafka.trainingprogram; 2 | 3 | record Topics(String registerProposal, String trainingProgramReleased, String trainingProgramRejected, String trainingProgramProposalReleaseFailed) { 4 | } 5 | -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/domain/proposal/GivenProposalFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | public class GivenProposalFactory { 4 | public static GivenProposalFactory create() { 5 | return new GivenProposalFactory(); 6 | } 7 | 8 | public GivenProposal proposal() { 9 | return new GivenProposal(); 10 | } 11 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/events/AlreadyRegisteredPersonFoundEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record AlreadyRegisteredPersonFoundEvent(EventId eventId, UUID offerId, UUID participantId) { 8 | } 9 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/events/DiscountCodeReturnedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record DiscountCodeReturnedEvent(EventId eventId, UUID offerId, UUID participantId, String discountCode) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/commands/BookTrainingPlaceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.util.UUID; 6 | 7 | public record BookTrainingPlaceCommand(CommandId commandId, UUID offerId, UUID participantId, UUID trainingOfferId) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingprogram/events/TrainingProgramRejectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingprogram.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record TrainingProgramRejectedEvent(EventId eventId, UUID trainingProgramProposalId, UUID reviewerId) { 8 | 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderInFinalStateException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import java.util.UUID; 4 | 5 | public class OrderInFinalStateException extends RuntimeException { 6 | OrderInFinalStateException(UUID orderId, OrderStatus status) { 7 | super("Order: " + orderId + " already " + status); 8 | } 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | 5 | @ValueObject 6 | enum OrderStatus { 7 | INITIATED, CONFIRMED, CANCELLED, TERMINATED, REJECTED; 8 | 9 | boolean isFinal() { 10 | return this != INITIATED; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/paymentmethod/UnsupportedPaymentMethodException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.paymentmethod; 2 | 3 | public class UnsupportedPaymentMethodException extends RuntimeException { 4 | UnsupportedPaymentMethodException(String paymentMethod) { 5 | super("Unsupported payment method: " + paymentMethod); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/commands/ReturnDiscountCodeCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.util.UUID; 6 | 7 | public record ReturnDiscountCodeCommand(CommandId commandId, UUID offerId, UUID participantId, String discountCode) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/NoAvailableTrainingPlacesLeftEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record NoAvailableTrainingPlacesLeftEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) { 8 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/commands/RegisterPersonCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.util.UUID; 6 | 7 | public record RegisterPersonCommand(CommandId commandId, UUID offerId, String firstName, String lastName, String email) { 8 | } 9 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/commands/BookTrainingPlaceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.commands; 2 | 3 | import com.smalaca.trainingoffer.domain.commandid.CommandId; 4 | 5 | import java.util.UUID; 6 | 7 | public record BookTrainingPlaceCommand(CommandId commandId, UUID offerId, UUID participantId, UUID trainingOfferId) { 8 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/trainingoffercatalogue/TrainingOfferCatalogue.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.trainingoffercatalogue; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | import java.util.UUID; 6 | 7 | @DrivenPort 8 | public interface TrainingOfferCatalogue { 9 | TrainingDto detailsOf(UUID trainingId); 10 | } 11 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/events/DiscountCodeAlreadyUsedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record DiscountCodeAlreadyUsedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingId, String discountCode) { 8 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/query/trainingprogramproposal/TrainingProgramProposalViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.query.trainingprogramproposal; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.UUID; 6 | 7 | interface TrainingProgramProposalViewRepository extends CrudRepository { 8 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/repository/jpa/proposal/SpringProposalCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.repository.jpa.proposal; 2 | 3 | import com.smalaca.reviews.domain.proposal.Proposal; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | interface SpringProposalCrudRepository extends CrudRepository { 9 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/commands/RegisterProposalCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal.commands; 2 | 3 | import com.smalaca.reviews.domain.commandid.CommandId; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public record RegisterProposalCommand(CommandId commandId, UUID proposalId, UUID authorId, String title, String content, List categoriesIds) { 9 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/events/TrainingProgramProposalEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingprograms.domain.eventid.EventId; 5 | 6 | @DomainEvent 7 | public interface TrainingProgramProposalEvent { 8 | EventId eventId(); 9 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/test/java/com/smalaca/trainingscatalogue/client/trainingcatalogue/RestTrainingOfferSummaryTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.client.trainingcatalogue; 2 | 3 | import java.time.LocalDate; 4 | import java.util.UUID; 5 | 6 | public record RestTrainingOfferSummaryTestDto( 7 | UUID trainingOfferId, UUID trainerId, String trainingProgramName, LocalDate startDate, LocalDate endDate) { 8 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/repository/jpa/proposal/ProposalDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.repository.jpa.proposal; 2 | 3 | import java.util.UUID; 4 | 5 | public class ProposalDoesNotExistException extends RuntimeException { 6 | ProposalDoesNotExistException(UUID proposalId) { 7 | super("Proposal with id " + proposalId + " does not exist."); 8 | } 9 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/reviews/commands/RegisterProposalCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public record RegisterProposalCommand(CommandId commandId, UUID proposalId, UUID authorId, String title, String content, List categoriesIds) { 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offeracceptancesaga/InvalidOfferAcceptanceSagaEventException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offeracceptancesaga; 2 | 3 | public class InvalidOfferAcceptanceSagaEventException extends RuntimeException { 4 | InvalidOfferAcceptanceSagaEventException(Exception exception) { 5 | super(exception); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingprogram/events/TrainingProgramProposalReleaseFailedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingprogram.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.UUID; 6 | 7 | public record TrainingProgramProposalReleaseFailedEvent( 8 | EventId eventId, UUID trainingProgramProposalId, UUID reviewerId) { 9 | 10 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramContent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | import java.util.List; 4 | import java.util.UUID; 5 | 6 | public record TrainingProgramContent( 7 | String name, 8 | String description, 9 | String agenda, 10 | String plan, 11 | List categoriesIds 12 | ) { 13 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offer/OfferDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public class OfferDoesNotExistException extends RuntimeException { 6 | OfferDoesNotExistException(UUID offerId) { 7 | super("Offer with id " + offerId + " does not exist."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/order/OrderDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.order; 2 | 3 | import java.util.UUID; 4 | 5 | public class OrderDoesNotExistException extends RuntimeException { 6 | OrderDoesNotExistException(UUID orderId) { 7 | super("Order with id " + orderId + " does not exist."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingPriceChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.UUID; 7 | 8 | public record TrainingPriceChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) { 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderTerminationNotYetPermittedException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import java.util.UUID; 4 | 5 | public class OrderTerminationNotYetPermittedException extends RuntimeException { 6 | OrderTerminationNotYetPermittedException(UUID orderId) { 7 | super("Order with id " + orderId + " cannot be terminated yet."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/paymentgateway/PaymentResponse.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.paymentgateway; 2 | 3 | public record PaymentResponse(boolean isSuccessful) { 4 | public static PaymentResponse successful() { 5 | return new PaymentResponse(true); 6 | } 7 | 8 | public static PaymentResponse failed() { 9 | return new PaymentResponse(false); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offer/SpringOfferCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offer; 2 | 3 | import com.smalaca.opentrainings.domain.offer.Offer; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface SpringOfferCrudRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/order/SpringOrderCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.order; 2 | 3 | import com.smalaca.opentrainings.domain.order.Order; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface SpringOrderCrudRepository extends CrudRepository { 9 | } 10 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/commandregistry/CommandRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.commandregistry; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.commands.OfferAcceptanceSagaCommand; 5 | 6 | @DrivenPort 7 | public interface CommandRegistry { 8 | void publish(OfferAcceptanceSagaCommand command); 9 | } 10 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/commands/ConfirmTrainingPriceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.UUID; 7 | 8 | public record ConfirmTrainingPriceCommand(CommandId commandId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) { 9 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogram/TrainingProgramRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogram; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | @DomainRepository 7 | @DrivenPort 8 | public interface TrainingProgramRepository { 9 | void save(TrainingProgram trainingProgram); 10 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingoffer/TrainingOfferSummary.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingoffer; 2 | 3 | import java.time.LocalDate; 4 | import java.util.UUID; 5 | 6 | public interface TrainingOfferSummary { 7 | UUID getTrainingOfferId(); 8 | UUID getTrainerId(); 9 | String getTrainingProgramName(); 10 | LocalDate getStartDate(); 11 | LocalDate getEndDate(); 12 | } 13 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/trainingoffercatalogue/TrainingDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.trainingoffercatalogue; 2 | 3 | import com.smalaca.opentrainings.domain.price.Price; 4 | 5 | import java.util.UUID; 6 | 7 | public record TrainingDto(UUID trainingId, int availablePlaces, Price price) { 8 | public boolean hasNoAvailablePlaces() { 9 | return availablePlaces == 0; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/UnsupportedProposalTransitionException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import java.util.UUID; 4 | 5 | public class UnsupportedProposalTransitionException extends RuntimeException { 6 | UnsupportedProposalTransitionException(UUID proposalId, ProposalStatus status) { 7 | super("Cannot transition proposal with id: " + proposalId + " from status: " + status.name()); 8 | } 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/OfferRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DrivenPort 9 | @DomainRepository 10 | public interface OfferRepository { 11 | Offer findById(UUID offerId); 12 | 13 | UUID save(Offer offer); 14 | } 15 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainRepository 9 | @DrivenPort 10 | public interface OrderRepository { 11 | Order findById(UUID orderId); 12 | 13 | UUID save(Order order); 14 | } 15 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/SpringOutboxMessageCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | interface SpringOutboxMessageCrudRepository extends CrudRepository { 9 | List findByIsPublishedFalse(); 10 | } 11 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/commands/ConfirmTrainingPriceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.commands; 2 | 3 | import com.smalaca.trainingoffer.domain.commandid.CommandId; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.UUID; 7 | 8 | public record ConfirmTrainingPriceCommand(CommandId commandId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) { 9 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/outbox/jpa/SpringOutboxMessageCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.outbox.jpa; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | interface SpringOutboxMessageCrudRepository extends CrudRepository { 9 | List findByIsPublishedFalse(); 10 | } 11 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/client/trainingoffer/trainingoffer/RescheduleTrainingOfferTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.client.trainingoffer.trainingoffer; 2 | 3 | import java.time.LocalDate; 4 | import java.time.LocalTime; 5 | import java.util.UUID; 6 | 7 | public record RescheduleTrainingOfferTestDto( 8 | UUID trainingOfferId, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 9 | } 10 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/price/PriceTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.price; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class PriceTest { 7 | @Test 8 | void shouldFulfillEqualsContract() { 9 | EqualsVerifier.simple().forClass(Price.class) 10 | .withNonnullFields("amount", "currency") 11 | .verify(); 12 | } 13 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/ProposalRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainRepository 9 | @DrivenPort 10 | public interface ProposalRepository { 11 | void save(Proposal proposal); 12 | 13 | Proposal findById(UUID proposalId); 14 | } 15 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/domain/price/PriceTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.price; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class PriceTest { 7 | @Test 8 | void shouldFulfillEqualsContract() { 9 | EqualsVerifier.simple().forClass(Price.class) 10 | .withNonnullFields("amount", "currency") 11 | .verify(); 12 | } 13 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/SpringOutboxMessageCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | interface SpringOutboxMessageCrudRepository extends CrudRepository { 9 | List findByIsPublishedFalse(); 10 | } -------------------------------------------------------------------------------- /annotations-test/src/main/java/com/smalaca/test/type/IntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.test.type; 2 | 3 | import org.junit.jupiter.api.Tag; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target(ElementType.TYPE) 12 | @Tag("IntegrationTest") 13 | public @interface IntegrationTest { 14 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/repository/jpa/trainingoffer/SpringTrainingOfferCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.repository.jpa.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.domain.trainingoffer.TrainingOffer; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | interface SpringTrainingOfferCrudRepository extends CrudRepository { 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/OfferAcceptanceSagaRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | 5 | import java.util.UUID; 6 | 7 | @DrivenPort 8 | public interface OfferAcceptanceSagaRepository { 9 | OfferAcceptanceSaga findById(UUID offerId); 10 | 11 | void save(OfferAcceptanceSaga offerAcceptanceSaga); 12 | } 13 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/OfferAcceptanceSagaEventRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceSagaEvent; 5 | 6 | @DrivenPort 7 | public interface OfferAcceptanceSagaEventRegistry { 8 | void publish(OfferAcceptanceSagaEvent event); 9 | } 10 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/commands/UseDiscountCodeCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.UUID; 7 | 8 | public record UseDiscountCodeCommand(CommandId commandId, UUID offerId, UUID participantId, UUID trainingId, BigDecimal priceAmount, String priceCurrencyCode, String discountCode) { 9 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingofferdraft/TrainingOfferDraftAlreadyPublishedException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingofferdraft; 2 | 3 | import java.util.UUID; 4 | 5 | public class TrainingOfferDraftAlreadyPublishedException extends RuntimeException { 6 | TrainingOfferDraftAlreadyPublishedException(UUID trainingOfferDraftId) { 7 | super("Training offer draft: " + trainingOfferDraftId + " already published."); 8 | } 9 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/repository/jpa/trainingoffer/TrainingOfferDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.repository.jpa.trainingoffer; 2 | 3 | import java.util.UUID; 4 | 5 | public class TrainingOfferDoesNotExistException extends RuntimeException { 6 | TrainingOfferDoesNotExistException(UUID trainingOfferId) { 7 | super("Training Offer with id " + trainingOfferId + " does not exist."); 8 | } 9 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/TrainingsCatalogueApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class TrainingsCatalogueApplication { 8 | public static void main(String[] args) { 9 | SpringApplication.run(TrainingsCatalogueApplication.class, args); 10 | } 11 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/offeracceptancesaga/events/DiscountCodeUsedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.UUID; 7 | 8 | public record DiscountCodeUsedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingId, String discountCode, BigDecimal originalPrice, BigDecimal newPrice, String priceCurrency) { 9 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/commandid/CommandId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.commandid; 2 | 3 | import com.smalaca.trainingprograms.domain.eventid.EventId; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.UUID; 7 | 8 | public record CommandId(UUID commandId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 9 | public EventId nextEventId() { 10 | return EventId.nextAfter(this); 11 | } 12 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/NoAvailablePlacesException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public class NoAvailablePlacesException extends RuntimeException { 6 | private final UUID trainingId; 7 | 8 | NoAvailablePlacesException(UUID trainingId) { 9 | this.trainingId = trainingId; 10 | } 11 | 12 | public UUID getTrainingId() { 13 | return trainingId; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/client/opentrainings/offer/RestOfferTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.client.opentrainings.offer; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDateTime; 5 | import java.util.UUID; 6 | 7 | public record RestOfferTestDto( 8 | UUID offerId, UUID trainingId, String offerNumber, BigDecimal trainingPriceAmount, String trainingPriceCurrency, 9 | LocalDateTime creationDateTime, String status) { 10 | } 11 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/eventregistry/EventRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.eventregistry; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.opentrainings.domain.offer.events.OfferEvent; 5 | import com.smalaca.opentrainings.domain.order.events.OrderEvent; 6 | 7 | @DrivenPort 8 | public interface EventRegistry { 9 | void publish(OrderEvent event); 10 | 11 | void publish(OfferEvent event); 12 | } 13 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/repository/jpa/trainingprogram/SpringTrainingProgramCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.repository.jpa.trainingprogram; 2 | 3 | import com.smalaca.trainingprograms.domain.trainingprogram.TrainingProgram; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface SpringTrainingProgramCrudRepository extends CrudRepository { 9 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/order/DiscountCodeTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class DiscountCodeTest { 7 | @Test 8 | void shouldFulfillEqualsContract() { 9 | EqualsVerifier.simple().forClass(DiscountCode.class) 10 | .withNonnullFields("discountCode", "isUsed", "isAlreadyUsed") 11 | .verify(); 12 | } 13 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/ReviewsApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling 9 | public class ReviewsApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(ReviewsApplication.class, args); 12 | } 13 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/repository/jpa/trainingofferdraft/SpringTrainingOfferDraftCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.repository.jpa.trainingofferdraft; 2 | 3 | import com.smalaca.trainingoffer.domain.trainingofferdraft.TrainingOfferDraft; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface SpringTrainingOfferDraftCrudRepository extends CrudRepository { 9 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/TrainingOfferRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DrivenPort 9 | @DomainRepository 10 | public interface TrainingOfferRepository { 11 | TrainingOffer findById(UUID trainingOfferId); 12 | 13 | void save(TrainingOffer trainingOffer); 14 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/repository/jpa/trainingofferdraft/TrainingOfferDraftDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.repository.jpa.trainingofferdraft; 2 | 3 | import java.util.UUID; 4 | 5 | public class TrainingOfferDraftDoesNotExistException extends RuntimeException { 6 | TrainingOfferDraftDoesNotExistException(UUID trainingOfferDraftId) { 7 | super("Training Offer Draft with id " + trainingOfferDraftId + " does not exist."); 8 | } 9 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/OfferNumber.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | import jakarta.persistence.Embeddable; 5 | 6 | @ValueObject 7 | @Embeddable 8 | class OfferNumber { 9 | private String value; 10 | 11 | OfferNumber(String value) { 12 | this.value = value; 13 | } 14 | 15 | private OfferNumber() {} 16 | 17 | String value() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderNumber.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | import jakarta.persistence.Embeddable; 5 | 6 | @ValueObject 7 | @Embeddable 8 | class OrderNumber { 9 | private String value; 10 | 11 | OrderNumber(String value) { 12 | this.value = value; 13 | } 14 | 15 | private OrderNumber() {} 16 | 17 | String value() { 18 | return value; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/offeracceptancesaga/ConsumedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class ConsumedEventTest { 7 | @Test 8 | void shouldFulfillEqualsContract() { 9 | EqualsVerifier.simple().forClass(ConsumedEvent.class) 10 | .withNonnullFields("eventId", "consumedAt", "event") 11 | .verify(); 12 | } 13 | } -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/client/reviews/proposal/RestProposalTestResponse.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.client.reviews.proposal; 2 | 3 | import org.springframework.mock.web.MockHttpServletResponse; 4 | 5 | public class RestProposalTestResponse { 6 | private final MockHttpServletResponse response; 7 | 8 | RestProposalTestResponse(MockHttpServletResponse response) { 9 | this.response = response; 10 | } 11 | 12 | int getStatus() { 13 | return response.getStatus(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/commands/CreateTrainingProgramProposalCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal.commands; 2 | 3 | import com.smalaca.trainingprograms.domain.commandid.CommandId; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public record CreateTrainingProgramProposalCommand(CommandId commandId, UUID authorId, String name, String description, String agenda, String plan, List categoriesIds) { 9 | } 10 | -------------------------------------------------------------------------------- /trainings-catalogue/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9070 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | kafka: 10 | bootstrap-servers: localhost:9092 11 | group-id: trainings-catalogue 12 | topics: 13 | trainingoffer: 14 | events: 15 | training-offer-published: training-offer-training-offer-published-event-topic 16 | trainingprogram: 17 | events: 18 | training-program-released: training-programs-training-program-released-event-topic -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/OfferStatus.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import com.smalaca.domaindrivendesign.ValueObject; 4 | 5 | @ValueObject 6 | enum OfferStatus { 7 | INITIATED, ACCEPTANCE_IN_PROGRESS, ACCEPTED, REJECTED, DECLINED, TERMINATED; 8 | 9 | boolean isNotInitiated() { 10 | return !INITIATED.equals(this); 11 | } 12 | 13 | boolean isAcceptanceNotInProgress() { 14 | return !ACCEPTANCE_IN_PROGRESS.equals(this); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/TrainingOfferApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling 9 | public class TrainingOfferApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(TrainingOfferApplication.class, args); 12 | } 13 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/OpenTrainingsApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling 9 | public class OpenTrainingsApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(OpenTrainingsApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /training-programs/src/test/java/com/smalaca/trainingprograms/client/trainingprogram/trainingprogramproposal/RestTrainingProgramProposalTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.client.trainingprogram.trainingprogramproposal; 2 | 3 | import java.util.List; 4 | import java.util.UUID; 5 | 6 | public record RestTrainingProgramProposalTestDto( 7 | UUID trainingProgramProposalId, UUID authorId, String name, 8 | String description, String agenda, String plan, UUID reviewerId, 9 | List categoriesIds, String status) { 10 | } 11 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/eventid/EventId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.eventid; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public record EventId(UUID eventId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 7 | public static EventId newEventId(UUID correlationId, LocalDateTime creationDateTime) { 8 | return new EventId(id(), id(), correlationId, creationDateTime); 9 | } 10 | 11 | private static UUID id() { 12 | return UUID.randomUUID(); 13 | } 14 | } -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/domain/proposal/ProposalTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.List; 5 | import java.util.UUID; 6 | 7 | public record ProposalTestDto( 8 | UUID proposalId, UUID authorId, String title, String content, UUID correlationId, LocalDateTime registeredAt, 9 | UUID reviewedById, LocalDateTime reviewedAt, ProposalStatus status, List categoriesIds, UUID assignedReviewerId, 10 | LocalDateTime lastAssignmentDateTime) { 11 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/repository/jpa/trainingprogramproposal/SpringTrainingProgramProposalCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.repository.jpa.trainingprogramproposal; 2 | 3 | import com.smalaca.trainingprograms.domain.trainingprogramproposal.TrainingProgramProposal; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.UUID; 7 | 8 | public interface SpringTrainingProgramProposalCrudRepository extends CrudRepository { 9 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingprogram/events/TrainingProgramReleasedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingprogram.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public record TrainingProgramReleasedEvent( 9 | EventId eventId, UUID trainingProgramProposalId, UUID trainingProgramId, String name, String description, 10 | String agenda, String plan, UUID authorId, UUID reviewerId, List categoriesIds) { 11 | 12 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/eventid/EventId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.eventid; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | import static java.time.LocalDateTime.now; 7 | 8 | public record EventId(UUID eventId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 9 | public static EventId newEventId() { 10 | return new EventId(id(), id(), id(), now()); 11 | } 12 | 13 | private static UUID id() { 14 | return UUID.randomUUID(); 15 | } 16 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingofferdraft/TrainingOfferDraftRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingofferdraft; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DrivenPort 9 | @DomainRepository 10 | public interface TrainingOfferDraftRepository { 11 | TrainingOfferDraft findById(UUID trainingOfferDraftId); 12 | 13 | UUID save(TrainingOfferDraft trainingOfferDraft); 14 | } 15 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/eventregistry/EventRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.eventregistry; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.trainingoffer.domain.trainingoffer.events.TrainingOfferEvent; 5 | import com.smalaca.trainingoffer.domain.trainingofferdraft.events.TrainingOfferPublishedEvent; 6 | 7 | @DrivenPort 8 | public interface EventRegistry { 9 | void publish(TrainingOfferPublishedEvent event); 10 | 11 | void publish(TrainingOfferEvent event); 12 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/TrainingProgramsApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.scheduling.annotation.EnableScheduling; 6 | 7 | @SpringBootApplication 8 | @EnableScheduling 9 | public class TrainingProgramsApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(TrainingProgramsApplication.class, args); 12 | } 13 | } -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/domain/trainingsessionperiod/TrainingSessionPeriodTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingsessionperiod; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import org.junit.jupiter.api.Test; 5 | 6 | class TrainingSessionPeriodTest { 7 | @Test 8 | void shouldFulfillEqualsContract() { 9 | EqualsVerifier.simple().forClass(TrainingSessionPeriod.class) 10 | .withNonnullFields("startDate", "endDate", "startTime", "endTime") 11 | .verify(); 12 | } 13 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/test/java/com/smalaca/trainingscatalogue/client/trainingcatalogue/RestTrainingProgramTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.client.trainingcatalogue; 2 | 3 | import java.util.List; 4 | import java.util.UUID; 5 | 6 | public record RestTrainingProgramTestDto( 7 | UUID trainingProgramId, 8 | UUID trainingProgramProposalId, 9 | UUID authorId, 10 | UUID reviewerId, 11 | String name, 12 | String agenda, 13 | String plan, 14 | String description, 15 | List categoriesIds) { 16 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/clock/localdatetime/LocalDateTimeClock.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.clock.localdatetime; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.reviews.domain.clock.Clock; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Component 10 | @DrivenAdapter 11 | public class LocalDateTimeClock implements Clock { 12 | @Override 13 | public LocalDateTime now() { 14 | return LocalDateTime.now(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/repository/jpa/trainingprogramproposal/TrainingProgramProposalDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.repository.jpa.trainingprogramproposal; 2 | 3 | import java.util.UUID; 4 | 5 | public class TrainingProgramProposalDoesNotExistException extends RuntimeException { 6 | TrainingProgramProposalDoesNotExistException(UUID trainingProgramProposalId) { 7 | super("Training Program Proposal with id " + trainingProgramProposalId + " does not exist."); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /trainings-catalogue/src/test/java/com/smalaca/trainingscatalogue/client/trainingcatalogue/TrainingCatalogueTestClient.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.client.trainingcatalogue; 2 | 3 | import org.springframework.test.web.servlet.MockMvc; 4 | 5 | public class TrainingCatalogueTestClient { 6 | private final MockMvc mockMvc; 7 | 8 | TrainingCatalogueTestClient(MockMvc mockMvc) { 9 | this.mockMvc = mockMvc; 10 | } 11 | 12 | public TrainingCatalogueEndpoints trainingCatalogue() { 13 | return new TrainingCatalogueEndpoints(mockMvc); 14 | } 15 | } -------------------------------------------------------------------------------- /personal-data-management/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9020 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | kafka: 10 | bootstrap-servers: localhost:9092 11 | group-id: personal-data-management 12 | topics: 13 | command: 14 | register-person: open-training-offer-acceptance-register-person-command-topic 15 | event: 16 | already-registered-person: open-training-offer-acceptance-already-registered-person-event-topic 17 | person-registered: open-training-offer-acceptance-person-registered-event-topic 18 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/OfferAcceptanceSagaEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public interface OfferAcceptanceSagaEvent { 10 | EventId eventId(); 11 | UUID offerId(); 12 | void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt); 13 | } 14 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offeracceptancesaga/SpringOfferAcceptanceSagaEventCrudRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offeracceptancesaga; 2 | 3 | import org.springframework.data.repository.CrudRepository; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | interface SpringOfferAcceptanceSagaEventCrudRepository extends CrudRepository { 9 | List findAllByOfferIdOrderByConsumedAtAsc(UUID offerId); 10 | } 11 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/offer/OfferTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import com.smalaca.opentrainings.domain.price.Price; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.UUID; 9 | 10 | @Builder 11 | @Getter 12 | public class OfferTestDto { 13 | private final UUID offerId; 14 | private final UUID trainingId; 15 | private final Price trainingPrice; 16 | private final LocalDateTime creationDateTime; 17 | private final OfferStatus status; 18 | } 19 | -------------------------------------------------------------------------------- /payment-gateway/src/main/java/com/smalaca/paymentgateway/PaymentGatewayApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.paymentgateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | 7 | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) 8 | public class PaymentGatewayApplication { 9 | public static void main(String[] args) { 10 | SpringApplication.run(PaymentGatewayApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/commands/RescheduleTrainingOfferCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.commands; 2 | 3 | import com.smalaca.trainingoffer.domain.commandid.CommandId; 4 | 5 | import java.time.LocalDate; 6 | import java.time.LocalTime; 7 | import java.util.UUID; 8 | 9 | public record RescheduleTrainingOfferCommand( 10 | CommandId commandId, 11 | UUID trainingOfferId, 12 | LocalDate startDate, 13 | LocalDate endDate, 14 | LocalTime startTime, 15 | LocalTime endTime) { 16 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/clock/localdatetime/LocalDateTimeClock.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.clock.localdatetime; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.opentrainings.domain.clock.Clock; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | @Component 10 | @DrivenAdapter 11 | public class LocalDateTimeClock implements Clock { 12 | @Override 13 | public LocalDateTime now() { 14 | return LocalDateTime.now(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramProposalRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.domaindrivendesign.DomainRepository; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainRepository 9 | @DrivenPort 10 | public interface TrainingProgramProposalRepository { 11 | void save(TrainingProgramProposal trainingProgramProposal); 12 | 13 | TrainingProgramProposal findById(UUID trainingProgramProposalId); 14 | } 15 | -------------------------------------------------------------------------------- /discount-management/src/main/java/com/smalaca/discountmanagement/DiscountManagementApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.discountmanagement; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | 7 | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 8 | public class DiscountManagementApplication { 9 | public static void main(String[] args) { 10 | SpringApplication.run(DiscountManagementApplication.class, args); 11 | } 12 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/client/opentrainings/order/RestOrderTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.client.opentrainings.order; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDateTime; 5 | import java.util.UUID; 6 | 7 | public record RestOrderTestDto( 8 | UUID orderId, UUID offerId, UUID trainingId, UUID participantId, String orderNumber, 9 | BigDecimal trainingPriceAmount, String trainingPriceCurrency, BigDecimal finalPriceAmount, String finalPriceCurrency, 10 | LocalDateTime creationDateTime, String status, String discountCode) { 11 | } 12 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingofferdraft/commands/CreateTrainingOfferDraftCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingofferdraft.commands; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | public record CreateTrainingOfferDraftCommand( 9 | UUID trainingProgramId, UUID trainerId, BigDecimal priceAmount, String priceCurrency, 10 | int minimumParticipants, int maximumParticipants, 11 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 12 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/api/rest/offer/AcceptOfferRestCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.api.rest.offer; 2 | 3 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceRequestedEvent; 4 | 5 | import java.util.UUID; 6 | 7 | public record AcceptOfferRestCommand(UUID offerId, String firstName, String lastName, String email, String discountCode) { 8 | OfferAcceptanceRequestedEvent asOfferAcceptanceRequestedEvent() { 9 | return OfferAcceptanceRequestedEvent.create(offerId, firstName, lastName, email, discountCode); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/eventregistry/EventRegistry.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.eventregistry; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenPort; 4 | import com.smalaca.reviews.domain.proposal.events.ProposalApprovedEvent; 5 | import com.smalaca.reviews.domain.proposal.events.ProposalAssignedEvent; 6 | import com.smalaca.reviews.domain.proposal.events.ProposalRejectedEvent; 7 | 8 | @DrivenPort 9 | public interface EventRegistry { 10 | void publish(ProposalApprovedEvent event); 11 | void publish(ProposalAssignedEvent event); 12 | void publish(ProposalRejectedEvent event); 13 | } 14 | -------------------------------------------------------------------------------- /personal-data-management/src/main/java/com/smalaca/personaldatamanagement/PersonalDataManagementApplication.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.personaldatamanagement; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | 7 | @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 8 | public class PersonalDataManagementApplication { 9 | public static void main(String[] args) { 10 | SpringApplication.run(PersonalDataManagementApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/client/trainingoffer/trainingofferdraft/CreateTrainingOfferDraftTestCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.client.trainingoffer.trainingofferdraft; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | public record CreateTrainingOfferDraftTestCommand( 9 | UUID trainingProgramId, UUID trainerId, BigDecimal priceAmount, String priceCurrency, 10 | int minimumParticipants, int maximumParticipants, 11 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 12 | } -------------------------------------------------------------------------------- /payment-gateway/src/main/java/com/smalaca/paymentgateway/api/PaymentRestController.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.paymentgateway.api; 2 | 3 | import org.springframework.web.bind.annotation.PostMapping; 4 | import org.springframework.web.bind.annotation.RequestBody; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @RequestMapping("payment") 10 | public class PaymentRestController { 11 | @PostMapping 12 | public PaymentResponse pay(@RequestBody PaymentRequest paymentRequest) { 13 | return PaymentResponse.successful(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramProposalReviewSpecification.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | import com.smalaca.domaindrivendesign.Specification; 4 | 5 | @Specification 6 | public interface TrainingProgramProposalReviewSpecification { 7 | boolean isSatisfiedBy(TrainingProgramContent proposalDto); 8 | 9 | default TrainingProgramProposalReviewSpecification and(TrainingProgramProposalReviewSpecification other) { 10 | return proposalDto -> this.isSatisfiedBy(proposalDto) && other.isSatisfiedBy(proposalDto); 11 | } 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | !**/src/main/**/target/ 4 | !**/src/test/**/target/ 5 | 6 | ### IntelliJ IDEA ### 7 | .idea/modules.xml 8 | .idea/jarRepositories.xml 9 | .idea/compiler.xml 10 | .idea/libraries/ 11 | *.iws 12 | *.iml 13 | *.ipr 14 | 15 | ### Eclipse ### 16 | .apt_generated 17 | .classpath 18 | .factorypath 19 | .project 20 | .settings 21 | .springBeans 22 | .sts4-cache 23 | 24 | ### NetBeans ### 25 | /nbproject/private/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | build/ 31 | !**/src/main/**/build/ 32 | !**/src/test/**/build/ 33 | 34 | ### VS Code ### 35 | .vscode/ 36 | 37 | ### Mac OS ### 38 | .DS_Store -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/OutboxMessageTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import nl.jqno.equalsverifier.Warning; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class OutboxMessageTest { 8 | @Test 9 | void shouldFulfillEqualsContract() { 10 | EqualsVerifier.simple().forClass(OutboxMessage.class) 11 | .withNonnullFields("messageId", "isPublished", "occurredOn", "messageType", "payload") 12 | .suppress(Warning.SURROGATE_OR_BUSINESS_KEY) 13 | .verify(); 14 | } 15 | } -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/infrastructure/outbox/jpa/OutboxMessageTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.outbox.jpa; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import nl.jqno.equalsverifier.Warning; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class OutboxMessageTest { 8 | @Test 9 | void shouldFulfillEqualsContract() { 10 | EqualsVerifier.simple().forClass(OutboxMessage.class) 11 | .withNonnullFields("messageId", "isPublished", "occurredOn", "messageType", "payload") 12 | .suppress(Warning.SURROGATE_OR_BUSINESS_KEY) 13 | .verify(); 14 | } 15 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramProposalReviewSpecificationFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | public class TrainingProgramProposalReviewSpecificationFactory { 4 | public TrainingProgramProposalReviewSpecification trainingProgramProposalReviewSpecification() { 5 | ContentCompletenessSpecification contentCompleteness = new ContentCompletenessSpecification(); 6 | QualityStandardsSpecification qualityStandards = new QualityStandardsSpecification(); 7 | 8 | return contentCompleteness.and(qualityStandards); 9 | } 10 | } -------------------------------------------------------------------------------- /training-programs/src/test/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/OutboxMessageTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | import nl.jqno.equalsverifier.EqualsVerifier; 4 | import nl.jqno.equalsverifier.Warning; 5 | import org.junit.jupiter.api.Test; 6 | 7 | class OutboxMessageTest { 8 | @Test 9 | void shouldFulfillEqualsContract() { 10 | EqualsVerifier.simple().forClass(OutboxMessage.class) 11 | .withNonnullFields("messageId", "isPublished", "occurredOn", "messageType", "payload") 12 | .suppress(Warning.SURROGATE_OR_BUSINESS_KEY) 13 | .verify(); 14 | } 15 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/trainingoffercatalogue/RestTrainingOfferDetailDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.trainingoffercatalogue; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | record RestTrainingOfferDetailDto( 9 | UUID trainingOfferId, UUID trainerId, UUID trainingProgramId, 10 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime, 11 | BigDecimal priceAmount, String priceCurrency, int availablePlaces, 12 | String name, String agenda, String plan, String description) { 13 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/paymentmethod/PaymentMethod.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.paymentmethod; 2 | 3 | import com.smalaca.domaindrivendesign.Factory; 4 | import com.smalaca.domaindrivendesign.ValueObject; 5 | 6 | @ValueObject 7 | public enum PaymentMethod { 8 | CREDIT_CARD, PAYPAL, BANK_TRANSFER; 9 | 10 | @Factory 11 | public static PaymentMethod of(String paymentMethod) { 12 | try { 13 | return PaymentMethod.valueOf(paymentMethod); 14 | } catch (IllegalArgumentException exception) { 15 | throw new UnsupportedPaymentMethodException(paymentMethod); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/architecture/NoCyclesTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.architecture; 2 | 3 | import com.tngtech.archunit.junit.AnalyzeClasses; 4 | import com.tngtech.archunit.junit.ArchTest; 5 | import com.tngtech.archunit.lang.ArchRule; 6 | 7 | import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices; 8 | 9 | @AnalyzeClasses(packages = "com.smalaca.reviews") 10 | public class NoCyclesTest { 11 | @ArchTest 12 | static final ArchRule noCycles = slices() 13 | .matching("com.smalaca.reviews.(domain|application|infrastructure).(*)..") 14 | .namingSlices("$1-$2") 15 | .should().beFreeOfCycles(); 16 | } 17 | -------------------------------------------------------------------------------- /trainings-catalogue/src/test/java/com/smalaca/trainingscatalogue/client/trainingcatalogue/RestTrainingOfferDetailTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.client.trainingcatalogue; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | public record RestTrainingOfferDetailTestDto( 9 | UUID trainingOfferId, UUID trainerId, UUID trainingProgramId, 10 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime, 11 | BigDecimal priceAmount, String priceCurrency, int availablePlaces, 12 | String name, String agenda, String plan, String description) { 13 | } -------------------------------------------------------------------------------- /schema-registry/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-schema-registry 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Schema Registry 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.test.exclusions=**/*Test.java 15 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/outbox/jpa/JpaOutboxMessageRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | class JpaOutboxMessageRepositoryFactory { 9 | 10 | @Bean 11 | JpaOutboxMessageRepository jpaOutboxMessageRepository(SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new JpaOutboxMessageRepository(repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/JpaOutboxMessageRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | class JpaOutboxMessageRepositoryFactory { 9 | 10 | @Bean 11 | JpaOutboxMessageRepository jpaOutboxMessageRepository(SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new JpaOutboxMessageRepository(repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/query/offer/OfferViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.query.offer; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.data.repository.query.Param; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.UUID; 9 | 10 | interface OfferViewRepository extends CrudRepository { 11 | @Query("SELECT o FROM OfferView o WHERE o.status = 'INITIATED' AND o.creationDateTime < :tenMinutesAgo") 12 | Iterable findAllInitiatedOffersOlderThan(@Param("tenMinutesAgo") LocalDateTime tenMinutesAgo); 13 | } 14 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/JpaOutboxMessageRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | class JpaOutboxMessageRepositoryFactory { 9 | 10 | @Bean 11 | JpaOutboxMessageRepository jpaOutboxMessageRepository(SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new JpaOutboxMessageRepository(repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } -------------------------------------------------------------------------------- /training-programs/src/test/java/com/smalaca/trainingprograms/client/trainingprogram/TrainingProgramTestClient.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.client.trainingprogram; 2 | 3 | import com.smalaca.trainingprograms.client.trainingprogram.trainingprogramproposal.TrainingProgramProposalEndpoints; 4 | import org.springframework.test.web.servlet.MockMvc; 5 | 6 | public class TrainingProgramTestClient { 7 | private final MockMvc mockMvc; 8 | 9 | TrainingProgramTestClient(MockMvc mockMvc) { 10 | this.mockMvc = mockMvc; 11 | } 12 | 13 | public TrainingProgramProposalEndpoints trainingProgramProposals() { 14 | return new TrainingProgramProposalEndpoints(mockMvc); 15 | } 16 | } -------------------------------------------------------------------------------- /annotations-test/src/main/java/com/smalaca/test/type/RepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.test.type; 2 | 3 | import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; 4 | import org.springframework.transaction.annotation.Propagation; 5 | import org.springframework.transaction.annotation.Transactional; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.TYPE) 14 | @IntegrationTest 15 | @DataJpaTest 16 | @Transactional(propagation = Propagation.NOT_SUPPORTED) 17 | public @interface RepositoryTest { 18 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/events/OrderCancelledEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.opentrainings.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainEvent 9 | public record OrderCancelledEvent(EventId eventId, UUID orderId, UUID offerId, UUID trainingId, UUID participantId) implements OrderEvent { 10 | public static OrderCancelledEvent create(UUID orderId, UUID offerId, UUID trainingId, UUID participantId) { 11 | return new OrderCancelledEvent(EventId.newEventId(), orderId, offerId, trainingId, participantId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/events/OrderTerminatedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.opentrainings.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainEvent 9 | public record OrderTerminatedEvent(EventId eventId, UUID orderId, UUID offerId, UUID trainingId, UUID participantId) implements OrderEvent { 10 | public static OrderTerminatedEvent create(UUID orderId, UUID offerId, UUID trainingId, UUID participantId) { 11 | return new OrderTerminatedEvent(EventId.newEventId(), orderId, offerId, trainingId, participantId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/DiscountCodeReturnedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record DiscountCodeReturnedEvent(EventId eventId, UUID offerId, UUID participantId, String discountCode) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga saga, LocalDateTime consumedAt) { 12 | saga.accept(this, () -> consumedAt); 13 | } 14 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/order/OrderTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import com.smalaca.opentrainings.domain.price.Price; 4 | import lombok.Builder; 5 | import lombok.Getter; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.UUID; 9 | 10 | @Builder 11 | @Getter 12 | public class OrderTestDto { 13 | private final UUID orderId; 14 | private final UUID offerId; 15 | private final UUID trainingId; 16 | private final UUID participantId; 17 | private final Price trainingPrice; 18 | private final Price finalPrice; 19 | private final String discountCode; 20 | private final LocalDateTime creationDateTime; 21 | } 22 | -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingprogram/JpaTrainingProgramRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingprogram; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | import java.util.List; 7 | import java.util.UUID; 8 | 9 | public interface JpaTrainingProgramRepository extends CrudRepository { 10 | @Query("SELECT tp.trainingProgramId as trainingProgramId, " + 11 | "tp.authorId as authorId, " + 12 | "tp.name as name " + 13 | "FROM TrainingProgram tp") 14 | List findAllTrainingProgramSummaries(); 15 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/events/TrainingPurchasedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.opentrainings.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainEvent 9 | public record TrainingPurchasedEvent(EventId eventId, UUID orderId, UUID offerId, UUID trainingId, UUID participantId) implements OrderEvent { 10 | public static TrainingPurchasedEvent create(UUID orderId, UUID offerId, UUID trainingId, UUID participantId) { 11 | return new TrainingPurchasedEvent(EventId.newEventId(), orderId, offerId, trainingId, participantId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/client/trainingoffer/trainingofferdraft/RestTrainingOfferDraftTestDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.client.trainingoffer.trainingofferdraft; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | public record RestTrainingOfferDraftTestDto( 9 | UUID trainingOfferDraftId, UUID trainingProgramId, UUID trainerId, 10 | BigDecimal priceAmount, String priceCurrency, 11 | int minimumParticipants, int maximumParticipants, 12 | LocalDate startDate, LocalDate endDate, 13 | LocalTime startTime, LocalTime endTime, 14 | boolean published) { 15 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/PersonRegisteredEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record PersonRegisteredEvent(EventId eventId, UUID offerId, UUID participantId) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /reviews/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-reviews 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Reviews 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/ReviewsApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /training-programs/src/test/java/com/smalaca/trainingprograms/architecture/NoCyclesTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.architecture; 2 | 3 | import com.tngtech.archunit.junit.AnalyzeClasses; 4 | import com.tngtech.archunit.junit.ArchTest; 5 | import com.tngtech.archunit.lang.ArchRule; 6 | 7 | import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices; 8 | 9 | @AnalyzeClasses(packages = "com.smalaca.trainingprograms") 10 | public class NoCyclesTest { 11 | @ArchTest 12 | static final ArchRule noCycles = slices() 13 | .matching("com.smalaca.trainingprograms.(application|domain|infrastructure)..") 14 | .namingSlices("$1") 15 | .should().beFreeOfCycles(); 16 | } 17 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/BeginOfferAcceptanceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceRequestedEvent; 5 | 6 | import java.util.UUID; 7 | 8 | public record BeginOfferAcceptanceCommand(CommandId commandId, UUID offerId) implements OfferAcceptanceSagaCommand { 9 | public static BeginOfferAcceptanceCommand nextAfter(OfferAcceptanceRequestedEvent event) { 10 | return new BeginOfferAcceptanceCommand(event.eventId().nextCommandId(), event.offerId()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/query/proposal/ProposalViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.query.proposal; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.data.repository.query.Param; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.UUID; 9 | 10 | interface ProposalViewRepository extends CrudRepository { 11 | @Query(value = "SELECT * FROM PROPOSALS p WHERE p.STATUS = 'QUEUED' AND p.LAST_ASSIGNMENT_DATE_TIME < :weekAgo", nativeQuery = true) 12 | Iterable findAllQueuedOffersWithLastAssignmentOlderThan(@Param("weekAgo") LocalDateTime weekAgo); 13 | } 14 | -------------------------------------------------------------------------------- /annotations-test/src/main/java/com/smalaca/test/type/SpringBootIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.test.type; 2 | 3 | import org.springframework.boot.test.context.SpringBootTest; 4 | import org.springframework.test.annotation.DirtiesContext; 5 | 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; 12 | 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target(ElementType.TYPE) 15 | @IntegrationTest 16 | @DirtiesContext(classMode = AFTER_CLASS) 17 | @SpringBootTest 18 | public @interface SpringBootIntegrationTest { 19 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/TrainingPriceNotChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record TrainingPriceNotChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingOfferPublishedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.math.BigDecimal; 6 | import java.time.LocalDate; 7 | import java.time.LocalTime; 8 | import java.util.UUID; 9 | 10 | public record TrainingOfferPublishedEvent( 11 | EventId eventId, UUID trainingOfferId, UUID trainingOfferDraftId, UUID trainingProgramId, UUID trainerId, 12 | BigDecimal priceAmount, String priceCurrencyCode, int minimumParticipants, int maximumParticipants, 13 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/TrainingPlaceBookedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record TrainingPlaceBookedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } -------------------------------------------------------------------------------- /reviews/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9060 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | services: 10 | trainers-catalogue: 11 | url: http://localhost:9080 12 | 13 | scheduled: 14 | proposal: 15 | assignment: 16 | rate: 60000 17 | 18 | kafka: 19 | bootstrap-servers: localhost:9092 20 | group-id: reviews 21 | topics: 22 | reviews: 23 | events: 24 | proposal-approved: reviews-proposal-approved-event-topic 25 | proposal-assigned: reviews-proposal-assigned-event-topic 26 | proposal-rejected: reviews-proposal-rejected-event-topic 27 | commands: 28 | register-proposal: reviews-register-proposal-command-topic 29 | -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/client/reviews/ReviewsTestClient.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.client.reviews; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.smalaca.reviews.client.reviews.proposal.ProposalEndpoints; 5 | import org.springframework.test.web.servlet.MockMvc; 6 | 7 | public class ReviewsTestClient { 8 | private final MockMvc mockMvc; 9 | private final ObjectMapper objectMapper; 10 | 11 | ReviewsTestClient(MockMvc mockMvc, ObjectMapper objectMapper) { 12 | this.mockMvc = mockMvc; 13 | this.objectMapper = objectMapper; 14 | } 15 | 16 | public ProposalEndpoints proposals() { 17 | return new ProposalEndpoints(mockMvc, objectMapper); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /open-trainings/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-open-trainings 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Open Trainings 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/OpenTrainingsApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/AlreadyRegisteredPersonFoundEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record AlreadyRegisteredPersonFoundEvent(EventId eventId, UUID offerId, UUID participantId) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /training-offer/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-training-offer 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Training Offer 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/TrainingOfferApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/InvalidOfferStatusException.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import java.util.UUID; 4 | 5 | public class InvalidOfferStatusException extends RuntimeException { 6 | private InvalidOfferStatusException(String message) { 7 | super(message); 8 | } 9 | 10 | static InvalidOfferStatusException notInitiated(UUID offerId) { 11 | return new InvalidOfferStatusException("Offer: " + offerId + " not in INITIATED status."); 12 | } 13 | 14 | static InvalidOfferStatusException acceptanceNotInProgress(UUID offerId) { 15 | return new InvalidOfferStatusException("Offer: " + offerId + " acceptance not in progress."); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /payment-gateway/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-payment-gateway 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Payment Gateway 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/PaymentGatewayApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /reviews/src/test/java/com/smalaca/reviews/infrastructure/clock/localdatetime/LocalDateTimeClockTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.clock.localdatetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class LocalDateTimeClockTest { 10 | 11 | @Test 12 | void shouldReturnLocalDateTimeNow() { 13 | LocalDateTimeClock clock = new LocalDateTimeClock(); 14 | LocalDateTime before = LocalDateTime.now(); 15 | 16 | LocalDateTime actual = clock.now(); 17 | 18 | assertThat(actual) 19 | .isAfterOrEqualTo(before) 20 | .isBeforeOrEqualTo(LocalDateTime.now()); 21 | } 22 | } -------------------------------------------------------------------------------- /training-programs/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-training-programs 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Training Programs 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/TrainingProgramsApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/NoAvailableTrainingPlacesLeftEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record NoAvailableTrainingPlacesLeftEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } -------------------------------------------------------------------------------- /discount-management/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-discount-management 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Discount Management 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/DiscountManagementApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/DiscountCodeAlreadyUsedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | public record DiscountCodeAlreadyUsedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingId, String discountCode) implements OfferAcceptanceSagaEvent { 10 | @Override 11 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 12 | offerAcceptanceSaga.accept(this, () -> consumedAt); 13 | } 14 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/infrastructure/clock/localdatetime/LocalDateTimeClockTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.clock.localdatetime; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.time.LocalDateTime; 6 | 7 | import static org.assertj.core.api.Assertions.assertThat; 8 | 9 | class LocalDateTimeClockTest { 10 | 11 | @Test 12 | void shouldReturnLocalDateTimeNow() { 13 | LocalDateTimeClock clock = new LocalDateTimeClock(); 14 | LocalDateTime before = LocalDateTime.now(); 15 | 16 | LocalDateTime actual = clock.now(); 17 | 18 | assertThat(actual) 19 | .isAfterOrEqualTo(before) 20 | .isBeforeOrEqualTo(LocalDateTime.now()); 21 | } 22 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingOfferRescheduledEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | 5 | import java.math.BigDecimal; 6 | import java.time.LocalDate; 7 | import java.time.LocalTime; 8 | import java.util.UUID; 9 | 10 | public record TrainingOfferRescheduledEvent( 11 | EventId eventId, UUID rescheduledTrainingOfferId, UUID trainingOfferId, UUID trainingOfferDraftId, UUID trainingProgramId, UUID trainerId, 12 | BigDecimal priceAmount, String priceCurrencyCode, int minimumParticipants, int maximumParticipants, 13 | LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 14 | 15 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/commandid/CommandId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.commandid; 2 | 3 | import com.smalaca.trainingoffer.domain.eventid.EventId; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.UUID; 7 | 8 | import static java.time.LocalDateTime.now; 9 | 10 | public record CommandId(UUID commandId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 11 | public static CommandId newCommandId() { 12 | return new CommandId(id(), id(), id(), now()); 13 | } 14 | 15 | private static UUID id() { 16 | return UUID.randomUUID(); 17 | } 18 | 19 | public EventId nextEventId() { 20 | return new EventId(id(), traceId, correlationId, now()); 21 | } 22 | } -------------------------------------------------------------------------------- /trainings-catalogue/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-trainings-catalogue 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Trainings Catalogue 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/TrainingsCatalogueApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/outbox/jpa/OutboxMessagePublisherFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | class OutboxMessagePublisherFactory { 10 | @Bean 11 | OutboxMessagePublisher outboxMessagePublisher(ApplicationEventPublisher publisher, SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new OutboxMessagePublisher(publisher, repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/paymentgateway/PaymentGatewayRestClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.paymentgateway; 2 | 3 | import com.smalaca.opentrainings.domain.paymentgateway.PaymentGateway; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestClient; 8 | 9 | @Configuration 10 | public class PaymentGatewayRestClientFactory { 11 | @Bean 12 | public PaymentGateway paymentGateway(@Value("${services.payment-gateway.url}") String baseUri) { 13 | return new PaymentGatewayRestClient(RestClient.create(baseUri)); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/trainerscatalogue/TrainersCatalogueRestClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.trainerscatalogue; 2 | 3 | import com.smalaca.reviews.domain.trainerscatalogue.TrainersCatalogue; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestClient; 8 | 9 | @Configuration 10 | public class TrainersCatalogueRestClientFactory { 11 | @Bean 12 | public TrainersCatalogue trainersCatalogue(@Value("${services.trainers-catalogue.url}") String baseUri) { 13 | return new TrainersCatalogueRestClient(RestClient.create(baseUri)); 14 | } 15 | } -------------------------------------------------------------------------------- /discount-management/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9030 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | kafka: 10 | bootstrap-servers: localhost:9092 11 | group-id: discount-management 12 | topics: 13 | command: 14 | use-discount-code: open-training-offer-acceptance-use-discount-code-command-topic 15 | return-discount-code: open-training-offer-acceptance-return-discount-code-command-topic 16 | event: 17 | discount-code-used: open-training-offer-acceptance-discount-code-used-event-topic 18 | discount-code-already-used: open-training-offer-acceptance-discount-code-already-used-event-topic 19 | discount-code-returned: open-training-offer-acceptance-discount-code-returned-event-topic 20 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/OutboxMessagePublisherFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | class OutboxMessagePublisherFactory { 10 | @Bean 11 | OutboxMessagePublisher outboxMessagePublisher(ApplicationEventPublisher publisher, SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new OutboxMessagePublisher(publisher, repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/architecture/NoCyclesTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.architecture; 2 | 3 | import com.tngtech.archunit.junit.AnalyzeClasses; 4 | import com.tngtech.archunit.junit.ArchTest; 5 | import com.tngtech.archunit.lang.ArchRule; 6 | 7 | import static com.tngtech.archunit.library.dependencies.SlicesRuleDefinition.slices; 8 | 9 | @AnalyzeClasses(packages = "com.smalaca.opentrainings") 10 | public class NoCyclesTest { 11 | @ArchTest 12 | static final ArchRule noCycles = slices() 13 | // Group by layer only to ensure no cyclic dependency between layers 14 | .matching("com.smalaca.opentrainings.(application|domain|infrastructure)..") 15 | .namingSlices("$1") 16 | .should().beFreeOfCycles(); 17 | } 18 | -------------------------------------------------------------------------------- /personal-data-management/sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.projectKey=smalaca-github_training-center-microservices-personal-data-management 2 | sonar.organization=smalaca-github 3 | sonar.projectName=Training Center: Personal Data Management 4 | sonar.host.url=https://sonarcloud.io 5 | sonar.links.homepage=https://github.com/smalaca/training-center-microservices 6 | sonar.links.issue=https://github.com/smalaca/training-center-microservices/issues 7 | 8 | sonar.sources=src/main/java 9 | sonar.tests=src/test/java 10 | sonar.java.binaries=target/classes 11 | sonar.java.test.binaries=target/test-classes 12 | 13 | sonar.coverage.jacoco.xmlReportPaths=target/jacoco/jacoco-ut/jacoco.xml 14 | sonar.coverage.exclusions=**/PersonalDataManagementApplication.java 15 | sonar.test.exclusions=**/*Test.java 16 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/OutboxMessagePublisherFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.context.ApplicationEventPublisher; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | class OutboxMessagePublisherFactory { 10 | @Bean 11 | OutboxMessagePublisher outboxMessagePublisher(ApplicationEventPublisher publisher, SpringOutboxMessageCrudRepository repository, ObjectMapper objectMapper) { 12 | return new OutboxMessagePublisher(publisher, repository, new OutboxMessageMapper(objectMapper)); 13 | } 14 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingoffer/TrainingOfferDetail.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingoffer; 2 | 3 | import java.math.BigDecimal; 4 | import java.time.LocalDate; 5 | import java.time.LocalTime; 6 | import java.util.UUID; 7 | 8 | public interface TrainingOfferDetail { 9 | UUID getTrainingOfferId(); 10 | UUID getTrainerId(); 11 | UUID getTrainingProgramId(); 12 | LocalDate getStartDate(); 13 | LocalDate getEndDate(); 14 | LocalTime getStartTime(); 15 | LocalTime getEndTime(); 16 | BigDecimal getPriceAmount(); 17 | String getPriceCurrency(); 18 | int getAvailablePlaces(); 19 | String getName(); 20 | String getAgenda(); 21 | String getPlan(); 22 | String getDescription(); 23 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/commandid/CommandId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.commandid; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.UUID; 7 | 8 | import static java.time.LocalDateTime.now; 9 | 10 | public record CommandId(UUID commandId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 11 | public static CommandId nextAfter(EventId eventId) { 12 | return new CommandId(id(), eventId.traceId(), eventId.correlationId(), now()); 13 | } 14 | 15 | private static UUID id() { 16 | return UUID.randomUUID(); 17 | } 18 | 19 | public EventId nextEventId() { 20 | return EventId.nextAfter(this); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/api/eventlistener/offeracceptance/OfferAcceptanceEventListenerFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.api.eventlistener.offeracceptance; 2 | 3 | import com.smalaca.opentrainings.application.offeracceptancesaga.OfferAcceptanceSagaEngine; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | class OfferAcceptanceEventListenerFactory { 9 | @Bean 10 | public OfferAcceptanceEventListener offerAcceptanceEventListener(OfferAcceptanceSagaEngine offerAcceptanceSagaEngine) { 11 | return new OfferAcceptanceEventListener(new ThreadSafeOfferAcceptanceSagaEngine(offerAcceptanceSagaEngine)); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/events/ProposalApprovedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.reviews.domain.eventid.EventId; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | import static com.smalaca.reviews.domain.eventid.EventId.newEventId; 10 | 11 | @DomainEvent 12 | public record ProposalApprovedEvent(EventId eventId, UUID proposalId, UUID reviewerId) { 13 | public static ProposalApprovedEvent create(UUID proposalId, UUID reviewerId, UUID correlationId, LocalDateTime reviewedAt) { 14 | EventId eventId = newEventId(correlationId, reviewedAt); 15 | return new ProposalApprovedEvent(eventId, proposalId, reviewerId); 16 | } 17 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/events/ProposalRejectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.reviews.domain.eventid.EventId; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | import static com.smalaca.reviews.domain.eventid.EventId.newEventId; 10 | 11 | @DomainEvent 12 | public record ProposalRejectedEvent(EventId eventId, UUID proposalId, UUID reviewerId) { 13 | public static ProposalRejectedEvent create(UUID proposalId, UUID reviewerId, UUID correlationId, LocalDateTime reviewedAt) { 14 | EventId eventId = newEventId(correlationId, reviewedAt); 15 | return new ProposalRejectedEvent(eventId, proposalId, reviewerId); 16 | } 17 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/RegisterPersonCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceRequestedEvent; 5 | 6 | import java.util.UUID; 7 | 8 | public record RegisterPersonCommand(CommandId commandId, UUID offerId, String firstName, String lastName, String email) implements OfferAcceptanceSagaCommand{ 9 | public static RegisterPersonCommand nextAfter(OfferAcceptanceRequestedEvent event) { 10 | return new RegisterPersonCommand(event.eventId().nextCommandId(), event.offerId(), event.firstName(), event.lastName(), event.email()); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/TrainingPriceChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.opentrainings.domain.eventid.EventId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 5 | 6 | import java.math.BigDecimal; 7 | import java.time.LocalDateTime; 8 | import java.util.UUID; 9 | 10 | public record TrainingPriceChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) implements OfferAcceptanceSagaEvent { 11 | @Override 12 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 13 | offerAcceptanceSaga.accept(this, () -> consumedAt); 14 | } 15 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/BookTrainingPlaceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceSagaEvent; 5 | 6 | import java.util.UUID; 7 | 8 | public record BookTrainingPlaceCommand(CommandId commandId, UUID offerId, UUID participantId, UUID trainingOfferId) implements OfferAcceptanceSagaCommand { 9 | public static BookTrainingPlaceCommand nextAfter(OfferAcceptanceSagaEvent event, UUID participantId, UUID trainingId) { 10 | return new BookTrainingPlaceCommand(CommandId.nextAfter(event.eventId()), event.offerId(), participantId, trainingId); 11 | } 12 | } -------------------------------------------------------------------------------- /payment-gateway/src/test/java/com/smalaca/paymentgateway/api/PaymentRestControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.paymentgateway.api; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | class PaymentRestControllerTest { 8 | private final PaymentRestController controller = new PaymentRestController(); 9 | 10 | @Test 11 | void shouldReturnSuccessfulPaymentResponse() { 12 | PaymentRequest paymentRequest = dummyPaymentRequest(); 13 | 14 | PaymentResponse paymentResponse = controller.pay(paymentRequest); 15 | 16 | assertThat(paymentResponse.isSuccessful()).isTrue(); 17 | } 18 | 19 | private PaymentRequest dummyPaymentRequest() { 20 | return new PaymentRequest(null, null, null, null, null); 21 | } 22 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/NoAssignmentPolicy.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import com.smalaca.domaindrivendesign.Policy; 4 | import com.smalaca.reviews.domain.clock.Clock; 5 | 6 | import java.util.Set; 7 | import java.util.UUID; 8 | 9 | import static com.smalaca.reviews.domain.proposal.ProposalStatus.QUEUED; 10 | 11 | @Policy 12 | class NoAssignmentPolicy implements ReviewerAssignmentPolicy { 13 | private static final UUID NO_REVIEWER = null; 14 | private final Clock clock; 15 | 16 | NoAssignmentPolicy(Clock clock) { 17 | this.clock = clock; 18 | } 19 | 20 | @Override 21 | public Assignment assign(UUID authorId, Set categoriesIds) { 22 | return new Assignment(NO_REVIEWER, QUEUED, clock.now()); 23 | } 24 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/ReviewerAssignmentPolicyFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import com.smalaca.reviews.domain.clock.Clock; 4 | import com.smalaca.reviews.domain.trainerscatalogue.TrainersCatalogue; 5 | 6 | public class ReviewerAssignmentPolicyFactory { 7 | public ReviewerAssignmentPolicy reviewerAssignmentPolicy(Clock clock, TrainersCatalogue trainersCatalogue) { 8 | NoAssignmentPolicy noAssignmentPolicy = new NoAssignmentPolicy(clock); 9 | WorkloadBalanceAssignmentPolicy workloadBalanceAssignmentPolicy = new WorkloadBalanceAssignmentPolicy(trainersCatalogue, clock, noAssignmentPolicy); 10 | 11 | return new SpecializationAssignmentPolicy(trainersCatalogue, clock, workloadBalanceAssignmentPolicy); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/ReturnDiscountCodeCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceSagaEvent; 5 | 6 | import java.util.UUID; 7 | 8 | public record ReturnDiscountCodeCommand(CommandId commandId, UUID offerId, UUID participantId, String discountCode) implements OfferAcceptanceSagaCommand { 9 | public static ReturnDiscountCodeCommand nextAfter(OfferAcceptanceSagaEvent event, UUID participantId, String discountCode) { 10 | return new ReturnDiscountCodeCommand(event.eventId().nextCommandId(), event.offerId(), participantId, discountCode); 11 | } 12 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/query/order/OrderViewRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.query.order; 2 | 3 | import org.springframework.data.jpa.repository.Query; 4 | import org.springframework.data.repository.CrudRepository; 5 | import org.springframework.data.repository.query.Param; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.List; 9 | import java.util.Optional; 10 | import java.util.UUID; 11 | 12 | public interface OrderViewRepository extends CrudRepository { 13 | @Query("SELECT o FROM OrderView o WHERE o.creationDateTime < :tenMinutesAgo AND o.status = 'INITIATED'") 14 | List findInitiatedOrdersOlderThan(@Param("tenMinutesAgo") LocalDateTime tenMinutesAgo); 15 | 16 | Optional findByOfferId(UUID offerId); 17 | } 18 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/events/TrainingProgramRejectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingprograms.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainEvent 9 | public record TrainingProgramRejectedEvent( 10 | EventId eventId, UUID trainingProgramProposalId, UUID reviewerId) implements TrainingProgramProposalEvent { 11 | 12 | public static TrainingProgramRejectedEvent create(UUID trainingProgramProposalId, UUID reviewerId) { 13 | return new TrainingProgramRejectedEvent( 14 | EventId.newEventId(), trainingProgramProposalId, reviewerId 15 | ); 16 | } 17 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/events/TrainingPriceNotChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingoffer.domain.eventid.EventId; 5 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.ConfirmTrainingPriceCommand; 6 | 7 | import java.util.UUID; 8 | 9 | @DomainEvent 10 | public record TrainingPriceNotChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId) implements TrainingOfferEvent { 11 | 12 | public static TrainingPriceNotChangedEvent nextAfter(ConfirmTrainingPriceCommand command) { 13 | return new TrainingPriceNotChangedEvent(command.commandId().nextEventId(), command.offerId(), command.trainingOfferId()); 14 | } 15 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/eventid/EventId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.eventid; 2 | 3 | import com.smalaca.trainingprograms.domain.commandid.CommandId; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.UUID; 7 | 8 | import static java.time.LocalDateTime.now; 9 | 10 | public record EventId(UUID eventId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 11 | public static EventId nextAfter(CommandId commandId) { 12 | return new EventId(id(), commandId.traceId(), commandId.correlationId(), now()); 13 | } 14 | 15 | public static EventId newEventId() { 16 | return new EventId(id(), id(), id(), now()); 17 | } 18 | 19 | private static UUID id() { 20 | return UUID.randomUUID(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /annotations/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.smalaca 8 | annotations 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 21 13 | 21 14 | 21 15 | UTF-8 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/events/ProposalAssignedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.reviews.domain.eventid.EventId; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | import static com.smalaca.reviews.domain.eventid.EventId.newEventId; 10 | 11 | @DomainEvent 12 | public record ProposalAssignedEvent(EventId eventId, UUID proposalId, UUID assignedReviewerId) { 13 | public static ProposalAssignedEvent create(UUID proposalId, UUID assignedReviewerId, UUID correlationId, LocalDateTime assignedAt) { 14 | EventId eventId = newEventId(correlationId, assignedAt); 15 | return new ProposalAssignedEvent(eventId, proposalId, assignedReviewerId); 16 | } 17 | } -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/metadata/CommandId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.metadata; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | import static java.time.LocalDateTime.now; 7 | 8 | public record CommandId(UUID commandId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 9 | public static CommandId newCommandId() { 10 | return new CommandId(id(), id(), id(), now()); 11 | } 12 | 13 | public EventId nextEventId() { 14 | return EventId.nextAfter(this); 15 | } 16 | 17 | static CommandId nextAfter(EventId eventId) { 18 | return new CommandId(id(), eventId.traceId(), eventId.correlationId(), now()); 19 | } 20 | 21 | private static UUID id() { 22 | return UUID.randomUUID(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /schema-registry/src/main/java/com/smalaca/schemaregistry/metadata/EventId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.metadata; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | import static java.time.LocalDateTime.now; 7 | 8 | public record EventId(UUID eventId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 9 | public static EventId newEventId() { 10 | return new EventId(id(), id(), id(), now()); 11 | } 12 | 13 | public CommandId nextCommandId() { 14 | return CommandId.nextAfter(this); 15 | } 16 | 17 | static EventId nextAfter(CommandId commandId) { 18 | return new EventId(id(), commandId.traceId(), commandId.correlationId(), now()); 19 | } 20 | 21 | private static UUID id() { 22 | return UUID.randomUUID(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/data/Random.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.data; 2 | 3 | import com.smalaca.opentrainings.domain.price.Price; 4 | import net.datafaker.Faker; 5 | 6 | import java.math.BigDecimal; 7 | import java.util.UUID; 8 | 9 | public class Random { 10 | private static final Faker FAKER = new Faker(); 11 | 12 | public static UUID randomId() { 13 | return UUID.randomUUID(); 14 | } 15 | 16 | public static Price randomPrice() { 17 | return Price.of(randomAmount(), randomCurrency()); 18 | } 19 | 20 | public static BigDecimal randomAmount() { 21 | return BigDecimal.valueOf(FAKER.number().numberBetween(100L, 10000L)); 22 | } 23 | 24 | public static String randomCurrency() { 25 | return FAKER.currency().code(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/order/OrderStatusTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import org.junit.jupiter.params.ParameterizedTest; 4 | import org.junit.jupiter.params.provider.EnumSource; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | class OrderStatusTest { 9 | 10 | @ParameterizedTest 11 | @EnumSource(value = OrderStatus.class, mode = EnumSource.Mode.EXCLUDE, names = {"INITIATED"}) 12 | void shouldRecognizeFinalStatus(OrderStatus actual) { 13 | assertThat(actual.isFinal()).isTrue(); 14 | } 15 | 16 | @ParameterizedTest 17 | @EnumSource(value = OrderStatus.class, names = {"INITIATED"}) 18 | void shouldRecognizeNonFinalStatus(OrderStatus actual) { 19 | assertThat(actual.isFinal()).isFalse(); 20 | } 21 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/events/TrainingPlaceBookedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingoffer.domain.eventid.EventId; 5 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.BookTrainingPlaceCommand; 6 | 7 | import java.util.UUID; 8 | 9 | @DomainEvent 10 | public record TrainingPlaceBookedEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) implements TrainingOfferEvent { 11 | 12 | public static TrainingPlaceBookedEvent nextAfter(BookTrainingPlaceCommand command) { 13 | return new TrainingPlaceBookedEvent(command.commandId().nextEventId(), command.offerId(), command.participantId(), command.trainingOfferId()); 14 | } 15 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/trainingoffercatalogue/TrainingOfferCatalogueRestClientFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.trainingoffercatalogue; 2 | 3 | import com.smalaca.opentrainings.domain.trainingoffercatalogue.TrainingOfferCatalogue; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.client.RestClient; 8 | 9 | @Configuration 10 | public class TrainingOfferCatalogueRestClientFactory { 11 | @Bean 12 | public TrainingOfferCatalogue trainingOfferCatalogue(@Value("${services.trainings-catalogue.url}") String baseUri) { 13 | return new TrainingOfferCatalogueRestClient(RestClient.create(baseUri)); 14 | } 15 | } -------------------------------------------------------------------------------- /annotations-test/src/main/java/com/smalaca/test/type/SystemTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.test.type; 2 | 3 | import org.junit.jupiter.api.Tag; 4 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.annotation.DirtiesContext; 7 | 8 | import java.lang.annotation.ElementType; 9 | import java.lang.annotation.Retention; 10 | import java.lang.annotation.RetentionPolicy; 11 | import java.lang.annotation.Target; 12 | 13 | import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS; 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.TYPE) 17 | @SpringBootTest 18 | @DirtiesContext(classMode = AFTER_CLASS) 19 | @AutoConfigureMockMvc 20 | @Tag("SystemTest") 21 | public @interface SystemTest { 22 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/events/OrderRejectedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.opentrainings.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | import static com.smalaca.opentrainings.domain.eventid.EventId.newEventId; 9 | 10 | @DomainEvent 11 | public record OrderRejectedEvent(EventId eventId, UUID orderId, String reason) implements OrderEvent { 12 | public static OrderRejectedEvent expired(UUID orderId) { 13 | return new OrderRejectedEvent(newEventId(), orderId, "Order expired"); 14 | } 15 | 16 | public static OrderRejectedEvent paymentFailed(UUID orderId) { 17 | return new OrderRejectedEvent(newEventId(), orderId, "Could not complete payment."); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/infrastructure/repository/jpa/trainingoffer/SpringTrainingOfferCrudTestRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.repository.jpa.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.domain.trainingoffer.TrainingOffer; 4 | 5 | import java.util.Optional; 6 | import java.util.UUID; 7 | 8 | public class SpringTrainingOfferCrudTestRepository { 9 | private final SpringTrainingOfferCrudRepository repository; 10 | 11 | SpringTrainingOfferCrudTestRepository(SpringTrainingOfferCrudRepository repository) { 12 | this.repository = repository; 13 | } 14 | 15 | public Optional findById(UUID trainingOfferId) { 16 | return repository.findById(trainingOfferId); 17 | } 18 | 19 | public void deleteAll() { 20 | repository.deleteAll(); 21 | } 22 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/query/proposal/ProposalQueryService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.query.proposal; 2 | 3 | import com.smalaca.architecture.cqrs.QueryOperation; 4 | import com.smalaca.reviews.domain.clock.Clock; 5 | import org.springframework.stereotype.Service; 6 | 7 | @Service 8 | public class ProposalQueryService { 9 | private static final int ONE_WEEK = 1; 10 | 11 | private final ProposalViewRepository repository; 12 | private final Clock clock; 13 | 14 | ProposalQueryService(ProposalViewRepository repository, Clock clock) { 15 | this.repository = repository; 16 | this.clock = clock; 17 | } 18 | 19 | @QueryOperation 20 | public Iterable findAllToAssign() { 21 | return repository.findAllQueuedOffersWithLastAssignmentOlderThan(clock.now().minusWeeks(ONE_WEEK)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/api/rest/trainingoffer/RescheduleTrainingOfferDto.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.api.rest.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.RescheduleTrainingOfferCommand; 4 | 5 | import java.time.LocalDate; 6 | import java.time.LocalTime; 7 | import java.util.UUID; 8 | 9 | import static com.smalaca.trainingoffer.domain.commandid.CommandId.newCommandId; 10 | 11 | public record RescheduleTrainingOfferDto( 12 | UUID trainingOfferId, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime) { 13 | RescheduleTrainingOfferCommand asRescheduleTrainingOfferCommand() { 14 | return new RescheduleTrainingOfferCommand(newCommandId(), trainingOfferId(), startDate(), endDate(), startTime(), endTime()); 15 | } 16 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/events/TrainingProgramProposalReleaseFailedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingprograms.domain.eventid.EventId; 5 | 6 | import java.util.UUID; 7 | 8 | @DomainEvent 9 | public record TrainingProgramProposalReleaseFailedEvent( 10 | EventId eventId, UUID trainingProgramProposalId, UUID reviewerId) implements TrainingProgramProposalEvent { 11 | 12 | public static TrainingProgramProposalReleaseFailedEvent create(UUID trainingProgramProposalId, UUID reviewerId) { 13 | return new TrainingProgramProposalReleaseFailedEvent( 14 | EventId.newEventId(), trainingProgramProposalId, reviewerId 15 | ); 16 | } 17 | } -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/client/trainingoffer/TrainingOfferTestClient.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.client.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.client.trainingoffer.trainingofferdraft.TrainingOfferDraftEndpoints; 4 | import com.smalaca.trainingoffer.client.trainingoffer.trainingoffer.TrainingOfferEndpoints; 5 | import org.springframework.test.web.servlet.MockMvc; 6 | 7 | public class TrainingOfferTestClient { 8 | private final MockMvc mockMvc; 9 | 10 | TrainingOfferTestClient(MockMvc mockMvc) { 11 | this.mockMvc = mockMvc; 12 | } 13 | 14 | public TrainingOfferDraftEndpoints trainingOfferDrafts() { 15 | return new TrainingOfferDraftEndpoints(mockMvc); 16 | } 17 | 18 | public TrainingOfferEndpoints trainingOffers() { 19 | return new TrainingOfferEndpoints(mockMvc); 20 | } 21 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/events/NoAvailableTrainingPlacesLeftEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingoffer.domain.eventid.EventId; 5 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.BookTrainingPlaceCommand; 6 | 7 | import java.util.UUID; 8 | 9 | @DomainEvent 10 | public record NoAvailableTrainingPlacesLeftEvent(EventId eventId, UUID offerId, UUID participantId, UUID trainingOfferId) implements TrainingOfferEvent { 11 | 12 | public static NoAvailableTrainingPlacesLeftEvent nextAfter(BookTrainingPlaceCommand command) { 13 | return new NoAvailableTrainingPlacesLeftEvent(command.commandId().nextEventId(), command.offerId(), command.participantId(), command.trainingOfferId()); 14 | } 15 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/domain/trainingprogramproposal/TrainingProgramProposalFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.domain.trainingprogramproposal; 2 | 3 | import com.smalaca.domaindrivendesign.Factory; 4 | import com.smalaca.trainingprograms.domain.trainingprogramproposal.commands.CreateTrainingProgramProposalCommand; 5 | import com.smalaca.trainingprograms.domain.trainingprogramproposal.events.TrainingProgramProposedEvent; 6 | 7 | import java.util.UUID; 8 | 9 | @Factory 10 | public class TrainingProgramProposalFactory { 11 | public TrainingProgramProposedEvent create(CreateTrainingProgramProposalCommand command) { 12 | return TrainingProgramProposedEvent.create(trainingProgramProposalId(), command); 13 | } 14 | 15 | private UUID trainingProgramProposalId() { 16 | return UUID.randomUUID(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offeracceptancesaga/JpaOfferAcceptanceSagaRepositoryFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offeracceptancesaga; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSagaRepository; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | @Configuration 9 | class JpaOfferAcceptanceSagaRepositoryFactory { 10 | @Bean 11 | OfferAcceptanceSagaRepository offerAcceptanceSagaRepository(SpringOfferAcceptanceSagaEventCrudRepository repository, ObjectMapper objectMapper) { 12 | return new JpaOfferAcceptanceSagaRepository(repository, new OfferAcceptanceSagaPersistableEventMapper(objectMapper)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingoffer/TrainingOfferService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingoffer; 2 | 3 | import com.smalaca.schemaregistry.trainingoffer.events.TrainingOfferPublishedEvent; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.transaction.annotation.Transactional; 6 | 7 | @Service 8 | public class TrainingOfferService { 9 | private final JpaTrainingOfferRepository trainingOfferRepository; 10 | 11 | TrainingOfferService(JpaTrainingOfferRepository trainingOfferRepository) { 12 | this.trainingOfferRepository = trainingOfferRepository; 13 | } 14 | 15 | @Transactional 16 | public void handle(TrainingOfferPublishedEvent event) { 17 | TrainingOffer trainingOffer = new TrainingOffer(event); 18 | trainingOfferRepository.save(trainingOffer); 19 | } 20 | } -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/domain/proposal/Assignment.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.domain.proposal; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.UUID; 5 | 6 | public final class Assignment { 7 | private final UUID reviewerId; 8 | private final ProposalStatus status; 9 | private final LocalDateTime occurredAt; 10 | 11 | Assignment(UUID reviewerId, ProposalStatus status, LocalDateTime occurredAt) { 12 | this.reviewerId = reviewerId; 13 | this.status = status; 14 | this.occurredAt = occurredAt; 15 | } 16 | 17 | UUID reviewerId() { 18 | return reviewerId; 19 | } 20 | 21 | ProposalStatus status() { 22 | return status; 23 | } 24 | 25 | LocalDateTime occurredAt() { 26 | return occurredAt; 27 | } 28 | 29 | boolean hasReviewer() { 30 | return reviewerId() != null; 31 | } 32 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/trainingprogram/TrainingProgramService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.trainingprogram; 2 | 3 | import com.smalaca.schemaregistry.trainingprogram.events.TrainingProgramReleasedEvent; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.transaction.annotation.Transactional; 6 | 7 | @Service 8 | public class TrainingProgramService { 9 | private final JpaTrainingProgramRepository trainingProgramRepository; 10 | 11 | TrainingProgramService(JpaTrainingProgramRepository trainingProgramRepository) { 12 | this.trainingProgramRepository = trainingProgramRepository; 13 | } 14 | 15 | @Transactional 16 | public void handle(TrainingProgramReleasedEvent event) { 17 | TrainingProgram trainingProgram = new TrainingProgram(event); 18 | trainingProgramRepository.save(trainingProgram); 19 | } 20 | } -------------------------------------------------------------------------------- /documentation/architecture-decision-record/template.md: -------------------------------------------------------------------------------- 1 | # Decision record template 2 | 3 | This is the template inspired by [Documenting architecture decisions - Michael Nygard](http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions). 4 | 5 | In each ADR file, write these sections: 6 | 7 | # Title 8 | 9 | ## Status 10 | 11 | What is the status, such as proposed, accepted, rejected, deprecated, superseded, etc.? 12 | 13 | ## Date 14 | 15 | Date when decision was made. 16 | 17 | ## Decision 18 | 19 | What is the change that we're proposing and/or doing? 20 | 21 | ## Context 22 | 23 | What is the issue that we're seeing that is motivating this decision or change? 24 | 25 | ## Solutions 26 | 27 | List of solutions with their pros and cons. 28 | 29 | ## Decision Rationale 30 | 31 | Why solution was chosen. 32 | 33 | ## Consequences 34 | 35 | What becomes easier or more difficult to do because of this change? -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/reviews/events/ProposalApprovedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class ProposalApprovedEventTest { 11 | 12 | @Test 13 | void shouldCreateProposalApprovedEvent() { 14 | EventId eventId = EventId.newEventId(); 15 | UUID proposalId = UUID.randomUUID(); 16 | UUID reviewerId = UUID.randomUUID(); 17 | 18 | ProposalApprovedEvent actual = new ProposalApprovedEvent(eventId, proposalId, reviewerId); 19 | 20 | assertThat(actual.eventId()).isEqualTo(eventId); 21 | assertThat(actual.proposalId()).isEqualTo(proposalId); 22 | assertThat(actual.reviewerId()).isEqualTo(reviewerId); 23 | } 24 | } -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/reviews/events/ProposalRejectedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class ProposalRejectedEventTest { 11 | 12 | @Test 13 | void shouldCreateProposalRejectedEvent() { 14 | EventId eventId = EventId.newEventId(); 15 | UUID proposalId = UUID.randomUUID(); 16 | UUID reviewerId = UUID.randomUUID(); 17 | 18 | ProposalRejectedEvent actual = new ProposalRejectedEvent(eventId, proposalId, reviewerId); 19 | 20 | assertThat(actual.eventId()).isEqualTo(eventId); 21 | assertThat(actual.proposalId()).isEqualTo(proposalId); 22 | assertThat(actual.reviewerId()).isEqualTo(reviewerId); 23 | } 24 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offer/OfferNumberFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import com.smalaca.domaindrivendesign.Factory; 4 | import com.smalaca.opentrainings.domain.clock.Clock; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | @Factory 10 | class OfferNumberFactory { 11 | private final Clock clock; 12 | 13 | OfferNumberFactory(Clock clock) { 14 | this.clock = clock; 15 | } 16 | 17 | OfferNumber create() { 18 | LocalDateTime now = clock.now(); 19 | String orderNumber = "OFR/" + now.getYear() + "/" + monthFor(now) + "/" + UUID.randomUUID(); 20 | 21 | return new OfferNumber(orderNumber); 22 | } 23 | 24 | private String monthFor(LocalDateTime now) { 25 | int month = now.getMonthValue(); 26 | return month < 10 ? ("0" + month) : String.valueOf(month); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/offeracceptancesaga/events/PersonRegisteredEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class PersonRegisteredEventTest { 11 | @Test 12 | void shouldCreatePersonRegisteredEvent() { 13 | EventId eventId = EventId.newEventId(); 14 | UUID offerId = UUID.randomUUID(); 15 | UUID participantId = UUID.randomUUID(); 16 | 17 | PersonRegisteredEvent event = new PersonRegisteredEvent(eventId, offerId, participantId); 18 | 19 | assertThat(event.eventId()).isEqualTo(eventId); 20 | assertThat(event.offerId()).isEqualTo(offerId); 21 | assertThat(event.participantId()).isEqualTo(participantId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/events/DiscountCodeUsedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.opentrainings.domain.eventid.EventId; 5 | import com.smalaca.opentrainings.domain.offeracceptancesaga.OfferAcceptanceSaga; 6 | 7 | import java.math.BigDecimal; 8 | import java.time.LocalDateTime; 9 | import java.util.UUID; 10 | 11 | @DomainEvent 12 | public record DiscountCodeUsedEvent( 13 | EventId eventId, UUID offerId, UUID participantId, UUID trainingId, String discountCode, 14 | BigDecimal originalPrice, BigDecimal newPrice, String priceCurrency) implements OfferAcceptanceSagaEvent { 15 | @Override 16 | public void accept(OfferAcceptanceSaga offerAcceptanceSaga, LocalDateTime consumedAt) { 17 | offerAcceptanceSaga.accept(this, () -> consumedAt); 18 | } 19 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/query/trainingofferdraft/TrainingOfferDraftQueryService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.query.trainingofferdraft; 2 | 3 | import com.smalaca.architecture.cqrs.QueryOperation; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.Optional; 7 | import java.util.UUID; 8 | 9 | @Service 10 | public class TrainingOfferDraftQueryService { 11 | private final TrainingOfferDraftViewRepository repository; 12 | 13 | TrainingOfferDraftQueryService(TrainingOfferDraftViewRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | @QueryOperation 18 | public Iterable findAll() { 19 | return repository.findAll(); 20 | } 21 | 22 | @QueryOperation 23 | public Optional findById(UUID trainingOfferDraftId) { 24 | return repository.findById(trainingOfferDraftId); 25 | } 26 | } -------------------------------------------------------------------------------- /training-programs/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9050 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | scheduled: 10 | outbox: 11 | message: 12 | rate: 1000 13 | 14 | kafka: 15 | bootstrap-servers: localhost:9092 16 | group-id: training-programs 17 | topics: 18 | reviews: 19 | events: 20 | proposal-approved: reviews-proposal-approved-event-topic 21 | proposal-rejected: reviews-proposal-rejected-event-topic 22 | commands: 23 | register-proposal: reviews-register-proposal-command-topic 24 | trainingprogram: 25 | events: 26 | training-program-released: training-programs-training-program-released-event-topic 27 | training-program-rejected: training-programs-training-program-rejected-event-topic 28 | training-program-proposal-release-failed: training-programs-training-program-proposal-release-failed-topic 29 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/ConfirmTrainingPriceCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offer.events.ExpiredOfferAcceptanceRequestedEvent; 5 | 6 | import java.math.BigDecimal; 7 | import java.util.UUID; 8 | 9 | public record ConfirmTrainingPriceCommand(CommandId commandId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) implements OfferAcceptanceSagaCommand { 10 | public static ConfirmTrainingPriceCommand nextAfter(ExpiredOfferAcceptanceRequestedEvent event) { 11 | return new ConfirmTrainingPriceCommand( 12 | CommandId.nextAfter(event.eventId()), event.offerId(), event.trainingId(), 13 | event.trainingPriceAmount(), event.trainingPriceCurrencyCode()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/reviews/events/ProposalAssignedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.reviews.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class ProposalAssignedEventTest { 11 | 12 | @Test 13 | void shouldCreateProposalAssignedEvent() { 14 | EventId eventId = EventId.newEventId(); 15 | UUID proposalId = UUID.randomUUID(); 16 | UUID assignedReviewerId = UUID.randomUUID(); 17 | 18 | ProposalAssignedEvent actual = new ProposalAssignedEvent(eventId, proposalId, assignedReviewerId); 19 | 20 | assertThat(actual.eventId()).isEqualTo(eventId); 21 | assertThat(actual.proposalId()).isEqualTo(proposalId); 22 | assertThat(actual.assignedReviewerId()).isEqualTo(assignedReviewerId); 23 | } 24 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/application/trainingofferdraft/TrainingOfferDraftApplicationServiceFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.application.trainingofferdraft; 2 | 3 | import com.smalaca.trainingoffer.domain.eventregistry.EventRegistry; 4 | import com.smalaca.trainingoffer.domain.trainingofferdraft.TrainingOfferDraftFactory; 5 | import com.smalaca.trainingoffer.domain.trainingofferdraft.TrainingOfferDraftRepository; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | @Configuration 10 | public class TrainingOfferDraftApplicationServiceFactory { 11 | @Bean 12 | TrainingOfferDraftApplicationService trainingOfferDraftApplicationService(TrainingOfferDraftRepository repository, EventRegistry eventRegistry) { 13 | return new TrainingOfferDraftApplicationService(repository, eventRegistry, new TrainingOfferDraftFactory()); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingPriceNotChangedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class TrainingPriceNotChangedEventTest { 11 | @Test 12 | void shouldCreateTrainingPriceNotChangedEvent() { 13 | EventId eventId = EventId.newEventId(); 14 | UUID offerId = UUID.randomUUID(); 15 | UUID trainingOfferId = UUID.randomUUID(); 16 | 17 | TrainingPriceNotChangedEvent event = new TrainingPriceNotChangedEvent(eventId, offerId, trainingOfferId); 18 | 19 | assertThat(event.eventId()).isEqualTo(eventId); 20 | assertThat(event.offerId()).isEqualTo(offerId); 21 | assertThat(event.trainingOfferId()).isEqualTo(trainingOfferId); 22 | } 23 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/order/OrderNumberFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import com.smalaca.domaindrivendesign.Factory; 4 | import com.smalaca.opentrainings.domain.clock.Clock; 5 | 6 | import java.time.LocalDateTime; 7 | import java.util.UUID; 8 | 9 | @Factory 10 | class OrderNumberFactory { 11 | private final Clock clock; 12 | 13 | OrderNumberFactory(Clock clock) { 14 | this.clock = clock; 15 | } 16 | 17 | OrderNumber createFor(UUID participantId) { 18 | LocalDateTime now = clock.now(); 19 | String orderNumber = "ORD/" + now.getYear() + "/" + monthFor(now) + "/" + participantId + "/" + UUID.randomUUID(); 20 | 21 | return new OrderNumber(orderNumber); 22 | } 23 | 24 | private String monthFor(LocalDateTime now) { 25 | int month = now.getMonthValue(); 26 | return month < 10 ? ("0" + month) : String.valueOf(month); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/infrastructure/outbox/jpa/OutboxMessageTestListener.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.outbox.jpa; 2 | 3 | import com.smalaca.opentrainings.domain.offer.events.OfferRejectedEvent; 4 | import com.smalaca.opentrainings.domain.order.events.OrderRejectedEvent; 5 | import org.springframework.context.event.EventListener; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | @Component 12 | class OutboxMessageTestListener { 13 | List offerRejectedEvents = new ArrayList<>(); 14 | List orderRejectedEvents = new ArrayList<>(); 15 | 16 | @EventListener 17 | void listen(OfferRejectedEvent event) { 18 | offerRejectedEvents.add(event); 19 | } 20 | 21 | @EventListener 22 | void listen(OrderRejectedEvent event) { 23 | orderRejectedEvents.add(event); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/client/trainingoffer/trainingoffer/RestTrainingOfferTestResponseAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.client.trainingoffer.trainingoffer; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | import static org.springframework.http.HttpStatus.OK; 5 | 6 | public class RestTrainingOfferTestResponseAssertion { 7 | private final RestTrainingOfferTestResponse actual; 8 | 9 | private RestTrainingOfferTestResponseAssertion(RestTrainingOfferTestResponse actual) { 10 | this.actual = actual; 11 | } 12 | 13 | public static RestTrainingOfferTestResponseAssertion assertThatTrainingOfferResponse(RestTrainingOfferTestResponse actual) { 14 | return new RestTrainingOfferTestResponseAssertion(actual); 15 | } 16 | 17 | public RestTrainingOfferTestResponseAssertion isOk() { 18 | assertThat(actual.getStatus()).isEqualTo(OK.value()); 19 | return this; 20 | } 21 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/api/eventlistener/order/OrderEventListener.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.api.eventlistener.order; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.opentrainings.application.order.OrderApplicationService; 5 | import com.smalaca.opentrainings.domain.offer.events.OfferAcceptedEvent; 6 | import org.springframework.context.event.EventListener; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class OrderEventListener { 11 | private final OrderApplicationService orderApplicationService; 12 | 13 | OrderEventListener(OrderApplicationService orderApplicationService) { 14 | this.orderApplicationService = orderApplicationService; 15 | } 16 | 17 | @EventListener 18 | @DrivenAdapter 19 | public void listen(OfferAcceptedEvent event) { 20 | orderApplicationService.initiate(event); 21 | } 22 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/repository/jpa/trainingprogram/JpaTrainingProgramRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.repository.jpa.trainingprogram; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.trainingprograms.domain.trainingprogram.TrainingProgram; 5 | import com.smalaca.trainingprograms.domain.trainingprogram.TrainingProgramRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | @Repository 9 | @DrivenAdapter 10 | public class JpaTrainingProgramRepository implements TrainingProgramRepository { 11 | private final SpringTrainingProgramCrudRepository repository; 12 | 13 | JpaTrainingProgramRepository(SpringTrainingProgramCrudRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | @Override 18 | public void save(TrainingProgram trainingProgram) { 19 | repository.save(trainingProgram); 20 | } 21 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/events/TrainingPriceChangedEvent.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer.events; 2 | 3 | import com.smalaca.domaindrivendesign.DomainEvent; 4 | import com.smalaca.trainingoffer.domain.eventid.EventId; 5 | import com.smalaca.trainingoffer.domain.price.Price; 6 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.ConfirmTrainingPriceCommand; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.UUID; 10 | 11 | @DomainEvent 12 | public record TrainingPriceChangedEvent(EventId eventId, UUID offerId, UUID trainingOfferId, BigDecimal priceAmount, String priceCurrencyCode) implements TrainingOfferEvent { 13 | 14 | public static TrainingPriceChangedEvent nextAfter(ConfirmTrainingPriceCommand command, Price price) { 15 | return new TrainingPriceChangedEvent(command.commandId().nextEventId(), command.offerId(), command.trainingOfferId(), price.amount(), price.currencyCode()); 16 | } 17 | } -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/offeracceptancesaga/events/AlreadyRegisteredPersonFoundEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.offeracceptancesaga.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class AlreadyRegisteredPersonFoundEventTest { 11 | @Test 12 | void shouldCreateAlreadyRegisteredPersonFoundEvent() { 13 | EventId eventId = EventId.newEventId(); 14 | UUID offerId = UUID.randomUUID(); 15 | UUID participantId = UUID.randomUUID(); 16 | 17 | AlreadyRegisteredPersonFoundEvent event = new AlreadyRegisteredPersonFoundEvent(eventId, offerId, participantId); 18 | 19 | assertThat(event.eventId()).isEqualTo(eventId); 20 | assertThat(event.offerId()).isEqualTo(offerId); 21 | assertThat(event.participantId()).isEqualTo(participantId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /discount-management/src/test/java/com/smalaca/discountmanagement/api/EventIdAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.discountmanagement.api; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | import com.smalaca.schemaregistry.metadata.EventId; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | class EventIdAssertion { 9 | private final EventId actual; 10 | 11 | private EventIdAssertion(EventId actual) { 12 | this.actual = actual; 13 | } 14 | 15 | static EventIdAssertion assertThatEventId(EventId actual) { 16 | return new EventIdAssertion(actual); 17 | } 18 | 19 | void isNextAfter(CommandId commandId) { 20 | assertThat(actual.traceId()).isEqualTo(commandId.traceId()); 21 | assertThat(actual.correlationId()).isEqualTo(commandId.correlationId()); 22 | assertThat(actual.eventId()).isNotEqualTo(commandId.commandId()); 23 | assertThat(actual.creationDateTime()).isAfterOrEqualTo(commandId.creationDateTime()); 24 | } 25 | } -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/order/events/OrderRejectedEventAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order.events; 2 | 3 | import java.util.UUID; 4 | 5 | import static org.assertj.core.api.Assertions.assertThat; 6 | 7 | public class OrderRejectedEventAssertion { 8 | private final OrderRejectedEvent actual; 9 | 10 | private OrderRejectedEventAssertion(OrderRejectedEvent actual) { 11 | this.actual = actual; 12 | } 13 | 14 | public static OrderRejectedEventAssertion assertThatOrderRejectedEvent(OrderRejectedEvent actual) { 15 | return new OrderRejectedEventAssertion(actual); 16 | } 17 | 18 | public OrderRejectedEventAssertion hasOrderId(UUID expected) { 19 | assertThat(actual.orderId()).isEqualTo(expected); 20 | return this; 21 | } 22 | 23 | public OrderRejectedEventAssertion hasReason(String expected) { 24 | assertThat(actual.reason()).isEqualTo(expected); 25 | return this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/query/trainingprogramproposal/TrainingProgramProposalQueryService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.query.trainingprogramproposal; 2 | 3 | import com.smalaca.architecture.cqrs.QueryOperation; 4 | import org.springframework.stereotype.Service; 5 | 6 | import java.util.Optional; 7 | import java.util.UUID; 8 | 9 | @Service 10 | public class TrainingProgramProposalQueryService { 11 | private final TrainingProgramProposalViewRepository repository; 12 | 13 | TrainingProgramProposalQueryService(TrainingProgramProposalViewRepository repository) { 14 | this.repository = repository; 15 | } 16 | 17 | @QueryOperation 18 | public Iterable findAll() { 19 | return repository.findAll(); 20 | } 21 | 22 | @QueryOperation 23 | public Optional findById(UUID trainingProgramProposalId) { 24 | return repository.findById(trainingProgramProposalId); 25 | } 26 | } -------------------------------------------------------------------------------- /personal-data-management/src/test/java/com/smalaca/personaldatamanagement/api/EventIdAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.personaldatamanagement.api; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | import com.smalaca.schemaregistry.metadata.EventId; 5 | 6 | import static org.assertj.core.api.Assertions.assertThat; 7 | 8 | class EventIdAssertion { 9 | private final EventId actual; 10 | 11 | private EventIdAssertion(EventId actual) { 12 | this.actual = actual; 13 | } 14 | 15 | static EventIdAssertion assertThatEventId(EventId actual) { 16 | return new EventIdAssertion(actual); 17 | } 18 | 19 | void isNextAfter(CommandId commandId) { 20 | assertThat(actual.traceId()).isEqualTo(commandId.traceId()); 21 | assertThat(actual.correlationId()).isEqualTo(commandId.correlationId()); 22 | assertThat(actual.eventId()).isNotEqualTo(commandId.commandId()); 23 | assertThat(actual.creationDateTime()).isAfterOrEqualTo(commandId.creationDateTime()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/trainingprogram/events/TrainingProgramRejectedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingprogram.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class TrainingProgramRejectedEventTest { 11 | 12 | @Test 13 | void shouldCreateTrainingProgramRejectedEvent() { 14 | EventId eventId = EventId.newEventId(); 15 | UUID trainingProgramProposalId = UUID.randomUUID(); 16 | UUID reviewerId = UUID.randomUUID(); 17 | 18 | TrainingProgramRejectedEvent actual = new TrainingProgramRejectedEvent(eventId, trainingProgramProposalId, reviewerId); 19 | 20 | assertThat(actual.eventId()).isEqualTo(eventId); 21 | assertThat(actual.trainingProgramProposalId()).isEqualTo(trainingProgramProposalId); 22 | assertThat(actual.reviewerId()).isEqualTo(reviewerId); 23 | } 24 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/eventid/EventId.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.eventid; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | 5 | import java.time.LocalDateTime; 6 | import java.util.UUID; 7 | 8 | import static java.time.LocalDateTime.now; 9 | 10 | public record EventId(UUID eventId, UUID traceId, UUID correlationId, LocalDateTime creationDateTime) { 11 | public static EventId newEventId() { 12 | return new EventId(id(), id(), id(), now()); 13 | } 14 | 15 | public static EventId nextAfter(CommandId commandId) { 16 | return new EventId(id(), commandId.traceId(), commandId.correlationId(), now()); 17 | } 18 | 19 | public CommandId nextCommandId() { 20 | return CommandId.nextAfter(this); 21 | } 22 | 23 | public EventId nextEventId() { 24 | return new EventId(id(), traceId, correlationId, now()); 25 | } 26 | 27 | private static UUID id() { 28 | return UUID.randomUUID(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/application/order/OrderApplicationServiceFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.application.order; 2 | 3 | import com.smalaca.opentrainings.domain.clock.Clock; 4 | import com.smalaca.opentrainings.domain.eventregistry.EventRegistry; 5 | import com.smalaca.opentrainings.domain.order.OrderRepository; 6 | import com.smalaca.opentrainings.domain.paymentgateway.PaymentGateway; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | import static com.smalaca.opentrainings.domain.order.OrderFactory.orderFactory; 11 | 12 | @Configuration 13 | public class OrderApplicationServiceFactory { 14 | @Bean 15 | public OrderApplicationService orderApplicationService( 16 | OrderRepository orderRepository, EventRegistry eventRegistry, PaymentGateway paymentGateway, Clock clock) { 17 | return new OrderApplicationService(orderFactory(clock), orderRepository, eventRegistry, paymentGateway, clock); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/UseDiscountCodeCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.OfferAcceptanceSagaEvent; 5 | 6 | import java.math.BigDecimal; 7 | import java.util.UUID; 8 | 9 | public record UseDiscountCodeCommand( 10 | CommandId commandId, UUID offerId, UUID participantId, UUID trainingId, BigDecimal priceAmount, String priceCurrencyCode, String discountCode) implements OfferAcceptanceSagaCommand { 11 | public static UseDiscountCodeCommand nextAfter(OfferAcceptanceSagaEvent event, UUID participantId, UUID trainingId, BigDecimal priceAmount, String priceCurrencyCode, String discountCode) { 12 | return new UseDiscountCodeCommand( 13 | CommandId.nextAfter(event.eventId()), event.offerId(), participantId, trainingId, priceAmount, priceCurrencyCode, discountCode); 14 | } 15 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.smalaca 8 | training-center 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | annotations 14 | annotations-test 15 | schema-registry 16 | 17 | discount-management 18 | open-trainings 19 | payment-gateway 20 | personal-data-management 21 | trainings-catalogue 22 | training-offer 23 | training-programs 24 | reviews 25 | 26 | 27 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/offer/OfferNumberAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offer; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | public class OfferNumberAssertion { 6 | private static final String UUID_REGEX = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"; 7 | private static final String OFFER_NUMBER_PATTERN = "OFR/20[0-9]{2}/[01][0-9]/" + UUID_REGEX ; 8 | 9 | private final OfferNumber actual; 10 | 11 | private OfferNumberAssertion(OfferNumber actual) { 12 | this.actual = actual; 13 | } 14 | 15 | public static OfferNumberAssertion assertThatOfferNumber(String actual) { 16 | return assertThatOfferNumber(new OfferNumber(actual)); 17 | } 18 | 19 | static OfferNumberAssertion assertThatOfferNumber(OfferNumber actual) { 20 | return new OfferNumberAssertion(actual); 21 | } 22 | 23 | public void isValid() { 24 | assertThat(actual.value()).matches(OFFER_NUMBER_PATTERN); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/application/trainingoffer/TrainingOfferApplicationServiceFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.application.trainingoffer; 2 | 3 | import com.smalaca.trainingoffer.domain.eventregistry.EventRegistry; 4 | import com.smalaca.trainingoffer.domain.trainingoffer.TrainingOfferDomainService; 5 | import com.smalaca.trainingoffer.domain.trainingoffer.TrainingOfferFactory; 6 | import com.smalaca.trainingoffer.domain.trainingoffer.TrainingOfferRepository; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | @Configuration 11 | public class TrainingOfferApplicationServiceFactory { 12 | @Bean 13 | TrainingOfferApplicationService trainingOfferApplicationService(TrainingOfferRepository repository, EventRegistry eventRegistry) { 14 | TrainingOfferFactory factory = new TrainingOfferFactory(); 15 | return new TrainingOfferApplicationService(repository, factory, new TrainingOfferDomainService(factory), eventRegistry); 16 | } 17 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/api/kafka/TrainingOfferKafkaListener.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.api.kafka; 2 | 3 | import com.smalaca.schemaregistry.trainingoffer.events.TrainingOfferPublishedEvent; 4 | import com.smalaca.trainingscatalogue.trainingoffer.TrainingOfferService; 5 | import org.springframework.kafka.annotation.KafkaListener; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class TrainingOfferKafkaListener { 10 | private final TrainingOfferService trainingOfferService; 11 | 12 | TrainingOfferKafkaListener(TrainingOfferService trainingOfferService) { 13 | this.trainingOfferService = trainingOfferService; 14 | } 15 | 16 | @KafkaListener( 17 | topics = "${kafka.topics.trainingoffer.events.training-offer-published}", 18 | groupId = "${kafka.group-id}", 19 | containerFactory = "listenerContainerFactory") 20 | public void listen(TrainingOfferPublishedEvent event) { 21 | trainingOfferService.handle(event); 22 | } 23 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/offer/JpaOfferRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.offer; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.opentrainings.domain.offer.Offer; 5 | import com.smalaca.opentrainings.domain.offer.OfferRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.UUID; 9 | 10 | @Repository 11 | @DrivenAdapter 12 | public class JpaOfferRepository implements OfferRepository { 13 | private final SpringOfferCrudRepository repository; 14 | 15 | JpaOfferRepository(SpringOfferCrudRepository repository) { 16 | this.repository = repository; 17 | } 18 | 19 | @Override 20 | public Offer findById(UUID offerId) { 21 | return repository.findById(offerId).orElseThrow(() -> new OfferDoesNotExistException(offerId)); 22 | } 23 | 24 | @Override 25 | public UUID save(Offer offer) { 26 | return repository.save(offer).offerId(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/infrastructure/repository/jpa/order/JpaOrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.infrastructure.repository.jpa.order; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.opentrainings.domain.order.Order; 5 | import com.smalaca.opentrainings.domain.order.OrderRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.UUID; 9 | 10 | @Repository 11 | @DrivenAdapter 12 | public class JpaOrderRepository implements OrderRepository { 13 | private final SpringOrderCrudRepository repository; 14 | 15 | JpaOrderRepository(SpringOrderCrudRepository repository) { 16 | this.repository = repository; 17 | } 18 | 19 | @Override 20 | public Order findById(UUID orderId) { 21 | return repository.findById(orderId).orElseThrow(() -> new OrderDoesNotExistException(orderId)); 22 | } 23 | 24 | @Override 25 | public UUID save(Order order) { 26 | return repository.save(order).orderId(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /reviews/src/main/java/com/smalaca/reviews/infrastructure/repository/jpa/proposal/JpaProposalRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.reviews.infrastructure.repository.jpa.proposal; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.reviews.domain.proposal.Proposal; 5 | import com.smalaca.reviews.domain.proposal.ProposalRepository; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.util.UUID; 9 | 10 | @Repository 11 | @DrivenAdapter 12 | public class JpaProposalRepository implements ProposalRepository { 13 | private final SpringProposalCrudRepository repository; 14 | 15 | JpaProposalRepository(SpringProposalCrudRepository repository) { 16 | this.repository = repository; 17 | } 18 | 19 | @Override 20 | public void save(Proposal proposal) { 21 | repository.save(proposal); 22 | } 23 | 24 | @Override 25 | public Proposal findById(UUID proposalId) { 26 | return repository.findById(proposalId).orElseThrow(() -> new ProposalDoesNotExistException(proposalId)); 27 | } 28 | } -------------------------------------------------------------------------------- /training-programs/src/main/java/com/smalaca/trainingprograms/infrastructure/outbox/jpa/JpaOutboxMessageRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingprograms.infrastructure.outbox.jpa; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivenAdapter; 4 | import com.smalaca.trainingprograms.domain.eventregistry.EventRegistry; 5 | import com.smalaca.trainingprograms.domain.trainingprogramproposal.events.TrainingProgramProposalEvent; 6 | 7 | @DrivenAdapter 8 | class JpaOutboxMessageRepository implements EventRegistry { 9 | private final SpringOutboxMessageCrudRepository repository; 10 | private final OutboxMessageMapper outboxMessageMapper; 11 | 12 | JpaOutboxMessageRepository(SpringOutboxMessageCrudRepository repository, OutboxMessageMapper outboxMessageMapper) { 13 | this.repository = repository; 14 | this.outboxMessageMapper = outboxMessageMapper; 15 | } 16 | 17 | @Override 18 | public void publish(TrainingProgramProposalEvent event) { 19 | repository.save(outboxMessageMapper.outboxMessage(event.eventId(), event)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /open-trainings/src/test/java/com/smalaca/opentrainings/domain/order/OrderNumberAssertion.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.order; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | public class OrderNumberAssertion { 6 | private static final String UUID_REGEX = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}"; 7 | private static final String ORDER_NUMBER_PATTERN = "ORD/20[0-9]{2}/[01][0-9]/" + UUID_REGEX + "/" + UUID_REGEX; 8 | 9 | private final OrderNumber actual; 10 | 11 | private OrderNumberAssertion(OrderNumber actual) { 12 | this.actual = actual; 13 | } 14 | 15 | public static OrderNumberAssertion assertThatOrderNumber(String actual) { 16 | return assertThatOrderNumber(new OrderNumber(actual)); 17 | } 18 | 19 | static OrderNumberAssertion assertThatOrderNumber(OrderNumber actual) { 20 | return new OrderNumberAssertion(actual); 21 | } 22 | 23 | public void isValid() { 24 | assertThat(actual.value()).matches(ORDER_NUMBER_PATTERN); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/trainingoffer/events/TrainingPlaceBookedEventTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.events; 2 | 3 | import com.smalaca.schemaregistry.metadata.EventId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class TrainingPlaceBookedEventTest { 11 | @Test 12 | void shouldCreateTrainingPlaceBookedEvent() { 13 | EventId eventId = EventId.newEventId(); 14 | UUID offerId = UUID.randomUUID(); 15 | UUID participantId = UUID.randomUUID(); 16 | UUID trainingOfferId = UUID.randomUUID(); 17 | 18 | TrainingPlaceBookedEvent event = new TrainingPlaceBookedEvent(eventId, offerId, participantId, trainingOfferId); 19 | 20 | assertThat(event.eventId()).isEqualTo(eventId); 21 | assertThat(event.offerId()).isEqualTo(offerId); 22 | assertThat(event.participantId()).isEqualTo(participantId); 23 | assertThat(event.trainingOfferId()).isEqualTo(trainingOfferId); 24 | } 25 | } -------------------------------------------------------------------------------- /training-offer/src/test/java/com/smalaca/trainingoffer/domain/trainingofferdraft/GivenTrainingOfferDraftWithRepository.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingofferdraft; 2 | 3 | class GivenTrainingOfferDraftWithRepository extends GivenTrainingOfferDraft { 4 | private final TrainingOfferDraftRepository repository; 5 | 6 | GivenTrainingOfferDraftWithRepository(TrainingOfferDraftFactory factory, TrainingOfferDraftRepository repository) { 7 | super(factory); 8 | this.repository = repository; 9 | } 10 | 11 | @Override 12 | public GivenTrainingOfferDraft initiated() { 13 | super.initiated(); 14 | saveTrainingOfferDraft(); 15 | return this; 16 | } 17 | 18 | @Override 19 | public GivenTrainingOfferDraft published() { 20 | super.published(); 21 | saveTrainingOfferDraft(); 22 | return this; 23 | } 24 | 25 | private void saveTrainingOfferDraft() { 26 | TrainingOfferDraft trainingOfferDraft = getTrainingOfferDraft(); 27 | repository.save(trainingOfferDraft); 28 | } 29 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/application/offer/OfferApplicationServiceFactory.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.application.offer; 2 | 3 | import com.smalaca.opentrainings.domain.clock.Clock; 4 | import com.smalaca.opentrainings.domain.eventregistry.EventRegistry; 5 | import com.smalaca.opentrainings.domain.offer.OfferFactory; 6 | import com.smalaca.opentrainings.domain.offer.OfferRepository; 7 | import com.smalaca.opentrainings.domain.trainingoffercatalogue.TrainingOfferCatalogue; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | 11 | @Configuration 12 | public class OfferApplicationServiceFactory { 13 | @Bean 14 | public OfferApplicationService offerApplicationService( 15 | OfferRepository offerRepository, EventRegistry eventRegistry, TrainingOfferCatalogue trainingOfferCatalogue, 16 | Clock clock) { 17 | return new OfferApplicationService(OfferFactory.offerFactory(trainingOfferCatalogue, clock), offerRepository, eventRegistry, clock); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/infrastructure/api/eventlistener/spring/TrainingOfferListener.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.infrastructure.api.eventlistener.spring; 2 | 3 | import com.smalaca.architecture.portsandadapters.DrivingAdapter; 4 | import com.smalaca.trainingoffer.application.trainingoffer.TrainingOfferApplicationService; 5 | import com.smalaca.trainingoffer.domain.trainingofferdraft.events.TrainingOfferPublishedEvent; 6 | import org.springframework.context.event.EventListener; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | public class TrainingOfferListener { 11 | private final TrainingOfferApplicationService trainingOfferApplicationService; 12 | 13 | TrainingOfferListener(TrainingOfferApplicationService trainingOfferApplicationService) { 14 | this.trainingOfferApplicationService = trainingOfferApplicationService; 15 | } 16 | 17 | @EventListener 18 | @DrivingAdapter 19 | public void listen(TrainingOfferPublishedEvent event) { 20 | trainingOfferApplicationService.create(event); 21 | } 22 | } -------------------------------------------------------------------------------- /trainings-catalogue/src/main/java/com/smalaca/trainingscatalogue/api/kafka/TrainingProgramKafkaListener.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingscatalogue.api.kafka; 2 | 3 | import com.smalaca.schemaregistry.trainingprogram.events.TrainingProgramReleasedEvent; 4 | import com.smalaca.trainingscatalogue.trainingprogram.TrainingProgramService; 5 | import org.springframework.kafka.annotation.KafkaListener; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class TrainingProgramKafkaListener { 10 | private final TrainingProgramService trainingProgramService; 11 | 12 | TrainingProgramKafkaListener(TrainingProgramService trainingProgramService) { 13 | this.trainingProgramService = trainingProgramService; 14 | } 15 | 16 | @KafkaListener( 17 | topics = "${kafka.topics.trainingprogram.events.training-program-released}", 18 | groupId = "${kafka.group-id}", 19 | containerFactory = "listenerContainerFactory") 20 | public void listen(TrainingProgramReleasedEvent event) { 21 | trainingProgramService.handle(event); 22 | } 23 | } -------------------------------------------------------------------------------- /training-offer/src/main/java/com/smalaca/trainingoffer/domain/trainingoffer/TrainingOfferDomainService.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.trainingoffer.domain.trainingoffer; 2 | 3 | import com.smalaca.domaindrivendesign.DomainService; 4 | import com.smalaca.trainingoffer.domain.trainingoffer.commands.RescheduleTrainingOfferCommand; 5 | import com.smalaca.trainingoffer.domain.trainingoffer.events.TrainingOfferRescheduledEvent; 6 | 7 | @DomainService 8 | public class TrainingOfferDomainService { 9 | private final TrainingOfferFactory factory; 10 | 11 | public TrainingOfferDomainService(TrainingOfferFactory factory) { 12 | this.factory = factory; 13 | } 14 | 15 | public RescheduledTrainingOffer reschedule(TrainingOffer trainingOffer, RescheduleTrainingOfferCommand command) { 16 | TrainingOfferRescheduledEvent trainingOfferRescheduledEvent = trainingOffer.reschedule(command); 17 | TrainingOffer newtrainingOffer = factory.create(trainingOfferRescheduledEvent); 18 | 19 | return new RescheduledTrainingOffer(newtrainingOffer, trainingOfferRescheduledEvent); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/query/offer/OfferView.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.query.offer; 2 | 3 | import jakarta.persistence.Column; 4 | import jakarta.persistence.Entity; 5 | import jakarta.persistence.Id; 6 | import jakarta.persistence.Table; 7 | import lombok.Getter; 8 | 9 | import java.math.BigDecimal; 10 | import java.time.LocalDateTime; 11 | import java.util.UUID; 12 | 13 | @Entity 14 | @Table(name = "OFFERS") 15 | @Getter 16 | public class OfferView { 17 | @Id 18 | @Column(name = "OFFER_ID") 19 | private UUID offerId; 20 | 21 | @Column(name = "TRAINING_ID") 22 | private UUID trainingId; 23 | 24 | @Column(name = "OFFER_NUMBER") 25 | private String offerNumber; 26 | 27 | @Column(name = "TRAINING_PRICE_AMOUNT") 28 | private BigDecimal trainingPriceAmount; 29 | 30 | @Column(name = "TRAINING_PRICE_CURRENCY") 31 | private String trainingPriceCurrency; 32 | 33 | @Column(name = "CREATION_DATE_TIME") 34 | private LocalDateTime creationDateTime; 35 | 36 | @Column(name = "STATUS") 37 | private String status; 38 | } 39 | -------------------------------------------------------------------------------- /training-offer/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9040 3 | 4 | spring: 5 | jackson: 6 | serialization: 7 | indent_output: true 8 | 9 | scheduled: 10 | outbox: 11 | message: 12 | rate: 1000 13 | 14 | kafka: 15 | bootstrap-servers: localhost:9092 16 | group-id: training-offer 17 | topics: 18 | trainingoffer: 19 | commands: 20 | confirm-training-price: training-offer-confirm-training-price-command-topic 21 | book-training-place: training-offer-book-training-place-command-topic 22 | events: 23 | training-offer-published: training-offer-training-offer-published-event-topic 24 | training-offer-rescheduled: training-offer-training-offer-rescheduled-event-topic 25 | training-price-changed: training-offer-training-price-changed-event-topic 26 | training-price-not-changed: training-offer-training-price-not-changed-event-topic 27 | training-place-booked: training-offer-training-place-booked-event-topic 28 | no-available-training-places-left: training-offer-no-available-training-places-left-event-topic 29 | -------------------------------------------------------------------------------- /schema-registry/src/test/java/com/smalaca/schemaregistry/trainingoffer/commands/BookTrainingPlaceCommandTest.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.schemaregistry.trainingoffer.commands; 2 | 3 | import com.smalaca.schemaregistry.metadata.CommandId; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.UUID; 7 | 8 | import static org.assertj.core.api.Assertions.assertThat; 9 | 10 | class BookTrainingPlaceCommandTest { 11 | @Test 12 | void shouldCreateBookTrainingPlaceCommand() { 13 | CommandId commandId = CommandId.newCommandId(); 14 | UUID offerId = UUID.randomUUID(); 15 | UUID participantId = UUID.randomUUID(); 16 | UUID trainingOfferId = UUID.randomUUID(); 17 | 18 | BookTrainingPlaceCommand command = new BookTrainingPlaceCommand(commandId, offerId, participantId, trainingOfferId); 19 | 20 | assertThat(command.commandId()).isEqualTo(commandId); 21 | assertThat(command.offerId()).isEqualTo(offerId); 22 | assertThat(command.participantId()).isEqualTo(participantId); 23 | assertThat(command.trainingOfferId()).isEqualTo(trainingOfferId); 24 | } 25 | } -------------------------------------------------------------------------------- /open-trainings/src/main/java/com/smalaca/opentrainings/domain/offeracceptancesaga/commands/RejectOfferCommand.java: -------------------------------------------------------------------------------- 1 | package com.smalaca.opentrainings.domain.offeracceptancesaga.commands; 2 | 3 | import com.smalaca.opentrainings.domain.commandid.CommandId; 4 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.NoAvailableTrainingPlacesLeftEvent; 5 | import com.smalaca.opentrainings.domain.offeracceptancesaga.events.TrainingPriceChangedEvent; 6 | 7 | import java.util.UUID; 8 | 9 | public record RejectOfferCommand(CommandId commandId, UUID offerId, String reason) implements OfferAcceptanceSagaCommand { 10 | public static RejectOfferCommand nextAfter(TrainingPriceChangedEvent event) { 11 | return new RejectOfferCommand(event.eventId().nextCommandId(), event.offerId(), "Training price changed to: " + event.priceAmount() + " " + event.priceCurrencyCode()); 12 | } 13 | 14 | public static RejectOfferCommand nextAfter(NoAvailableTrainingPlacesLeftEvent event) { 15 | return new RejectOfferCommand(event.eventId().nextCommandId(), event.offerId(), "No available training places left"); 16 | } 17 | } 18 | --------------------------------------------------------------------------------