Cannot update an activity in an inbox feed - getstream-io

is it even possible to update an activity in an inbox feed?
const activityRequest = {
actor: `ContentFeed:${origin}`,
verb: "follow",
object: `User:${destination}`,
foreign_id: "...:followRequest:5fb68...",
time: new Date().toISOString(),
};
const res = await getStreamAdminClient
.updateActivity(activityRequest)
.catch((err) => console.error(err));
I'm trying to update the verb of the activity from followRequest to follow.
I'm getting a 200OK from getstream but it doesn't update the activity at all. The foreign id is definitely correct. Does someone know what I'm doing wrong?

Related

Possible to enrich data in a collection?

As the title suggests, I'm wondering if it's possible to enrich data in a collection or if there is another recommended best practice to achieve the same result.
Consider the following example:
const user = await client.user(userId).get();
const object = await client.collections.add({
'Message',
messageId,
message: {
contents: 'Hello world!',
user // this fails with the error "Converting circular structure to JSON"
}
});
await feed.addActivity({
actor,
verb,
object
});
// I want the objects enriched in this request to also contain the enriched user object
await feed.get({ enrich: true });

What is the best way to update different properties?

I'm building an API with Restify which is based on Express. I'm using Typeorm and I'm wondering what is the best way to update different properties which came from user input.
Essentially I have a route like this:
server.put('/users/:id', errorHandler(update));
which fire this method:
const update = async (req: Request, res: Response) => {
const user = { ...req.body, id: req.params.id } as User;
res.send(await userService.update(user));
}
as you can see I used the spread operator to create an User entity. Then, inside userService.update I have the following:
export const update = async (user: User): Promise<User> => {
const repository = getRepository(User);
const entity = await repository.findOne({ id: user.id });
if (!entity) throw new errors.ResourceNotFoundError(`There is no user with id of ${user.id}`);
Object.assign(entity, user, { id: entity.id, chat_id: entity.chat_id, project_id: entity.project_id, deleted: false });
return await repository.save(entity);
}
as you can see, I want prevent that the data provided by the API consumer will replace some important properties like: id, chat_id, project_id, deleted, so I used the method Object.assign to achieve this.
Is this a good way? What do you suggest for improve this?
You can use update method of typeorm like this, it will partially update the values that you give as a second argument.
// this will find a user with id ${user.id} and will only
// change the fields that is specified in the user object
await repository.update(user.id, user);
// check if updated for debugging
const updatedUser = await repository.findOne(user.id);
console.log(updatedUser, null, 2)
If you want to create a new record of the existing user in db, then you only need to change it's id. To do that
Deep clone the object so there will be another user object with new reference
Remove id field from the deep cloned object and use insert afterwards
// Deep clone user object
const clonedUser = JSON.parse(JSON.stringify(user))
// Delete id field from the deep clone
delete clonedUser.id;
// create a new user with different id
await repository.insert(clonedUser);
You can filter your important properties.
And pass the user id to the update method of your userService.
const { id, chat_id, project_id, deleted, ...user } = req.body;
const { id } = req.params;
res.send(await userService.update(id, user));
This will make sure user object don't have the properties(that is important).
And you can change your update method like below:
export const update = (userId: string, user: User): Promise<User> => {
return getRepository(User).update(userId, user);
}

how to rollback changes for an update query in mongoose

I made a query in mongodb for updating a document in a collection that include adding additional fields in that document.
Then i made another to update another document in another collection and executed in the result function of first query,but i got error while updating the second one.
I need to roll back changes made on the 1 st document.
please help
According to docs you can rollback a transaction in mongoose using session.abortTransaction()
Sample code from docs
let session = null;
return Customer.createCollection().
then(() => Customer.startSession()).
then(_session => {
session = _session;
session.startTransaction();
return Customer.create([{ name: 'Test' }], { session: session });
}).
then(() => Customer.create([{ name: 'Test2' }], { session: session })).
then(() => session.abortTransaction()).
then(() => Customer.countDocuments()).
then(count => assert.strictEqual(count, 0));

How to show Created By "NAME" using MongoDB

I am new to MongoDB, so I was wondering if there any way to show the name of created by or modified by XYZ user? I want it in my application to display the name who created or modified something.
You need to account for this info when structuring your data model. E.g. let's say you're writing posts to the posts collection, and want to add the post author from authors collection.
Now, the simplest way to do this is to have this data directly embedded in your post document. E.g. for creation data we use insert, something like this:
// posts.service.js
function save(postData, userData) {
// We return a Promise here
return db.posts.insert({
title: postData.title,
text: postData.text,
published: true,
// now comes your audit data
createdBy: user.username,
createdAt: new Date().toISOString(),
});
}
module.exports = { save };
You use it like this, ie. in your /posts API controller:
// ... other stuff then:
const postsService = require('./posts.service');
route.post('/posts', function(req, res, next) {
postsService.save({
title: req.body.title,
text: req.body.text,
}, req.user)
// Handle response and error.
.then(response => res.json(response))
.catch(error => next(error));
And for updating a post, you'd add this to posts.service.js (using update):
// posts.service
// ...after your *save* function above
function update(postId, postData, userData) {
return db.posts.update({
id: postId,
}{
title: postData.title,
text: postData.text,
published: true,
// now comes your audit data
modifiedBy: user.username,
modifiedAt: new Date().toISOString(),
});
}
// update module exports:
module.exports = { save, update };
Now, on your controller, add the route to handle updates:
// ... after the creation route
route.put('/posts/:postId', function(req, res, next) {
postsService.update(req.params.postId, {
title: req.body.title,
text: req.body.text,
}, req.user)
// Handle response and error.
.then(response => res.json(response))
.catch(error => next(error));
Now, other ways to do this can mean you only include reference (ObjectId) of whomever modified the data. Or maybe more info.
But smarter and easier thing to do would be to use something like mongoose for handling your data, and then use a plugin that does all this automatically. Something like this: https://github.com/taptaptech/mongoose-audit.
You could look for something similar at npm: https://www.npmjs.com/search?q=mongoose%20audit.
What these things do is they add pre-save hooks to your documents and in those hooks the audit data is tracked. So you can use something finished, or you can look at what these packages do and try to replicate the functionality - better if this is a hobby project and you wanna learn how things work.
Now, how do you show this information in your frontend is likely good for a new question, as you specify no information about any of the software/packages you're using.
you should just write it down in your db upon edit/create, there is no build in functionality for this.

Sequelize - How to set association, save entity and return the saved entity with the associated entity

I am trying to create an association between an existing (user) entity and save the new entity (visit).
I've read the sequelize docs and can't see a better way of doing this than saving the first entity using async/await, then fetching it again passing include as an option. See below.
export const createVisit = async(req, res) => {
req.assert('BusinessId', 'Must pass businessId').notEmpty();
req.assert('UserId', 'Must pass customerId').notEmpty();
const visit = await new Visit({
UserId: req.body.UserId,
BusinessId: req.body.BusinessId,
redemption: false,
})
.save()
.catch((error) => {
res.status(400).send({ error });
});
const visitWithUser = await Visit.findById(visit.id, {include: [{model: User, attributes: ['firstName','lastName','facebook', 'gender','email']}]})
res.status(200).send({ visit: visitWithUser })
};
Is there a way to save the entity and get sequelize to return the saved entity along with any associations?
I think it supports this feature , as per the doc , you can do it like this :
Visit.create({
UserId: req.body.UserId,
BusinessId: req.body.BusinessId,
redemption: false,
}, {
include: [User]
}).then(function(comment) {
console.log(comment.user.id);
});
Here is the git discussion if you want to read.

Resources