public async Task <IActionResult> PatchCategoriesTree(Guid id, [FromBody] JsonPatchDocument <UpdateCategoryTreeRequest> request, int version)
        {
            var treeView = await _categoryTreeCollection.Find(new BsonDocument("_id", id)).FirstOrDefaultAsync();

            if (treeView == null)
            {
                return(NotFound());
            }

            var operationsCollection = new UpdateCategoryTreeRequest();

            request.ApplyTo(operationsCollection);

            if (operationsCollection.Nodes.Any())
            {
                var tree = await _session.Get <CategoryTree>(id);

                var aggregateIds = tree.Nodes.GetNodeIds();
                var requestIds   = operationsCollection.Nodes.GetNodeIds();

                if (!requestIds.All(i => aggregateIds.Contains(i)))
                {
                    var invalidIds = requestIds.Where(i => !aggregateIds.Contains(i));

                    return(BadRequest($"Can not find nodes with ids {string.Join(", ", invalidIds)}"));
                }

                operationsCollection.Nodes.InitNodeIds();

                await Bus.Publish <UpdateCategoryTree>(new
                {
                    Id              = id,
                    UserId          = UserId,
                    Nodes           = operationsCollection.Nodes,
                    ExpectedVersion = version
                });
            }

            if (operationsCollection.IsDeleted)
            {
                await Bus.Publish <DeleteCategoryTree>(new
                {
                    Id = id,
                    UserId,
                    ExpectedVersion = version
                });
            }

            return(Accepted());
        }
        public async Task <IActionResult> PatchCategoriesTreeNode(Guid id, Guid nodeId, [FromBody] JsonPatchDocument <UpdateCategoryTreeRequest> request, int version)
        {
            //TODO: Validate input parapeters e.g. title
            var treeView = await _categoryTreeCollection.Find(new BsonDocument("_id", id)).FirstOrDefaultAsync();

            if (treeView == null)
            {
                return(NotFound());
            }

            var tree = await _session.Get <CategoryTree>(id);

            if (!tree.Nodes.ContainsTree(nodeId))
            {
                return(NotFound());
            }

            var operations = new UpdateCategoryTreeRequest();

            request.ApplyTo(operations);

            if (operations.Nodes.Any())
            {
                operations.Nodes.InitNodeIds();

                await Bus.Publish <UpdateCategoryTree>(new
                {
                    Id              = id,
                    ParentId        = nodeId,
                    UserId          = UserId,
                    Nodes           = operations.Nodes,
                    ExpectedVersion = version
                });
            }

            if (operations.IsDeleted)
            {
                await Bus.Publish <DeleteCategoryTreeNode>(new
                {
                    Id     = id,
                    NodeId = nodeId,
                    UserId,
                    ExpectedVersion = version
                });
            }

            return(Accepted());
        }