Notification Schema Structure in MongoDB-NodeJS - node.js

I am developing notification process & technology I am using is MongoDB & NodeJS(Express)
Please do let me know how to design schema for this notification process.
What are the collections & documents will be defined.
Thanks

After researching a lot, I wrote my schema in a flowing way. It has helped me to keep scalability in my application and do the best solution for multiple notification features.
NotificationSchema = new Schema({
sender: {type:mongoose.Schema.Types.ObjectId, ref:'User'}, // Notification creator
receiver: [{type:mongoose.Schema.Types.ObjectId, ref:'User'}], // Ids of the receivers of the notification
message: String, // any description of the notification message
read_by:[{
readerId:{type:mongoose.Schema.Types.ObjectId, ref:'User'},
read_at: {type: Date, default: Date.now}
}],
created_at:{type: Date, default: Date.now},
});
Why this looks best notification schema to me:
Let’s explain the schema, I wrote here and what things can be done with this solution.
Sender: I have to keep the sender field as an object, the object is referred to as a user collection for the population. Because the notification happens generally for a single action, I mean it may create from the activity of a single person. So, the sender is who is sending this notification, the source of the notification.
Receiver: I have kept the receiver field as an array of objects and the object is referred to user collection if needed for the population. The receiver can be one person or many persons. So, the receiver field will hold the IDs of the recipients.
Message: message field is used for holding the notification message details.
Read_by: the read_by field is an array of two object properties. this object contain readerId(user-id) and read_at (the seen date-time). The read_by array reduced many works and has given more advanced options to work with. It will be used to track each recipient’s view time to track. So, the notification sender can track which recipient has read the message at which time.
Created_at: this field simply holds the notification creation date and time.
So, this schema is very helpful to use for making notifications from one to one and one to many. That’s why I have considered it as the best notification schema for the MongoDB database.

Related

Looking for Mongoose Schema suggestions for individual models

I am in the process of developing a REACT app that would allow a user to find a plant based on their homes environment (long term goal). For my MVP I want to have the user create an account, name their home, add individual rooms with lighting conditions and add plants to each of those rooms. In the event the user does not create any rooms the plants would just sit under their home rather than a specific room by default.
I am struggling on how to design my models and am looking for some suggestions. This will only be my second project on my own so my experience is quite limited.
Currently I have the following models; (attached is a screenshot of each of these models)
plantScheme w/ commonName, scientificName, lightLevel, careLevel, waterReq, etc - This will be seeded with around 100 of the most common household plants to begin with and I intend to use the database to display varying plants on the site whether or not a user is logged in. I also want to link these plants to a specific user when the plant is added to their home.
userSchema w/ username, email, password, home { type: String, required: false, default: 'My Home' } (This begins with where I am open to suggestions. I am not sure if this is the most effective way of establishing the users home), rooms: [ Room.schema ] (pulls from a separate model), plants: [ UserPlant.schema ] (also pulls from a separate model to keep track of plant IDs and room IDs I THINK - haven't tested yet)
userPlantSchema w/ plant_id: { type: Schema.Types.ObjectId, ref: 'Plant', required: true } and room_id: { type: Schema.Types.ObjectId, ref: 'Room', required: false }
and lastly..
roomSchema w/ roomName and lightLevel
If there is a better way of setting up these models and/or keeping track of the users plants I would greatly appreciate the help. Thank you for your time.
screenshot of each model and their established relationships

Threaded messaging on pubnub

We want to create threads for messages within a chat channel on Pubnub. For example, someone could respond to a specific message in a channel by 'creating a thread' and starting to chat. Is there a prescribed way to model this behavior? If so, can you please reference documentation?
This is the behavior you see in slack, for reference.
There's no ready-made solution documented for threaded messaging. However, building a hierarchical relationship between messages could be achieved by tagging them with metadata (using PN Objects and/or MessageActions) and then some coding on your end to maintain and handle their relationship.
You could use the time token of the thread's first message as the key, group messages based on it, and use the messages' own time tokens to generate the order for the UI.
https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe#methods
Here's the high-level design for doing this:
A message is published to a channel with the name chat_11223344 (channel name uses chat_ as a prefix for all chat channels and a generated id - keeping it short here but you can use a uuid generator for this). That publish returns a publish timetoken, something like this: 16183330926487763.
Using PN Objects, your display name for the channel can be set along with a description.
In your chat UI, you allow a person to create a thread on that message. The message gets published to a channel named chat_11223344.16183330926487763 , using the publish timetoken of the top-level message as the "sub-channel" name.
So that you can easily identify top-level messages that are threaded, you would add a MessageAction to that message when the first "threaded" message is published. You may also want to add custom Channel Metadata (PN Objects, again) to add a "isThreaded":true key/value.
So with PubNub you can append meta data to either the message itself or PubNub has a section called meta (https://www.pubnub.com/docs/sdks/javascript/api-reference/publish-and-subscribe#methods).
An example payload could be:
{
"type":"message",
"payload":"What do people want for lunch? Pizza?",
"sender":"me",
"sent":1618336638,
"messageActive":true,
"channel":"main",
"messageID":"main.abc123"
}
where abc123 is a uuid that references that message.
When someone wants to thread a message you can append "threaded":true variable to the object.
{
...
"messageID":"main.abc123",
"threaded":true,
...
}
Now your UI knows that there is a breakout thread, using main.abc123.thread as the channelID for that specific thread.
Your app then subscribes to the new channel main.abc123.thread and you can use fetchMessages(); to get history messages as well as new real time messages.

design noSQL database mongoose nodejs

I build booking appointments barbershop app in react native with node js mongoose.
in short, each user can make an appointment to barber. each barber has some types of hair cuts types.
user - Appointment (many to many) -> should I need to add appointment array in user?
Appointment - users (many to many) -> ref: user_id.
Barber- Appointment (many to many)-> should I need to add appointment array in user?
Appointment - Barber(many to many) ref: barber_id
Barber- HairCut Types(many to many): ref: types array
that's my demo design
I would like to know if the db design looks right? do I need to save appointments array in user and barber also?

Displaying a User's name after account has been deleted? (Mongoose Schema)

//User Schema
{ name: String } //_id automatically added by Mongoose
//Post Schema
{ content: String,
comments: [{
date: Date,
user: Schema.ObjectId,
content: String
}]
}
In my application, users will be able to leave comments on particular articles. In my comments schema, I will have an ObjectID referencing the user, so that I can populate his or her username on the front end. However, when the user deletes his or her account, the ObjectIDs in all of the comments they have posted in the past are now meaningless, so I cannot retrieve his or her username to display on the front end. My solution was to initially have a comment reference a user by ObjectID, and then on the pre-delete Mongoose middleware go through all of the comment objects with a matching ObjectID and replace the user field with a string of their username, so that my front end can still display their name even when their account is deleted.
How would I go about making a field in my Mongoose Schema be valid as either a String or an ObjectID?
Is there a better solution to this problem?
I can suggest you a very simple way to solve the kind of problem you are in. Add a field names status in your User document. When an user deletes their accounts, you don't delete their account. The reason I am suggesting this is you need the user's detail even after they delete their account. All the users will have active status for their accounts except those who have deleted their accounts. For the users who have deleted their accounts, have their status as inactive or archived. To make sure users with inactive status are not able to perform some actions, kindly make some checks in login about the user status.
Hope this helps.

Meta data in event and command messages

I am curious to find out how you guys are incorporating meta data about command/event messages in a cqrs solution. For example, I want to know who, when, which host, etc. generated the command. I don't want to put these into message itself.
Say in a web app, user created a shopping cart CreateShoppingCart { CartID, UserID }. Then added items to it, AddItem { CartID, ItemID, Amount, etc }. I want to record exacty when the used clicked the "Add To Cart" button.
I can add this into some Dictionary<string, object> Headers { get;
set; } property. That property could be in a BaseMessage class.
I can rely on the messaging framework (something like NServiceBus) and add this data into the message header in the message context.
Send seperate command for this info. Something like LogCommandDetails { CommandID: 'id of AddItem command', DateTime, Some other meta data }. When this comamnd is handled, I can update the projection of ItemAdded event and add this data into the projection.
What are your thoughts?
Thanks
Typically this information is stored in message headers, which is option 2. This is exactly what message headers are for. Note, there is a subtle difference between a message from perspective of a messaging framework and a message in your domain which is the body of the message in a messaging framework.
However, it can be difficult to discern what is data and what is metadata. I run into this issue with dates, among other things. For example, is a timestamp associated with an event metadata or proper domain data? What if the timestamp is required for execution of certain business logic? In your example, do you need to record the date for reporting or audit purposes, or is the date needed for the domain to function? In the former case, use headers, in the latter, place the date in the message body.

Resources