My sample DDD system contains two microservices, each of them defined for specific context - User domain microservice and Estate domain microservice.
I am well aware that aggreagte roots are single entry points for management of bussiness entities, f.e. User (an aggregate) can be owner of an Estate (an aggregate from second context), so the management of estates is executed through UserAggregate.
What I cannot fully understand is how does it apply in terms of design of APIs and use cases - assume that I have created my profile, and I want to add an Estate as my belonging.
How can I determine if I should send request to
/user_domain/{user_id}/addNewEstate - retrieve the User from the database, try to add an Estate which enforces business rules defined (f.e. maximum of 5 estates), and then replicate the change in EstateService (create the entity and save it within Estate context)
or to
/estate_domain/addnewEstate?userId=sampleId - which would simply call the UserContext to check if the user exists, and If he does, create the estate (applying business rules) and persist it.
If we talk DDD, then User cannot be an estate owner. It is another bounded context.
You can introduce Owner aggregate in Estate context.
I don't know what is the business task of Estate, but most there could be both the case when an estate belongs to an owner (think AirB'n'B), or when it is an independent aggregate root (think cadaster domain).
Owner then can be associated with User from another context by id. Most likely owner is created after a user has signed up. User is a login. But owner means passing some checks, signing agreements and passing other business rules.
Then the endpoint would look like POST /estate_domain/owner/1234/property/
Related
I am building the inventory service, all tables keep track the owner of each record in column createdBy which store the user id.
The problem is this service does not hold the user info, so it cannot map the id to username which is required for FE to display data.
Calling user service to map the username and userid for each request does not make sense in term of decouple and performance. Because 1 request can ask for maximum 100 records. If I store the username instead of ID, there will be problem when user change their username.
Is there any better way or pattern to solve this problem?
I'd extend the info with the data needed with from the user service.
User name is a slow changing dimension so for most of the time the data is correct (i.e. "safe to cache")
Now we get to what to do when user info changes - this is, of course, a business decision. In some places it makes sense to keep the original info (for example what happens when the user is deleted - do we still want to keep the original user name (and whatever other info) that created the item). If this is not the case, you can use several strategies - you can have a daily (or whatever period) job to go and refresh the users info from the user service for all users used in the inventory, you can publish a daily summary of changes from the user service and have the inventory subscribe to that, you can publish changes as they happen and subscribe to that etc. - depending on the requirement for freshness. The technology to use depends on the strategy..
In my option what you have done so far is correct. Inventory related data should be Inventory Services' responsibility just like user related data should be User Services'.
It is FE's responsibility to fetch the relevant user details from User Service that are required to populate the UI (Remember, call backend for each user is not acceptable at all. Bulk search is more suitable).
What you can do is when you fetch inventory data from Inventory Service, you can publish a message to User Service to notify that "inventory related data was fetched for these users. So there is a possibility to fetch user related data for these users. Therefore you better cache them."
PS - I'm not an expert in microservices architecture. Please add any counter arguments if you have any.*
Is it possible to do authorization / access control in FHIR store?
Let me show one example:
The insurance company receive clinical information from 3 different partners, but the company need to create a different role for each one.
So, the first partner can GET any patients and POST only encounter resource.
Second partner can GET several patients and POST encounters and conditions resources.
Third partner can GET some patients and PUT some elements in conditions resource
Each partner would be responsible for authenticating the insurance company. This might be through mutual TLS certificate verification, OAuth or some other means. Once the insurance company has authenticated, the clinical system would determine what 'authorization' the company had. Every data source has full control over determining what a given requester has authorization to receive. Ideally, the server will expose a distinct CapabilityStatement to the requester after they've authenticated that reflects what they are allowed to do. Any requests that are not permitted will result in an appropriate error or will result in the data returned being appropriately filtered. The determination of what sort of filtering happens is managed by internal business rules and is not defined by FHIR, though in some cases, FHIR resources such as Contract or Consent may include terms that will influence the filtering.
I have the below requirement -
We have an entity named Garden. A garden is owned by a person or company, and can also be leased by one or more people or companies. Each garden has a unique number.
Ideally, we would want to be able to see a single grid of all the people that own and/or lease the garden, regardless of whether they are a person or a company.
Questions -
1) Which entity to choose for person -> User or Contact
2) Which entity to choose for company?
3) How to design record ownership or leasing of garden?
This is a broad question, I’ll try my best.
Fact: We don’t have an option today to create a custom polymorphic entity - to capture/store multiple types of entities. There are some available OOB entities - Customer to store Account/Contact, Owner to store User/Team, Activity Regarding to store any Activity enabled entities.
If you look at Bookable Resource entity, even MS store the type like User or Equipment & respective lookup records separately. This is what you need exactly. Read more
1) Which entity to choose for person -> User or Contact
2) Which entity to choose for company?
User (owner) in case you need security around the ownership of the records. Then company has to be the Teams, because you mentioned Garden maybe owned by Person or Company. How many records you’re going to manage and are they going to get login in CRM?
You may have to look at PowerApps (Dynamics) portals which gives B2B, B2C options to control records ownership by Accounts/Contacts.
3) How to design record ownership or leasing of garden?
Partially answered in the above points. For leasing, you can have multiple subgrid (1:N) relationship. If required, you may need a custom component or web resource to pull the multiple type of owned/leasing records by UNION the results & render as a grid.
I have users in a team having access to particular fields on lead, opportunity and account entities. I have few users who are in team they just need access to fields on lead and Opportunity entity not on account ?
I thought Ill use field level security on the fields to achieve this, having field level security will have effect other functionality in the system. Any thoughts on how to achieve this ?
Breaking down CRM security levels:
Role level - Entity level (e.g. access to Lead but not marketing list)
Record level - Read/Write/Access (e.g. read lead record but not modify them)
Field level - Field level show/hide (e.g. hide a lead's account field for certain users or team).
In your case, it depends on what defines having access (is it more of a don't need to see or a should not see scenario). If it is just a case of a set of users don't have to deal with certain fields use different CRM forms for different teams, if it is a case of they should not be seeing the data use field level security.
This also would hopefully answer "having field level security will have effect other functionality in the system?" questions, if field level security is implemented, the fields which are restricted read won't show up in the advanced find queries or reports for the users who are not assigned the field level security profiles. Also once you have secured the field, every new user or team needs the field level security profile assigned, else they won't be able to see the field.
Suppose I have one aggregate, Ticket. A Ticket will have one assigned Department and one or more assigned Employee.
When instantiating a Ticket, should a TicketFactory be responsible for ensuring that a Ticket is created with a valid/existent Department and Employee?
Likewise, when decommissioning a Department or Employee, what is responsible for ensuring that a new Department or Employee is assigned to a Ticket so as to maintain its invariants? Could there be a service in the domain responsible for decommissioning, or is this a case where eventual consistency or some form of event listening should be adopted?
The TicketFactory would be declare that in order to create a Ticket you need references to both a Department and an Employee. It would not verify that those actually exist. It would be the responsibility of the calling code to obtain the appropriate references.
If using eventual consistency, the decommissioning of a Department and Employee would publish events indicating the decommission. There would be a handler associated with a Ticket which would subscribe to that event and either assign a new department and employee or send some sort of warning to task.
Take a look at Effective Aggregate Design for more on this.
I've recently started exploring DDD, so I have ran into some of the issues you mention.
I think that TicketFactory should always return validated/properly built Ticket instances. If you model is complex, you can have a domain service that validates that a given Department or Employee can be attached to it and then the factory uses it. Otherwise, you can just put it all in the factory. But what comes out of the factory should be a proper ticket.
I'd say that if e.g. only Ticket knows about the other two, a domain service that uses the Department and Employee repos would get the job done. If the relationship is bidirectional, then you can utilize event sourcing. Also, if it's really a event that should be captured in your domain model, and has other consequences other than reshuffling tickets, you can attach one of the handlers to this event to be InvalidTicketHandler. But if it's a small scale thing, keep it simple, just have a domain service that maintains the invariants.
Sidenote: If the Department and/or Employee are aggregates themselves, then you can reference them within Ticket via their identifier (e.g. employee's company ID or ID-code of the department). In that way you'll achieve consistency easier as you will not cross consistency boundaries between different aggregates.
A FACTORY is responsible for ensuring that all invariants are met for the object or AGGREGATE it creates; yet you should always think twice before removing the rules applying to an object outside that object. The FACTORY can delegate invariant checking to the product, and this is often best. [Domain-Driven Design: Tackling Complexity at the Heart of Software]
A depends on question type, but from the look of it it seems like a great candidate for an application layer functionality, i wouldn't go for the event solution though cause i find it only suitable in between layers and not between objects in the same layer.