public async Task HandleAsync(JoinGroupCommand command) { var invitationCode = InvitationCode.From(command.Code); var invitation = await _invitationRepository.GetAsync(invitationCode) ?? throw new InvalidInvitationCodeException(command.Code); var group = await _groupRepository.GetAsync(invitation.GroupId) ?? throw new GroupNotFoundException(invitation.GroupId); invitation.Use(UserId.From(command.UserId), group, _clock); }
private static void Build(EntityTypeBuilder <Invitation> invitation) { invitation.ToTable("Invitations"); invitation.HasKey(x => x.Id) .HasName("PK_Invitations"); invitation.Property(x => x.Id) .HasConversion(x => x.Value, x => InvitationId.From(x)) .ValueGeneratedNever() .HasColumnName("InvitationId") .IsRequired(); invitation.Property(x => x.GroupId).IsRequired(); invitation.HasOne <Group>() .WithMany() .HasForeignKey(x => x.GroupId) .HasConstraintName("FK_Invitations_Groups") .IsRequired(); invitation.OwnsOne <ExpirationTimeContainer>( "_expirationTime", b => { b.Property <ExpirationTimeType>("_type") .HasConversion <string>() .IsRequired().HasColumnName("ExpirationTimeType"); b.Property <DateTimeOffset>("_start").IsRequired().HasColumnName("ExpirationStart"); b.Property <TimeSpan?>("_period").IsRequired(false).HasColumnName("ExpirationPeriod"); b.Ignore(x => x.ExpirationTime); } ); invitation.Ignore(x => x.ExpirationTime); invitation.OwnsOne <UsageCounterContainer>( "_usageCounter", b => { b.Property <UsageCounterType>("_type") .HasConversion <string>() .IsRequired().HasColumnName("UsageCounterType"); b.Property <int?>("_value").IsRequired(false).HasColumnName("UsageCounter"); b.Ignore(x => x.UsageCounter); } ); invitation.Ignore(x => x.UsageCounter); invitation.HasIndex(x => x.InvitationCode) .IsUnique(); invitation.Property(x => x.InvitationCode) .HasConversion(x => x.Value, x => InvitationCode.From(x)) .HasMaxLength(8) .IsRequired(); }