N
Novu8mo ago
todd

Tenants

I am now seeing my use case for tenants and wondering about functions that will support it and whether I am on the right track. I can see it would be great if fully implemented. I have an application with Employers and Jobseekers (so two different user groups/apps). They negotiate employment. So I have created a separation based on Organisations: Business and Jobseeker As they negotiate employment, I trigger the jobseeker workflow and add the business as the tenant. Things I would expect in the web UI: * filter activity feed on tenant * test workflow with tenant field In the API: * 'tenant' field in the event looks to be polymorphic between string and {identifier: string}—just plain confusing and have to go to source code to reconcile UI curl versus API documentation * tenant errors when no tenant found—given other 'PUT' like behaviours adding the tenant would be consistent and great * corresponding to UI, I was expecting /notifications to have the tenant dimension—why not, just wondering?
17 Replies
Gali Baum
Gali Baum8mo ago
@todd great questions!
1. 'tenant' field in the event looks to be polymorphic between string and {identifier: string}—just plain confusing and have to go to source code to reconcile UI curl versus API documentation
It follows the same structure of the 'to' or 'actor' in trigger. You can use to:'subscriberId' or to: {subscriberId: 'subscriberId'}. What did you feel would have been more natural there?
2. tenant errors when no tenant found—given other 'PUT' like behaviours adding the tenant would be consistent and great
It does create the tenant, similarly to subscriber, but with tenant you must also add name and not only identifier. We could say that more clearly.
3. corresponding to UI, I was expecting /notifications to have the tenant dimension—why not, just wondering?
Could you please elaborate a bit more about what you mean? If you mean inside the content of a notification, you can use tenant information like {{tenant.name}} {{tenant.data.address}} etc
4. filter activity feed on tenant
We might add that. Good idea @Pawan Jain
5. test workflow with tenant field
You can actually! if you use {{tenant.<field>}} anywhere in the editors, the tenant will be added to the test workflow. Same for actor. Worth considering allowing that even without using them somewhere. In addition you can use a tenant to affect which integration instance will be used through the conditions. And next version will allow using the tenant in the filtering of steps FYI Pawan, added a ticket for #5, to allow using tenant/actor in test workflow without having to use it in the editor
todd
todd8mo ago
@Gali Baum * point 5 clarification: the API has a GET /notifications endpoint and it doesn't have tenant as a query param.
todd
todd8mo ago
@Gali Baum I have to apologise about the documentation. I have never noticed in the documentation the polymorphic aspect on an attribute (ie inverted caret). I needed that pointed out to me, perhaps others are making a similar mistake—or not!
No description
Pawan Jain
Pawan Jain8mo ago
Yeah, you are right /notifications api does not have tenant query params.
todd
todd8mo ago
@Gali Baum Back to point two that the tenant is created. My testing doesn't bear out that result. For breveity (hope that's okay). I POST on events/trigger adding the tenant
"tenant": {"identifier": "YYYY", "name": "HHHH", "data": {} }
"tenant": {"identifier": "YYYY", "name": "HHHH", "data": {} }
and get response {"data":{"acknowledged":true,"status":"no_tenant_found"}}
todd
todd8mo ago
@Gali Baum I can't see here where you can add tenant to run a test through the UI
No description
Max1228
Max12288mo ago
I am also getting the same the response when attempting a trigger event (novu.trigger) on Node.js
Gali Baum
Gali Baum7mo ago
@todd @Max1228 , you are correct. We did have this functionality, but it seems some later changes were made. I will look into that and keep you updated @George, after the improvements for the subscriber mappings the functionality of creating a tenant inline in the trigger has been lost. I see its because we validate the tenant's identifier in parse-event-request before actually doing the processTenant in event-trigger. What do you think? can we only check in the validate that we have all the needed fields to create the tenant? Or maybe not do the validation there and if there is a problem we could add an execution detail log?
george.d
george.d7mo ago
True i think that due the reason we do 'processTenant' in the trigger-event and create a new tenant if it is not exists. I think we can remove validateTenant from parse-event-request because it will be created in trigger-event. wdyt? @Gali Baum
Gali Baum
Gali Baum7mo ago
Sounds good 🙂
george.d
george.d7mo ago
Regarding the execution detail, at the moment we wont be able to create one in this step or the 'trigger' because we still do not have 'job' entity, and the system is not supporting creation of execution detail without it.
todd
todd7mo ago
@George @Gali Baum thanks for attending to this because I really need it working!—has anyone logged an issue? --------------- May I speak out of turn and without enough context. I see/feel alarm bells ... This discussion requires in-depth knowledge of a pipeline from inside rather than outside. And certainly coding it would—I apologise but haven't looked at the implementation. It feels to me that the 'tenant' domain concept should be cross-cutting/orthogonal—making it a loosely coupled design. It sounds like it has high coupling right in the middle. When I look at tenants, I think of the tenant as merely a tag—and one of others. I can then see that some tags are able to also be mapped to decorators (which in this case is to override providers or settings). My sense is that tenants is going to remain essentially difficult to test, maintain and, importantly, extend in its current form—the tests and changes required for tenants will probably provide/disproved if this is the design approach. From the outside, I have really struggled with the tenant as a domain design concept and how it fits with the other parts of the domain (particularly because organisation is really the tenancy isolation I would expect). Finally, I may be right off the mark and if so please let me know so that I can look at the code and stop making wild comments! Thanks (for patience if you have read this far) 🙂
Gali Baum
Gali Baum7mo ago
Hi @todd7201 , thank you for sharing! @dimagrossman could you please share your thoughts? ❤️
Dima Grossman
Dima Grossman7mo ago
Hi @todd I'm sorry for the delayed response, missed your message previously. The organization is defiently a tenancy isolation at the highest level in Novu. One of the main usecases for multi tenancy across all of our existing customers is to be able to customize the experienec of notifications depending on the context of the tenant. For example, being able to show different attributes inside an email, depending on which tenant is used. And one of the important things, to still be able to manage workflows and integrations in a single places and not need to duplicate them. Tenants allow overriding part of the experience for the receiver of the notification, for example: - The content of the email - The configurations of a workflow (digest config, and etc...) - The providers used to deliver a message and etc... I hope this makes sense, and would be pleased to jump on a quick call to hear about how you view this and perhaps find a way to improve the current structure
todd
todd7mo ago
@Dima Grossman I would interested to see your example of names for a "tenant" in your usecase—I still think I am missing some point. As you point out, tenancy is about isolation—which is what organisations do. Tenancy in your case doesn't isolate, it provides "overriding part"s (specifics/decorates/alternatives). Yet, the tenant also logically needs to function as a grouping mechanism IMHO—or something else needs to for my use case. As a product, naming is hard (duh, of course). Have you chosen "tenant" because your customers want this or from your team choosing it? As a (development focussed) customer, it seems "wrong" because tenancy is about separation—but you are really used it as association. I understand that I am not the key customer (the paying ones are!) and I wonder what they call the concept? I am happy to talk about it. I have the same concept/problem in my own product and we struggle to name it to. We have called it "overrides" which can be applied when needed. I know its not quite right because people are able to be taught it (instantly) but don't grasp it themselves (generally). Finally, I have raised it at the design level because my sense is that this concept is being coded out usecase by usecase through your product UI (client app) and then surfaced through the private/public APIs. So given I only use the public API its limits are more obvious because a lot of work is being done in the client app to stitch it together. Again, I am happy to discuss what I mean here if you want. Cheers
Dima Grossman
Dima Grossman7mo ago
Tenancy is defiently something that was used in the conversations with all of our users, and we've done something of wether to use the same name or have a different concept naming and than need to do the usecase education around it. I think it's also important to note that the multi-tenancy usecase we are solving are regarding to the notification domain of our users, and this come with different set of challenges. Overrides resembles this in most of the usecases I believe, in terms of naming, but really no one who comes to us was looking for overrides, they tried to solve their multi tenancy needs in that. The concept of isolation today is only achieved using the Organization and Environments concepts, do you think it's worth creating another level of "Application" perhaps?