Exemplo n.º 1
0
        public UserMapping(RefToken initiator)
        {
            Guard.NotNull(initiator, nameof(initiator));

            this.initiator = initiator;
        }
Exemplo n.º 2
0
        public Task StartBackupAsync(DomainId appId, RefToken actor)
        {
            var grain = grainFactory.GetGrain <IBackupGrain>(appId.ToString());

            return(grain.BackupAsync(actor));
        }
Exemplo n.º 3
0
        public async override Task RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
        {
            switch (@event.Payload)
            {
            case AppCreated appCreated:
            {
                appName = appCreated.Name;

                await ResolveUsersAsync(reader, actor);
                await ReserveAppAsync(appId);

                break;
            }

            case AppContributorAssigned contributorAssigned:
            {
                if (isActorAssigned)
                {
                    contributorAssigned.ContributorId = MapUser(contributorAssigned.ContributorId, actor).Identifier;
                }
                else
                {
                    isActorAssigned = true;

                    contributorAssigned.ContributorId = actor.Identifier;
                }

                activeUsers.Add(contributorAssigned.ContributorId);
                break;
            }

            case AppContributorRemoved contributorRemoved:
            {
                contributorRemoved.ContributorId = MapUser(contributorRemoved.ContributorId, actor).Identifier;

                activeUsers.Remove(contributorRemoved.ContributorId);
                break;
            }
            }

            if (@event.Payload is SquidexEvent squidexEvent)
            {
                squidexEvent.Actor = MapUser(squidexEvent.Actor.Identifier, actor);
            }
        }
Exemplo n.º 4
0
 private RefToken MapUser(string userId, RefToken fallback)
 {
     return(userMapping.GetOrAdd(userId, fallback));
 }
Exemplo n.º 5
0
        public async Task Should_retrieve_new_app(short numSilos, bool shouldBreak)
        {
            var env = new GrainEnvironment();

            var cluster =
                new TestClusterBuilder(numSilos)
                .AddSiloBuilderConfigurator <Configurator>()
                .Build();

            await cluster.DeployAsync();

            try
            {
                var indexes = GetIndexes(shouldBreak, env, cluster);

                var appId = env.AppId;

                foreach (var index in indexes)
                {
                    Assert.Null(await index.GetAppAsync(appId.Id, true));
                    Assert.Null(await index.GetAppByNameAsync(appId.Name, true));
                }

                var creatorId     = Guid.NewGuid().ToString();
                var creatorToken  = new RefToken(RefTokenType.Subject, creatorId);
                var createCommand = new CreateApp {
                    Actor = creatorToken, AppId = appId.Id
                };

                var commandContext = new CommandContext(createCommand, A.Fake <ICommandBus>());

                var randomIndex = indexes[new Random().Next(3)];

                await indexes[0].HandleAsync(commandContext, x =>
                {
                    if (x.Command is CreateApp command)
                    {
                        env.HandleCommand(command);
                    }

                    x.Complete(true);

                    return(Task.CompletedTask);
                });

                foreach (var index in indexes)
                {
                    var appById = await index.GetAppAsync(appId.Id, true);

                    var appByName = await index.GetAppByNameAsync(appId.Name, true);

                    if (index == randomIndex || !shouldBreak)
                    {
                        Assert.True(appById?.Contributors.ContainsKey(creatorId));
                        Assert.True(appByName?.Contributors.ContainsKey(creatorId));
                    }
                    else
                    {
                        Assert.False(appById?.Contributors.ContainsKey(creatorId));
                        Assert.False(appByName?.Contributors.ContainsKey(creatorId));
                    }
                }
            }
            finally
            {
                await Task.WhenAny(Task.Delay(2000), cluster.StopAllSilosAsync());
            }
        }
Exemplo n.º 6
0
        protected void On(AppPlanChanged @event)
        {
            planId = @event.PlanId;

            planOwner = string.IsNullOrWhiteSpace(planId) ? null : @event.Actor;
        }
Exemplo n.º 7
0
 private void Process(BackupJob job, RefToken actor, CancellationToken ct)
 {
     ProcessAsync(job, actor, ct).Forget();
 }
Exemplo n.º 8
0
 private static RefToken Client(string identifier)
 {
     return(RefToken.Client(identifier));
 }
Exemplo n.º 9
0
 private static RefToken Subject(string identifier)
 {
     return(RefToken.User(identifier));
 }
Exemplo n.º 10
0
 private static AppLanguageAdded CreateInitialLanguage(NamedId <Guid> appId, RefToken actor)
 {
     return(new AppLanguageAdded {
         AppId = appId, Actor = actor, Language = Language.EN
     });
 }
Exemplo n.º 11
0
 private static AppContributorAssigned CreateInitialOwner(NamedId <Guid> appId, RefToken actor)
 {
     return(new AppContributorAssigned {
         AppId = appId, Actor = actor, ContributorId = actor.Identifier, Permission = AppContributorPermission.Owner
     });
 }
Exemplo n.º 12
0
 private static AppPatternAdded CreateInitialPattern(NamedId <Guid> appId, RefToken actor, Guid id, AppPattern p)
 {
     return(new AppPatternAdded {
         AppId = appId, Actor = actor, PatternId = id, Name = p.Name, Pattern = p.Pattern, Message = p.Message
     });
 }
Exemplo n.º 13
0
 private static AppCreated CreateInitalEvent(NamedId <Guid> appId, RefToken actor, string name)
 {
     return(new AppCreated {
         AppId = appId, Actor = actor, Name = name
     });
 }
Exemplo n.º 14
0
        public async Task UpdateAsync()
        {
            var apps = new Dictionary <NamedId <DomainId>, Dictionary <DomainId, (string Name, string Pattern, string?Message)> >();

            await eventStore.QueryAsync(storedEvent =>
            {
                var @event = eventDataFormatter.ParseIfKnown(storedEvent);

                if (@event != null)
                {
                    switch (@event.Payload)
                    {
                    case AppPatternAdded patternAdded:
                        {
                            var patterns = apps.GetOrAddNew(patternAdded.AppId);

                            patterns[patternAdded.PatternId] = (patternAdded.Name, patternAdded.Pattern, patternAdded.Message);
                            break;
                        }

                    case AppPatternUpdated patternUpdated:
                        {
                            var patterns = apps.GetOrAddNew(patternUpdated.AppId);

                            patterns[patternUpdated.PatternId] = (patternUpdated.Name, patternUpdated.Pattern, patternUpdated.Message);
                            break;
                        }

                    case AppPatternDeleted patternDeleted:
                        {
                            var patterns = apps.GetOrAddNew(patternDeleted.AppId);

                            patterns.Remove(patternDeleted.PatternId);
                            break;
                        }

                    case AppArchived appArchived:
                        {
                            apps.Remove(appArchived.AppId);
                            break;
                        }
                    }
                }

                return(Task.CompletedTask);
            }, "^app\\-");

            var actor = RefToken.Client("Migrator");

            foreach (var(appId, patterns) in apps)
            {
                if (patterns.Count > 0)
                {
                    var settings = new AppSettings
                    {
                        Patterns = patterns.Values.Select(x => new Pattern(x.Name, x.Pattern)
                        {
                            Message = x.Message
                        }).ToReadOnlyCollection()
                    };

                    await commandBus.PublishAsync(new UpdateAppSettings
                    {
                        AppId    = appId,
                        Settings = settings,
                        FromRule = true,
                        Actor    = actor
                    });
                }
            }
        }
Exemplo n.º 15
0
        public static IEnrichedContentEntity Create(DomainId id, DomainId refId = default, DomainId assetId = default, ContentData?data = null)
        {
            var now = SystemClock.Instance.GetCurrentInstant();

            data ??=
            new ContentData()
            .AddField("my-localized-string",
                      new ContentFieldData()
                      .AddLocalized("de-DE", "de-DE"))
            .AddField("my-string",
                      new ContentFieldData()
                      .AddInvariant(null))
            .AddField("my-assets",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(assetId.ToString())))
            .AddField("my-number",
                      new ContentFieldData()
                      .AddInvariant(1.0))
            .AddField("my-boolean",
                      new ContentFieldData()
                      .AddInvariant(true))
            .AddField("my-datetime",
                      new ContentFieldData()
                      .AddInvariant(now))
            .AddField("my-tags",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array("tag1", "tag2")))
            .AddField("my-references",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(refId.ToString())))
            .AddField("my-union",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(refId.ToString())))
            .AddField("my-geolocation",
                      new ContentFieldData()
                      .AddInvariant(
                          JsonValue.Object()
                          .Add("latitude", 10)
                          .Add("longitude", 20)))
            .AddField("my-component",
                      new ContentFieldData()
                      .AddInvariant(
                          JsonValue.Object()
                          .Add(Component.Discriminator, TestSchemas.Ref1.Id)
                          .Add("schemaRef1Field", "Component1")))
            .AddField("my-components",
                      new ContentFieldData()
                      .AddInvariant(
                          JsonValue.Array(
                              JsonValue.Object()
                              .Add(Component.Discriminator, TestSchemas.Ref1.Id)
                              .Add("schemaRef1Field", "Component1"),
                              JsonValue.Object()
                              .Add(Component.Discriminator, TestSchemas.Ref2.Id)
                              .Add("schemaRef2Field", "Component2"))))
            .AddField("my-json",
                      new ContentFieldData()
                      .AddInvariant(
                          JsonValue.Object()
                          .Add("value", 1)))
            .AddField("my-array",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(
                                        JsonValue.Object()
                                        .Add("nested-number", 10)
                                        .Add("nested-boolean", true),
                                        JsonValue.Object()
                                        .Add("nested-number", 20)
                                        .Add("nested-boolean", false))));

            var content = new ContentEntity
            {
                Id             = id,
                AppId          = TestApp.DefaultId,
                Version        = 1,
                Created        = now,
                CreatedBy      = RefToken.User("user1"),
                LastModified   = now,
                LastModifiedBy = RefToken.Client("client1"),
                Data           = data,
                SchemaId       = TestSchemas.DefaultId,
                Status         = Status.Draft,
                StatusColor    = "red"
            };

            return(content);
        }
Exemplo n.º 16
0
 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
 {
     return(reader.TokenType == JsonToken.Null ? null : RefToken.Parse((string)reader.Value));
 }
Exemplo n.º 17
0
 private static AppContributorAssigned CreateInitialOwner(RefToken actor)
 {
     return(new AppContributorAssigned {
         ContributorId = actor.Identifier, Permission = AppContributorPermission.Owner
     });
 }
Exemplo n.º 18
0
        public override Task <bool> RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
        {
            switch (@event.Payload)
            {
            case RuleCreated ruleCreated:
                ruleIds.Add(ruleCreated.RuleId);
                break;

            case RuleDeleted ruleDeleted:
                ruleIds.Remove(ruleDeleted.RuleId);
                break;
            }

            return(TaskHelper.True);
        }
Exemplo n.º 19
0
        protected IEnrichedContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData?data = null, NamedContentData?dataDraft = null)
        {
            var now = SystemClock.Instance.GetCurrentInstant();

            data ??=
            new NamedContentData()
            .AddField("my-string",
                      new ContentFieldData()
                      .AddValue("de", "value"))
            .AddField("my-assets",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Array(assetId.ToString())))
            .AddField("my-number",
                      new ContentFieldData()
                      .AddValue("iv", 1.0))
            .AddField("my_number",
                      new ContentFieldData()
                      .AddValue("iv", 2.0))
            .AddField("my-boolean",
                      new ContentFieldData()
                      .AddValue("iv", true))
            .AddField("my-datetime",
                      new ContentFieldData()
                      .AddValue("iv", now))
            .AddField("my-tags",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Array("tag1", "tag2")))
            .AddField("my-references",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Array(refId.ToString())))
            .AddField("my-union",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Array(refId.ToString())))
            .AddField("my-geolocation",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Object().Add("latitude", 10).Add("longitude", 20)))
            .AddField("my-json",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Object().Add("value", 1)))
            .AddField("my-localized",
                      new ContentFieldData()
                      .AddValue("de-DE", "de-DE"))
            .AddField("my-array",
                      new ContentFieldData()
                      .AddValue("iv", JsonValue.Array(
                                    JsonValue.Object()
                                    .Add("nested-boolean", true)
                                    .Add("nested-number", 10)
                                    .Add("nested_number", 11),
                                    JsonValue.Object()
                                    .Add("nested-boolean", false)
                                    .Add("nested-number", 20)
                                    .Add("nested_number", 21))));

            var content = new ContentEntity
            {
                Id             = id,
                Version        = 1,
                Created        = now,
                CreatedBy      = new RefToken(RefTokenType.Subject, "user1"),
                LastModified   = now,
                LastModifiedBy = new RefToken(RefTokenType.Subject, "user2"),
                Data           = data,
                DataDraft      = dataDraft !,
                SchemaId       = schemaId,
                Status         = Status.Draft,
                StatusColor    = "red"
            };

            return(content);
        }
Exemplo n.º 20
0
        public override async Task <bool> RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
        {
            switch (@event.Payload)
            {
            case AssetCreated assetCreated:
                await ReadAssetAsync(assetCreated.AssetId, assetCreated.FileVersion, reader);

                break;

            case AssetUpdated assetUpdated:
                await ReadAssetAsync(assetUpdated.AssetId, assetUpdated.FileVersion, reader);

                break;
            }

            return(true);
        }
Exemplo n.º 21
0
        private async Task ProcessAsync(BackupJob job, RefToken actor, CancellationToken ct)
        {
            var handlers = CreateHandlers();

            var lastTimestamp = job.Started;

            try
            {
                using (var stream = backupArchiveLocation.OpenStream(job.Id))
                {
                    using (var writer = await backupArchiveLocation.OpenWriterAsync(stream))
                    {
                        var userMapping = new UserMapping(actor);

                        var context = new BackupContext(Key, userMapping, writer);

                        await eventStore.QueryAsync(async storedEvent =>
                        {
                            var @event = eventDataFormatter.Parse(storedEvent.Data);

                            if (@event.Payload is SquidexEvent squidexEvent)
                            {
                                context.UserMapping.Backup(squidexEvent.Actor);
                            }

                            foreach (var handler in handlers)
                            {
                                await handler.BackupEventAsync(@event, context);
                            }

                            writer.WriteEvent(storedEvent);

                            job.HandledEvents = writer.WrittenEvents;
                            job.HandledAssets = writer.WrittenAttachments;

                            lastTimestamp = await WritePeriodically(lastTimestamp);
                        }, SquidexHeaders.AppId, Key.ToString(), null, ct);

                        foreach (var handler in handlers)
                        {
                            ct.ThrowIfCancellationRequested();

                            await handler.BackupAsync(context);
                        }

                        foreach (var handler in handlers)
                        {
                            ct.ThrowIfCancellationRequested();

                            await handler.CompleteBackupAsync(context);
                        }

                        await userMapping.StoreAsync(writer, userResolver);
                    }

                    stream.Position = 0;

                    ct.ThrowIfCancellationRequested();

                    await backupArchiveStore.UploadAsync(job.Id, stream, ct);
                }

                job.Status = JobStatus.Completed;
            }
            catch (OperationCanceledException)
            {
                await RemoveAsync(job);
            }
            catch (Exception ex)
            {
                log.LogError(ex, job.Id.ToString(), (ctx, w) => w
                             .WriteProperty("action", "makeBackup")
                             .WriteProperty("status", "failed")
                             .WriteProperty("backupId", ctx));

                job.Status = JobStatus.Failed;
            }
            finally
            {
                job.Stopped = clock.GetCurrentInstant();

                await state.WriteAsync();

                currentTaskToken = null;
                currentJob       = null;
            }
        }
Exemplo n.º 22
0
        public async Task Should_replace_asset_url_in_content()
        {
            var me = RefToken.User("123");

            var newAssetsUrl    = "https://new.squidex.com/api/assets";
            var newAssetsUrlApp = "https://old.squidex.com/api/assets/my-new-app";

            var oldAssetsUrl    = "https://old.squidex.com/api/assets";
            var oldAssetsUrlApp = "https://old.squidex.com/api/assets/my-old-app";

            var reader = A.Fake <IBackupReader>();

            A.CallTo(() => urlGenerator.AssetContentBase())
            .Returns(newAssetsUrl);

            A.CallTo(() => urlGenerator.AssetContentBase(appId.Name))
            .Returns(newAssetsUrlApp);

            A.CallTo(() => reader.ReadJsonAsync <BackupContents.Urls>(A <string> ._, ct))
            .Returns(new BackupContents.Urls
            {
                Assets    = oldAssetsUrl,
                AssetsApp = oldAssetsUrlApp
            });

            var data =
                new ContentData()
                .AddField("asset",
                          new ContentFieldData()
                          .AddLocalized("en", $"Asset: {oldAssetsUrlApp}/my-asset.jpg.")
                          .AddLocalized("it", $"Asset: {oldAssetsUrl}/my-asset.jpg."))
                .AddField("assetsInArray",
                          new ContentFieldData()
                          .AddLocalized("iv",
                                        JsonValue.Array(
                                            $"Asset: {oldAssetsUrlApp}/my-asset.jpg.")))
                .AddField("assetsInObj",
                          new ContentFieldData()
                          .AddLocalized("iv",
                                        JsonValue.Object()
                                        .Add("asset", $"Asset: {oldAssetsUrlApp}/my-asset.jpg.")));

            var updateData =
                new ContentData()
                .AddField("asset",
                          new ContentFieldData()
                          .AddLocalized("en", $"Asset: {newAssetsUrlApp}/my-asset.jpg.")
                          .AddLocalized("it", $"Asset: {newAssetsUrl}/my-asset.jpg."))
                .AddField("assetsInArray",
                          new ContentFieldData()
                          .AddLocalized("iv",
                                        JsonValue.Array(
                                            $"Asset: {newAssetsUrlApp}/my-asset.jpg.")))
                .AddField("assetsInObj",
                          new ContentFieldData()
                          .AddLocalized("iv",
                                        JsonValue.Object()
                                        .Add("asset", $"Asset: {newAssetsUrlApp}/my-asset.jpg.")));

            var context = new RestoreContext(appId.Id, new UserMapping(me), reader, DomainId.NewGuid());

            await sut.RestoreEventAsync(Envelope.Create(new AppCreated
            {
                Name = appId.Name
            }), context, ct);

            await sut.RestoreEventAsync(Envelope.Create(new ContentUpdated
            {
                Data = data
            }), context, ct);

            Assert.Equal(updateData, data);
        }
Exemplo n.º 23
0
        public override async Task <bool> RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
        {
            switch (@event.Payload)
            {
            case AppCreated appCreated:
            {
                appName = appCreated.Name;

                await ResolveUsersAsync(reader);
                await ReserveAppAsync(appId);

                break;
            }

            case AppContributorAssigned contributorAssigned:
            {
                if (!userMapping.TryGetValue(contributorAssigned.ContributorId, out var user) || user.Equals(actor))
                {
                    return(false);
                }

                contributorAssigned.ContributorId = user.Identifier;
                contributors.Add(contributorAssigned.ContributorId);
                break;
            }

            case AppContributorRemoved contributorRemoved:
            {
                if (!userMapping.TryGetValue(contributorRemoved.ContributorId, out var user) || user.Equals(actor))
                {
                    return(false);
                }

                contributorRemoved.ContributorId = user.Identifier;
                contributors.Remove(contributorRemoved.ContributorId);
                break;
            }
            }

            if (@event.Payload is SquidexEvent squidexEvent)
            {
                squidexEvent.Actor = MapUser(squidexEvent.Actor.Identifier, actor);
            }

            return(true);
        }
Exemplo n.º 24
0
        public static IEnrichedContentEntity Create(NamedId <DomainId> appId, NamedId <DomainId> schemaId, DomainId id, DomainId refId, DomainId assetId, ContentData?data = null)
        {
            var now = SystemClock.Instance.GetCurrentInstant();

            data ??=
            new ContentData()
            .AddField("my-string",
                      new ContentFieldData()
                      .AddLocalized("de", "value"))
            .AddField("my-string2",
                      new ContentFieldData()
                      .AddInvariant(null))
            .AddField("my-assets",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(assetId.ToString())))
            .AddField("2_numbers",
                      new ContentFieldData()
                      .AddInvariant(22))
            .AddField("2-numbers",
                      new ContentFieldData()
                      .AddInvariant(23))
            .AddField("content",
                      new ContentFieldData()
                      .AddInvariant(24))
            .AddField("my-number",
                      new ContentFieldData()
                      .AddInvariant(1.0))
            .AddField("my_number",
                      new ContentFieldData()
                      .AddInvariant(null))
            .AddField("my-boolean",
                      new ContentFieldData()
                      .AddInvariant(true))
            .AddField("my-datetime",
                      new ContentFieldData()
                      .AddInvariant(now))
            .AddField("my-tags",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array("tag1", "tag2")))
            .AddField("my-references",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(refId.ToString())))
            .AddField("my-union",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(refId.ToString())))
            .AddField("my-geolocation",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Object().Add("latitude", 10).Add("longitude", 20)))
            .AddField("my-json",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Object().Add("value", 1)))
            .AddField("my-localized",
                      new ContentFieldData()
                      .AddLocalized("de-DE", "de-DE"))
            .AddField("my-array",
                      new ContentFieldData()
                      .AddInvariant(JsonValue.Array(
                                        JsonValue.Object()
                                        .Add("nested-number", 10)
                                        .Add("nested_number", null)
                                        .Add("nested-boolean", true),
                                        JsonValue.Object()
                                        .Add("nested-number", 20)
                                        .Add("nested_number", null)
                                        .Add("nested-boolean", false))));

            var content = new ContentEntity
            {
                Id             = id,
                AppId          = appId,
                Version        = 1,
                Created        = now,
                CreatedBy      = RefToken.User("user1"),
                LastModified   = now,
                LastModifiedBy = RefToken.User("user2"),
                Data           = data,
                SchemaId       = schemaId,
                Status         = Status.Draft,
                StatusColor    = "red"
            };

            return(content);
        }
Exemplo n.º 25
0
 public virtual Task <bool> RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
 {
     return(TaskHelper.True);
 }
Exemplo n.º 26
0
        public override Task <bool> RestoreEventAsync(Envelope <IEvent> @event, Guid appId, BackupReader reader, RefToken actor)
        {
            switch (@event.Payload)
            {
            case ContentCreated contentCreated:
                contentIdsBySchemaId.GetOrAddNew(contentCreated.SchemaId.Id).Add(contentCreated.ContentId);
                break;

            case SchemaDeleted schemaDeleted:
                contentIdsBySchemaId.Remove(schemaDeleted.SchemaId.Id);
                break;
            }

            return(TaskHelper.True);
        }
Exemplo n.º 27
0
        public Task StartRestoreAsync(RefToken actor, Uri url, string?newAppName)
        {
            var grain = grainFactory.GetGrain <IRestoreGrain>(SingleGrain.Id);

            return(grain.RestoreAsync(url, actor, newAppName));
        }
Exemplo n.º 28
0
 public static ScheduleJob Build(Status status, RefToken scheduledBy, Instant dueTime)
 {
     return(new ScheduleJob(Guid.NewGuid(), status, scheduledBy, dueTime));
 }