├── .github └── workflows │ └── buildPipeline.yml ├── .gitignore ├── .nuke ├── build.schema.json └── parameters.json ├── LICENSE ├── README.md ├── azure-pipelines.yml ├── build.cmd ├── build.ps1 ├── build.sh ├── build ├── .editorconfig ├── Build.cs ├── BuildIntegrationTests.cs ├── Configuration.cs ├── Database.cs ├── Directory.Build.props ├── Directory.Build.targets ├── SUTCreator.cs ├── Utils │ └── SqlReadinessChecker.cs ├── _build.csproj └── _build.csproj.DotSettings ├── docker-compose.yml ├── docs ├── C4 │ ├── c1_system_context.puml │ ├── c2_container.puml │ ├── c3_components.puml │ ├── c3_components_module.puml │ └── c4_class.puml ├── Images │ ├── Architecture_high_level.png │ ├── CQRS.jpg │ ├── Conceptual_Model.png │ ├── Decorator.jpg │ ├── ES_command_handling.png │ ├── ES_elements.jpg │ ├── ES_event_store_db_sample.png │ ├── ES_events_projection.png │ ├── Meeting_Group_Creation.jpg │ ├── Meeting_Organization.jpg │ ├── Module_level_diagram.png │ ├── OutboxInbox.jpg │ ├── OutboxProcessing.png │ ├── OutboxSave.png │ ├── Payments_EventStorming_Design.jpg │ ├── Payments_EventStorming_Design_HighRes.jpg │ ├── SystemIntegrationTests.jpg │ ├── UnitTestsGeneral.jpg │ ├── User_Registration.jpg │ ├── VSSolution.png │ ├── architecture_unit_tests.png │ ├── ci.jpg │ ├── ci_job1.png │ ├── ci_job2.png │ ├── glory_to_ukraine.jpg │ ├── integration_tests.jpg │ ├── mutation_testing_example.png │ ├── mutation_testing_report.png │ ├── sut-preparation.jpg │ └── unit_tests.jpg ├── PlantUML │ ├── Commenting_Conceptual_Model.puml │ └── Conceptual_Model.puml ├── Project │ └── MyMeetings.vpp ├── architecture-decision-log │ ├── 0001-record-architecture-decisions.md │ ├── 0002-use_modular-monolith-system-architecture.md │ ├── 0003-use_dotnetcore_and_csharp.md │ ├── 0004-divide-the-system-into-4-modules.md │ ├── 0005-create-one-rest-api-module.md │ ├── 0006-create-facade-between-api-and-business-module.md │ ├── 0007-use-cqrs-architectural-style.md │ ├── 0008-allow-return-result-after-command-processing.md │ ├── 0009-use-2-layered-architectural-style-for-reads.md │ ├── 0010-use-clean-architecture-for-writes.md │ ├── 0011-create-rich-domain-models.md │ ├── 0012-use-domain-driven-design-tactical-patterns.md │ ├── 0013-protect-business-invariants-using-exceptions.md │ ├── 0014-event-driven-communication-between-modules.md │ ├── 0015-use-in-memory-events-bus.md │ ├── 0016-create-ioc-container-per-module.md │ └── 0017-implement-archictecture-tests.md ├── catalog-of-terms │ ├── Aggregate-DDD │ │ ├── README.md │ │ └── aggregate-ddd.puml │ ├── Command │ │ ├── README.md │ │ └── command.puml │ ├── Decorator-Pattern │ │ ├── README.md │ │ └── decorator-pattern.puml │ ├── Dependency-Injection │ │ ├── README.md │ │ └── dependency-injection.puml │ ├── Domain-Event │ │ ├── README.md │ │ └── domain-event.puml │ ├── Entity-DDD │ │ ├── README.md │ │ └── entity-ddd.puml │ ├── Event-Driven-Architecture │ │ └── README.md │ ├── Event-Sourcing │ │ └── README.md │ ├── Event-Storming │ │ └── README.md │ ├── Event │ │ └── README.md │ ├── Integration-Event │ │ └── README.md │ ├── README.md │ ├── Strategy-Pattern │ │ ├── README.md │ │ └── strategy-pattern.puml │ └── ValueObject-DDD │ │ ├── README.md │ │ └── value-object-ddd.puml └── mutation-tests-reports │ └── mutation-report.html ├── runIntegrationTests.cmd └── src ├── .dockerignore ├── .editorconfig ├── API ├── CompanyName.MyMeetings.API │ ├── CompanyName.MyMeetings.API.csproj │ ├── Configuration │ │ ├── Authorization │ │ │ ├── AttributeAuthorizationHandler.cs │ │ │ ├── AuthorizationChecker.cs │ │ │ ├── HasPermissionAttribute.cs │ │ │ ├── HasPermissionAuthorizationHandler.cs │ │ │ ├── HasPermissionAuthorizationRequirement.cs │ │ │ └── NoPermissionRequiredAttribute.cs │ │ ├── ExecutionContext │ │ │ ├── CorrelationMiddleware.cs │ │ │ └── ExecutionContextAccessor.cs │ │ ├── Extensions │ │ │ └── SwaggerExtensions.cs │ │ └── Validation │ │ │ ├── BusinessRuleValidationExceptionProblemDetails.cs │ │ │ └── InvalidCommandProblemDetails.cs │ ├── Modules │ │ ├── Administration │ │ │ ├── AdministrationAutofacModule.cs │ │ │ ├── AdministrationPermissions.cs │ │ │ └── MeetingGroupProposals │ │ │ │ └── MeetingGroupProposalsController.cs │ │ ├── Meetings │ │ │ ├── Countries │ │ │ │ └── CountriesController.cs │ │ │ ├── MeetingCommentingConfiguration │ │ │ │ └── MeetingCommentingConfigurationController.cs │ │ │ ├── MeetingComments │ │ │ │ ├── AddMeetingCommentRequest.cs │ │ │ │ ├── EditMeetingCommentRequest.cs │ │ │ │ └── MeetingCommentsController.cs │ │ │ ├── MeetingGroupProposals │ │ │ │ ├── MeetingGroupProposalsController.cs │ │ │ │ └── ProposeMeetingGroupRequest.cs │ │ │ ├── MeetingGroups │ │ │ │ ├── CreateNewMeetingGroupRequest.cs │ │ │ │ ├── EditMeetingGroupGeneralAttributesRequest.cs │ │ │ │ └── MeetingGroupsController.cs │ │ │ ├── Meetings │ │ │ │ ├── AddMeetingAttendeeRequest.cs │ │ │ │ ├── ChangeMeetingMainAttributesRequest.cs │ │ │ │ ├── CreateMeetingRequest.cs │ │ │ │ ├── MeetingsController.cs │ │ │ │ ├── RemoveMeetingAttendeeRequest.cs │ │ │ │ ├── SetMeetingAttendeeRequest.cs │ │ │ │ └── SetMeetingHostRequest.cs │ │ │ ├── MeetingsAutofacModule.cs │ │ │ └── MeetingsPermissions.cs │ │ ├── Payments │ │ │ ├── MeetingFees │ │ │ │ ├── CreateMeetingFeePaymentRequest.cs │ │ │ │ ├── MeetingFeePaymentsController.cs │ │ │ │ └── RegisterMeetingFeePaymentRequest.cs │ │ │ ├── Payers │ │ │ │ └── PayersController.cs │ │ │ ├── PaymentsAutofacModule.cs │ │ │ ├── PaymentsPermissions.cs │ │ │ ├── PriceListItems │ │ │ │ ├── ChangePriceListItemAttributesRequest.cs │ │ │ │ ├── CreatePriceListItemRequest.cs │ │ │ │ ├── GetPriceListItemRequest.cs │ │ │ │ └── PriceListItemsController.cs │ │ │ ├── RegisterSubscriptionRenewalPaymentRequest.cs │ │ │ ├── SubscriptionRenewalsController.cs │ │ │ └── Subscriptions │ │ │ │ ├── BuySubscriptionRequest.cs │ │ │ │ ├── RegisterSubscriptionPaymentRequest.cs │ │ │ │ ├── RenewSubscriptionRequest.cs │ │ │ │ ├── SubscriptionPaymentsController.cs │ │ │ │ └── SubscriptionsController.cs │ │ └── UserAccess │ │ │ ├── AuthenticatedUserController.cs │ │ │ ├── EmailsController.cs │ │ │ ├── RegisterNewUserRequest.cs │ │ │ ├── ResourceOwnerPasswordValidator.cs │ │ │ ├── UserAccessAutofacModule.cs │ │ │ └── UserRegistrationsController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.Production.json │ ├── appsettings.json │ ├── entrypoint.sh │ └── tempkey.rsa └── RequestExamples │ ├── Authentication.http │ ├── Users.http │ └── http-client.env.json ├── BuildingBlocks ├── Application │ ├── CompanyName.MyMeetings.BuildingBlocks.Application.csproj │ ├── Data │ │ └── ISqlConnectionFactory.cs │ ├── Emails │ │ ├── EmailMessage.cs │ │ └── IEmailSender.cs │ ├── Events │ │ ├── DomainNotificationBase.cs │ │ └── IDomainEventNotification.cs │ ├── IExecutionContextAccessor.cs │ ├── InvalidCommandException.cs │ ├── Outbox │ │ ├── IOutbox.cs │ │ └── OutboxMessage.cs │ └── Queries │ │ ├── IPagedQuery.cs │ │ ├── PageData.cs │ │ └── PagedQueryHelper.cs ├── Domain │ ├── BusinessRuleValidationException.cs │ ├── CompanyName.MyMeetings.BuildingBlocks.Domain.csproj │ ├── DomainEventBase.cs │ ├── Entity.cs │ ├── IAggregateRoot.cs │ ├── IBusinessRule.cs │ ├── IDomainEvent.cs │ ├── IgnoreMemberAttribute.cs │ ├── TypedIdValueBase.cs │ └── ValueObject.cs ├── Infrastructure │ ├── BiDictionary.cs │ ├── CompanyName.MyMeetings.BuildingBlocks.Infrastructure.csproj │ ├── DomainEventsDispatching │ │ ├── DomainEventsAccessor.cs │ │ ├── DomainEventsDispatcher.cs │ │ ├── DomainEventsDispatcherNotificationHandlerDecorator.cs │ │ ├── DomainNotificationsMapper.cs │ │ ├── IDomainEventsAccessor.cs │ │ ├── IDomainEventsDispatcher.cs │ │ ├── IDomainNotificationsMapper.cs │ │ └── UnitOfWorkCommandHandlerDecorator.cs │ ├── Emails │ │ ├── EmailSender.cs │ │ └── EmailsConfiguration.cs │ ├── EventBus │ │ ├── IEventsBus.cs │ │ ├── IIntegrationEventHandler.cs │ │ ├── InMemoryEventBus.cs │ │ ├── InMemoryEventBusClient.cs │ │ └── IntegrationEvent.cs │ ├── IUnitOfWork.cs │ ├── Inbox │ │ └── InboxMessage.cs │ ├── InternalCommands │ │ ├── IInternalCommandsMapper.cs │ │ ├── InternalCommand.cs │ │ └── InternalCommandsMapper.cs │ ├── Serialization │ │ └── AllPropertiesContractResolver.cs │ ├── ServiceProviderWrapper.cs │ ├── SqlConnectionFactory.cs │ ├── StronglyTypedIdValueConverterSelector.cs │ ├── TypedIdValueConverter.cs │ └── UnitOfWork.cs └── Tests │ ├── Application.UnitTests │ ├── CompanyName.MyMeetings.BuildingBlocks.Application.UnitTests.csproj │ └── Queries │ │ └── PagedQueryHelperTests.cs │ └── IntegrationTests │ ├── CompanyName.MyMeetings.BuildingBlocks.IntegrationTests.csproj │ ├── EnvironmentVariablesProvider.cs │ └── Probing │ ├── AssertErrorException.cs │ ├── IProbe.cs │ ├── Poller.cs │ └── Timeout.cs ├── CompanyName.MyMeetings.sln ├── Database ├── .dockerignore ├── ClearDatabase.sql ├── CompanyName.MyMeetings.Database.Build │ └── CompanyName.MyMeetings.Database.Build.csproj ├── CompanyName.MyMeetings.Database │ ├── CompanyName.MyMeetings.Database.sqlproj │ ├── Scripts │ │ ├── ClearDatabase.sql │ │ ├── CreateDatabase.sql │ │ ├── CreateDatabase_Linux.sql │ │ ├── CreateDatabase_Windows.sql │ │ ├── CreateStructure.sql │ │ ├── Migrations │ │ │ └── 1_0_0_0 │ │ │ │ ├── 0001_initial_structure.sql │ │ │ │ ├── 0002_change_meeting_comments_edit_date_type_and_add_meeting_comments_view.sql │ │ │ │ ├── 0003_add_meetings_countries_table.sql │ │ │ │ ├── 0004_add_meeting_commenting_configurations_table.sql │ │ │ │ ├── 0005_add_payer_id_to_subcription_details_view.sql │ │ │ │ ├── 0006_add_member_meeting_groups_view.sql │ │ │ │ ├── 0007_add_meeting_attendees_view.sql │ │ │ │ ├── 0008_add_meeting_details_view.sql │ │ │ │ ├── 0009_add_mock_emails_table.sql │ │ │ │ ├── 0010_add_member_meetings_view.sql │ │ │ │ ├── 0011_add_likes_count_to_meeting_comments_table.sql │ │ │ │ ├── 0012_add_likes_count_to_meeting_comments_view.sql │ │ │ │ └── 0013_add_meeting_member_comment_likes_table.sql │ │ ├── SeedDatabase.sql │ │ └── Seeds │ │ │ └── 0001_SeedCountries.sql │ └── Structure │ │ ├── Security │ │ └── Schemas.sql │ │ ├── administration │ │ ├── Tables │ │ │ ├── InboxMessages.sql │ │ │ ├── InternalCommands.sql │ │ │ ├── MeetingGroupProposals.sql │ │ │ ├── Members.sql │ │ │ └── OutboxMessages.sql │ │ └── Views │ │ │ ├── v_MeetingGroupProposals.sql │ │ │ └── v_Members.sql │ │ ├── app │ │ └── Tables │ │ │ ├── Emails.sql │ │ │ └── MigrationsJournal.sql │ │ ├── meetings │ │ ├── Tables │ │ │ ├── Countries.sql │ │ │ ├── InboxMessages.sql │ │ │ ├── InternalCommands.sql │ │ │ ├── MeetingAttendees.sql │ │ │ ├── MeetingCommentingConfigurations.sql │ │ │ ├── MeetingComments.sql │ │ │ ├── MeetingGroupMembers.sql │ │ │ ├── MeetingGroupProposals.sql │ │ │ ├── MeetingGroups.sql │ │ │ ├── MeetingMemberCommentLikes.sql │ │ │ ├── MeetingNotAttendees.sql │ │ │ ├── MeetingWaitlistMembers.sql │ │ │ ├── Meetings.sql │ │ │ ├── MemberSubscriptions.sql │ │ │ ├── Members.sql │ │ │ └── OutboxMessages.sql │ │ └── Views │ │ │ ├── v_Countries.sql │ │ │ ├── v_MeetingAttendees.sql │ │ │ ├── v_MeetingComments.sql │ │ │ ├── v_MeetingDetails.sql │ │ │ ├── v_MeetingGroupMembers.sql │ │ │ ├── v_MeetingGroupProposals.sql │ │ │ ├── v_MeetingGroups.sql │ │ │ ├── v_Meetings.sql │ │ │ ├── v_MemberMeetingGroups.sql │ │ │ ├── v_MemberMeetings.sql │ │ │ └── v_Members.sql │ │ ├── payments │ │ ├── Tables │ │ │ ├── InboxMessages.sql │ │ │ ├── InternalCommands.sql │ │ │ ├── MeetingFees.sql │ │ │ ├── Messages.sql │ │ │ ├── OutboxMessages.sql │ │ │ ├── Payers.sql │ │ │ ├── PriceListItems.sql │ │ │ ├── Streams.sql │ │ │ ├── SubscriptionCheckpoints.sql │ │ │ ├── SubscriptionDetails.sql │ │ │ └── SubscriptionPayments.sql │ │ └── Types │ │ │ └── NewStreamMessages.sql │ │ └── users │ │ ├── Tables │ │ ├── InboxMessages.sql │ │ ├── InternalCommands.sql │ │ ├── OutboxMessages.sql │ │ ├── Permissions.sql │ │ ├── RolesToPermissions.sql │ │ ├── UserRegistrations.sql │ │ ├── UserRoles.sql │ │ └── Users.sql │ │ └── Views │ │ ├── v_UserPermissions.sql │ │ ├── v_UserRegistrations.sql │ │ ├── v_UserRoles.sql │ │ └── v_Users.sql ├── DatabaseMigrator │ ├── .dockerignore │ ├── DatabaseMigrator.csproj │ ├── Program.cs │ └── SerilogUpgradeLog.cs ├── Dockerfile ├── Dockerfile_DatabaseMigrator ├── InitializeDatabase.sql ├── entrypoint.sh ├── entrypoint_DatabaseMigrator.sh └── wait-for-it.sh ├── Directory.Build.props ├── Directory.Build.targets ├── Dockerfile ├── Modules ├── Administration │ ├── Application │ │ ├── CompanyName.MyMeetings.Modules.Administration.Application.csproj │ │ ├── Configuration │ │ │ ├── Commands │ │ │ │ ├── ICommandHandler.cs │ │ │ │ ├── ICommandsScheduler.cs │ │ │ │ └── InternalCommandBase.cs │ │ │ └── Queries │ │ │ │ └── IQueryHandler.cs │ │ ├── Contracts │ │ │ ├── CommandBase.cs │ │ │ ├── IAdministrationModule.cs │ │ │ ├── ICommand.cs │ │ │ ├── IQuery.cs │ │ │ ├── IRecurringCommand.cs │ │ │ └── QueryBase.cs │ │ ├── MeetingGroupProposals │ │ │ ├── AcceptMeetingGroupProposal │ │ │ │ ├── AcceptMeetingGroupProposalCommand.cs │ │ │ │ ├── AcceptMeetingGroupProposalCommandHandler.cs │ │ │ │ ├── MeetingGroupProposalAcceptedNotification.cs │ │ │ │ └── MeetingGroupProposalAcceptedNotificationHandler.cs │ │ │ ├── GetMeetingGroupProposal │ │ │ │ ├── GetMeetingGroupProposalQuery.cs │ │ │ │ ├── GetMeetingGroupProposalQueryHandler.cs │ │ │ │ └── MeetingGroupProposalDto.cs │ │ │ ├── GetMeetingGroupProposals │ │ │ │ ├── GetMeetingGroupProposalsQuery.cs │ │ │ │ └── GetMeetingGroupProposalsQueryHandler.cs │ │ │ ├── MeetingGroupProposedIntegrationEventHandler.cs │ │ │ └── RequestMeetingGroupProposalVerification │ │ │ │ ├── RequestMeetingGroupProposalVerificationCommand.cs │ │ │ │ └── RequestMeetingGroupProposalVerificationCommandHandler.cs │ │ └── Members │ │ │ ├── CreateMember │ │ │ ├── CreateMemberCommand.cs │ │ │ └── CreateMemberCommandHandler.cs │ │ │ ├── GetMember │ │ │ ├── GetMemberQuery.cs │ │ │ ├── GetMemberQueryHandler.cs │ │ │ └── MemberDto.cs │ │ │ └── NewUserRegisteredIntegrationEventHandler.cs │ ├── Domain │ │ ├── CompanyName.MyMeetings.Modules.Administration.Domain.csproj │ │ ├── MeetingGroupProposals │ │ │ ├── Events │ │ │ │ ├── MeetingGroupProposalAcceptedDomainEvent.cs │ │ │ │ ├── MeetingGroupProposalRejectedDomainEvent.cs │ │ │ │ └── MeetingGroupProposalVerificationRequestedDomainEvent.cs │ │ │ ├── IMeetingGroupProposalRepository.cs │ │ │ ├── MeetingGroupLocation.cs │ │ │ ├── MeetingGroupProposal.cs │ │ │ ├── MeetingGroupProposalDecision.cs │ │ │ ├── MeetingGroupProposalId.cs │ │ │ ├── MeetingGroupProposalStatus.cs │ │ │ └── Rules │ │ │ │ ├── MeetingGroupProposalCanBeVerifiedOnceRule.cs │ │ │ │ └── MeetingGroupProposalRejectionMustHaveAReasonRule.cs │ │ ├── Members │ │ │ ├── Events │ │ │ │ └── MemberCreatedDomainEvent.cs │ │ │ ├── IMemberRepository.cs │ │ │ ├── Member.cs │ │ │ └── MemberId.cs │ │ └── Users │ │ │ ├── IUserContext.cs │ │ │ └── UserId.cs │ ├── Infrastructure │ │ ├── AdministrationContext.cs │ │ ├── AdministrationModule.cs │ │ ├── CompanyName.MyMeetings.Modules.Administration.Infrastructure.csproj │ │ ├── Configuration │ │ │ ├── AdministrationCompositionRoot.cs │ │ │ ├── AdministrationStartup.cs │ │ │ ├── AllConstructorFinder.cs │ │ │ ├── Assemblies.cs │ │ │ ├── Authentication │ │ │ │ └── AuthenticationModule.cs │ │ │ ├── DataAccess │ │ │ │ └── DataAccessModule.cs │ │ │ ├── EventsBus │ │ │ │ ├── EventsBusModule.cs │ │ │ │ ├── EventsBusStartup.cs │ │ │ │ └── IntegrationEventGenericHandler.cs │ │ │ ├── Logging │ │ │ │ └── LoggingModule.cs │ │ │ ├── Mediation │ │ │ │ └── MediatorModule.cs │ │ │ ├── Processing │ │ │ │ ├── CommandsExecutor.cs │ │ │ │ ├── IRecurringCommand.cs │ │ │ │ ├── Inbox │ │ │ │ │ ├── InboxMessageDto.cs │ │ │ │ │ ├── ProcessInboxCommand.cs │ │ │ │ │ ├── ProcessInboxCommandHandler.cs │ │ │ │ │ └── ProcessInboxJob.cs │ │ │ │ ├── InternalCommands │ │ │ │ │ ├── CommandsScheduler.cs │ │ │ │ │ ├── InternalCommandsModule.cs │ │ │ │ │ ├── ProcessInternalCommandsCommand.cs │ │ │ │ │ ├── ProcessInternalCommandsCommandHandler.cs │ │ │ │ │ └── ProcessInternalCommandsJob.cs │ │ │ │ ├── LoggingCommandHandlerDecorator.cs │ │ │ │ ├── LoggingCommandHandlerWithResultDecorator.cs │ │ │ │ ├── Outbox │ │ │ │ │ ├── OutboxMessageDto.cs │ │ │ │ │ ├── OutboxModule.cs │ │ │ │ │ ├── ProcessOutboxCommand.cs │ │ │ │ │ ├── ProcessOutboxCommandHandler.cs │ │ │ │ │ └── ProcessOutboxJob.cs │ │ │ │ ├── ProcessingModule.cs │ │ │ │ ├── UnitOfWorkCommandHandlerDecorator.cs │ │ │ │ ├── UnitOfWorkCommandHandlerWithResultDecorator.cs │ │ │ │ ├── ValidationCommandHandlerDecorator.cs │ │ │ │ └── ValidationCommandHandlerWithResultDecorator.cs │ │ │ ├── Quartz │ │ │ │ ├── QuartzModule.cs │ │ │ │ ├── QuartzStartup.cs │ │ │ │ └── SerilogLogProvider.cs │ │ │ └── Users │ │ │ │ └── UserContext.cs │ │ ├── Domain │ │ │ ├── MeetingGroupProposals │ │ │ │ ├── MeetingGroupProposalEntityTypeConfiguration.cs │ │ │ │ └── MeetingGroupProposalRepository.cs │ │ │ └── Members │ │ │ │ ├── MemberEntityTypeConfiguration.cs │ │ │ │ └── MemberRepository.cs │ │ ├── InternalCommands │ │ │ └── InternalCommandEntityTypeConfiguration.cs │ │ └── Outbox │ │ │ ├── OutboxAccessor.cs │ │ │ └── OutboxMessageEntityTypeConfiguration.cs │ ├── IntegrationEvents │ │ ├── CompanyName.MyMeetings.Modules.Administration.IntegrationEvents.csproj │ │ └── MeetingGroupProposals │ │ │ └── MeetingGroupProposalAcceptedIntegrationEvent.cs │ └── Tests │ │ ├── ArchTests │ │ ├── Application │ │ │ └── ApplicationTests.cs │ │ ├── CompanyName.MyMeetings.Modules.Administration.ArchTests.csproj │ │ ├── Domain │ │ │ └── DomainTests.cs │ │ ├── Module │ │ │ └── LayersTests.cs │ │ └── SeedWork │ │ │ └── TestBase.cs │ │ ├── IntegrationTests │ │ ├── AssemblyInfo.cs │ │ ├── CompanyName.MyMeetings.Modules.Administration.IntegrationTests.csproj │ │ ├── MeetingGroupProposals │ │ │ ├── MeetingGroupProposalSampleData.cs │ │ │ └── MeetingGroupProposalTests.cs │ │ ├── Members │ │ │ ├── CreateMemberTests.cs │ │ │ └── MemberSampleData.cs │ │ └── SeedWork │ │ │ ├── ExecutionContextMock.cs │ │ │ ├── OutboxMessagesHelper.cs │ │ │ └── TestBase.cs │ │ └── UnitTests │ │ ├── CompanyName.MyMeetings.Modules.Administration.Domain.UnitTests.csproj │ │ ├── MeetingGroupProposals │ │ └── MeetingGroupProposalTests.cs │ │ ├── Members │ │ └── MemberTests.cs │ │ └── SeedWork │ │ ├── DomainEventsTestHelper.cs │ │ └── TestBase.cs ├── Meetings │ ├── Application │ │ ├── CompanyName.MyMeetings.Modules.Meetings.Application.csproj │ │ ├── Configuration │ │ │ ├── Commands │ │ │ │ ├── ICommandHandler.cs │ │ │ │ ├── ICommandsScheduler.cs │ │ │ │ └── InternalCommandBase.cs │ │ │ └── Queries │ │ │ │ └── IQueryHandler.cs │ │ ├── Contracts │ │ │ ├── CommandBase.cs │ │ │ ├── ICommand.cs │ │ │ ├── IMeetingsModule.cs │ │ │ ├── IQuery.cs │ │ │ ├── IRecurringCommand.cs │ │ │ └── QueryBase.cs │ │ ├── Countries │ │ │ ├── CountryDto.cs │ │ │ ├── GetAllCountriesQuery.cs │ │ │ └── GetAllCountriesQueryHandler.cs │ │ ├── MeetingCommentingConfigurations │ │ │ ├── DisableMeetingCommentingConfiguration │ │ │ │ ├── DisableMeetingCommentingConfigurationCommand.cs │ │ │ │ └── DisableMeetingCommentingConfigurationCommandHandler.cs │ │ │ ├── EnableMeetingCommentingConfiguration │ │ │ │ ├── EnableMeetingCommentingConfigurationCommand.cs │ │ │ │ └── EnableMeetingCommentingConfigurationCommandHandler.cs │ │ │ ├── GetMeetingCommentingConfiguration │ │ │ │ ├── GetMeetingCommentingConfigurationQuery.cs │ │ │ │ ├── GetMeetingCommentingConfigurationQueryHandler.cs │ │ │ │ └── MeetingCommentingConfigurationDto.cs │ │ │ └── MeetingCreatedEventHandler.cs │ │ ├── MeetingComments │ │ │ ├── AddMeetingComment │ │ │ │ ├── AddMeetingCommentCommand.cs │ │ │ │ ├── AddMeetingCommentCommandHandler.cs │ │ │ │ └── AddMeetingCommentCommandValidator.cs │ │ │ ├── AddMeetingCommentLike │ │ │ │ ├── AddMeetingCommentLikeCommand.cs │ │ │ │ └── AddMeetingCommentLikeCommandHandler.cs │ │ │ ├── AddMeetingCommentReply │ │ │ │ ├── AddReplyToMeetingCommentCommand.cs │ │ │ │ └── AddReplyToMeetingCommentCommandHandler.cs │ │ │ ├── EditMeetingComment │ │ │ │ ├── EditMeetingCommentCommand.cs │ │ │ │ ├── EditMeetingCommentCommandHandler.cs │ │ │ │ └── EditMeetingCommentCommandValidator.cs │ │ │ ├── GetMeetingCommentLikers │ │ │ │ ├── GetMeetingCommentLikersQuery.cs │ │ │ │ ├── GetMeetingCommentLikersQueryHandler.cs │ │ │ │ └── MeetingCommentLikerDto.cs │ │ │ ├── GetMeetingComments │ │ │ │ ├── GetMeetingCommentsQuery.cs │ │ │ │ ├── GetMeetingCommentsQueryHandler.cs │ │ │ │ └── MeetingCommentDto.cs │ │ │ ├── MeetingCommentLikedNotification.cs │ │ │ ├── MeetingCommentLikedNotificationHandler.cs │ │ │ ├── MeetingCommentUnlikeNotificationHandler.cs │ │ │ ├── MeetingCommentUnlikedNotification.cs │ │ │ ├── RemoveMeetingComment │ │ │ │ ├── RemoveMeetingCommentCommand.cs │ │ │ │ └── RemoveMeetingCommentCommandHandler.cs │ │ │ └── RemoveMeetingCommentLike │ │ │ │ ├── RemoveMeetingCommentLikeCommand.cs │ │ │ │ └── RemoveMeetingCommentLikeCommandHandler.cs │ │ ├── MeetingGroupProposals │ │ │ ├── AcceptMeetingGroupProposal │ │ │ │ ├── AcceptMeetingGroupProposalCommand.cs │ │ │ │ ├── AcceptMeetingGroupProposalCommandHandler.cs │ │ │ │ ├── AcceptMeetingGroupProposalCommandValidator.cs │ │ │ │ ├── MeetingGroupProposalAcceptedNotification.cs │ │ │ │ └── MeetingGroupProposalAcceptedNotificationHandler.cs │ │ │ ├── GetAllMeetingGroupProposals │ │ │ │ ├── GetAllMeetingGroupProposalsQuery.cs │ │ │ │ └── GetAllMeetingGroupProposalsQueryHandler.cs │ │ │ ├── GetMeetingGroupProposal │ │ │ │ ├── GetMeetingGroupProposalQuery.cs │ │ │ │ ├── GetMeetingGroupProposalQueryHandler.cs │ │ │ │ └── MeetingGroupProposalDto.cs │ │ │ ├── GetMemberMeetingGroupProposals │ │ │ │ ├── GetMemberMeetingGroupProposalsQuery.cs │ │ │ │ └── GetMemberMeetingGroupProposalsQueryHandler.cs │ │ │ ├── MeetingGroupProposalAcceptedIntegrationEventHandler.cs │ │ │ ├── MeetingGroupProposedNotification.cs │ │ │ ├── MeetingGroupProposedNotificationHandler.cs │ │ │ └── ProposeMeetingGroup │ │ │ │ ├── ProposeMeetingGroupCommand.cs │ │ │ │ ├── ProposeMeetingGroupCommandHandler.cs │ │ │ │ └── ProposeMeetingGroupCommandValidator.cs │ │ ├── MeetingGroups │ │ │ ├── CreateNewMeetingGroup │ │ │ │ ├── CreateNewMeetingGroupCommand.cs │ │ │ │ └── CreateNewMeetingGroupCommandHandler.cs │ │ │ ├── EditMeetingGroupGeneralAttributes │ │ │ │ ├── EditMeetingGroupGeneralAttributesCommand.cs │ │ │ │ └── EditMeetingGroupGeneralAttributesCommandHandler.cs │ │ │ ├── GetAllMeetingGroups │ │ │ │ ├── GetAllMeetingGroupsQuery.cs │ │ │ │ ├── GetAllMeetingGroupsQueryHandler.cs │ │ │ │ └── MeetingGroupDto.cs │ │ │ ├── GetAuthenticationMemberMeetingGroups │ │ │ │ ├── GetAuthenticationMemberMeetingGroupsQuery.cs │ │ │ │ ├── GetAuthenticationMemberMeetingGroupsQueryHandler.cs │ │ │ │ └── MemberMeetingGroupDto.cs │ │ │ ├── GetMeetingGroupDetails │ │ │ │ ├── GetMeetingGroupDetailsQuery.cs │ │ │ │ ├── GetMeetingGroupDetailsQueryHandler.cs │ │ │ │ └── MeetingGroupDetailsDto.cs │ │ │ ├── JoinToGroup │ │ │ │ ├── JoinToGroupCommand.cs │ │ │ │ └── JoinToGroupCommandHandler.cs │ │ │ ├── LeaveMeetingGroup │ │ │ │ ├── LeaveMeetingGroupCommand.cs │ │ │ │ └── LeaveMeetingGroupCommandHandler.cs │ │ │ ├── MeetingGroupCreatedNotification.cs │ │ │ ├── MeetingGroupCreatedSendEmailHandler.cs │ │ │ ├── SendMeetingGroupCreatedEmail │ │ │ │ ├── SendMeetingGroupCreatedEmailCommand.cs │ │ │ │ └── SendMeetingGroupCreatedEmailCommandHandler.cs │ │ │ └── SetMeetingGroupExpirationDate │ │ │ │ ├── SetMeetingGroupExpirationDateCommand.cs │ │ │ │ └── SetMeetingGroupExpirationDateCommandHandler.cs │ │ ├── Meetings │ │ │ ├── AddMeetingAttendee │ │ │ │ ├── AddMeetingAttendeeCommand.cs │ │ │ │ └── AddMeetingAttendeeCommandHandler.cs │ │ │ ├── AddMeetingNotAttendee │ │ │ │ ├── AddMeetingNotAttendeeCommand.cs │ │ │ │ └── AddMeetingNotAttendeeCommandHandler.cs │ │ │ ├── CancelMeeting │ │ │ │ ├── CancelMeetingCommand.cs │ │ │ │ └── CancelMeetingCommandHandler.cs │ │ │ ├── ChangeMeetingMainAttributes │ │ │ │ ├── ChangeMeetingMainAttributesCommand.cs │ │ │ │ └── ChangeMeetingMainAttributesCommandHandler.cs │ │ │ ├── ChangeNotAttendeeDecision │ │ │ │ ├── ChangeNotAttendeeDecisionCommand.cs │ │ │ │ └── ChangeNotAttendeeDecisionCommandHandler.cs │ │ │ ├── CreateMeeting │ │ │ │ ├── CreateMeetingCommand.cs │ │ │ │ └── CreateMeetingCommandHandler.cs │ │ │ ├── GetAuthenticatedMemberMeetings │ │ │ │ ├── GetAuthenticatedMemberMeetingsQuery.cs │ │ │ │ ├── GetAuthenticatedMemberMeetingsQueryHandler.cs │ │ │ │ └── MemberMeetingDto.cs │ │ │ ├── GetMeetingAttendees │ │ │ │ ├── GetMeetingAttendeesQuery.cs │ │ │ │ ├── GetMeetingAttendeesQueryHandler.cs │ │ │ │ └── MeetingAttendeeDto.cs │ │ │ ├── GetMeetingDetails │ │ │ │ ├── GetMeetingDetailsQuery.cs │ │ │ │ ├── GetMeetingDetailsQueryHandler.cs │ │ │ │ └── MeetingDetailsDto.cs │ │ │ ├── MarkMeetingAttendeeFeeAsPayedCommand.cs │ │ │ ├── MarkMeetingAttendeeFeeAsPayedCommandHandler.cs │ │ │ ├── MeetingDto.cs │ │ │ ├── MeetingFeePaidIntegrationEventHandler.cs │ │ │ ├── MeetingsQueryHelper.cs │ │ │ ├── RemoveMeetingAttendee │ │ │ │ ├── RemoveMeetingAttendeeCommand.cs │ │ │ │ └── RemoveMeetingAttendeeCommandHandler.cs │ │ │ ├── SendMeetingAttendeeAddedEmail │ │ │ │ ├── MeetingAttendeeAddedNotification.cs │ │ │ │ ├── MeetingAttendeeAddedNotificationHandler.cs │ │ │ │ ├── MeetingAttendeeAddedPublishEventNotificationHandler.cs │ │ │ │ ├── SendMeetingAttendeeAddedEmailCommand.cs │ │ │ │ └── SendMeetingAttendeeAddedEmailCommandHandler.cs │ │ │ ├── SetMeetingAttendeeRole │ │ │ │ ├── SetMeetingAttendeeRoleCommand.cs │ │ │ │ └── SetMeetingAttendeeRoleCommandHandler.cs │ │ │ ├── SetMeetingHostRole │ │ │ │ ├── SetMeetingHostRoleCommand.cs │ │ │ │ └── SetMeetingHostRoleCommandHandler.cs │ │ │ ├── SignOffMemberFromWaitlist │ │ │ │ ├── SignOffMemberFromWaitlistCommand.cs │ │ │ │ └── SignOffMemberFromWaitlistCommandHandler.cs │ │ │ └── SignUpMemberToWaitlist │ │ │ │ ├── SignUpMemberToWaitlistCommand.cs │ │ │ │ └── SignUpMemberToWaitlistCommandHandler.cs │ │ ├── MemberSubscriptions │ │ │ ├── ChangeSubscriptionExpirationDateForMember │ │ │ │ ├── ChangeSubscriptionExpirationDateForMemberCommand.cs │ │ │ │ └── ChangeSubscriptionExpirationDateForMemberCommandHandler.cs │ │ │ ├── MemberSubscriptionExpirationDateChangedNotification.cs │ │ │ ├── MemberSubscriptionExpirationDateChangedNotificationHandler.cs │ │ │ └── SubscriptionExpirationDateChangedIntegrationEventHandler.cs │ │ └── Members │ │ │ ├── CreateMember │ │ │ ├── CreateMemberCommand.cs │ │ │ ├── CreateMemberCommandHandler.cs │ │ │ ├── MemberCratedNotificationHandler.cs │ │ │ ├── MemberCreatedNotification.cs │ │ │ └── NewUserRegisteredIntegrationEventHandler.cs │ │ │ ├── MemberContext.cs │ │ │ ├── MemberDto.cs │ │ │ └── MembersQueryHelper.cs │ ├── Domain │ │ ├── CompanyName.MyMeetings.Modules.Meetings.Domain.csproj │ │ ├── MeetingCommentingConfigurations │ │ │ ├── Events │ │ │ │ ├── MeetingCommentingConfigurationCreatedDomainEvent.cs │ │ │ │ ├── MeetingCommentingDisabledDomainEvent.cs │ │ │ │ └── MeetingCommentingEnabledDomainEvent.cs │ │ │ ├── IMeetingCommentingConfigurationRepository.cs │ │ │ ├── MeetingCommentingConfiguration.cs │ │ │ ├── MeetingCommentingConfigurationId.cs │ │ │ └── Rules │ │ │ │ ├── MeetingCommentingCanBeDisabledOnlyByGroupOrganizerRule.cs │ │ │ │ └── MeetingCommentingCanBeEnabledOnlyByGroupOrganizerRule.cs │ │ ├── MeetingComments │ │ │ ├── Events │ │ │ │ ├── MeetingCommentAddedDomainEvent.cs │ │ │ │ ├── MeetingCommentEditedDomainEvent.cs │ │ │ │ ├── MeetingCommentRemovedDomainEvent.cs │ │ │ │ └── ReplyToMeetingCommentAddedDomainEvent.cs │ │ │ ├── IMeetingCommentRepository.cs │ │ │ ├── MeetingComment.cs │ │ │ ├── MeetingCommentId.cs │ │ │ └── Rules │ │ │ │ ├── CommentCanBeAddedOnlyByMeetingGroupMemberRule.cs │ │ │ │ ├── CommentCanBeCreatedOnlyIfCommentingForMeetingEnabledRule.cs │ │ │ │ ├── CommentCanBeEditedOnlyIfCommentingForMeetingEnabledRule.cs │ │ │ │ ├── CommentCanBeLikedOnlyByMeetingGroupMemberRule.cs │ │ │ │ ├── CommentCannotBeLikedByTheSameMemberMoreThanOnceRule.cs │ │ │ │ ├── CommentTextMustBeProvidedRule.cs │ │ │ │ ├── MeetingCommentCanBeEditedOnlyByAuthorRule.cs │ │ │ │ ├── MeetingCommentCanBeRemovedOnlyByAuthorOrGroupOrganizerRule.cs │ │ │ │ └── RemovingReasonCanBeProvidedOnlyByGroupOrganizerRule.cs │ │ ├── MeetingGroupProposals │ │ │ ├── Events │ │ │ │ ├── MeetingGroupProposalAcceptedDomainEvent.cs │ │ │ │ └── MeetingGroupProposedDomainEvent.cs │ │ │ ├── IMeetingGroupProposalRepository.cs │ │ │ ├── MeetingGroupProposal.cs │ │ │ ├── MeetingGroupProposalId.cs │ │ │ ├── MeetingGroupProposalStatus.cs │ │ │ └── Rules │ │ │ │ └── MeetingGroupProposalCannotBeAcceptedMoreThanOnceRule.cs │ │ ├── MeetingGroups │ │ │ ├── Events │ │ │ │ ├── MeetingAttendeeChangedDecisionDomainEvent.cs │ │ │ │ ├── MeetingGroupCreatedDomainEvent.cs │ │ │ │ ├── MeetingGroupGeneralAttributesEditedDomainEvent.cs │ │ │ │ ├── MeetingGroupMemberLeftGroupDomainEvent.cs │ │ │ │ ├── MeetingGroupPaymentInfoUpdatedDomainEvent.cs │ │ │ │ ├── MeetingNotAttendeeChangedDecisionDomainEvent.cs │ │ │ │ └── NewMeetingGroupMemberJoinedDomainEvent.cs │ │ │ ├── IMeetingGroupRepository.cs │ │ │ ├── MeetingGroup.cs │ │ │ ├── MeetingGroupId.cs │ │ │ ├── MeetingGroupLocation.cs │ │ │ ├── MeetingGroupMember.cs │ │ │ ├── MeetingGroupMemberRole.cs │ │ │ ├── Policies │ │ │ │ ├── MeetingGroupExpirationDatePolicy.cs │ │ │ │ └── MeetingGroupMemberData.cs │ │ │ └── Rules │ │ │ │ ├── MeetingCanBeOrganizedOnlyByPayedGroupRule.cs │ │ │ │ ├── MeetingGroupMemberCannotBeAddedTwiceRule.cs │ │ │ │ ├── MeetingHostMustBeAMeetingGroupMemberRule.cs │ │ │ │ └── NotActualGroupMemberCannotLeaveGroupRule.cs │ │ ├── MeetingMemberCommentLikes │ │ │ ├── Events │ │ │ │ ├── MeetingCommentLikedDomainEvent.cs │ │ │ │ └── MeetingCommentUnlikedDomainEvent.cs │ │ │ ├── IMeetingMemberCommentLikesRepository.cs │ │ │ ├── MeetingMemberCommentLike.cs │ │ │ └── MeetingMemberCommentLikeId.cs │ │ ├── Meetings │ │ │ ├── Events │ │ │ │ ├── MeetingAttendeeAddedDomainEvent.cs │ │ │ │ ├── MeetingAttendeeFeePaidDomainEvent.cs │ │ │ │ ├── MeetingAttendeeRemovedDomainEvent.cs │ │ │ │ ├── MeetingCanceledDomainEvent.cs │ │ │ │ ├── MeetingCreatedDomainEvent.cs │ │ │ │ ├── MeetingEditedDomainEvent.cs │ │ │ │ ├── MeetingMainAttributesChangedDomainEvent.cs │ │ │ │ ├── MeetingNotAttendeeAddedDomainEvent.cs │ │ │ │ ├── MeetingWaitlistMemberAddedDomainEvent.cs │ │ │ │ ├── MemberSetAsAttendeeDomainEvent.cs │ │ │ │ ├── MemberSignedOffFromMeetingWaitlistDomainEvent.cs │ │ │ │ └── NewMeetingHostSetDomainEvent.cs │ │ │ ├── IMeetingRepository.cs │ │ │ ├── Meeting.cs │ │ │ ├── MeetingAttendee.cs │ │ │ ├── MeetingAttendeeRole.cs │ │ │ ├── MeetingId.cs │ │ │ ├── MeetingLimits.cs │ │ │ ├── MeetingLocation.cs │ │ │ ├── MeetingNotAttendee.cs │ │ │ ├── MeetingTerm.cs │ │ │ ├── MeetingWaitlistMember.cs │ │ │ ├── MoneyValue.cs │ │ │ ├── Rules │ │ │ │ ├── AttendeeCanBeAddedOnlyInRsvpTermRule.cs │ │ │ │ ├── AttendeesLimitCannotBeChangedToSmallerThanActiveAttendeesRule.cs │ │ │ │ ├── MeetingAttendeeMustBeAMemberOfGroupRule.cs │ │ │ │ ├── MeetingAttendeesLimitCannotBeNegativeRule.cs │ │ │ │ ├── MeetingAttendeesLimitMustBeGreaterThanGuestsLimitRule.cs │ │ │ │ ├── MeetingAttendeesNumberIsAboveLimitRule.cs │ │ │ │ ├── MeetingCannotBeChangedAfterStartRule.cs │ │ │ │ ├── MeetingGuestsLimitCannotBeNegativeRule.cs │ │ │ │ ├── MeetingGuestsNumberIsAboveLimitRule.cs │ │ │ │ ├── MeetingMustHaveAtLeastOneHostRule.cs │ │ │ │ ├── MemberCannotBeAnAttendeeOfMeetingMoreThanOnceRule.cs │ │ │ │ ├── MemberCannotBeMoreThanOnceOnMeetingWaitlistRule.cs │ │ │ │ ├── MemberCannotBeNotAttendeeTwiceRule.cs │ │ │ │ ├── MemberCannotHaveSetAttendeeRoleMoreThanOnceRule.cs │ │ │ │ ├── MemberOnWaitlistMustBeAMemberOfGroupRule.cs │ │ │ │ ├── NotActiveMemberOfWaitlistCannotBeSignedOffRule.cs │ │ │ │ ├── NotActiveNotAttendeeCannotChangeDecisionRule.cs │ │ │ │ ├── OnlyActiveAttendeeCanBeRemovedFromMeetingRule.cs │ │ │ │ ├── OnlyMeetingAttendeeCanHaveChangedRoleRule.cs │ │ │ │ ├── OnlyMeetingOrGroupOrganizerCanSetMeetingMemberRolesRule.cs │ │ │ │ └── ReasonOfRemovingAttendeeFromMeetingMustBeProvidedRule.cs │ │ │ └── Term.cs │ │ ├── Members │ │ │ ├── Events │ │ │ │ └── MemberCreatedDomainEvent.cs │ │ │ ├── IMemberContext.cs │ │ │ ├── IMemberRepository.cs │ │ │ ├── MeetingGroupMemberData.cs │ │ │ ├── Member.cs │ │ │ ├── MemberId.cs │ │ │ └── MemberSubscriptions │ │ │ │ ├── Events │ │ │ │ └── MemberSubscriptionExpirationDateChangedDomainEvent.cs │ │ │ │ ├── IMemberSubscriptionRepository.cs │ │ │ │ ├── MemberSubscription.cs │ │ │ │ └── MemberSubscriptionId.cs │ │ └── SharedKernel │ │ │ └── SystemClock.cs │ ├── Infrastructure │ │ ├── CompanyName.MyMeetings.Modules.Meetings.Infrastructure.csproj │ │ ├── Configuration │ │ │ ├── AllConstructorFinder.cs │ │ │ ├── Assemblies.cs │ │ │ ├── Authentication │ │ │ │ └── AuthenticationModule.cs │ │ │ ├── DataAccess │ │ │ │ └── DataAccessModule.cs │ │ │ ├── Email │ │ │ │ └── EmailModule.cs │ │ │ ├── EventsBus │ │ │ │ ├── EventsBusModule.cs │ │ │ │ ├── EventsBusStartup.cs │ │ │ │ └── IntegrationEventGenericHandler.cs │ │ │ ├── Logging │ │ │ │ └── LoggingModule.cs │ │ │ ├── Mediation │ │ │ │ └── MediatorModule.cs │ │ │ ├── MeetingsCompositionRoot.cs │ │ │ ├── MeetingsStartup.cs │ │ │ ├── Processing │ │ │ │ ├── CommandsExecutor.cs │ │ │ │ ├── IRecurringCommand.cs │ │ │ │ ├── Inbox │ │ │ │ │ ├── InboxMessageDto.cs │ │ │ │ │ ├── ProcessInboxCommand.cs │ │ │ │ │ ├── ProcessInboxCommandHandler.cs │ │ │ │ │ └── ProcessInboxJob.cs │ │ │ │ ├── InternalCommands │ │ │ │ │ ├── CommandsScheduler.cs │ │ │ │ │ ├── ProcessInternalCommandsCommand.cs │ │ │ │ │ ├── ProcessInternalCommandsCommandHandler.cs │ │ │ │ │ └── ProcessInternalCommandsJob.cs │ │ │ │ ├── LoggingCommandHandlerDecorator.cs │ │ │ │ ├── LoggingCommandHandlerWithResultDecorator.cs │ │ │ │ ├── Outbox │ │ │ │ │ ├── OutboxMessageDto.cs │ │ │ │ │ ├── OutboxModule.cs │ │ │ │ │ ├── ProcessOutboxCommand.cs │ │ │ │ │ ├── ProcessOutboxCommandHandler.cs │ │ │ │ │ └── ProcessOutboxJob.cs │ │ │ │ ├── ProcessingModule.cs │ │ │ │ ├── UnitOfWorkCommandHandlerDecorator.cs │ │ │ │ ├── UnitOfWorkCommandHandlerWithResultDecorator.cs │ │ │ │ ├── ValidationCommandHandlerDecorator.cs │ │ │ │ └── ValidationCommandHandlerWithResultDecorator.cs │ │ │ └── Quartz │ │ │ │ ├── QuartzModule.cs │ │ │ │ ├── QuartzStartup.cs │ │ │ │ └── SerilogLogProvider.cs │ │ ├── Domain │ │ │ ├── MeetingCommentingConfigurations │ │ │ │ ├── MeetingCommentingConfigurationEntityTypeConfiguration.cs │ │ │ │ └── MeetingCommentingConfigurationRepository.cs │ │ │ ├── MeetingComments │ │ │ │ ├── MeetingCommentEntityTypeConfiguration.cs │ │ │ │ └── MeetingCommentRepository.cs │ │ │ ├── MeetingGroupProposals │ │ │ │ ├── MeetingGroupProposalEntityTypeConfiguration.cs │ │ │ │ └── MeetingGroupProposalRepository.cs │ │ │ ├── MeetingGroups │ │ │ │ ├── MeetingGroupRepository.cs │ │ │ │ └── MeetingGroupsEntityTypeConfiguration.cs │ │ │ ├── MeetingMemberCommentLikes │ │ │ │ ├── MeetingMemberCommentLikeEntityTypeConfiguration.cs │ │ │ │ └── MeetingMemberCommentLikeRepository.cs │ │ │ ├── Meetings │ │ │ │ ├── MeetingEntityTypeConfiguration.cs │ │ │ │ └── MeetingRepository.cs │ │ │ └── Members │ │ │ │ ├── MemberEntityTypeConfiguration.cs │ │ │ │ ├── MemberRepository.cs │ │ │ │ └── MemberSubscriptions │ │ │ │ ├── MemberSubscriptionEntityTypeConfiguration.cs │ │ │ │ └── MemberSubscriptionRepository.cs │ │ ├── InternalCommands │ │ │ └── InternalCommandEntityTypeConfiguration.cs │ │ ├── MeetingsContext.cs │ │ ├── MeetingsModule.cs │ │ └── Outbox │ │ │ ├── OutboxAccessor.cs │ │ │ └── OutboxMessageEntityTypeConfiguration.cs │ ├── IntegrationEvents │ │ ├── CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents.csproj │ │ ├── MeetingAttendeeAddedIntegrationEvent.cs │ │ ├── MeetingGroupProposedIntegrationEvent.cs │ │ └── MemberCreatedIntegrationEvent.cs │ └── Tests │ │ ├── ArchTests │ │ ├── Application │ │ │ └── ApplicationTests.cs │ │ ├── CompanyName.MyMeetings.Modules.Meetings.ArchTests.csproj │ │ ├── Domain │ │ │ └── DomainTests.cs │ │ ├── Module │ │ │ └── LayersTests.cs │ │ └── SeedWork │ │ │ └── TestBase.cs │ │ ├── IntegrationTests │ │ ├── AssemblyInfo.cs │ │ ├── CompanyName.MyMeetings.Modules.Meetings.IntegrationTests.csproj │ │ ├── Countries │ │ │ ├── 0001_SeedCountries.sql │ │ │ └── GetCountriesTests.cs │ │ ├── MeetingCommentLikes │ │ │ ├── AddMeetingCommentLikeTests.cs │ │ │ ├── GetLikedMeetingCommentProbe.cs │ │ │ ├── GetMeetingCommentsProbe.cs │ │ │ └── RemoveMeetingCommentLikeTests.cs │ │ ├── MeetingCommentingConfigurations │ │ │ ├── CreateMeetingCommentingConfigurationTests.cs │ │ │ ├── DisableMeetingCommentingConfigurationTests.cs │ │ │ └── EnableMeetingCommentingConfigurationTests.cs │ │ ├── MeetingComments │ │ │ ├── AddMeetingCommentTests.cs │ │ │ ├── AddReplyToMeetingCommentTests.cs │ │ │ ├── EditMeetingCommentTests.cs │ │ │ ├── GetMeetingCommentsTests.cs │ │ │ └── RemoveMeetingCommentTests.cs │ │ ├── MeetingGroupProposals │ │ │ ├── GetMeetingGroupProposalsTests.cs │ │ │ ├── MeetingGroupProposalSampleData.cs │ │ │ └── ProposeMeetingGroupTests.cs │ │ ├── MeetingGroups │ │ │ └── CreateNewMeetingGroupTests.cs │ │ ├── Meetings │ │ │ ├── MeetingCreateTests.cs │ │ │ └── MeetingHelper.cs │ │ └── SeedWork │ │ │ ├── EventsBusMock.cs │ │ │ ├── ExecutionContextMock.cs │ │ │ ├── OutboxMessagesHelper.cs │ │ │ └── TestBase.cs │ │ └── UnitTests │ │ ├── CompanyName.MyMeetings.Modules.Meetings.Domain.UnitTests.csproj │ │ ├── MeetingGroupProposals │ │ └── MeetingGroupProposalTests.cs │ │ ├── MeetingGroups │ │ └── MeetingGroupTests.cs │ │ ├── Meetings │ │ ├── MeetingAddAttendeeTests.cs │ │ ├── MeetingAddNotAttendeeTests.cs │ │ ├── MeetingCommentTests.cs │ │ ├── MeetingCommentingConfigurationTests.cs │ │ ├── MeetingLimitsTests.cs │ │ ├── MeetingRolesTests.cs │ │ ├── MeetingTests.cs │ │ ├── MeetingTestsBase.cs │ │ └── MeetingWaitlistTests.cs │ │ ├── Members │ │ └── MemberTests.cs │ │ └── SeedWork │ │ ├── DomainEventsTestHelper.cs │ │ └── TestBase.cs ├── Payments │ ├── Application │ │ ├── CompanyName.MyMeetings.Modules.Payments.Application.csproj │ │ ├── Configuration │ │ │ ├── Commands │ │ │ │ ├── ICommandHandler.cs │ │ │ │ ├── ICommandsScheduler.cs │ │ │ │ └── InternalCommandBase.cs │ │ │ ├── Projections │ │ │ │ ├── IProjector.cs │ │ │ │ └── ProjectorBase.cs │ │ │ └── Queries │ │ │ │ └── IQueryHandler.cs │ │ ├── Contracts │ │ │ ├── CommandBase.cs │ │ │ ├── ICommand.cs │ │ │ ├── IPaymentsModule.cs │ │ │ ├── IQuery.cs │ │ │ ├── IRecurringCommand.cs │ │ │ └── QueryBase.cs │ │ ├── MeetingFees │ │ │ ├── CreateMeetingFee │ │ │ │ ├── CreateMeetingFeeCommand.cs │ │ │ │ └── CreateMeetingFeeCommandHandler.cs │ │ │ ├── CreateMeetingFeePayment │ │ │ │ ├── CreateMeetingFeePaymentCommand.cs │ │ │ │ └── CreateMeetingFeePaymentCommandHandler.cs │ │ │ ├── GetMeetingFees │ │ │ │ ├── GetMeetingFeesQuery.cs │ │ │ │ ├── GetMeetingFeesQueryHandler.cs │ │ │ │ ├── MeetingFeeDto.cs │ │ │ │ └── MeetingFeesProjector.cs │ │ │ ├── MarkMeetingFeeAsPaid │ │ │ │ ├── MarkMeetingFeeAsPaidCommand.cs │ │ │ │ ├── MarkMeetingFeeAsPaidCommandHandler.cs │ │ │ │ ├── MeetingFeePaidNotification.cs │ │ │ │ └── MeetingFeePaidNotificationHandler.cs │ │ │ ├── MarkMeetingFeePaymentAsPaid │ │ │ │ ├── MarkMeetingFeePaymentAsPaidCommand.cs │ │ │ │ ├── MarkMeetingFeePaymentAsPaidCommandHandler.cs │ │ │ │ ├── MeetingFeePaymentPaidNotification.cs │ │ │ │ └── MeetingFeePaymentPaidNotificationHandler.cs │ │ │ └── MeetingAttendeeAddedIntegrationEventHandler.cs │ │ ├── Payers │ │ │ ├── CreatePayer │ │ │ │ ├── CreatePayerCommand.cs │ │ │ │ ├── CreatePayerCommandHandler.cs │ │ │ │ └── NewUserRegisteredIntegrationEventHandler.cs │ │ │ ├── GetPayer │ │ │ │ ├── GetPayerQuery.cs │ │ │ │ ├── GetPayerQueryHandler.cs │ │ │ │ ├── PayerDetailsProjector.cs │ │ │ │ └── PayerDto.cs │ │ │ └── GetPayerEmail │ │ │ │ └── PayerEmailProvider.cs │ │ ├── PriceListItems │ │ │ ├── ActivatePriceListItem │ │ │ │ ├── ActivatePriceListItemCommand.cs │ │ │ │ └── ActivatePriceListItemCommandHandler.cs │ │ │ ├── ChangePriceListItemAttributes │ │ │ │ ├── ChangePriceListItemAttributesCommand.cs │ │ │ │ └── ChangePriceListItemAttributesCommandHandler.cs │ │ │ ├── CreatePriceListItem │ │ │ │ ├── CreatePriceListItemCommand.cs │ │ │ │ └── CreatePriceListItemCommandHandler.cs │ │ │ ├── DeactivatePriceListItem │ │ │ │ ├── DeactivatePriceListItemCommand.cs │ │ │ │ └── DeactivatePriceListItemCommandHandler.cs │ │ │ ├── GetPriceListItem │ │ │ │ ├── GetPriceListItemQuery.cs │ │ │ │ ├── GetPriceListItemQueryHandler.cs │ │ │ │ ├── PriceListItemMoneyValueDto.cs │ │ │ │ └── PriceListItemsProjector.cs │ │ │ ├── GetPriceListItems │ │ │ │ ├── GetPriceListItemsQuery.cs │ │ │ │ └── GetPriceListItemsQueryHandler.cs │ │ │ ├── PriceListFactory.cs │ │ │ └── PriceListItemDto.cs │ │ └── Subscriptions │ │ │ ├── BuySubscription │ │ │ ├── BuySubscriptionCommand.cs │ │ │ └── BuySubscriptionCommandHandler.cs │ │ │ ├── BuySubscriptionRenewal │ │ │ ├── BuySubscriptionRenewalCommand.cs │ │ │ └── BuySubscriptionRenewalCommandHandler.cs │ │ │ ├── CreateSubscription │ │ │ ├── CreateSubscriptionCommand.cs │ │ │ ├── CreateSubscriptionCommandHandler.cs │ │ │ ├── SubscriptionCreatedEnqueueEmailConfirmationHandler.cs │ │ │ ├── SubscriptionCreatedNotification.cs │ │ │ └── SubscriptionCreatedNotificationHandler.cs │ │ │ ├── ExpireSubscription │ │ │ ├── ExpireSubscriptionCommand.cs │ │ │ └── ExpireSubscriptionCommandHandler.cs │ │ │ ├── ExpireSubscriptionPayment │ │ │ ├── ExpireSubscriptionPaymentCommand.cs │ │ │ └── ExpireSubscriptionPaymentCommandHandler.cs │ │ │ ├── ExpireSubscriptionPayments │ │ │ ├── ExpireSubscriptionPaymentsCommand.cs │ │ │ └── ExpireSubscriptionPaymentsCommandHandler.cs │ │ │ ├── ExpireSubscriptions │ │ │ ├── ExpireSubscriptionsCommand.cs │ │ │ └── ExpireSubscriptionsCommandHandler.cs │ │ │ ├── GetPayerSubscription │ │ │ ├── GetAuthenticatedPayerSubscriptionQuery.cs │ │ │ └── GetAuthenticatedPayerSubscriptionQueryHandler.cs │ │ │ ├── GetSubscriptionDetails │ │ │ ├── GetSubscriptionDetailsQuery.cs │ │ │ ├── GetSubscriptionDetailsQueryHandler.cs │ │ │ ├── SubscriptionDetailsDto.cs │ │ │ └── SubscriptionDetailsProjector.cs │ │ │ ├── GetSubscriptionPayments │ │ │ ├── GetSubscriptionPaymentsQuery.cs │ │ │ ├── GetSubscriptionPaymentsQueryHandler.cs │ │ │ ├── SubscriptionPaymentDto.cs │ │ │ └── SubscriptionPaymentsProjector.cs │ │ │ ├── MarkSubscriptionPaymentAsPaid │ │ │ ├── MarkSubscriptionPaymentAsPaidCommand.cs │ │ │ ├── MarkSubscriptionPaymentAsPaidCommandHandler.cs │ │ │ ├── SubscriptionPaymentPaidNotification.cs │ │ │ └── SubscriptionPaymentPaidNotificationHandler.cs │ │ │ ├── MarkSubscriptionRenewalPaymentAsPaid │ │ │ ├── MarkSubscriptionRenewalPaymentAsPaidCommand.cs │ │ │ ├── MarkSubscriptionRenewalPaymentAsPaidCommandHandler.cs │ │ │ ├── SubscriptionRenewalPaymentAsPaidNotificationHandler.cs │ │ │ └── SubscriptionRenewalPaymentPaidNotification.cs │ │ │ ├── RenewSubscription │ │ │ ├── RenewSubscriptionCommand.cs │ │ │ ├── RenewSubscriptionCommandHandler.cs │ │ │ ├── SubscriptionRenewedEnqueueEmailConfirmationHandler.cs │ │ │ ├── SubscriptionRenewedNotification.cs │ │ │ └── SubscriptionRenewedNotificationHandler.cs │ │ │ ├── SendSubscriptionCreationConfirmationEmail │ │ │ ├── SendSubscriptionCreationConfirmationEmailCommand.cs │ │ │ └── SendSubscriptionCreationConfirmationEmailCommandHandler.cs │ │ │ └── SendSubscriptionRenewalConfirmationEmail │ │ │ ├── SendSubscriptionRenewalConfirmationEmailCommand.cs │ │ │ └── SendSubscriptionRenewalConfirmationEmailCommandHandler.cs │ ├── Domain │ │ ├── CompanyName.MyMeetings.Modules.Payments.Domain.csproj │ │ ├── MeetingFeePayments │ │ │ ├── Events │ │ │ │ ├── MeetingFeePaymentCreatedDomainEvent.cs │ │ │ │ ├── MeetingFeePaymentExpiredDomainEvent.cs │ │ │ │ └── MeetingFeePaymentPaidDomainEvent.cs │ │ │ ├── MeetingFeePayment.cs │ │ │ ├── MeetingFeePaymentId.cs │ │ │ ├── MeetingFeePaymentSnapshot.cs │ │ │ └── MeetingFeePaymentStatus.cs │ │ ├── MeetingFees │ │ │ ├── Events │ │ │ │ ├── MeetingFeeCanceledDomainEvent.cs │ │ │ │ ├── MeetingFeeCreatedDomainEvent.cs │ │ │ │ ├── MeetingFeeExpiredDomainEvent.cs │ │ │ │ └── MeetingFeePaidDomainEvent.cs │ │ │ ├── MeetingFee.cs │ │ │ ├── MeetingFeeId.cs │ │ │ ├── MeetingFeeSnapshot.cs │ │ │ ├── MeetingFeeStatus.cs │ │ │ └── MeetingId.cs │ │ ├── Payers │ │ │ ├── Events │ │ │ │ └── PayerCreatedDomainEvent.cs │ │ │ ├── IPayerContext.cs │ │ │ ├── IPayerRepository.cs │ │ │ ├── Payer.cs │ │ │ └── PayerId.cs │ │ ├── PriceListItems │ │ │ ├── Events │ │ │ │ ├── PriceListItemActivatedDomainEvent.cs │ │ │ │ ├── PriceListItemAttributesChangedDomainEvent.cs │ │ │ │ ├── PriceListItemCreatedDomainEvent.cs │ │ │ │ └── PriceListItemDeactivatedDomainEvent.cs │ │ │ ├── PriceList.cs │ │ │ ├── PriceListItem.cs │ │ │ ├── PriceListItemCategory.cs │ │ │ ├── PriceListItemData.cs │ │ │ ├── PriceListItemId.cs │ │ │ └── PricingStrategies │ │ │ │ ├── DirectValueFromPriceListPricingStrategy.cs │ │ │ │ ├── DirectValuePricingStrategy.cs │ │ │ │ ├── DiscountedValueFromPriceListPricingStrategy.cs │ │ │ │ └── IPricingStrategy.cs │ │ ├── SeedWork │ │ │ ├── AggregateId.cs │ │ │ ├── AggregateRoot.cs │ │ │ ├── IAggregateStore.cs │ │ │ ├── MoneyValue.cs │ │ │ ├── Rules │ │ │ │ ├── MoneyMustHaveTheSameCurrencyRule.cs │ │ │ │ └── ValueOfMoneyMustNotBeNegativeRule.cs │ │ │ └── SystemClock.cs │ │ ├── SubscriptionPayments │ │ │ ├── Events │ │ │ │ ├── SubscriptionPaymentCreatedDomainEvent.cs │ │ │ │ ├── SubscriptionPaymentExpiredDomainEvent.cs │ │ │ │ └── SubscriptionPaymentPaidDomainEvent.cs │ │ │ ├── Rules │ │ │ │ ├── PriceForSubscriptionMustBeDefinedRule.cs │ │ │ │ └── PriceOfferMustMatchPriceInPriceListRule.cs │ │ │ ├── SubscriptionPayment.cs │ │ │ ├── SubscriptionPaymentId.cs │ │ │ ├── SubscriptionPaymentSnapshot.cs │ │ │ └── SubscriptionPaymentStatus.cs │ │ ├── SubscriptionRenewalPayments │ │ │ ├── Events │ │ │ │ ├── SubscriptionRenewalPaymentCreatedDomainEvent.cs │ │ │ │ └── SubscriptionRenewalPaymentPaidDomainEvent.cs │ │ │ ├── Rules │ │ │ │ └── PriceOfferMustMatchPriceInPriceListRule.cs │ │ │ ├── SubscriptionRenewalPayment.cs │ │ │ ├── SubscriptionRenewalPaymentId.cs │ │ │ ├── SubscriptionRenewalPaymentSnapshot.cs │ │ │ └── SubscriptionRenewalPaymentStatus.cs │ │ ├── Subscriptions │ │ │ ├── Events │ │ │ │ ├── SubscriptionCreatedDomainEvent.cs │ │ │ │ ├── SubscriptionExpiredDomainEvent.cs │ │ │ │ └── SubscriptionRenewedDomainEvent.cs │ │ │ ├── SubscriberId.cs │ │ │ ├── Subscription.cs │ │ │ ├── SubscriptionDateExpirationCalculator.cs │ │ │ ├── SubscriptionId.cs │ │ │ ├── SubscriptionPeriod.cs │ │ │ └── SubscriptionStatus.cs │ │ └── Users │ │ │ ├── IUserContext.cs │ │ │ └── UserId.cs │ ├── Infrastructure │ │ ├── AggregateStore │ │ │ ├── AggregateStoreDomainEventsAccessor.cs │ │ │ ├── DomainEventTypeMappings.cs │ │ │ ├── ICheckpointStore.cs │ │ │ ├── SqlOutboxAccessor.cs │ │ │ ├── SqlServerCheckpointStore.cs │ │ │ ├── SqlStreamAggregateStore.cs │ │ │ ├── SubscriptionCode.cs │ │ │ └── SubscriptionsManager.cs │ │ ├── CompanyName.MyMeetings.Modules.Payments.Infrastructure.csproj │ │ ├── Configuration │ │ │ ├── AllConstructorFinder.cs │ │ │ ├── Assemblies.cs │ │ │ ├── Authentication │ │ │ │ ├── AuthenticationModule.cs │ │ │ │ └── PayerContext.cs │ │ │ ├── DataAccess │ │ │ │ └── DataAccessModule.cs │ │ │ ├── DatabaseSchema.cs │ │ │ ├── Email │ │ │ │ └── EmailModule.cs │ │ │ ├── EventsBus │ │ │ │ ├── EventsBusModule.cs │ │ │ │ ├── EventsBusStartup.cs │ │ │ │ └── IntegrationEventGenericHandler.cs │ │ │ ├── Logging │ │ │ │ └── LoggingModule.cs │ │ │ ├── Mediation │ │ │ │ └── MediatorModule.cs │ │ │ ├── PaymentsCompositionRoot.cs │ │ │ ├── PaymentsStartup.cs │ │ │ ├── Processing │ │ │ │ ├── CommandsExecutor.cs │ │ │ │ ├── Inbox │ │ │ │ │ ├── InboxMessageDto.cs │ │ │ │ │ ├── ProcessInboxCommand.cs │ │ │ │ │ ├── ProcessInboxCommandHandler.cs │ │ │ │ │ └── ProcessInboxJob.cs │ │ │ │ ├── InternalCommands │ │ │ │ │ ├── CommandsScheduler.cs │ │ │ │ │ ├── ProcessInternalCommandsCommand.cs │ │ │ │ │ ├── ProcessInternalCommandsCommandHandler.cs │ │ │ │ │ └── ProcessInternalCommandsJob.cs │ │ │ │ ├── LoggingCommandHandlerDecorator.cs │ │ │ │ ├── LoggingCommandHandlerWithResultDecorator.cs │ │ │ │ ├── Outbox │ │ │ │ │ ├── OutboxMessageDto.cs │ │ │ │ │ ├── OutboxModule.cs │ │ │ │ │ ├── ProcessOutboxCommand.cs │ │ │ │ │ ├── ProcessOutboxCommandHandler.cs │ │ │ │ │ └── ProcessOutboxJob.cs │ │ │ │ ├── PaymentsUnitOfWork.cs │ │ │ │ ├── ProcessingModule.cs │ │ │ │ ├── UnitOfWorkCommandHandlerDecorator.cs │ │ │ │ ├── UnitOfWorkCommandHandlerWithResultDecorator.cs │ │ │ │ ├── ValidationCommandHandlerDecorator.cs │ │ │ │ └── ValidationCommandHandlerWithResultDecorator.cs │ │ │ └── Quartz │ │ │ │ ├── Jobs │ │ │ │ ├── ExpireSubscriptionPaymentsJob.cs │ │ │ │ └── ExpireSubscriptionsJob.cs │ │ │ │ ├── QuartzModule.cs │ │ │ │ ├── QuartzStartup.cs │ │ │ │ └── SerilogLogProvider.cs │ │ ├── InternalCommands │ │ │ └── InternalCommandEntityTypeConfiguration.cs │ │ └── PaymentsModule.cs │ ├── IntegrationEvents │ │ ├── CompanyName.MyMeetings.Modules.Payments.IntegrationEvents.csproj │ │ ├── MeetingFeePaidIntegrationEvent.cs │ │ └── SubscriptionExpirationDateChangedIntegrationEvent.cs │ └── Tests │ │ ├── ArchTests │ │ ├── Application │ │ │ └── ApplicationTests.cs │ │ ├── CompanyName.MyMeetings.Modules.Payments.ArchTests.csproj │ │ ├── Domain │ │ │ └── DomainTests.cs │ │ ├── Module │ │ │ └── LayersTests.cs │ │ └── SeedWork │ │ │ └── TestBase.cs │ │ ├── IntegrationTests │ │ ├── AssemblyInfo.cs │ │ ├── CompanyName.MyMeetings.Modules.Payments.IntegrationTests.csproj │ │ ├── MeetingFees │ │ │ └── MeetingFeesTests.cs │ │ ├── Payers │ │ │ ├── PayerSampleData.cs │ │ │ └── PayerTests.cs │ │ ├── PriceList │ │ │ └── PriceListHelper.cs │ │ ├── SeedWork │ │ │ ├── EventsBusMock.cs │ │ │ ├── ExecutionContextMock.cs │ │ │ ├── OutboxMessagesHelper.cs │ │ │ └── TestBase.cs │ │ └── Subscriptions │ │ │ ├── BuySubscriptionTests.cs │ │ │ ├── GetSubscriptionPaymentsProbe.cs │ │ │ ├── SubscriptionLifecycleTests.cs │ │ │ └── SubscriptionPaymentsTests.cs │ │ └── UnitTests │ │ ├── CompanyName.MyMeetings.Modules.Payments.Domain.UnitTests.csproj │ │ ├── Payers │ │ └── PayerTests.cs │ │ ├── PriceListItems │ │ └── PriceListItemTests.cs │ │ ├── SeedWork │ │ ├── DomainEventsTestHelper.cs │ │ └── TestBase.cs │ │ ├── SubscriptionPayments │ │ ├── SubscriptionPaymentTests.cs │ │ └── SubscriptionPaymentTestsBase.cs │ │ ├── SubscriptionRenewalPayments │ │ ├── SubscriptionRenewalPaymentTests.cs │ │ └── SubscriptionRenewalPaymentTestsBase.cs │ │ └── Subscriptions │ │ ├── SubscriptionDateExpirationCalculatorTests.cs │ │ └── SubscriptionTests.cs └── UserAccess │ ├── Application │ ├── Authentication │ │ ├── Authenticate │ │ │ ├── AuthenticateCommand.cs │ │ │ ├── AuthenticateCommandHandler.cs │ │ │ ├── AuthenticateCommandValidator.cs │ │ │ ├── AuthenticationResult.cs │ │ │ └── UserDto.cs │ │ └── PasswordManager.cs │ ├── Authorization │ │ ├── GetAuthenticatedUserPermissions │ │ │ ├── GetAuthenticatedUserPermissionsQuery.cs │ │ │ └── GetAuthenticatedUserPermissionsQueryHandler.cs │ │ └── GetUserPermissions │ │ │ ├── GetUserPermissionsQuery.cs │ │ │ ├── GetUserPermissionsQueryHandler.cs │ │ │ └── UserPermissionDto.cs │ ├── CompanyName.MyMeetings.Modules.UserAccess.Application.csproj │ ├── Configuration │ │ ├── Commands │ │ │ ├── ICommandHandler.cs │ │ │ ├── ICommandsScheduler.cs │ │ │ └── InternalCommandBase.cs │ │ └── Queries │ │ │ └── IQueryHandler.cs │ ├── Contracts │ │ ├── CommandBase.cs │ │ ├── CustomClaimTypes.cs │ │ ├── ICommand.cs │ │ ├── IQuery.cs │ │ ├── IRecurringCommand.cs │ │ ├── IUserAccessModule.cs │ │ ├── QueryBase.cs │ │ └── Roles.cs │ ├── Emails │ │ ├── EmailDto.cs │ │ ├── GetAllEmailsQuery.cs │ │ └── GetAllEmailsQueryHandler.cs │ ├── IdentityServer │ │ ├── IdentityServerConfig.cs │ │ └── ProfileService.cs │ ├── UserRegistrations │ │ ├── ConfirmUserRegistration │ │ │ ├── ConfirmUserRegistrationCommand.cs │ │ │ ├── ConfirmUserRegistrationCommandHandler.cs │ │ │ └── UserRegistrationConfirmedHandler.cs │ │ ├── GetUserRegistration │ │ │ ├── GetUserRegistrationQuery.cs │ │ │ ├── GetUserRegistrationQueryHandler.cs │ │ │ └── UserRegistrationDto.cs │ │ ├── RegisterNewUser │ │ │ ├── NewUserRegisteredEnqueueEmailConfirmationHandler.cs │ │ │ ├── NewUserRegisteredNotification.cs │ │ │ ├── NewUserRegisteredPublishEventHandler.cs │ │ │ ├── RegisterNewUserCommand.cs │ │ │ └── RegisterNewUserCommandHandler.cs │ │ ├── SendUserRegistrationConfirmationEmail │ │ │ ├── SendUserRegistrationConfirmationEmailCommand.cs │ │ │ └── SendUserRegistrationConfirmationEmailCommandHandler.cs │ │ └── UsersCounter.cs │ └── Users │ │ ├── AddAdminUser │ │ ├── AddAdminUserCommand.cs │ │ └── AddAdminUserCommandHandler.cs │ │ ├── GetAuthenticatedUser │ │ ├── GetAuthenticatedUserQuery.cs │ │ └── GetAuthenticatedUserQueryHandler.cs │ │ └── GetUser │ │ ├── GetUserQuery.cs │ │ ├── GetUserQueryHandler.cs │ │ └── UserDto.cs │ ├── Domain │ ├── CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj │ ├── UserRegistrations │ │ ├── Events │ │ │ ├── NewUserRegisteredDomainEvent.cs │ │ │ ├── UserRegistrationConfirmedDomainEvent.cs │ │ │ └── UserRegistrationExpiredDomainEvent.cs │ │ ├── IUserRegistrationRepository.cs │ │ ├── IUsersCounter.cs │ │ ├── Rules │ │ │ ├── UserCannotBeCreatedWhenRegistrationIsNotConfirmedRule.cs │ │ │ ├── UserLoginMustBeUniqueRule.cs │ │ │ ├── UserRegistrationCannotBeConfirmedAfterExpirationRule.cs │ │ │ ├── UserRegistrationCannotBeConfirmedMoreThanOnceRule.cs │ │ │ └── UserRegistrationCannotBeExpiredMoreThanOnceRule.cs │ │ ├── UserRegistration.cs │ │ ├── UserRegistrationId.cs │ │ └── UserRegistrationStatus.cs │ └── Users │ │ ├── Events │ │ └── UserCreatedDomainEvent.cs │ │ ├── IUserRepository.cs │ │ ├── User.cs │ │ ├── UserId.cs │ │ └── UserRole.cs │ ├── Infrastructure │ ├── CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj │ ├── Configuration │ │ ├── AllConstructorFinder.cs │ │ ├── Assemblies.cs │ │ ├── DataAccess │ │ │ └── DataAccessModule.cs │ │ ├── Domain │ │ │ └── DomainModule.cs │ │ ├── Email │ │ │ └── EmailModule.cs │ │ ├── EventsBus │ │ │ ├── EventsBusModule.cs │ │ │ ├── EventsBusStartup.cs │ │ │ └── IntegrationEventGenericHandler.cs │ │ ├── Logging │ │ │ └── LoggingModule.cs │ │ ├── Mediation │ │ │ └── MediatorModule.cs │ │ ├── Processing │ │ │ ├── CommandsExecutor.cs │ │ │ ├── IRecurringCommand.cs │ │ │ ├── Inbox │ │ │ │ ├── InboxMessageDto.cs │ │ │ │ ├── ProcessInboxCommand.cs │ │ │ │ ├── ProcessInboxCommandHandler.cs │ │ │ │ └── ProcessInboxJob.cs │ │ │ ├── InternalCommands │ │ │ │ ├── CommandsScheduler.cs │ │ │ │ ├── ProcessInternalCommandsCommand.cs │ │ │ │ ├── ProcessInternalCommandsCommandHandler.cs │ │ │ │ └── ProcessInternalCommandsJob.cs │ │ │ ├── LoggingCommandHandlerDecorator.cs │ │ │ ├── LoggingCommandHandlerWithResultDecorator.cs │ │ │ ├── Outbox │ │ │ │ ├── OutboxMessageDto.cs │ │ │ │ ├── OutboxModule.cs │ │ │ │ ├── ProcessOutboxCommand.cs │ │ │ │ ├── ProcessOutboxCommandHandler.cs │ │ │ │ └── ProcessOutboxJob.cs │ │ │ ├── ProcessingModule.cs │ │ │ ├── UnitOfWorkCommandHandlerDecorator.cs │ │ │ ├── UnitOfWorkCommandHandlerWithResultDecorator.cs │ │ │ ├── ValidationCommandHandlerDecorator.cs │ │ │ └── ValidationCommandHandlerWithResultDecorator.cs │ │ ├── Quartz │ │ │ ├── QuartzModule.cs │ │ │ ├── QuartzStartup.cs │ │ │ └── SerilogLogProvider.cs │ │ ├── Security │ │ │ ├── AesDataProtector.cs │ │ │ ├── IDataProtector.cs │ │ │ └── SecurityModule.cs │ │ ├── UserAccessCompositionRoot.cs │ │ └── UserAccessStartup.cs │ ├── Domain │ │ ├── UserRegistrations │ │ │ ├── UserRegistrationEntityTypeConfiguration.cs │ │ │ └── UserRegistrationRepository.cs │ │ └── Users │ │ │ ├── UserEntityTypeConfiguration.cs │ │ │ └── UserRepository.cs │ ├── InternalCommands │ │ └── InternalCommandEntityTypeConfiguration.cs │ ├── Outbox │ │ ├── OutboxAccessor.cs │ │ └── OutboxMessageEntityTypeConfiguration.cs │ ├── UserAccessContext.cs │ └── UserAccessModule.cs │ ├── IntegrationEvents │ ├── CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj │ └── NewUserRegisteredIntegrationEvent.cs │ └── Tests │ ├── ArchTests │ ├── Application │ │ └── ApplicationTests.cs │ ├── CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj │ ├── Domain │ │ └── DomainTests.cs │ ├── Module │ │ └── LayersTests.cs │ └── SeedWork │ │ └── TestBase.cs │ ├── IntegrationTests │ ├── AssemblyInfo.cs │ ├── CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj │ ├── SeedWork │ │ ├── ExecutionContextMock.cs │ │ ├── OutboxMessagesHelper.cs │ │ └── TestBase.cs │ ├── UserRegistrations │ │ ├── ConfirmUserRegistrationTests.cs │ │ ├── SendUserRegistrationConfirmationEmailTests.cs │ │ ├── UserRegistrationSampleData.cs │ │ └── UserRegistrationTests.cs │ └── Users │ │ └── CreateUserTests.cs │ └── UnitTests │ ├── CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj │ ├── SeedWork │ ├── DomainEventsTestHelper.cs │ └── TestBase.cs │ └── UserRegistrations │ └── UserRegistrationTests.cs ├── Tests ├── ArchTests │ ├── Api │ │ └── ApiTests.cs │ ├── CompanyName.MyMeetings.ArchTests.csproj │ ├── Modules │ │ └── ModuleTests.cs │ └── SeedWork │ │ └── TestBase.cs ├── IntegrationTests │ ├── AssemblyInfo.cs │ ├── CompanyName.MyMeetings.IntegrationTests.csproj │ ├── CreateMeetingGroup │ │ └── CreateMeetingGroupTests.cs │ └── SeedWork │ │ ├── ExecutionContextMock.cs │ │ └── TestBase.cs └── SUT │ ├── CompanyName.MyMeetings.SUT.csproj │ ├── Helpers │ ├── MeetingGroupsFactory.cs │ ├── TestMeetingFactory.cs │ ├── TestMeetingGroupManager.cs │ ├── TestMeetingManager.cs │ ├── TestPaymentsManager.cs │ ├── TestPriceListManager.cs │ └── UsersFactory.cs │ ├── Scripts │ └── SeedPermissions.sql │ ├── SeedWork │ ├── AsyncOperationsHelper.cs │ ├── DatabaseCleaner.cs │ ├── ExecutionContextMock.cs │ ├── Probing │ │ ├── AssertErrorException.cs │ │ ├── IProbe.cs │ │ ├── Poller.cs │ │ └── Timeout.cs │ └── TestBase.cs │ └── TestCases │ ├── CleanDatabase.cs │ ├── CreateMeeting.cs │ └── OnlyAdmin.cs ├── entrypoint.sh ├── global.json └── stylecop.json /.nuke/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./build.schema.json", 3 | "Solution": "src/CompanyName.MyMeetings.sln" 4 | } -------------------------------------------------------------------------------- /build.cmd: -------------------------------------------------------------------------------- 1 | :; set -eo pipefail 2 | :; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 3 | :; ${SCRIPT_DIR}/build.sh "$@" 4 | :; exit $? 5 | 6 | @ECHO OFF 7 | powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* 8 | -------------------------------------------------------------------------------- /build/.editorconfig: -------------------------------------------------------------------------------- 1 | [*.cs] 2 | dotnet_style_qualification_for_field = false:warning 3 | dotnet_style_qualification_for_property = false:warning 4 | dotnet_style_qualification_for_method = false:warning 5 | dotnet_style_qualification_for_event = false:warning 6 | dotnet_style_require_accessibility_modifiers = never:warning 7 | 8 | csharp_style_expression_bodied_methods = true:silent 9 | csharp_style_expression_bodied_properties = true:warning 10 | csharp_style_expression_bodied_indexers = true:warning 11 | csharp_style_expression_bodied_accessors = true:warning 12 | -------------------------------------------------------------------------------- /build/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | using Nuke.Common.Tooling; 3 | 4 | [TypeConverter(typeof(TypeConverter))] 5 | public class Configuration : Enumeration 6 | { 7 | public static Configuration Debug = new Configuration { Value = nameof(Debug) }; 8 | public static Configuration Release = new Configuration { Value = nameof(Release) }; 9 | 10 | public static implicit operator string(Configuration configuration) 11 | { 12 | return configuration.Value; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /build/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /build/Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/Images/Architecture_high_level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Architecture_high_level.png -------------------------------------------------------------------------------- /docs/Images/CQRS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/CQRS.jpg -------------------------------------------------------------------------------- /docs/Images/Conceptual_Model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Conceptual_Model.png -------------------------------------------------------------------------------- /docs/Images/Decorator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Decorator.jpg -------------------------------------------------------------------------------- /docs/Images/ES_command_handling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ES_command_handling.png -------------------------------------------------------------------------------- /docs/Images/ES_elements.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ES_elements.jpg -------------------------------------------------------------------------------- /docs/Images/ES_event_store_db_sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ES_event_store_db_sample.png -------------------------------------------------------------------------------- /docs/Images/ES_events_projection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ES_events_projection.png -------------------------------------------------------------------------------- /docs/Images/Meeting_Group_Creation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Meeting_Group_Creation.jpg -------------------------------------------------------------------------------- /docs/Images/Meeting_Organization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Meeting_Organization.jpg -------------------------------------------------------------------------------- /docs/Images/Module_level_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Module_level_diagram.png -------------------------------------------------------------------------------- /docs/Images/OutboxInbox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/OutboxInbox.jpg -------------------------------------------------------------------------------- /docs/Images/OutboxProcessing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/OutboxProcessing.png -------------------------------------------------------------------------------- /docs/Images/OutboxSave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/OutboxSave.png -------------------------------------------------------------------------------- /docs/Images/Payments_EventStorming_Design.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Payments_EventStorming_Design.jpg -------------------------------------------------------------------------------- /docs/Images/Payments_EventStorming_Design_HighRes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/Payments_EventStorming_Design_HighRes.jpg -------------------------------------------------------------------------------- /docs/Images/SystemIntegrationTests.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/SystemIntegrationTests.jpg -------------------------------------------------------------------------------- /docs/Images/UnitTestsGeneral.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/UnitTestsGeneral.jpg -------------------------------------------------------------------------------- /docs/Images/User_Registration.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/User_Registration.jpg -------------------------------------------------------------------------------- /docs/Images/VSSolution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/VSSolution.png -------------------------------------------------------------------------------- /docs/Images/architecture_unit_tests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/architecture_unit_tests.png -------------------------------------------------------------------------------- /docs/Images/ci.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ci.jpg -------------------------------------------------------------------------------- /docs/Images/ci_job1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ci_job1.png -------------------------------------------------------------------------------- /docs/Images/ci_job2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/ci_job2.png -------------------------------------------------------------------------------- /docs/Images/glory_to_ukraine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/glory_to_ukraine.jpg -------------------------------------------------------------------------------- /docs/Images/integration_tests.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/integration_tests.jpg -------------------------------------------------------------------------------- /docs/Images/mutation_testing_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/mutation_testing_example.png -------------------------------------------------------------------------------- /docs/Images/mutation_testing_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/mutation_testing_report.png -------------------------------------------------------------------------------- /docs/Images/sut-preparation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/sut-preparation.jpg -------------------------------------------------------------------------------- /docs/Images/unit_tests.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Images/unit_tests.jpg -------------------------------------------------------------------------------- /docs/Project/MyMeetings.vpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ardalis/modular-monolith-with-ddd/5eb11ed268f86f5916b9a4aa49184f9200d99f68/docs/Project/MyMeetings.vpp -------------------------------------------------------------------------------- /docs/catalog-of-terms/Command/command.puml: -------------------------------------------------------------------------------- 1 | @startuml Command 2 | 3 | class CancelMeetingCommand { 4 | MeetingGroupId: Id 5 | } 6 | 7 | note top of CancelMeetingCommand : Command as part of Application Layer 8 | 9 | class Meeting { 10 | void Cancel(MemberId cancelMemberId) 11 | } 12 | 13 | note top of Meeting : Command defined in Domain Model (on an Aggregate) 14 | 15 | @enduml -------------------------------------------------------------------------------- /docs/catalog-of-terms/Dependency-Injection/dependency-injection.puml: -------------------------------------------------------------------------------- 1 | @startuml Dependency Injection 2 | 3 | class "CancelMeetingCommandHandler" { 4 | CancelMeetingCommandHandler(IMeetingRepository meetingRepository, IMemberContext memberContext) 5 | } 6 | 7 | interface "IMeetingRepository" { 8 | 9 | } 10 | 11 | interface "IMemberContext" { 12 | 13 | } 14 | 15 | "CancelMeetingCommandHandler" -> "IMeetingRepository" : uses 16 | "CancelMeetingCommandHandler" -> "IMemberContext" : uses 17 | 18 | @enduml -------------------------------------------------------------------------------- /docs/catalog-of-terms/Domain-Event/domain-event.puml: -------------------------------------------------------------------------------- 1 | @startuml 2 | class SubscriptionPaymentCreatedDomainEvent { 3 | +SubscriptionPaymentId 4 | +PayerId 5 | +SubscriptionPeriodCode 6 | +CountryCode 7 | +Status 8 | +Value 9 | +Currency 10 | } 11 | class DomainEventBase 12 | interface IDomainEvent { 13 | +Id 14 | +OccurredOn 15 | } 16 | 17 | IDomainEvent <|-- DomainEventBase: implements 18 | DomainEventBase <|-- SubscriptionPaymentCreatedDomainEvent: extends 19 | @enduml -------------------------------------------------------------------------------- /docs/catalog-of-terms/Entity-DDD/entity-ddd.puml: -------------------------------------------------------------------------------- 1 | @startuml Entity 2 | 3 | class "MeetingGroup" << Entity >> { 4 | MeetingGroupId: Id 5 | -string: _description 6 | -DateTime: _createDate 7 | -DateTime: _paymentDateTo 8 | {static} MeetingGroup CreateBasedOnProposal() 9 | Meeting CreateMeeting(..) 10 | void SetExpirationDate(DateTime dateTo) 11 | void JoinToGroupMember(MemberId memberId) 12 | void LeaveGroup(MemberId memberId) 13 | void EditGeneralAttributes(...) 14 | bool IsMemberOfGroup(MemberId attendeeId) 15 | bool IsOrganizer(MemberId memberId) 16 | } 17 | 18 | @enduml -------------------------------------------------------------------------------- /docs/catalog-of-terms/Event-Driven-Architecture/README.md: -------------------------------------------------------------------------------- 1 | # Event Driven Architecture 2 | 3 | TODO -------------------------------------------------------------------------------- /docs/catalog-of-terms/Event-Sourcing/README.md: -------------------------------------------------------------------------------- 1 | # Event Sourcing 2 | 3 | TODO -------------------------------------------------------------------------------- /docs/catalog-of-terms/Event-Storming/README.md: -------------------------------------------------------------------------------- 1 | # Event Storming 2 | 3 | TODO -------------------------------------------------------------------------------- /docs/catalog-of-terms/Integration-Event/README.md: -------------------------------------------------------------------------------- 1 | # Integration Event 2 | 3 | TODO -------------------------------------------------------------------------------- /docs/catalog-of-terms/ValueObject-DDD/value-object-ddd.puml: -------------------------------------------------------------------------------- 1 | @startuml ValueObject 2 | 3 | class "MeetingGroup" << ValueObject >> { 4 | decimal: Value {readonly} 5 | string: Currency {readonly} 6 | } 7 | 8 | @enduml -------------------------------------------------------------------------------- /src/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Configuration/Authorization/HasPermissionAuthorizationRequirement.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Authorization; 2 | 3 | namespace CompanyName.MyMeetings.API.Configuration.Authorization 4 | { 5 | public class HasPermissionAuthorizationRequirement : IAuthorizationRequirement 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Configuration/Authorization/NoPermissionRequiredAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Configuration.Authorization 4 | { 5 | [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 6 | public class NoPermissionRequiredAttribute : Attribute 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Administration/AdministrationPermissions.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Administration 2 | { 3 | public class AdministrationPermissions 4 | { 5 | public const string AcceptMeetingGroupProposal = "AcceptMeetingGroupProposal"; 6 | } 7 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingComments/AddMeetingCommentRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Meetings.MeetingComments 4 | { 5 | public class AddMeetingCommentRequest 6 | { 7 | public Guid MeetingId { get; set; } 8 | 9 | public string Comment { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingComments/EditMeetingCommentRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.MeetingComments 2 | { 3 | public class EditMeetingCommentRequest 4 | { 5 | public string EditedComment { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingGroupProposals/ProposeMeetingGroupRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.MeetingGroupProposals 2 | { 3 | public class ProposeMeetingGroupRequest 4 | { 5 | public string Name { get; set; } 6 | 7 | public string Description { get; set; } 8 | 9 | public string LocationCity { get; set; } 10 | 11 | public string LocationCountryCode { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingGroups/CreateNewMeetingGroupRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.MeetingGroups 2 | { 3 | public class CreateNewMeetingGroupRequest 4 | { 5 | public string Name { get; set; } 6 | 7 | public string Description { get; set; } 8 | 9 | public string LocationCity { get; set; } 10 | 11 | public string LocationCountry { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingGroups/EditMeetingGroupGeneralAttributesRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.MeetingGroups 2 | { 3 | public class EditMeetingGroupGeneralAttributesRequest 4 | { 5 | public string Name { get; set; } 6 | 7 | public string Description { get; set; } 8 | 9 | public string LocationCity { get; set; } 10 | 11 | public string LocationCountry { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/Meetings/AddMeetingAttendeeRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.Meetings 2 | { 3 | public class AddMeetingAttendeeRequest 4 | { 5 | public int GuestsNumber { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/Meetings/RemoveMeetingAttendeeRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Meetings.Meetings 2 | { 3 | public class RemoveMeetingAttendeeRequest 4 | { 5 | public string RemovingReason { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/Meetings/SetMeetingAttendeeRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Meetings.Meetings 4 | { 5 | public class SetMeetingAttendeeRequest 6 | { 7 | public Guid AttendeeId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/Meetings/SetMeetingHostRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Meetings.Meetings 4 | { 5 | public class SetMeetingHostRequest 6 | { 7 | public Guid AttendeeId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Meetings/MeetingsAutofacModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | using CompanyName.MyMeetings.Modules.Meetings.Infrastructure; 4 | 5 | namespace CompanyName.MyMeetings.API.Modules.Meetings 6 | { 7 | public class MeetingsAutofacModule : Module 8 | { 9 | protected override void Load(ContainerBuilder builder) 10 | { 11 | builder.RegisterType() 12 | .As() 13 | .InstancePerLifetimeScope(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/MeetingFees/CreateMeetingFeePaymentRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Payments.MeetingFees 4 | { 5 | public class CreateMeetingFeePaymentRequest 6 | { 7 | public Guid MeetingFeeId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/MeetingFees/RegisterMeetingFeePaymentRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Payments.MeetingFees 4 | { 5 | public class RegisterMeetingFeePaymentRequest 6 | { 7 | public Guid PaymentId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/PaymentsAutofacModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 3 | using CompanyName.MyMeetings.Modules.Payments.Infrastructure; 4 | 5 | namespace CompanyName.MyMeetings.API.Modules.Payments 6 | { 7 | public class PaymentsAutofacModule : Module 8 | { 9 | protected override void Load(ContainerBuilder builder) 10 | { 11 | builder.RegisterType() 12 | .As() 13 | .InstancePerLifetimeScope(); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/PriceListItems/CreatePriceListItemRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Payments.PriceListItems 2 | { 3 | public class CreatePriceListItemRequest 4 | { 5 | public string CountryCode { get; set; } 6 | 7 | public string SubscriptionPeriodCode { get; set; } 8 | 9 | public string CategoryCode { get; set; } 10 | 11 | public decimal PriceValue { get; set; } 12 | 13 | public string PriceCurrency { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/PriceListItems/GetPriceListItemRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Payments.PriceListItems 2 | { 3 | public class GetPriceListItemRequest 4 | { 5 | public string CountryCode { get; set; } 6 | 7 | public string CategoryCode { get; set; } 8 | 9 | public string PeriodTypeCode { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/RegisterSubscriptionRenewalPaymentRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Payments 4 | { 5 | public class RegisterSubscriptionRenewalPaymentRequest 6 | { 7 | public Guid PaymentId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/Subscriptions/BuySubscriptionRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Payments.Subscriptions 2 | { 3 | public class BuySubscriptionRequest 4 | { 5 | public string SubscriptionTypeCode { get; set; } 6 | 7 | public string CountryCode { get; set; } 8 | 9 | public decimal Value { get; set; } 10 | 11 | public string Currency { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/Subscriptions/RegisterSubscriptionPaymentRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.API.Modules.Payments.Subscriptions 4 | { 5 | public class RegisterSubscriptionPaymentRequest 6 | { 7 | public Guid PaymentId { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/Payments/Subscriptions/RenewSubscriptionRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.Payments.Subscriptions 2 | { 3 | public class RenewSubscriptionRequest 4 | { 5 | public string SubscriptionTypeCode { get; set; } 6 | 7 | public string CountryCode { get; set; } 8 | 9 | public decimal Value { get; set; } 10 | 11 | public string Currency { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/Modules/UserAccess/RegisterNewUserRequest.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.API.Modules.UserAccess 2 | { 3 | public class RegisterNewUserRequest 4 | { 5 | public string Login { get; set; } 6 | 7 | public string Password { get; set; } 8 | 9 | public string Email { get; set; } 10 | 11 | public string FirstName { get; set; } 12 | 13 | public string LastName { get; set; } 14 | 15 | public string ConfirmLink { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Trace", 5 | "System": "Information", 6 | "Microsoft": "None" 7 | } 8 | 9 | }, 10 | "AllowedHosts": "*", 11 | 12 | "EmailsConfiguration": { 13 | "FromEmail": "no-reply@mymeetings.com" 14 | }, 15 | "Security": { 16 | /* NOTE! This is sensitive data and should be stored in secure way (not here). Added only for demo purpose. */ 17 | "TextEncryptionKey": "E546C8DF278CK5990069B522" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/API/CompanyName.MyMeetings.API/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | sleep 30 ; 3 | 4 | dotnet CompanyName.MyMeetings.API.dll -------------------------------------------------------------------------------- /src/API/RequestExamples/Authentication.http: -------------------------------------------------------------------------------- 1 | ### Authenticate Member 2 | POST {{baseUrl}}/connect/token 3 | Content-Type: application/x-www-form-urlencoded 4 | 5 | grant_type=password&username=testMember@mail.com&password=testMemberPass&client_id=ro.client&client_secret=secret 6 | 7 | ### Authenticate Admin 8 | POST {{baseUrl}}/connect/token 9 | Content-Type: application/x-www-form-urlencoded 10 | 11 | grant_type=password&username=testAdmin@mail.com&password=testAdminPass&client_id=ro.client&client_secret=secret 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/API/RequestExamples/Users.http: -------------------------------------------------------------------------------- 1 | ### Register a new user 2 | POST {{baseUrl}}/userAccess/UserRegistrations 3 | Content-Type: application/json 4 | 5 | { 6 | "Login": "login", 7 | "Password": "password", 8 | "Email": "email@mail.com", 9 | "FirstName": "John", 10 | "LastName": "Doe", 11 | "ConfirmLink": "Abc" 12 | } 13 | 14 | 15 | ### User registration confirmation 16 | PATCH {{baseUrl}}/userAccess/UserRegistrations/e80985c5-bf97-4bb3-b178-9423d70ef87b/confirm -------------------------------------------------------------------------------- /src/API/RequestExamples/http-client.env.json: -------------------------------------------------------------------------------- 1 | { 2 | "dev": { 3 | "baseUrl": "http://localhost:5000" 4 | } 5 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Data/ISqlConnectionFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Data 4 | { 5 | public interface ISqlConnectionFactory 6 | { 7 | IDbConnection GetOpenConnection(); 8 | 9 | IDbConnection CreateNewConnection(); 10 | 11 | string GetConnectionString(); 12 | } 13 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Emails/EmailMessage.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Emails 2 | { 3 | public struct EmailMessage 4 | { 5 | public string To { get; } 6 | 7 | public string Subject { get; } 8 | 9 | public string Content { get; } 10 | 11 | public EmailMessage( 12 | string to, 13 | string subject, 14 | string content) 15 | { 16 | this.To = to; 17 | this.Subject = subject; 18 | this.Content = content; 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Emails/IEmailSender.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Emails 4 | { 5 | public interface IEmailSender 6 | { 7 | Task SendEmail(EmailMessage message); 8 | } 9 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Events/DomainNotificationBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Events 5 | { 6 | public class DomainNotificationBase : IDomainEventNotification 7 | where T : IDomainEvent 8 | { 9 | public T DomainEvent { get; } 10 | 11 | public Guid Id { get; } 12 | 13 | public DomainNotificationBase(T domainEvent, Guid id) 14 | { 15 | this.Id = id; 16 | this.DomainEvent = domainEvent; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Events/IDomainEventNotification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Events 5 | { 6 | public interface IDomainEventNotification : IDomainEventNotification 7 | { 8 | TEventType DomainEvent { get; } 9 | } 10 | 11 | public interface IDomainEventNotification : INotification 12 | { 13 | Guid Id { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/IExecutionContextAccessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Application 4 | { 5 | public interface IExecutionContextAccessor 6 | { 7 | Guid UserId { get; } 8 | 9 | Guid CorrelationId { get; } 10 | 11 | bool IsAvailable { get; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/InvalidCommandException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Application 5 | { 6 | public class InvalidCommandException : Exception 7 | { 8 | public List Errors { get; } 9 | 10 | public InvalidCommandException(List errors) 11 | { 12 | this.Errors = errors; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Outbox/IOutbox.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Outbox 4 | { 5 | public interface IOutbox 6 | { 7 | void Add(OutboxMessage message); 8 | 9 | Task Save(); 10 | } 11 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Queries/IPagedQuery.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Queries 2 | { 3 | public interface IPagedQuery 4 | { 5 | /// 6 | /// Page number. If null then default is 1. 7 | /// 8 | int? Page { get; } 9 | 10 | /// 11 | /// Records number per page (page size). 12 | /// 13 | int? PerPage { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Application/Queries/PageData.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Application.Queries 2 | { 3 | public struct PageData 4 | { 5 | public int Offset { get; } 6 | 7 | public int Next { get; } 8 | 9 | public PageData(int offset, int next) 10 | { 11 | this.Offset = offset; 12 | this.Next = next; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/CompanyName.MyMeetings.BuildingBlocks.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/DomainEventBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Domain 4 | { 5 | public class DomainEventBase : IDomainEvent 6 | { 7 | public Guid Id { get; } 8 | 9 | public DateTime OccurredOn { get; } 10 | 11 | public DomainEventBase() 12 | { 13 | this.Id = Guid.NewGuid(); 14 | this.OccurredOn = DateTime.UtcNow; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/IAggregateRoot.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Domain 2 | { 3 | public interface IAggregateRoot 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/IBusinessRule.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Domain 2 | { 3 | public interface IBusinessRule 4 | { 5 | bool IsBroken(); 6 | 7 | string Message { get; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/IDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Domain 5 | { 6 | public interface IDomainEvent : INotification 7 | { 8 | Guid Id { get; } 9 | 10 | DateTime OccurredOn { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Domain/IgnoreMemberAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Domain 4 | { 5 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] 6 | public class IgnoreMemberAttribute : Attribute 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/DomainEventsDispatching/IDomainEventsAccessor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching 5 | { 6 | public interface IDomainEventsAccessor 7 | { 8 | IReadOnlyCollection GetAllDomainEvents(); 9 | 10 | void ClearAllDomainEvents(); 11 | } 12 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/DomainEventsDispatching/IDomainEventsDispatcher.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching 4 | { 5 | public interface IDomainEventsDispatcher 6 | { 7 | Task DispatchEventsAsync(); 8 | } 9 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/DomainEventsDispatching/IDomainNotificationsMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.DomainEventsDispatching 4 | { 5 | public interface IDomainNotificationsMapper 6 | { 7 | string GetName(Type type); 8 | 9 | Type GetType(string name); 10 | } 11 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/Emails/EmailsConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.Emails 2 | { 3 | public class EmailsConfiguration 4 | { 5 | public EmailsConfiguration(string fromEmail) 6 | { 7 | FromEmail = fromEmail; 8 | } 9 | 10 | public string FromEmail { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/EventBus/IEventsBus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus 5 | { 6 | public interface IEventsBus : IDisposable 7 | { 8 | Task Publish(T @event) 9 | where T : IntegrationEvent; 10 | 11 | void Subscribe(IIntegrationEventHandler handler) 12 | where T : IntegrationEvent; 13 | 14 | void StartConsuming(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/EventBus/IIntegrationEventHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus 4 | { 5 | public interface IIntegrationEventHandler : IIntegrationEventHandler 6 | where TIntegrationEvent : IntegrationEvent 7 | { 8 | Task Handle(TIntegrationEvent @event); 9 | } 10 | 11 | public interface IIntegrationEventHandler 12 | { 13 | } 14 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/EventBus/IntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus 5 | { 6 | public abstract class IntegrationEvent : INotification 7 | { 8 | public Guid Id { get; } 9 | 10 | public DateTime OccurredOn { get; } 11 | 12 | protected IntegrationEvent(Guid id, DateTime occurredOn) 13 | { 14 | this.Id = id; 15 | this.OccurredOn = occurredOn; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Threading.Tasks; 4 | 5 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure 6 | { 7 | public interface IUnitOfWork 8 | { 9 | Task CommitAsync( 10 | CancellationToken cancellationToken = default, 11 | Guid? internalCommandId = null); 12 | } 13 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/InternalCommands/IInternalCommandsMapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.InternalCommands 4 | { 5 | public interface IInternalCommandsMapper 6 | { 7 | string GetName(Type type); 8 | 9 | Type GetType(string name); 10 | } 11 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Infrastructure/InternalCommands/InternalCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.Infrastructure.InternalCommands 4 | { 5 | public class InternalCommand 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | 13 | public DateTime? ProcessedDate { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Tests/Application.UnitTests/CompanyName.MyMeetings.BuildingBlocks.Application.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/BuildingBlocks/Tests/IntegrationTests/CompanyName.MyMeetings.BuildingBlocks.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/BuildingBlocks/Tests/IntegrationTests/Probing/AssertErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.IntegrationTests.Probing 4 | { 5 | public class AssertErrorException : Exception 6 | { 7 | public AssertErrorException(string message) 8 | : base(message) 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Tests/IntegrationTests/Probing/IProbe.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.IntegrationTests.Probing 4 | { 5 | public interface IProbe 6 | { 7 | bool IsSatisfied(); 8 | 9 | Task SampleAsync(); 10 | 11 | string DescribeFailureTo(); 12 | } 13 | 14 | public interface IProbe 15 | { 16 | bool IsSatisfied(T sample); 17 | 18 | Task GetSampleAsync(); 19 | 20 | string DescribeFailureTo(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/Tests/IntegrationTests/Probing/Timeout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.BuildingBlocks.IntegrationTests.Probing 4 | { 5 | public class Timeout 6 | { 7 | private readonly DateTime _endTime; 8 | 9 | public Timeout(int duration) 10 | { 11 | this._endTime = DateTime.Now.AddMilliseconds(duration); 12 | } 13 | 14 | public bool HasTimedOut() 15 | { 16 | return DateTime.Now > _endTime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Database/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database.Build/CompanyName.MyMeetings.Database.Build.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Sql130 4 | false 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/CreateDatabase.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE [MyMeetings] 2 | CONTAINMENT = NONE 3 | ON PRIMARY 4 | ( NAME = N'MyMeetings', FILENAME = N'/var/opt/mssql/data/MyMeetings.mdf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) 5 | LOG ON 6 | ( NAME = N'MyMeetings_log', FILENAME = N'/var/opt/mssql/data/MyMeetings_log.ldf' , SIZE = 8192KB , FILEGROWTH = 65536KB ) 7 | GO 8 | 9 | CREATE SCHEMA app AUTHORIZATION dbo 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/CreateDatabase_Linux.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE [MyMeetings] 2 | CONTAINMENT = NONE 3 | GO 4 | 5 | USE [MyMeetings] 6 | GO 7 | 8 | CREATE SCHEMA app AUTHORIZATION dbo 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/CreateDatabase_Windows.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE [MyMeetings] 2 | CONTAINMENT = NONE 3 | GO 4 | 5 | USE [MyMeetings] 6 | GO 7 | 8 | CREATE SCHEMA app AUTHORIZATION dbo 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0003_add_meetings_countries_table.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].[Countries] 2 | ( 3 | [Code] CHAR(2) NOT NULL, 4 | [Name] NVARCHAR(50) NOT NULL 5 | CONSTRAINT [PK_meetings_Countries_Code] PRIMARY KEY ([Code] ASC) 6 | ) 7 | GO 8 | 9 | CREATE VIEW [meetings].[v_Countries] 10 | AS 11 | SELECT 12 | [Country].[Code], 13 | [Country].[Name] 14 | FROM meetings.Countries AS [Country] 15 | GO 16 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0004_add_meeting_commenting_configurations_table.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingCommentingConfigurations 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [MeetingId] UNIQUEIDENTIFIER NOT NULL, 5 | [IsCommentingEnabled] BIT NOT NULL, 6 | CONSTRAINT [PK_meetings_MeetingCommentingConfigurations_Id] PRIMARY KEY ([Id] ASC), 7 | CONSTRAINT [FK_meetings_MeetingCommentingConfigurations_Meetings] FOREIGN KEY ([MeetingId]) REFERENCES meetings.Meetings ([Id]) 8 | ); 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0005_add_payer_id_to_subcription_details_view.sql: -------------------------------------------------------------------------------- 1 | DELETE FROM payments.SubscriptionDetails 2 | GO 3 | 4 | ALTER TABLE payments.SubscriptionDetails ADD [PayerId] UNIQUEIDENTIFIER NOT NULL 5 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0007_add_meeting_attendees_view.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_MeetingAttendees] 2 | AS 3 | SELECT 4 | [MeetingAttendee].[MeetingId], 5 | [MeetingAttendee].[AttendeeId], 6 | [MeetingAttendee].[DecisionDate], 7 | [MeetingAttendee].[RoleCode], 8 | [MeetingAttendee].[GuestsNumber], 9 | 10 | [Member].[FirstName], 11 | [Member].[LastName] 12 | FROM [meetings].[MeetingAttendees] AS [MeetingAttendee] 13 | INNER JOIN [meetings].[Members] AS [Member] 14 | ON [MeetingAttendee].[AttendeeId] = [Member].[Id] 15 | GO 16 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0009_add_mock_emails_table.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [app].[Emails] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [From] NVARCHAR(255) NOT NULL, 5 | [To] NVARCHAR(255) NOT NULL, 6 | [Subject] NVARCHAR(255) NOT NULL, 7 | [Content] NVARCHAR(MAX) NOT NULL, 8 | [Date] DATETIME NOT NULL, 9 | CONSTRAINT [PK_app_Emails_Id] PRIMARY KEY CLUSTERED ([Id] ASC) 10 | ) 11 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0011_add_likes_count_to_meeting_comments_table.sql: -------------------------------------------------------------------------------- 1 | ALTER TABLE [meetings].[MeetingComments] ADD [LikesCount] INT DEFAULT 0 2 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Scripts/Migrations/1_0_0_0/0012_add_likes_count_to_meeting_comments_view.sql: -------------------------------------------------------------------------------- 1 | ALTER VIEW [meetings].[v_MeetingComments] 2 | AS 3 | SELECT 4 | [MeetingComments].Id, 5 | [MeetingComments].MeetingId, 6 | [MeetingComments].AuthorId, 7 | [MeetingComments].InReplyToCommentId, 8 | [MeetingComments].Comment, 9 | [MeetingComments].CreateDate, 10 | [MeetingComments].EditDate, 11 | [MeetingComments].LikesCount 12 | FROM [meetings].[MeetingComments] AS [MeetingComments] 13 | WHERE [MeetingComments].IsRemoved = 0 14 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/Security/Schemas.sql: -------------------------------------------------------------------------------- 1 | CREATE SCHEMA app AUTHORIZATION dbo 2 | GO 3 | 4 | CREATE SCHEMA administration AUTHORIZATION dbo 5 | GO 6 | 7 | CREATE SCHEMA meetings AUTHORIZATION dbo 8 | GO 9 | 10 | CREATE SCHEMA users AUTHORIZATION dbo 11 | GO 12 | 13 | CREATE SCHEMA payments AUTHORIZATION dbo 14 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/administration/Tables/InboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [administration].InboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_administration_InboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/administration/Tables/InternalCommands.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [administration].InternalCommands 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [EnqueueDate] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | [Error] NVARCHAR(MAX) NULL, 9 | CONSTRAINT [PK_administration_InternalCommands_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/administration/Tables/Members.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [administration].[Members] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Login] NVARCHAR(100) NOT NULL, 5 | [Email] NVARCHAR (255) NOT NULL, 6 | [FirstName] NVARCHAR(50) NOT NULL, 7 | [LastName] NVARCHAR(50) NOT NULL, 8 | [Name] NVARCHAR (255) NOT NULL, 9 | CONSTRAINT [PK_administration_Members_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/administration/Tables/OutboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [administration].OutboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_administration_OutboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/administration/Views/v_Members.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [administration].[v_Members] 2 | AS 3 | SELECT 4 | [Member].[Id], 5 | [Member].[Login], 6 | [Member].[Email], 7 | [Member].[FirstName], 8 | [Member].[LastName], 9 | [Member].[Name] 10 | FROM [administration].[Members] AS [Member] 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/app/Tables/Emails.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [app].[Emails] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [From] NVARCHAR(255) NOT NULL, 5 | [To] NVARCHAR(255) NOT NULL, 6 | [Subject] NVARCHAR(255) NOT NULL, 7 | [Content] NVARCHAR(MAX) NOT NULL, 8 | [Date] DATETIME NOT NULL, 9 | CONSTRAINT [PK_app_Emails_Id] PRIMARY KEY CLUSTERED ([Id] ASC) 10 | ) 11 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/app/Tables/MigrationsJournal.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [app].[MigrationsJournal]( 2 | [Id] [int] IDENTITY(1, 1) NOT NULL, 3 | [ScriptName] NVARCHAR(255) NOT NULL, 4 | [Applied] DATETIME NOT NULL, 5 | CONSTRAINT [PK_app_MigrationsJournal_Id] PRIMARY KEY CLUSTERED 6 | ( 7 | [Id] ASC 8 | )) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/Countries.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].[Countries] 2 | ( 3 | [Code] CHAR(2) NOT NULL, 4 | [Name] NVARCHAR(50) NOT NULL 5 | CONSTRAINT [PK_meetings_Countries_Code] PRIMARY KEY ([Code] ASC) 6 | ) 7 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/InboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].InboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_meetings_InboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/InternalCommands.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].InternalCommands 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [EnqueueDate] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | [Error] NVARCHAR(MAX) NULL, 9 | CONSTRAINT [PK_meetings_InternalCommands_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingCommentingConfigurations.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingCommentingConfigurations 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [MeetingId] UNIQUEIDENTIFIER NOT NULL, 5 | [IsCommentingEnabled] BIT NOT NULL, 6 | CONSTRAINT [PK_meetings_MeetingCommentingConfigurations_Id] PRIMARY KEY ([Id] ASC), 7 | CONSTRAINT [FK_meetings_MeetingCommentingConfigurations_Meetings] FOREIGN KEY ([MeetingId]) REFERENCES meetings.Meetings ([Id]) 8 | ); 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingGroupMembers.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingGroupMembers 2 | ( 3 | [MeetingGroupId] UNIQUEIDENTIFIER NOT NULL, 4 | [MemberId] UNIQUEIDENTIFIER NOT NULL, 5 | [JoinedDate] DATETIME2 NOT NULL, 6 | [RoleCode] VARCHAR(50) NOT NULL, 7 | [IsActive] BIT NOT NULL, 8 | [LeaveDate] DATETIME NULL, 9 | CONSTRAINT [PK_meetings_MeetingGroupMembers_MeetingGroupId_MemberId_JoinedDate] PRIMARY KEY ([MeetingGroupId] ASC, [MemberId] ASC, [JoinedDate] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingGroupProposals.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].[MeetingGroupProposals] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Name] NVARCHAR(255) NOT NULL, 5 | [Description] VARCHAR(200) NULL, 6 | [LocationCity] NVARCHAR(50) NOT NULL, 7 | [LocationCountryCode] NVARCHAR(3) NOT NULL, 8 | [ProposalUserId] UNIQUEIDENTIFIER NOT NULL, 9 | [ProposalDate] DATETIME NOT NULL, 10 | [StatusCode] NVARCHAR(50) NOT NULL 11 | CONSTRAINT [PK_meetings_MeetingGroupProposals_Id] PRIMARY KEY ([Id] ASC) 12 | ) 13 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingGroups.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingGroups 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Name] NVARCHAR(255) NOT NULL, 5 | [Description] VARCHAR(200) NULL, 6 | [LocationCity] NVARCHAR(50) NOT NULL, 7 | [LocationCountryCode] NVARCHAR(3) NOT NULL, 8 | [CreatorId] UNIQUEIDENTIFIER NOT NULL, 9 | [CreateDate] DATETIME NOT NULL, 10 | [PaymentDateTo] DATE NULL, 11 | CONSTRAINT [PK_meetings_MeetingGroups_Id] PRIMARY KEY ([Id] ASC) 12 | ) 13 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingNotAttendees.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingNotAttendees 2 | ( 3 | [MeetingId] UNIQUEIDENTIFIER NOT NULL, 4 | [MemberId] UNIQUEIDENTIFIER NOT NULL, 5 | [DecisionDate] DATETIME2 NOT NULL, 6 | [DecisionChanged] BIT NOT NULL, 7 | [DecisionChangeDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_meetings_MeetingNotAttendees_Id] PRIMARY KEY ([MeetingId] ASC, [MemberId] ASC, [DecisionDate] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MeetingWaitlistMembers.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE meetings.MeetingWaitlistMembers 2 | ( 3 | [MeetingId] UNIQUEIDENTIFIER NOT NULL, 4 | [MemberId] UNIQUEIDENTIFIER NOT NULL, 5 | [SignUpDate] DATETIME2 NOT NULL, 6 | [IsSignedOff] BIT NOT NULL, 7 | [SignOffDate] DATETIME2 NULL, 8 | [IsMovedToAttendees] BIT NOT NULL, 9 | [MovedToAttendeesDate] DATETIME2 NULL, 10 | CONSTRAINT [PK_meetings_MeetingWaitlistMembers_MeetingId_MemberId_SignUpDate] PRIMARY KEY ([MeetingId] ASC, [MemberId] ASC, [SignUpDate] ASC) 11 | ) 12 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/MemberSubscriptions.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].[MemberSubscriptions] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [ExpirationDate] DATETIME NOT NULL, 5 | CONSTRAINT [PK_meetings_MemberSubscriptions_Id] PRIMARY KEY ([Id] ASC) 6 | ) 7 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/Members.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].[Members] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Login] NVARCHAR(100) NOT NULL, 5 | [Email] NVARCHAR (255) NOT NULL, 6 | [FirstName] NVARCHAR(50) NOT NULL, 7 | [LastName] NVARCHAR(50) NOT NULL, 8 | [Name] NVARCHAR (255) NOT NULL, 9 | CONSTRAINT [PK_meetings_Members_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Tables/OutboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [meetings].OutboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_meetings_OutboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_Countries.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_Countriess] 2 | AS 3 | SELECT 4 | [Country].[Code], 5 | [Country].[Name] 6 | FROM meetings.Countries AS [Country] 7 | GO 8 | -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_MeetingAttendees.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_MeetingAttendees] 2 | AS 3 | SELECT 4 | [MeetingAttendee].[MeetingId], 5 | [MeetingAttendee].[AttendeeId], 6 | [MeetingAttendee].[DecisionDate], 7 | [MeetingAttendee].[RoleCode], 8 | [MeetingAttendee].[GuestsNumber], 9 | 10 | [Member].[FirstName], 11 | [Member].[LastName] 12 | FROM [meetings].[MeetingAttendees] AS [MeetingAttendee] 13 | INNER JOIN [meetings].[Members] AS [Member] 14 | ON [MeetingAttendee].[AttendeeId] = [Member].[Id] 15 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_MeetingComments.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_MeetingComments] 2 | AS 3 | SELECT 4 | [MeetingComments].Id, 5 | [MeetingComments].MeetingId, 6 | [MeetingComments].AuthorId, 7 | [MeetingComments].InReplyToCommentId, 8 | [MeetingComments].Comment, 9 | [MeetingComments].CreateDate, 10 | [MeetingComments].EditDate 11 | FROM [meetings].[MeetingComments] AS [MeetingComments] 12 | WHERE [MeetingComments].IsRemoved = 0 13 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_MeetingGroupMembers.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_MeetingGroupMembers] 2 | AS 3 | SELECT 4 | [MeetingGroupMember].MeetingGroupId, 5 | [MeetingGroupMember].MemberId, 6 | [MeetingGroupMember].RoleCode 7 | FROM meetings.MeetingGroupMembers AS [MeetingGroupMember] 8 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_MeetingGroupProposals.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_MeetingGroupProposals] 2 | AS 3 | SELECT 4 | [MeetingGroupProposal].[Id], 5 | [MeetingGroupProposal].[Name], 6 | [MeetingGroupProposal].[Description], 7 | [MeetingGroupProposal].[LocationCity], 8 | [MeetingGroupProposal].[LocationCountryCode], 9 | [MeetingGroupProposal].[ProposalUserId], 10 | [MeetingGroupProposal].[ProposalDate], 11 | [MeetingGroupProposal].[StatusCode] 12 | FROM [meetings].[MeetingGroupProposals] AS [MeetingGroupProposal] 13 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_MeetingGroups.sql: -------------------------------------------------------------------------------- 1 |  2 | CREATE VIEW [meetings].[v_MeetingGroups] 3 | AS 4 | SELECT 5 | [MeetingGroup].Id, 6 | [MeetingGroup].[Name], 7 | [MeetingGroup].[Description], 8 | [MeetingGroup].[LocationCountryCode], 9 | [MeetingGroup].[LocationCity] 10 | FROM meetings.MeetingGroups AS [MeetingGroup] 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_Meetings.sql: -------------------------------------------------------------------------------- 1 |  2 | CREATE VIEW [meetings].[v_Meetings] 3 | AS 4 | SELECT 5 | Meeting.[Id], 6 | Meeting.[Title], 7 | Meeting.[Description], 8 | Meeting.LocationAddress, 9 | Meeting.LocationCity, 10 | Meeting.LocationPostalCode, 11 | Meeting.TermStartDate, 12 | Meeting.TermEndDate 13 | FROM meetings.Meetings AS [Meeting] 14 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/meetings/Views/v_Members.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [meetings].[v_Members] 2 | AS 3 | SELECT 4 | [Member].Id, 5 | [Member].[Name], 6 | [Member].[Login], 7 | [Member].[Email] 8 | FROM meetings.Members AS [Member] 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/InboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [payments].InboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_payments_InboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/InternalCommands.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [payments].InternalCommands 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [EnqueueDate] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | [Error] NVARCHAR(MAX) NULL, 9 | CONSTRAINT [PK_payments_InternalCommands_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/MeetingFees.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [payments].[MeetingFees] 2 | ( 3 | [MeetingFeeId] UNIQUEIDENTIFIER NOT NULL, 4 | [PayerId] UNIQUEIDENTIFIER NOT NULL, 5 | [MeetingId] UNIQUEIDENTIFIER NOT NULL, 6 | [FeeValue] DECIMAL(18, 2) NOT NULL, 7 | [FeeCurrency] VARCHAR(50) NOT NULL, 8 | [Status] VARCHAR(50) NOT NULL, 9 | CONSTRAINT [PK_payments_MeetingFees_MeetingFeeId] PRIMARY KEY ([MeetingFeeId] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/OutboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [payments].OutboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_payments_OutboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/Payers.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [payments].[Payers] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Login] NVARCHAR(100) NOT NULL, 5 | [Email] NVARCHAR (255) NOT NULL, 6 | [FirstName] NVARCHAR(50) NOT NULL, 7 | [LastName] NVARCHAR(50) NOT NULL, 8 | [Name] NVARCHAR (255) NOT NULL, 9 | CONSTRAINT [PK_payments_Payers_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/PriceListItems.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE payments.PriceListItems 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [SubscriptionPeriodCode] VARCHAR(50) NOT NULL, 5 | [CategoryCode] VARCHAR(50) NOT NULL, 6 | [CountryCode] VARCHAR(50) NOT NULL, 7 | [MoneyValue] DECIMAL(18, 2) NOT NULL, 8 | [MoneyCurrency] VARCHAR(50) NOT NULL, 9 | [IsActive] BIT NOT NULL 10 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/SubscriptionCheckpoints.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE payments.SubscriptionCheckpoints 2 | ( 3 | [Code] VARCHAR(50) NOT NULL, 4 | [Position] BIGINT NOT NULL 5 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/SubscriptionDetails.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE payments.SubscriptionDetails 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [PayerId] UNIQUEIDENTIFIER NOT NULL, 5 | [Period] VARCHAR(50) NOT NULL, 6 | [Status] VARCHAR(50) NOT NULL, 7 | [CountryCode] VARCHAR(50) NOT NULL, 8 | [ExpirationDate] DATETIME NOT NULL, 9 | CONSTRAINT [PK_payments_SubscriptionDetails_Id] PRIMARY KEY CLUSTERED ([Id] ASC) 10 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Tables/SubscriptionPayments.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE payments.SubscriptionPayments 2 | ( 3 | [PaymentId] UNIQUEIDENTIFIER NOT NULL, 4 | [PayerId] UNIQUEIDENTIFIER NOT NULL, 5 | [Type] VARCHAR(50) NOT NULL, 6 | [Status] VARCHAR(50) NOT NULL, 7 | [Period] VARCHAR(50) NOT NULL, 8 | [Date] DATETIME NOT NULL, 9 | [SubscriptionId] UNIQUEIDENTIFIER NULL, 10 | [MoneyValue] DECIMAL(18, 2) NOT NULL, 11 | [MoneyCurrency] VARCHAR(50) NOT NULL 12 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/payments/Types/NewStreamMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TYPE payments.NewStreamMessages AS TABLE ( 2 | StreamVersion INT IDENTITY(0,1) NOT NULL, 3 | Id UNIQUEIDENTIFIER NOT NULL, 4 | Created DATETIME DEFAULT(GETUTCDATE()) NOT NULL, 5 | [Type] NVARCHAR(128) NOT NULL, 6 | JsonData NVARCHAR(max) NULL, 7 | JsonMetadata NVARCHAR(max) NULL 8 | ); 9 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/InboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].InboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_users_InboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/InternalCommands.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].InternalCommands 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [EnqueueDate] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | [Error] NVARCHAR(MAX) NULL, 9 | CONSTRAINT [PK_users_InternalCommands_Id] PRIMARY KEY ([Id] ASC) 10 | ) 11 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/OutboxMessages.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].OutboxMessages 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [OccurredOn] DATETIME2 NOT NULL, 5 | [Type] VARCHAR(255) NOT NULL, 6 | [Data] VARCHAR(MAX) NOT NULL, 7 | [ProcessedDate] DATETIME2 NULL, 8 | CONSTRAINT [PK_users_OutboxMessages_Id] PRIMARY KEY ([Id] ASC) 9 | ) 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/Permissions.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].[Permissions] 2 | ( 3 | [Code] VARCHAR(50) NOT NULL, 4 | [Name] VARCHAR(100) NOT NULL, 5 | [Description] [varchar](255) NULL, 6 | CONSTRAINT [PK_users_Permissions_Code] PRIMARY KEY ([Code] ASC) 7 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/RolesToPermissions.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].[RolesToPermissions] 2 | ( 3 | [RoleCode] VARCHAR(50) NOT NULL, 4 | [PermissionCode] VARCHAR(50) NOT NULL, 5 | CONSTRAINT [PK_RolesToPermissions_RoleCode_PermissionCode] PRIMARY KEY (RoleCode ASC, PermissionCode ASC) 6 | ) -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/UserRoles.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].[UserRoles] 2 | ( 3 | [UserId] UNIQUEIDENTIFIER NOT NULL, 4 | [RoleCode] NVARCHAR(50) 5 | ) 6 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Tables/Users.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE [users].[Users] 2 | ( 3 | [Id] UNIQUEIDENTIFIER NOT NULL, 4 | [Login] NVARCHAR(100) NOT NULL, 5 | [Email] NVARCHAR (255) NOT NULL, 6 | [Password] NVARCHAR(255) NOT NULL, 7 | [IsActive] BIT NOT NULL, 8 | [FirstName] NVARCHAR(50) NOT NULL, 9 | [LastName] NVARCHAR(50) NOT NULL, 10 | [Name] NVARCHAR (255) NOT NULL, 11 | CONSTRAINT [PK_users_Users_Id] PRIMARY KEY ([Id] ASC) 12 | ) 13 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Views/v_UserPermissions.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [users].[v_UserPermissions] 2 | AS 3 | SELECT 4 | DISTINCT 5 | [UserRole].UserId, 6 | [RolesToPermission].PermissionCode 7 | FROM [users].UserRoles AS [UserRole] 8 | INNER JOIN [users].RolesToPermissions AS [RolesToPermission] 9 | ON [UserRole].RoleCode = [RolesToPermission].RoleCode 10 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Views/v_UserRegistrations.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [users].[v_UserRegistrations] 2 | AS 3 | SELECT 4 | [UserRegistration].[Id], 5 | [UserRegistration].[Login], 6 | [UserRegistration].[Email], 7 | [UserRegistration].[FirstName], 8 | [UserRegistration].[LastName], 9 | [UserRegistration].[Name], 10 | [UserRegistration].[StatusCode] 11 | FROM [users].[UserRegistrations] AS [UserRegistration] 12 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Views/v_UserRoles.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [users].[v_UserRoles] 2 | AS 3 | SELECT 4 | [UserRole].[UserId], 5 | [UserRole].[RoleCode] 6 | FROM [users].[UserRoles] AS [UserRole] 7 | GO -------------------------------------------------------------------------------- /src/Database/CompanyName.MyMeetings.Database/Structure/users/Views/v_Users.sql: -------------------------------------------------------------------------------- 1 | CREATE VIEW [users].[v_Users] 2 | AS 3 | SELECT 4 | [User].[Id], 5 | [User].[IsActive], 6 | [User].[Login], 7 | [User].[Password], 8 | [User].[Email], 9 | [User].[Name] 10 | FROM [users].[Users] AS [User] 11 | GO -------------------------------------------------------------------------------- /src/Database/DatabaseMigrator/.dockerignore: -------------------------------------------------------------------------------- 1 | **/.classpath 2 | **/.dockerignore 3 | **/.env 4 | **/.git 5 | **/.gitignore 6 | **/.project 7 | **/.settings 8 | **/.toolstarget 9 | **/.vs 10 | **/.vscode 11 | **/*.*proj.user 12 | **/*.dbmdl 13 | **/*.jfm 14 | **/azds.yaml 15 | **/bin 16 | **/charts 17 | **/docker-compose* 18 | **/Dockerfile* 19 | **/node_modules 20 | **/npm-debug.log 21 | **/obj 22 | **/secrets.dev.yaml 23 | **/values.dev.yaml 24 | LICENSE 25 | README.md -------------------------------------------------------------------------------- /src/Database/DatabaseMigrator/DatabaseMigrator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Database/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/mssql/server:2022-latest 2 | 3 | COPY ./CompanyName.MyMeetings.Database/Scripts/CreateDatabase_Linux.sql /scripts/ 4 | 5 | ENV ACCEPT_EULA=Y 6 | ENV SA_PASSWORD=Test@12345 7 | ENV MSSQL_PID=Express 8 | ENV MSSQL_TCP_PORT=1433 9 | 10 | ADD entrypoint.sh / 11 | ENTRYPOINT ["/bin/bash", "/entrypoint.sh"] -------------------------------------------------------------------------------- /src/Database/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 'Starting sql server..' ; 4 | 5 | # Start SQL Server 6 | /opt/mssql/bin/sqlservr & 7 | 8 | echo 'SQL server started.'; 9 | 10 | sleep 30 ; 11 | 12 | echo 'Create database..' ; 13 | 14 | # Create database 15 | /opt/mssql-tools/bin/sqlcmd -d master -i /scripts/CreateDatabase_Linux.sql -U sa -P Test@12345 ; 16 | 17 | echo 'Database created' ; 18 | 19 | tail -f /dev/null -------------------------------------------------------------------------------- /src/Database/entrypoint_DatabaseMigrator.sh: -------------------------------------------------------------------------------- 1 | # Wait 30 seconds after SQL Server is running for database creation. 2 | sleep 30; 3 | 4 | echo $ASPNETCORE_MyMeetings_IntegrationTests_ConnectionString 5 | 6 | dotnet DatabaseMigrator.dll $ASPNETCORE_MyMeetings_IntegrationTests_ConnectionString "/migrations" -------------------------------------------------------------------------------- /src/Modules/Administration/Application/CompanyName.MyMeetings.Modules.Administration.Application.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Configuration/Commands/ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Configuration.Commands 5 | { 6 | public interface ICommandHandler : IRequestHandler 7 | where TCommand : ICommand 8 | { 9 | } 10 | 11 | public interface ICommandHandler : 12 | IRequestHandler 13 | where TCommand : ICommand 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Configuration/Commands/ICommandsScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Configuration.Commands 5 | { 6 | public interface ICommandsScheduler 7 | { 8 | Task EnqueueAsync(ICommand command); 9 | 10 | Task EnqueueAsync(ICommand command); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Configuration/Queries/IQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Configuration.Queries 5 | { 6 | public interface IQueryHandler : 7 | IRequestHandler 8 | where TQuery : IQuery 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Contracts/IAdministrationModule.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Contracts 4 | { 5 | public interface IAdministrationModule 6 | { 7 | Task ExecuteCommandAsync(ICommand command); 8 | 9 | Task ExecuteCommandAsync(ICommand command); 10 | 11 | Task ExecuteQueryAsync(IQuery query); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Contracts/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Contracts 5 | { 6 | public interface ICommand : IRequest 7 | { 8 | Guid Id { get; } 9 | } 10 | 11 | public interface ICommand : IRequest 12 | { 13 | Guid Id { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Contracts/IQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Contracts 4 | { 5 | public interface IQuery : IRequest 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Contracts/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Contracts 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Contracts/QueryBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Contracts 4 | { 5 | public abstract class QueryBase : IQuery 6 | { 7 | public Guid Id { get; } 8 | 9 | protected QueryBase() 10 | { 11 | Id = Guid.NewGuid(); 12 | } 13 | 14 | protected QueryBase(Guid id) 15 | { 16 | Id = id; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Members/GetMember/GetMemberQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Members.GetMember 5 | { 6 | public class GetMemberQuery : QueryBase 7 | { 8 | public GetMemberQuery(Guid memberId) 9 | { 10 | MemberId = memberId; 11 | } 12 | 13 | public Guid MemberId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Application/Members/GetMember/MemberDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Application.Members.GetMember 4 | { 5 | public class MemberDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Login { get; set; } 10 | 11 | public string Email { get; set; } 12 | 13 | public string FirstName { get; set; } 14 | 15 | public string LastName { get; set; } 16 | 17 | public string Name { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/CompanyName.MyMeetings.Modules.Administration.Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/MeetingGroupProposals/IMeetingGroupProposalRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.MeetingGroupProposals 4 | { 5 | public interface IMeetingGroupProposalRepository 6 | { 7 | Task AddAsync(MeetingGroupProposal meetingGroupProposal); 8 | 9 | Task GetByIdAsync(MeetingGroupProposalId meetingGroupProposalId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/MeetingGroupProposals/MeetingGroupProposalId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.MeetingGroupProposals 5 | { 6 | public class MeetingGroupProposalId : TypedIdValueBase 7 | { 8 | public MeetingGroupProposalId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/Members/Events/MemberCreatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.Members.Events 4 | { 5 | public class MemberCreatedDomainEvent : DomainEventBase 6 | { 7 | public MemberCreatedDomainEvent(MemberId memberId) 8 | { 9 | MemberId = memberId; 10 | } 11 | 12 | public MemberId MemberId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/Members/IMemberRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.Members 4 | { 5 | public interface IMemberRepository 6 | { 7 | Task AddAsync(Member member); 8 | 9 | Task GetByIdAsync(MemberId memberId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/Members/MemberId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.Members 5 | { 6 | public class MemberId : TypedIdValueBase 7 | { 8 | public MemberId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/Users/IUserContext.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.Users 2 | { 3 | public interface IUserContext 4 | { 5 | UserId UserId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Domain/Users/UserId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Domain.Users 5 | { 6 | public class UserId : TypedIdValueBase 7 | { 8 | public UserId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/CompanyName.MyMeetings.Modules.Administration.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Assemblies.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration 5 | { 6 | internal static class Assemblies 7 | { 8 | public static readonly Assembly Application = typeof(IAdministrationModule).Assembly; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class InboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class ProcessInboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Inbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.InternalCommands 4 | { 5 | internal class ProcessInternalCommandsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.InternalCommands 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInternalCommandsJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInternalCommandsCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class OutboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Administration.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class ProcessOutboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Processing.Outbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessOutboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessOutboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Infrastructure/Configuration/Quartz/QuartzModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.Infrastructure.Configuration.Quartz 5 | { 6 | public class QuartzModule : Autofac.Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | builder.RegisterAssemblyTypes(ThisAssembly) 11 | .Where(x => typeof(IJob).IsAssignableFrom(x)).InstancePerDependency(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Administration/IntegrationEvents/CompanyName.MyMeetings.Modules.Administration.IntegrationEvents.csproj: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/Modules/Administration/Tests/ArchTests/CompanyName.MyMeetings.Modules.Administration.ArchTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Modules/Administration/Tests/IntegrationTests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: NonParallelizable] 4 | [assembly: LevelOfParallelism(1)] 5 | 6 | namespace CompanyName.MyMeetings.Modules.Administration.IntegrationTests 7 | { 8 | public class AssemblyInfo 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Tests/IntegrationTests/CompanyName.MyMeetings.Modules.Administration.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/Administration/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Application; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Administration.IntegrationTests.SeedWork 5 | { 6 | public class ExecutionContextMock : IExecutionContextAccessor 7 | { 8 | public ExecutionContextMock(Guid userId) 9 | { 10 | UserId = userId; 11 | } 12 | 13 | public Guid UserId { get; } 14 | 15 | public Guid CorrelationId { get; } 16 | 17 | public bool IsAvailable { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Administration/Tests/UnitTests/CompanyName.MyMeetings.Modules.Administration.Domain.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/CompanyName.MyMeetings.Modules.Meetings.Application.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Configuration/Commands/ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Configuration.Commands 5 | { 6 | public interface ICommandHandler : IRequestHandler 7 | where TCommand : ICommand 8 | { 9 | } 10 | 11 | public interface ICommandHandler : 12 | IRequestHandler 13 | where TCommand : ICommand 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Configuration/Commands/ICommandsScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Configuration.Commands 5 | { 6 | public interface ICommandsScheduler 7 | { 8 | Task EnqueueAsync(ICommand command); 9 | 10 | Task EnqueueAsync(ICommand command); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Configuration/Queries/IQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Configuration.Queries 5 | { 6 | public interface IQueryHandler : 7 | IRequestHandler 8 | where TQuery : IQuery 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Contracts/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Contracts 5 | { 6 | public interface ICommand : IRequest 7 | { 8 | Guid Id { get; } 9 | } 10 | 11 | public interface ICommand : IRequest 12 | { 13 | Guid Id { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Contracts/IMeetingsModule.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Contracts 4 | { 5 | public interface IMeetingsModule 6 | { 7 | Task ExecuteCommandAsync(ICommand command); 8 | 9 | Task ExecuteCommandAsync(ICommand command); 10 | 11 | Task ExecuteQueryAsync(IQuery query); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Contracts/IQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Contracts 4 | { 5 | public interface IQuery : IRequest 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Contracts/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Contracts 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Contracts/QueryBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Contracts 4 | { 5 | public abstract class QueryBase : IQuery 6 | { 7 | public Guid Id { get; } 8 | 9 | protected QueryBase() 10 | { 11 | Id = Guid.NewGuid(); 12 | } 13 | 14 | protected QueryBase(Guid id) 15 | { 16 | Id = id; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Countries/CountryDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Countries 2 | { 3 | public class CountryDto 4 | { 5 | public string Code { get; set; } 6 | 7 | public string Name { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Countries/GetAllCountriesQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Countries 5 | { 6 | public class GetAllCountriesQuery : QueryBase> 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingCommentingConfigurations/GetMeetingCommentingConfiguration/MeetingCommentingConfigurationDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingCommentingConfigurations.GetMeetingCommentingConfiguration 4 | { 5 | public class MeetingCommentingConfigurationDto 6 | { 7 | public Guid MeetingId { get; } 8 | 9 | public bool IsCommentingEnabled { get; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingComments/AddMeetingCommentLike/AddMeetingCommentLikeCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingComments.AddMeetingCommentLike 5 | { 6 | public class AddMeetingCommentLikeCommand : CommandBase 7 | { 8 | public Guid MeetingCommentId { get; } 9 | 10 | public AddMeetingCommentLikeCommand(Guid meetingCommentId) 11 | { 12 | MeetingCommentId = meetingCommentId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingComments/EditMeetingComment/EditMeetingCommentCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingComments.EditMeetingComment 4 | { 5 | internal class EditMeetingCommentCommandValidator : AbstractValidator 6 | { 7 | public EditMeetingCommentCommandValidator() 8 | { 9 | RuleFor(c => c.EditedComment).NotNull().NotEmpty() 10 | .WithMessage("Comment cannot be null or empty."); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingComments/GetMeetingCommentLikers/MeetingCommentLikerDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingComments.GetMeetingCommentLikers 4 | { 5 | public class MeetingCommentLikerDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingComments/GetMeetingComments/GetMeetingCommentsQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 4 | 5 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingComments.GetMeetingComments 6 | { 7 | public class GetMeetingCommentsQuery : QueryBase> 8 | { 9 | public Guid MeetingId { get; } 10 | 11 | public GetMeetingCommentsQuery(Guid meetingId) 12 | { 13 | MeetingId = meetingId; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingComments/RemoveMeetingCommentLike/RemoveMeetingCommentLikeCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingComments.RemoveMeetingCommentLike 5 | { 6 | public class RemoveMeetingCommentLikeCommand : CommandBase 7 | { 8 | public Guid MeetingCommentId { get; } 9 | 10 | public RemoveMeetingCommentLikeCommand(Guid meetingCommentId) 11 | { 12 | MeetingCommentId = meetingCommentId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/GetAllMeetingGroups/GetAllMeetingGroupsQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.GetAllMeetingGroups 5 | { 6 | public class GetAllMeetingGroupsQuery : IQuery> 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/GetAllMeetingGroups/MeetingGroupDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.GetAllMeetingGroups 4 | { 5 | public class MeetingGroupDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public string Description { get; set; } 12 | 13 | public string LocationCountryCode { get; set; } 14 | 15 | public string LocationCity { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/GetAuthenticationMemberMeetingGroups/GetAuthenticationMemberMeetingGroupsQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.GetAuthenticationMemberMeetingGroups 5 | { 6 | public class GetAuthenticationMemberMeetingGroupsQuery : QueryBase> 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/GetMeetingGroupDetails/GetMeetingGroupDetailsQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.GetMeetingGroupDetails 5 | { 6 | public class GetMeetingGroupDetailsQuery : QueryBase 7 | { 8 | public GetMeetingGroupDetailsQuery(Guid meetingGroupId) 9 | { 10 | MeetingGroupId = meetingGroupId; 11 | } 12 | 13 | public Guid MeetingGroupId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/GetMeetingGroupDetails/MeetingGroupDetailsDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.GetMeetingGroupDetails 4 | { 5 | public class MeetingGroupDetailsDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public string Description { get; set; } 12 | 13 | public string LocationCountryCode { get; set; } 14 | 15 | public string LocationCity { get; set; } 16 | 17 | public int MembersCount { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/JoinToGroup/JoinToGroupCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.JoinToGroup 5 | { 6 | public class JoinToGroupCommand : CommandBase 7 | { 8 | public JoinToGroupCommand(Guid meetingGroupId) 9 | { 10 | MeetingGroupId = meetingGroupId; 11 | } 12 | 13 | internal Guid MeetingGroupId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/MeetingGroups/LeaveMeetingGroup/LeaveMeetingGroupCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.MeetingGroups.LeaveMeetingGroup 5 | { 6 | public class LeaveMeetingGroupCommand : CommandBase 7 | { 8 | public LeaveMeetingGroupCommand(Guid meetingGroupId) 9 | { 10 | MeetingGroupId = meetingGroupId; 11 | } 12 | 13 | internal Guid MeetingGroupId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/AddMeetingNotAttendee/AddMeetingNotAttendeeCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.AddMeetingNotAttendee 5 | { 6 | public class AddMeetingNotAttendeeCommand : CommandBase 7 | { 8 | public Guid MeetingId { get; } 9 | 10 | public AddMeetingNotAttendeeCommand(Guid meetingId) 11 | { 12 | MeetingId = meetingId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/CancelMeeting/CancelMeetingCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.CancelMeeting 5 | { 6 | public class CancelMeetingCommand : CommandBase 7 | { 8 | public CancelMeetingCommand(Guid meetingId) 9 | { 10 | MeetingId = meetingId; 11 | } 12 | 13 | public Guid MeetingId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/ChangeNotAttendeeDecision/ChangeNotAttendeeDecisionCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.ChangeNotAttendeeDecision 5 | { 6 | public class ChangeNotAttendeeDecisionCommand : CommandBase 7 | { 8 | public Guid MeetingId { get; } 9 | 10 | public ChangeNotAttendeeDecisionCommand(Guid meetingId) 11 | { 12 | MeetingId = meetingId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/GetAuthenticatedMemberMeetings/GetAuthenticatedMemberMeetingsQuery.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.GetAuthenticatedMemberMeetings 5 | { 6 | public class GetAuthenticatedMemberMeetingsQuery : QueryBase> 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/GetMeetingAttendees/GetMeetingAttendeesQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 4 | 5 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.GetMeetingAttendees 6 | { 7 | public class GetMeetingAttendeesQuery : QueryBase> 8 | { 9 | public GetMeetingAttendeesQuery(Guid meetingId) 10 | { 11 | MeetingId = meetingId; 12 | } 13 | 14 | public Guid MeetingId { get; } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/GetMeetingAttendees/MeetingAttendeeDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.GetMeetingAttendees 4 | { 5 | public class MeetingAttendeeDto 6 | { 7 | public string FirstName { get; set; } 8 | 9 | public string LastName { get; set; } 10 | 11 | public Guid AttendeeId { get; set; } 12 | 13 | public string RoleCode { get; set; } 14 | 15 | public int GuestsNumber { get; set; } 16 | 17 | public DateTime DecisionDate { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/GetMeetingDetails/GetMeetingDetailsQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.GetMeetingDetails 5 | { 6 | public class GetMeetingDetailsQuery : QueryBase 7 | { 8 | public GetMeetingDetailsQuery(Guid meetingId) 9 | { 10 | MeetingId = meetingId; 11 | } 12 | 13 | public Guid MeetingId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/SignOffMemberFromWaitlist/SignOffMemberFromWaitlistCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.SignOffMemberFromWaitlist 5 | { 6 | public class SignOffMemberFromWaitlistCommand : CommandBase 7 | { 8 | public Guid MeetingId { get; } 9 | 10 | public SignOffMemberFromWaitlistCommand(Guid meetingId) 11 | { 12 | MeetingId = meetingId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Meetings/SignUpMemberToWaitlist/SignUpMemberToWaitlistCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Meetings.SignUpMemberToWaitlist 5 | { 6 | public class SignUpMemberToWaitlistCommand : CommandBase 7 | { 8 | public Guid MeetingId { get; } 9 | 10 | public SignUpMemberToWaitlistCommand(Guid meetingId) 11 | { 12 | MeetingId = meetingId; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Members/CreateMember/MemberCratedNotificationHandler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | using System.Threading.Tasks; 3 | using MediatR; 4 | 5 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Members.CreateMember 6 | { 7 | public class MemberCratedNotificationHandler : INotificationHandler 8 | { 9 | public Task Handle(MemberCreatedNotification notification, CancellationToken cancellationToken) 10 | { 11 | return Task.CompletedTask; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Application/Members/MemberDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Application.Members 4 | { 5 | public class MemberDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public string Email { get; set; } 12 | 13 | public string Login { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/CompanyName.MyMeetings.Modules.Meetings.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingCommentingConfigurations/IMeetingCommentingConfigurationRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingCommentingConfigurations 5 | { 6 | public interface IMeetingCommentingConfigurationRepository 7 | { 8 | Task AddAsync(MeetingCommentingConfiguration meetingCommentingConfiguration); 9 | 10 | Task GetByMeetingIdAsync(MeetingId meetingId); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingCommentingConfigurations/MeetingCommentingConfigurationId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingCommentingConfigurations 5 | { 6 | public class MeetingCommentingConfigurationId : TypedIdValueBase 7 | { 8 | public MeetingCommentingConfigurationId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingComments/Events/MeetingCommentRemovedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingComments.Events 4 | { 5 | public class MeetingCommentRemovedDomainEvent : DomainEventBase 6 | { 7 | public MeetingCommentId MeetingCommentId { get; } 8 | 9 | public MeetingCommentRemovedDomainEvent(MeetingCommentId meetingCommentId) 10 | { 11 | MeetingCommentId = meetingCommentId; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingComments/IMeetingCommentRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingComments 4 | { 5 | public interface IMeetingCommentRepository 6 | { 7 | Task AddAsync(MeetingComment meetingComment); 8 | 9 | Task GetByIdAsync(MeetingCommentId meetingCommentId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingComments/MeetingCommentId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingComments 5 | { 6 | public class MeetingCommentId : TypedIdValueBase 7 | { 8 | public MeetingCommentId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingGroupProposals/IMeetingGroupProposalRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroupProposals 4 | { 5 | public interface IMeetingGroupProposalRepository 6 | { 7 | Task AddAsync(MeetingGroupProposal meetingGroupProposal); 8 | 9 | Task GetByIdAsync(MeetingGroupProposalId meetingGroupProposalId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingGroupProposals/MeetingGroupProposalId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroupProposals 5 | { 6 | public class MeetingGroupProposalId : TypedIdValueBase 7 | { 8 | public MeetingGroupProposalId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingGroups/IMeetingGroupRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroups 4 | { 5 | public interface IMeetingGroupRepository 6 | { 7 | Task AddAsync(MeetingGroup meetingGroup); 8 | 9 | Task Commit(); 10 | 11 | Task GetByIdAsync(MeetingGroupId id); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingGroups/MeetingGroupId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroups 5 | { 6 | public class MeetingGroupId : TypedIdValueBase 7 | { 8 | public MeetingGroupId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingGroups/Policies/MeetingGroupMemberData.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroups.Policies 2 | { 3 | public class MeetingGroupMemberData 4 | { 5 | public MeetingGroupMemberData(MeetingGroupId meetingGroupId, MeetingGroupMemberRole role) 6 | { 7 | MeetingGroupId = meetingGroupId; 8 | Role = role; 9 | } 10 | 11 | public MeetingGroupId MeetingGroupId { get; } 12 | 13 | public MeetingGroupMemberRole Role { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/MeetingMemberCommentLikes/MeetingMemberCommentLikeId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingMemberCommentLikes 5 | { 6 | public class MeetingMemberCommentLikeId : TypedIdValueBase 7 | { 8 | public MeetingMemberCommentLikeId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Meetings/Events/MeetingCreatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings.Events 4 | { 5 | public class MeetingCreatedDomainEvent : DomainEventBase 6 | { 7 | public MeetingCreatedDomainEvent(MeetingId meetingId) 8 | { 9 | MeetingId = meetingId; 10 | } 11 | 12 | public MeetingId MeetingId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Meetings/Events/MeetingEditedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings.Events 5 | { 6 | public class MeetingEditedDomainEvent : DomainEventBase 7 | { 8 | public MeetingEditedDomainEvent(Guid meetingId) 9 | { 10 | MeetingId = meetingId; 11 | } 12 | 13 | public Guid MeetingId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Meetings/Events/MeetingMainAttributesChangedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings.Events 4 | { 5 | public class MeetingMainAttributesChangedDomainEvent : DomainEventBase 6 | { 7 | public MeetingMainAttributesChangedDomainEvent(MeetingId meetingId) 8 | { 9 | MeetingId = meetingId; 10 | } 11 | 12 | public MeetingId MeetingId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Meetings/IMeetingRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings 4 | { 5 | public interface IMeetingRepository 6 | { 7 | Task AddAsync(Meeting meeting); 8 | 9 | Task GetByIdAsync(MeetingId id); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Meetings/MeetingId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Meetings 5 | { 6 | public class MeetingId : TypedIdValueBase 7 | { 8 | public MeetingId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/Events/MemberCreatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members.Events 4 | { 5 | public class MemberCreatedDomainEvent : DomainEventBase 6 | { 7 | public MemberId MemberId { get; } 8 | 9 | public MemberCreatedDomainEvent(MemberId memberId) 10 | { 11 | MemberId = memberId; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/IMemberContext.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members 2 | { 3 | public interface IMemberContext 4 | { 5 | MemberId MemberId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/IMemberRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members 4 | { 5 | public interface IMemberRepository 6 | { 7 | Task AddAsync(Member member); 8 | 9 | Task GetByIdAsync(MemberId memberId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/MeetingGroupMemberData.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Domain.MeetingGroups; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members 4 | { 5 | public class MeetingGroupMemberData 6 | { 7 | public MeetingGroupId MeetingGroupId { get; } 8 | 9 | public MemberId MemberId { get; } 10 | 11 | public MeetingGroupMemberData(MeetingGroupId meetingGroupId, MemberId memberId) 12 | { 13 | MemberId = memberId; 14 | MeetingGroupId = meetingGroupId; 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/MemberId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members 5 | { 6 | public class MemberId : TypedIdValueBase 7 | { 8 | public MemberId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/MemberSubscriptions/IMemberSubscriptionRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members.MemberSubscriptions 4 | { 5 | public interface IMemberSubscriptionRepository 6 | { 7 | Task GetByIdOptionalAsync(MemberSubscriptionId memberSubscriptionId); 8 | 9 | Task AddAsync(MemberSubscription memberSubscription); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Domain/Members/MemberSubscriptions/MemberSubscriptionId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Domain.Members.MemberSubscriptions 5 | { 6 | public class MemberSubscriptionId : TypedIdValueBase 7 | { 8 | public MemberSubscriptionId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/CompanyName.MyMeetings.Modules.Meetings.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Assemblies.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration 5 | { 6 | internal static class Assemblies 7 | { 8 | public static readonly Assembly Application = typeof(IMeetingsModule).Assembly; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/MeetingsCompositionRoot.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration 4 | { 5 | internal static class MeetingsCompositionRoot 6 | { 7 | private static IContainer _container; 8 | 9 | internal static void SetContainer(IContainer container) 10 | { 11 | _container = container; 12 | } 13 | 14 | internal static ILifetimeScope BeginLifetimeScope() 15 | { 16 | return _container.BeginLifetimeScope(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class InboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class ProcessInboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Inbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.InternalCommands 4 | { 5 | internal class ProcessInternalCommandsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.InternalCommands 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInternalCommandsJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInternalCommandsCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class OutboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Meetings.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class ProcessOutboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Processing.Outbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessOutboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessOutboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Infrastructure/Configuration/Quartz/QuartzModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.Infrastructure.Configuration.Quartz 5 | { 6 | public class QuartzModule : Autofac.Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | builder.RegisterAssemblyTypes(ThisAssembly) 11 | .Where(x => typeof(IJob).IsAssignableFrom(x)).InstancePerDependency(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/IntegrationEvents/CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Meetings/IntegrationEvents/MemberCreatedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Infrastructure.EventBus; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.IntegrationEvents 5 | { 6 | public class MemberCreatedIntegrationEvent : IntegrationEvent 7 | { 8 | public Guid MemberId { get; } 9 | 10 | public MemberCreatedIntegrationEvent(Guid id, DateTime occurredOn, Guid memberId) 11 | : base(id, occurredOn) 12 | { 13 | MemberId = memberId; 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Tests/ArchTests/CompanyName.MyMeetings.Modules.Meetings.ArchTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Tests/IntegrationTests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: NonParallelizable] 4 | [assembly: LevelOfParallelism(1)] 5 | 6 | namespace CompanyName.MyMeetings.Modules.Meetings.IntegrationTests 7 | { 8 | public class AssemblyInfo 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Tests/IntegrationTests/CompanyName.MyMeetings.Modules.Meetings.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/Meetings/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Application; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Meetings.IntegrationTests.SeedWork 5 | { 6 | public class ExecutionContextMock : IExecutionContextAccessor 7 | { 8 | public ExecutionContextMock(Guid userId) 9 | { 10 | UserId = userId; 11 | } 12 | 13 | public Guid UserId { get; } 14 | 15 | public Guid CorrelationId { get; } 16 | 17 | public bool IsAvailable { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Meetings/Tests/UnitTests/CompanyName.MyMeetings.Modules.Meetings.Domain.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/Payments/Application/CompanyName.MyMeetings.Modules.Payments.Application.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Configuration/Commands/ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Commands 5 | { 6 | public interface ICommandHandler : IRequestHandler 7 | where TCommand : ICommand 8 | { 9 | } 10 | 11 | public interface ICommandHandler : 12 | IRequestHandler 13 | where TCommand : ICommand 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Configuration/Commands/ICommandsScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Commands 5 | { 6 | public interface ICommandsScheduler 7 | { 8 | Task EnqueueAsync(ICommand command); 9 | 10 | Task EnqueueAsync(ICommand command); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Configuration/Projections/IProjector.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Projections 4 | { 5 | public interface IProjector 6 | { 7 | Task Project(IDomainEvent @event); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Configuration/Projections/ProjectorBase.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Projections 4 | { 5 | internal abstract class ProjectorBase 6 | { 7 | protected static Task When(IDomainEvent @event) 8 | { 9 | return Task.CompletedTask; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Configuration/Queries/IQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Configuration.Queries 5 | { 6 | public interface IQueryHandler : 7 | IRequestHandler 8 | where TQuery : IQuery 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Contracts/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Contracts 5 | { 6 | public interface ICommand : IRequest 7 | { 8 | Guid Id { get; } 9 | } 10 | 11 | public interface ICommand : IRequest 12 | { 13 | Guid Id { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Contracts/IPaymentsModule.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Contracts 2 | { 3 | public interface IPaymentsModule 4 | { 5 | Task ExecuteCommandAsync(ICommand command); 6 | 7 | Task ExecuteCommandAsync(ICommand command); 8 | 9 | Task ExecuteQueryAsync(IQuery query); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Contracts/IQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Contracts 4 | { 5 | public interface IQuery : IRequest 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Contracts/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Contracts 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Contracts/QueryBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Contracts 4 | { 5 | public abstract class QueryBase : IQuery 6 | { 7 | public Guid Id { get; } 8 | 9 | protected QueryBase() 10 | { 11 | Id = Guid.NewGuid(); 12 | } 13 | 14 | protected QueryBase(Guid id) 15 | { 16 | Id = id; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/MeetingFees/CreateMeetingFeePayment/CreateMeetingFeePaymentCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.MeetingFees.CreateMeetingFeePayment 4 | { 5 | public class CreateMeetingFeePaymentCommand : CommandBase 6 | { 7 | public CreateMeetingFeePaymentCommand(Guid meetingFeeId) 8 | { 9 | MeetingFeeId = meetingFeeId; 10 | } 11 | 12 | public Guid MeetingFeeId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/MeetingFees/GetMeetingFees/GetMeetingFeesQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.MeetingFees.GetMeetingFees 4 | { 5 | public class GetMeetingFeesQuery : QueryBase> 6 | { 7 | public GetMeetingFeesQuery(Guid meetingId) 8 | { 9 | MeetingId = meetingId; 10 | } 11 | 12 | public Guid MeetingId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/MeetingFees/GetMeetingFees/MeetingFeeDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.MeetingFees.GetMeetingFees 2 | { 3 | public class MeetingFeeDto 4 | { 5 | public Guid MeetingFeeId { get; } 6 | 7 | public Guid PayerId { get; } 8 | 9 | public Guid MeetingId { get; } 10 | 11 | public decimal FeeValue { get; } 12 | 13 | public string FeeCurrency { get; } 14 | 15 | public string Status { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/MeetingFees/MarkMeetingFeePaymentAsPaid/MarkMeetingFeePaymentAsPaidCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.MeetingFees.MarkMeetingFeePaymentAsPaid 4 | { 5 | public class MarkMeetingFeePaymentAsPaidCommand : CommandBase 6 | { 7 | public MarkMeetingFeePaymentAsPaidCommand(Guid meetingFeePaymentId) 8 | { 9 | MeetingFeePaymentId = meetingFeePaymentId; 10 | } 11 | 12 | public Guid MeetingFeePaymentId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Payers/GetPayer/GetPayerQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Payers.GetPayer 4 | { 5 | public class GetPayerQuery : QueryBase 6 | { 7 | public GetPayerQuery(Guid payerId) 8 | { 9 | PayerId = payerId; 10 | } 11 | 12 | public Guid PayerId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Payers/GetPayer/PayerDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Payers.GetPayer 2 | { 3 | public class PayerDto 4 | { 5 | public Guid Id { get; set; } 6 | 7 | public string Login { get; set; } 8 | 9 | public string Email { get; set; } 10 | 11 | public string FirstName { get; set; } 12 | 13 | public string LastName { get; set; } 14 | 15 | public string Name { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/PriceListItems/ActivatePriceListItem/ActivatePriceListItemCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems.ActivatePriceListItem 4 | { 5 | public class ActivatePriceListItemCommand : CommandBase 6 | { 7 | public ActivatePriceListItemCommand(Guid priceListItemId) 8 | { 9 | PriceListItemId = priceListItemId; 10 | } 11 | 12 | public Guid PriceListItemId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/PriceListItems/DeactivatePriceListItem/DeactivatePriceListItemCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems.DeactivatePriceListItem 4 | { 5 | public class DeactivatePriceListItemCommand : CommandBase 6 | { 7 | public DeactivatePriceListItemCommand(Guid priceListItemId) 8 | { 9 | PriceListItemId = priceListItemId; 10 | } 11 | 12 | public Guid PriceListItemId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/PriceListItems/GetPriceListItem/PriceListItemMoneyValueDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems.GetPriceListItem 2 | { 3 | public class PriceListItemMoneyValueDto 4 | { 5 | public decimal Value { get; set; } 6 | 7 | public string Currency { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/PriceListItems/GetPriceListItems/GetPriceListItemsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems.GetPriceListItems 4 | { 5 | public class GetPriceListItemsQuery : QueryBase> 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/PriceListItems/PriceListItemDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.PriceListItems 2 | { 3 | public class PriceListItemDto 4 | { 5 | public string CountryCode { get; set; } 6 | 7 | public string SubscriptionPeriodCode { get; set; } 8 | 9 | public decimal MoneyValue { get; set; } 10 | 11 | public string MoneyCurrency { get; set; } 12 | 13 | public string CategoryCode { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/ExpireSubscriptionPayment/ExpireSubscriptionPaymentCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.ExpireSubscriptionPayment 4 | { 5 | public class ExpireSubscriptionPaymentCommand : CommandBase 6 | { 7 | public ExpireSubscriptionPaymentCommand(Guid paymentId) 8 | { 9 | PaymentId = paymentId; 10 | } 11 | 12 | public Guid PaymentId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/ExpireSubscriptionPayments/ExpireSubscriptionPaymentsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.ExpireSubscriptionPayments 4 | { 5 | public class ExpireSubscriptionPaymentsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/ExpireSubscriptions/ExpireSubscriptionsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.ExpireSubscriptions 4 | { 5 | public class ExpireSubscriptionsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/GetPayerSubscription/GetAuthenticatedPayerSubscriptionQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | using CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.GetSubscriptionDetails; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.GetPayerSubscription 5 | { 6 | public class GetAuthenticatedPayerSubscriptionQuery : QueryBase 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/GetSubscriptionDetails/GetSubscriptionDetailsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.GetSubscriptionDetails 4 | { 5 | public class GetSubscriptionDetailsQuery : QueryBase 6 | { 7 | public GetSubscriptionDetailsQuery(Guid subscriptionId) 8 | { 9 | SubscriptionId = subscriptionId; 10 | } 11 | 12 | public Guid SubscriptionId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/GetSubscriptionDetails/SubscriptionDetailsDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.GetSubscriptionDetails 2 | { 3 | public class SubscriptionDetailsDto 4 | { 5 | public Guid SubscriptionId { get; set; } 6 | 7 | public string Period { get; set; } 8 | 9 | public DateTime ExpirationDate { get; set; } 10 | 11 | public string Status { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Application/Subscriptions/GetSubscriptionPayments/GetSubscriptionPaymentsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Application.Subscriptions.GetSubscriptionPayments 4 | { 5 | public class GetSubscriptionPaymentsQuery : QueryBase> 6 | { 7 | public GetSubscriptionPaymentsQuery(Guid payerId) 8 | { 9 | PayerId = payerId; 10 | } 11 | 12 | public Guid PayerId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/CompanyName.MyMeetings.Modules.Payments.Domain.csproj: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFeePayments/MeetingFeePaymentId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFeePayments 5 | { 6 | public class MeetingFeePaymentId : AggregateId 7 | { 8 | public MeetingFeePaymentId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFeePayments/MeetingFeePaymentSnapshot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFeePayments 4 | { 5 | public class MeetingFeePaymentSnapshot 6 | { 7 | public MeetingFeePaymentSnapshot(Guid meetingFeePaymentId, Guid meetingFeeId) 8 | { 9 | MeetingFeePaymentId = meetingFeePaymentId; 10 | MeetingFeeId = meetingFeeId; 11 | } 12 | 13 | public Guid MeetingFeePaymentId { get; } 14 | 15 | public Guid MeetingFeeId { get; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFees/Events/MeetingFeeExpiredDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFees.Events 5 | { 6 | public class MeetingFeeExpiredDomainEvent : DomainEventBase 7 | { 8 | public MeetingFeeExpiredDomainEvent(Guid meetingFeeId, string status) 9 | { 10 | MeetingFeeId = meetingFeeId; 11 | Status = status; 12 | } 13 | 14 | public Guid MeetingFeeId { get; } 15 | 16 | public string Status { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFees/Events/MeetingFeePaidDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFees.Events 5 | { 6 | public class MeetingFeePaidDomainEvent : DomainEventBase 7 | { 8 | public MeetingFeePaidDomainEvent(Guid meetingFeeId, string status) 9 | { 10 | MeetingFeeId = meetingFeeId; 11 | Status = status; 12 | } 13 | 14 | public Guid MeetingFeeId { get; } 15 | 16 | public string Status { get; } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFees/MeetingFeeId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFees 5 | { 6 | public class MeetingFeeId : AggregateId 7 | { 8 | public MeetingFeeId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFees/MeetingFeeSnapshot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFees 4 | { 5 | public class MeetingFeeSnapshot 6 | { 7 | public MeetingFeeSnapshot(Guid meetingFeeId, Guid payerId, Guid meetingId) 8 | { 9 | MeetingFeeId = meetingFeeId; 10 | PayerId = payerId; 11 | MeetingId = meetingId; 12 | } 13 | 14 | public Guid MeetingFeeId { get; } 15 | 16 | public Guid PayerId { get; } 17 | 18 | public Guid MeetingId { get; } 19 | } 20 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/MeetingFees/MeetingId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.MeetingFees 5 | { 6 | public class MeetingId : TypedIdValueBase 7 | { 8 | public MeetingId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Payers/IPayerContext.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Payers 2 | { 3 | public interface IPayerContext 4 | { 5 | PayerId PayerId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Payers/IPayerRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Payers 4 | { 5 | public interface IPayerRepository 6 | { 7 | Task AddAsync(Payer payer); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Payers/PayerId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Payers 5 | { 6 | public class PayerId : TypedIdValueBase 7 | { 8 | public PayerId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/PriceListItems/Events/PriceListItemActivatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.PriceListItems.Events 5 | { 6 | public class PriceListItemActivatedDomainEvent : DomainEventBase 7 | { 8 | public PriceListItemActivatedDomainEvent(Guid priceListItemId) 9 | { 10 | PriceListItemId = priceListItemId; 11 | } 12 | 13 | public Guid PriceListItemId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/PriceListItems/Events/PriceListItemDeactivatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.PriceListItems.Events 5 | { 6 | public class PriceListItemDeactivatedDomainEvent : DomainEventBase 7 | { 8 | public PriceListItemDeactivatedDomainEvent(Guid priceListItemId) 9 | { 10 | PriceListItemId = priceListItemId; 11 | } 12 | 13 | public Guid PriceListItemId { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/PriceListItems/PriceListItemId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.PriceListItems 5 | { 6 | public class PriceListItemId : AggregateId 7 | { 8 | public PriceListItemId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/PriceListItems/PricingStrategies/IPricingStrategy.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.Subscriptions; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.PriceListItems.PricingStrategies 5 | { 6 | public interface IPricingStrategy 7 | { 8 | MoneyValue GetPrice( 9 | string countryCode, 10 | SubscriptionPeriod subscriptionPeriod, 11 | PriceListItemCategory category); 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/SeedWork/AggregateId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork 4 | { 5 | public abstract class AggregateId 6 | where T : AggregateRoot 7 | { 8 | protected AggregateId(Guid value) 9 | { 10 | Value = value; 11 | } 12 | 13 | public Guid Value { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/SubscriptionPayments/SubscriptionPaymentId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.SubscriptionPayments 5 | { 6 | public class SubscriptionPaymentId : AggregateId 7 | { 8 | public SubscriptionPaymentId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/SubscriptionRenewalPayments/SubscriptionRenewalPaymentId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.SubscriptionRenewalPayments 5 | { 6 | public class SubscriptionRenewalPaymentId : AggregateId 7 | { 8 | public SubscriptionRenewalPaymentId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Subscriptions/SubscriberId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Subscriptions 5 | { 6 | public class SubscriberId : TypedIdValueBase 7 | { 8 | public SubscriberId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Subscriptions/SubscriptionId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.SeedWork; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Subscriptions 5 | { 6 | public class SubscriptionId : AggregateId 7 | { 8 | public SubscriptionId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Users/IUserContext.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Users 2 | { 3 | public interface IUserContext 4 | { 5 | UserId UserId { get; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Domain/Users/UserId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Domain.Users 5 | { 6 | public class UserId : TypedIdValueBase 7 | { 8 | public UserId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/AggregateStore/ICheckpointStore.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.AggregateStore 4 | { 5 | public interface ICheckpointStore 6 | { 7 | long? GetCheckpoint(SubscriptionCode subscriptionCode); 8 | 9 | Task StoreCheckpoint(SubscriptionCode subscriptionCode, long checkpoint); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/AggregateStore/SubscriptionCode.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.AggregateStore 2 | { 3 | public enum SubscriptionCode 4 | { 5 | All 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/CompanyName.MyMeetings.Modules.Payments.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Assemblies.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration 5 | { 6 | internal static class Assemblies 7 | { 8 | public static readonly Assembly Application = typeof(IPaymentsModule).Assembly; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Authentication/AuthenticationModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using CompanyName.MyMeetings.Modules.Payments.Domain.Payers; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Authentication 5 | { 6 | internal class AuthenticationModule : Autofac.Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | builder.RegisterType() 11 | .As() 12 | .InstancePerLifetimeScope(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/DatabaseSchema.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration 2 | { 3 | public class DatabaseSchema 4 | { 5 | public const string Name = "payments"; 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/PaymentsCompositionRoot.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration 4 | { 5 | public static class PaymentsCompositionRoot 6 | { 7 | private static IContainer _container; 8 | 9 | public static void SetContainer(IContainer container) 10 | { 11 | _container = container; 12 | } 13 | 14 | public static ILifetimeScope BeginLifetimeScope() 15 | { 16 | return _container.BeginLifetimeScope(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class InboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class ProcessInboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Inbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.InternalCommands 4 | { 5 | internal class ProcessInternalCommandsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.InternalCommands 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInternalCommandsJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInternalCommandsCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class OutboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.Payments.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class ProcessOutboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Processing.Outbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessOutboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessOutboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Infrastructure/Configuration/Quartz/QuartzModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.Infrastructure.Configuration.Quartz 5 | { 6 | public class QuartzModule : Autofac.Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | builder.RegisterAssemblyTypes(ThisAssembly) 11 | .Where(x => typeof(IJob).IsAssignableFrom(x)).InstancePerDependency(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/Payments/IntegrationEvents/CompanyName.MyMeetings.Modules.Payments.IntegrationEvents.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/Payments/Tests/ArchTests/CompanyName.MyMeetings.Modules.Payments.ArchTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Modules/Payments/Tests/IntegrationTests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: NonParallelizable] 4 | [assembly: LevelOfParallelism(1)] 5 | 6 | namespace CompanyName.MyMeetings.Modules.Payments.IntegrationTests 7 | { 8 | public class AssemblyInfo 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Tests/IntegrationTests/CompanyName.MyMeetings.Modules.Payments.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/Payments/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Application; 3 | 4 | namespace CompanyName.MyMeetings.Modules.Payments.IntegrationTests.SeedWork 5 | { 6 | public class ExecutionContextMock : IExecutionContextAccessor 7 | { 8 | public ExecutionContextMock(Guid userId) 9 | { 10 | UserId = userId; 11 | } 12 | 13 | public Guid UserId { get; } 14 | 15 | public Guid CorrelationId { get; } 16 | 17 | public bool IsAvailable { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/Payments/Tests/UnitTests/CompanyName.MyMeetings.Modules.Payments.Domain.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Authentication/Authenticate/AuthenticateCommandValidator.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authentication.Authenticate 4 | { 5 | internal class AuthenticateCommandValidator : AbstractValidator 6 | { 7 | public AuthenticateCommandValidator() 8 | { 9 | this.RuleFor(x => x.Login).NotEmpty().WithMessage("Login cannot be empty"); 10 | this.RuleFor(x => x.Password).NotEmpty().WithMessage("Password cannot be empty"); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Authorization/GetAuthenticatedUserPermissions/GetAuthenticatedUserPermissionsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions; 2 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetAuthenticatedUserPermissions 5 | { 6 | public class GetAuthenticatedUserPermissionsQuery : QueryBase> 7 | { 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Authorization/GetUserPermissions/GetUserPermissionsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions 4 | { 5 | public class GetUserPermissionsQuery : QueryBase> 6 | { 7 | public GetUserPermissionsQuery(Guid userId) 8 | { 9 | UserId = userId; 10 | } 11 | 12 | public Guid UserId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Authorization/GetUserPermissions/UserPermissionDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Authorization.GetUserPermissions 2 | { 3 | public class UserPermissionDto 4 | { 5 | public string Code { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/CompanyName.MyMeetings.Modules.UserAccess.Application.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Configuration/Commands/ICommandHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands 5 | { 6 | public interface ICommandHandler : IRequestHandler 7 | where TCommand : ICommand 8 | { 9 | } 10 | 11 | public interface ICommandHandler : 12 | IRequestHandler 13 | where TCommand : ICommand 14 | { 15 | } 16 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Configuration/Commands/ICommandsScheduler.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Commands 5 | { 6 | public interface ICommandsScheduler 7 | { 8 | Task EnqueueAsync(ICommand command); 9 | 10 | Task EnqueueAsync(ICommand command); 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Configuration/Queries/IQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Configuration.Queries 5 | { 6 | public interface IQueryHandler : 7 | IRequestHandler 8 | where TQuery : IQuery 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/CustomClaimTypes.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 2 | { 3 | internal class CustomClaimTypes 4 | { 5 | internal const string Roles = "roles"; 6 | internal const string Email = "email"; 7 | internal const string Name = "name"; 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MediatR; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 5 | { 6 | public interface ICommand : IRequest 7 | { 8 | Guid Id { get; } 9 | } 10 | 11 | public interface ICommand : IRequest 12 | { 13 | Guid Id { get; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/IQuery.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 4 | { 5 | public interface IQuery : IRequest 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/IUserAccessModule.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 2 | { 3 | public interface IUserAccessModule 4 | { 5 | Task ExecuteCommandAsync(ICommand command); 6 | 7 | Task ExecuteCommandAsync(ICommand command); 8 | 9 | Task ExecuteQueryAsync(IQuery query); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/QueryBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 4 | { 5 | public abstract class QueryBase : IQuery 6 | { 7 | public Guid Id { get; } 8 | 9 | protected QueryBase() 10 | { 11 | Id = Guid.NewGuid(); 12 | } 13 | 14 | protected QueryBase(Guid id) 15 | { 16 | Id = id; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Contracts/Roles.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts 2 | { 3 | public class Roles 4 | { 5 | public const string Admin = "Admin"; 6 | public const string User = "User"; 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Emails/EmailDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Emails 2 | { 3 | public class EmailDto 4 | { 5 | public Guid Id { get; set; } 6 | 7 | public string From { get; set; } 8 | 9 | public string To { get; set; } 10 | 11 | public string Subject { get; set; } 12 | 13 | public string Content { get; set; } 14 | 15 | public DateTime Date { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Emails/GetAllEmailsQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Emails 4 | { 5 | public class GetAllEmailsQuery : QueryBase> 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/UserRegistrations/ConfirmUserRegistration/ConfirmUserRegistrationCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.ConfirmUserRegistration 4 | { 5 | public class ConfirmUserRegistrationCommand : CommandBase 6 | { 7 | public ConfirmUserRegistrationCommand(Guid userRegistrationId) 8 | { 9 | UserRegistrationId = userRegistrationId; 10 | } 11 | 12 | public Guid UserRegistrationId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/UserRegistrations/GetUserRegistration/GetUserRegistrationQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.UserRegistrations.GetUserRegistration 4 | { 5 | public class GetUserRegistrationQuery : QueryBase 6 | { 7 | public GetUserRegistrationQuery(Guid userRegistrationId) 8 | { 9 | UserRegistrationId = userRegistrationId; 10 | } 11 | 12 | public Guid UserRegistrationId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Users/GetAuthenticatedUser/GetAuthenticatedUserQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetAuthenticatedUser 5 | { 6 | public class GetAuthenticatedUserQuery : QueryBase 7 | { 8 | public GetAuthenticatedUserQuery() 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Users/GetUser/GetUserQuery.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser 4 | { 5 | public class GetUserQuery : QueryBase 6 | { 7 | public GetUserQuery(Guid userId) 8 | { 9 | UserId = userId; 10 | } 11 | 12 | public Guid UserId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Application/Users/GetUser/UserDto.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Application.Users.GetUser 2 | { 3 | public class UserDto 4 | { 5 | public Guid Id { get; set; } 6 | 7 | public bool IsActive { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public string Login { get; set; } 12 | 13 | public string Email { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/CompanyName.MyMeetings.Modules.UserAccess.Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationConfirmedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events 4 | { 5 | public class UserRegistrationConfirmedDomainEvent : DomainEventBase 6 | { 7 | public UserRegistrationConfirmedDomainEvent(UserRegistrationId userRegistrationId) 8 | { 9 | UserRegistrationId = userRegistrationId; 10 | } 11 | 12 | public UserRegistrationId UserRegistrationId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/UserRegistrations/Events/UserRegistrationExpiredDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations.Events 4 | { 5 | public class UserRegistrationExpiredDomainEvent : DomainEventBase 6 | { 7 | public UserRegistrationExpiredDomainEvent(UserRegistrationId userRegistrationId) 8 | { 9 | UserRegistrationId = userRegistrationId; 10 | } 11 | 12 | public UserRegistrationId UserRegistrationId { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/UserRegistrations/IUserRegistrationRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations 4 | { 5 | public interface IUserRegistrationRepository 6 | { 7 | Task AddAsync(UserRegistration userRegistration); 8 | 9 | Task GetByIdAsync(UserRegistrationId userRegistrationId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/UserRegistrations/IUsersCounter.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations 2 | { 3 | public interface IUsersCounter 4 | { 5 | int CountUsersWithLogin(string login); 6 | } 7 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/UserRegistrations/UserRegistrationId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.UserRegistrations 5 | { 6 | public class UserRegistrationId : TypedIdValueBase 7 | { 8 | public UserRegistrationId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/Users/Events/UserCreatedDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users.Events 4 | { 5 | public class UserCreatedDomainEvent : DomainEventBase 6 | { 7 | public UserCreatedDomainEvent(UserId id) 8 | { 9 | Id = id; 10 | } 11 | 12 | public new UserId Id { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/Users/IUserRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users 4 | { 5 | public interface IUserRepository 6 | { 7 | Task AddAsync(User user); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/Users/UserId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users 5 | { 6 | public class UserId : TypedIdValueBase 7 | { 8 | public UserId(Guid value) 9 | : base(value) 10 | { 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Domain/Users/UserRole.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.BuildingBlocks.Domain; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Domain.Users 4 | { 5 | public class UserRole : ValueObject 6 | { 7 | public static UserRole Member => new UserRole(nameof(Member)); 8 | 9 | public static UserRole Administrator => new UserRole(nameof(Administrator)); 10 | 11 | public string Value { get; } 12 | 13 | private UserRole(string value) 14 | { 15 | this.Value = value; 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Assemblies.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration 5 | { 6 | internal static class Assemblies 7 | { 8 | public static readonly Assembly Application = typeof(IUserAccessModule).Assembly; 9 | } 10 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/IRecurringCommand.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing 2 | { 3 | public interface IRecurringCommand 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/InboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class InboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox 4 | { 5 | public class ProcessInboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Inbox/ProcessInboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Inbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands 4 | { 5 | internal class ProcessInternalCommandsCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/InternalCommands/ProcessInternalCommandsJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.InternalCommands 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessInternalCommandsJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessInternalCommandsCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/OutboxMessageDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class OutboxMessageDto 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Type { get; set; } 10 | 11 | public string Data { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxCommand.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.Modules.UserAccess.Application.Contracts; 2 | 3 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox 4 | { 5 | public class ProcessOutboxCommand : CommandBase, IRecurringCommand 6 | { 7 | } 8 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Processing/Outbox/ProcessOutboxJob.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Processing.Outbox 5 | { 6 | [DisallowConcurrentExecution] 7 | public class ProcessOutboxJob : IJob 8 | { 9 | public async Task Execute(IJobExecutionContext context) 10 | { 11 | await CommandsExecutor.Execute(new ProcessOutboxCommand()); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Quartz/QuartzModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Quartz; 3 | 4 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Quartz 5 | { 6 | public class QuartzModule : Autofac.Module 7 | { 8 | protected override void Load(ContainerBuilder builder) 9 | { 10 | builder.RegisterAssemblyTypes(ThisAssembly) 11 | .Where(x => typeof(IJob).IsAssignableFrom(x)).InstancePerDependency(); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Infrastructure/Configuration/Security/IDataProtector.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyName.MyMeetings.Modules.UserAccess.Infrastructure.Configuration.Security 2 | { 3 | public interface IDataProtector 4 | { 5 | string Encrypt(string plainText); 6 | 7 | string Decrypt(string encryptedText); 8 | } 9 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/IntegrationEvents/CompanyName.MyMeetings.Modules.UserAccess.IntegrationEvents.csproj: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Tests/ArchTests/CompanyName.MyMeetings.Modules.UserAccess.ArchTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Tests/IntegrationTests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: NonParallelizable] 4 | [assembly: LevelOfParallelism(1)] 5 | 6 | namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests 7 | { 8 | public class AssemblyInfo 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Tests/IntegrationTests/CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Modules/UserAccess/Tests/IntegrationTests/UserRegistrations/UserRegistrationSampleData.cs: -------------------------------------------------------------------------------- 1 | namespace CompanyNames.MyMeetings.Modules.UserAccess.IntegrationTests.UserRegistrations 2 | { 3 | public struct UserRegistrationSampleData 4 | { 5 | public static string Login => "jdoe"; 6 | 7 | public static string Email => "jdoe@mail.com"; 8 | 9 | public static string FirstName => "John"; 10 | 11 | public static string LastName => "Doe"; 12 | 13 | public static string Password => "qwerty"; 14 | } 15 | } -------------------------------------------------------------------------------- /src/Modules/UserAccess/Tests/UnitTests/CompanyName.MyMeetings.Modules.UserAccess.Domain.UnitTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Tests/IntegrationTests/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | 3 | [assembly: NonParallelizable] 4 | [assembly: LevelOfParallelism(1)] 5 | 6 | namespace CompanyName.MyMeetings.IntegrationTests 7 | { 8 | public class AssemblyInfo 9 | { 10 | } 11 | } -------------------------------------------------------------------------------- /src/Tests/IntegrationTests/SeedWork/ExecutionContextMock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CompanyName.MyMeetings.BuildingBlocks.Application; 3 | 4 | namespace CompanyName.MyMeetings.IntegrationTests.SeedWork 5 | { 6 | public class ExecutionContextMock : IExecutionContextAccessor 7 | { 8 | public ExecutionContextMock(Guid userId) 9 | { 10 | UserId = userId; 11 | } 12 | 13 | public Guid UserId { get; } 14 | 15 | public Guid CorrelationId { get; } 16 | 17 | public bool IsAvailable { get; } 18 | } 19 | } -------------------------------------------------------------------------------- /src/Tests/SUT/SeedWork/Probing/AssertErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.SUT.SeedWork.Probing 4 | { 5 | public class AssertErrorException : Exception 6 | { 7 | public AssertErrorException(string message) 8 | : base(message) 9 | { 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tests/SUT/SeedWork/Probing/IProbe.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace CompanyName.MyMeetings.SUT.SeedWork.Probing 4 | { 5 | public interface IProbe 6 | { 7 | bool IsSatisfied(); 8 | 9 | Task SampleAsync(); 10 | 11 | string DescribeFailureTo(); 12 | } 13 | 14 | public interface IProbe 15 | { 16 | bool IsSatisfied(T sample); 17 | 18 | Task GetSampleAsync(); 19 | 20 | string DescribeFailureTo(); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Tests/SUT/SeedWork/Probing/Timeout.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace CompanyName.MyMeetings.SUT.SeedWork.Probing 4 | { 5 | public class Timeout 6 | { 7 | private readonly DateTime _endTime; 8 | 9 | public Timeout(int duration) 10 | { 11 | this._endTime = DateTime.Now.AddMilliseconds(duration); 12 | } 13 | 14 | public bool HasTimedOut() 15 | { 16 | return DateTime.Now > _endTime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Tests/SUT/TestCases/CleanDatabase.cs: -------------------------------------------------------------------------------- 1 | using CompanyName.MyMeetings.SUT.SeedWork; 2 | using NUnit.Framework; 3 | 4 | namespace CompanyName.MyMeetings.SUT.TestCases 5 | { 6 | public class CleanDatabaseTestCase : TestBase 7 | { 8 | protected override bool PerformDatabaseCleanup => true; 9 | 10 | protected override bool CreatePermissions => false; 11 | 12 | [Test] 13 | public void Prepare() 14 | { 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Waiting 60 seconds to start backend" 3 | 4 | sleep 60; 5 | 6 | echo "Backend starting..." 7 | 8 | dotnet CompanyName.MyMeetings.API.dll -------------------------------------------------------------------------------- /src/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "8.0.0", 4 | "rollForward": "latestFeature", 5 | "allowPrerelease": false 6 | } 7 | } --------------------------------------------------------------------------------