DDD and CQRS - Define an entity for Scheduling use case - entity

I have a use case of scheduling a person to some work for some time range. Eg. A service for assigning a person A to work for time range X to Z in location C.
The only constraint it has, is one person cannot work on 2 things at same time. Eg. if person A is assigned to work in time 2019-07-21 to 2010-07-25, then person A cannot be assigned to any other work in that time. Eg. Person A for time range 2019-07-23 to 2019-07-27 should not be possible.
I am trying to make a service for it using domain driven design which would assign a person to some work. The entity I thought would be something like:
class Assignment {
PersonId,
startTime,
endTime,
location
}
Now, I wanted to make sure that if I found a entry in my database for Person A in some time range, then the call to create an entry for Person A in time range that is overlapping with the existing ones should fail.
Since, I am using CQRS model with DDD, so I don't want to make a query to my database asking for all the assignments for that person. This may not always be recent data because of eventual consistency in CQRS model.
I know in my primary key, PersonId would be there but I am not sure how can I use start and end time in it.
Any suggestions what I can do to achieve my goal for this? Is doing DDD and CQRS not a good idea in this? Or there is a better way to model this entity so that I can achieve my goal.

Since, I am using CQRS model with DDD, so I don't want to make a query to my database asking for all the assignments for that person.
CQRS is just the separation between the read and write (commands and queries). When executing commands, you can query the write model.
If you have the assignments as a value object of the Person aggregate, checking if there is more than 2 assignments at the same time is easy. And if the assignments should be a separate aggregate then the Person aggregate should keep reference of the assignments.

Related

Repository Pattern Dilemma: Redundant Queries vs. Database Round Trips

This is the situation:
Say I have an application in which two entity types exist:
Company
Person
Moreover, Person has a reference to Company via Person.employer, which denotes the company a person is employed at.
In my application I am using repositories to separate the database operations from my business-model related services: I have a PersonRepository.findOne(id) method to retrieve a Person entity and a CompanyRepository.findOne(id) method to retrieve a Company. So far so good.
This is the dilemma:
Now if I make a call to PersonRepository.findOne(id) to fetch a Person entity, I also need to have a fully resolved Company included inline via the Person.employer property – and this is where I am facing the dilemma of having two implementation options that are both suboptimal:
Option A) Redundant queries throughout my repositories but less database round trips:
Within the PersonRepository I can build a query which selects the user and also selects the company in a single query – however, the select expression for the company is difficult and includes some joins in order to assemble the company correctly. The CompanyRepository already contains this logic to select the company and rewriting it in the UserRepository is redundant. Hence, ideally I only want the CompanyRepository to take care of the company selection logic in order to avoid having to code the same query expression redundantly in two repositories.
Option B): Separation of concerns without query-code redundancy but at the price of additional db roundtrips and repo-dependencies:
Within the PersonRepository I could reference the CompanyRepository to take care of fetching the Company object and then I would add this entity to the Person.employer property in the PersonRepository. This way, I kept the logic to query the company encapsulated inside the CompanyRepository by which a clean separation of concerns is achieved. The downside of this is that I make additional round trips to the database as two separate queries are executed by two repositories.
So generally speaking, what is the preferred way to deal with this dilemma?
Also, what is the preferred way to handle this situation in ASP.NET Core and EF Core?
Edit: To avoid opinion based answers I want to stress: I am not looking for a pros and cons of the two options presented above but rather striving for a solution that integrates the good parts of both options – because maybe I am just on the wrong track here with my two listed options. I am also fine with an answer that explains why there is no such integrative solution, so I can sleep better and move on.
In order to retrieve a company by ID you need to read Person's data, and fetch company ID from it. Hence if you would like to keep company-querying logic in a single place, you would end up with two round-trips - one to get company ID (along with whatever other attributes a Person has) and one more to get the company itself.
You could reuse the code that makes a company from DbDataReader, but the person+company query would presumably require joining to "forward" person's companyId to the Company query, so the text of these queries would have to be different.
You could have it both ways (one roundtrip, no repeated queries) if you move querying logic into stored procedures. This way your person_sp would execute company_sp, and return you all the relevant data. If necessary, your C# code would be able to harvest multi-part result set using reader.NextResult(). Now the "hand-off" of the company ID would happen on RDBMS side, eliminating the second round-trip. However, this approach would require maintaining stored procedures on RDBMS side, effectively shipping some repository logic out of your C# code base.

Optaplanner : list of planning variables in one planning entity?

I am looking into the example use cases from OptaPlanner. And I could not find any similar example which can solve multiple planning variables in one planning entity. For example, in nurse rostering, each ShiftAssignment(PlanningEntity) for one shift might require multiple assigned Employee(PlanningVariables). In this case, how can we make use of planner and write rules?
Instead of making the OneToMany side a planning variable, make the ManyToOne side a planning variable. If you have a ManyToMany side, introduce a class between (like in relational database design) and acts as a ManyToOne-OneToMany.
In the nurse rostering example, an example can need 4 nurses on the Shift at ShiftDate 1-JAN for ShiftType Early. In that case, Shift has requiredEmployeeSize 4, and 4 ShiftAssignments are created for that single Shift, each with a different indexInShift. That way, the ShiftAssignment has a planning variable Employee which is a ManyToOne relationship, (even though between Shift and Employee there's a ManyToMany relationship).

When to create a new table?

I have an application with employees and their work contracts.
Each work contract has a Vacation. We keep track of how many days the company owes the employee ("VacationOwe") and how many he has taken ("VacationTaken").
Should I make this "VacationOwe" and "VacationTaken" a property of the Contract, or should I create a class (table) called Vacaction with the properties "VacationOwe", "VacationTaken" and "ContractId" and join the two tables?
What are the advantange of both methods?
Is there any rule when you should create a new class or table or keep the data in one.
If the two properties are truly only related to an employee, there's no benefit of creating a separate table. Performance will be worse and you'll constantly have to join on those tables.
For this specific example, it seems like the vacation days may also be linked to a year. If that's the case, a separate table would make sense so you can track vacation days taken/owed by employee and year.
should I make this "VacationOwe" and "VacationTaken" a propertie o the employee
Most probably...No. Because this defeats normalization. Also, it does not provide information about when the vacations were taken (in case you care about that). In addition to that, you have to do this calculation for every employee, every year.
Use a class (table) Call Vacaction with properties "VacationOwe" and "VacationTaken" and "EmployeeId" and cross the two tables?
It is not good to have a singleton class in this case. In general you should avoid singletons in most cases.
So what to do? Well, if you system does not care about vacation details, you could go with the first solution. Maybe you want to consider option (A) below or If you would like to have a more generic approach you could do something similar to option (B). It all depends on your detailed requirements.

Table structure for Scheduling App in SQL DB

I'm working on a database to hold information for an on-call schedule. Currently I have a structure that looks about like this:
Table - Person: (key)ID, LName, FName, Phone, Email
Table - PersonTeam: (from Person)ID, (from Team)ID
Table - Team: (key)ID, TeamName
Table - Calendar: (key dateTime)dt, year, month, day, etc...
Table - Schedule: (from Calendar)dt, (id of Person)OnCall_NY, (id of Person)OnCall_MA, (id of Person)OnCall_CA
My question is: With the Schedule table, should I leave it structured as is, where the dt is a unique key, or should I rearrange it so that dt is non-unique and the table looks like this:
Table - Schedule: (from Calendar)dt, (from Team)ID, (from Person)ID
and have multiple entries for each day, OR would it make sense to just use:
Table - Schedule: (from Calendar)dt, (from PersonTeam)KeyID - [make a key ID on each of the person/team pairings]
A team will always have someone on call, but a person can be on call for more than one team at a time (if they are on multiple teams).
If a completely different setup would work better let me know too!
Thanks for any help! I apologize if my question is unclear. I'm learning fast but nevertheless still fairly new to using SQL daily, so I want to make sure I'm using best practices when I learn so I don't develop bad habits.
The current version, one column per team, is probably not a good idea. Since you're representing teams as a table (and not as an enum or equivalent), it means you expect to add/remove teams over time. That would force you to add/remove columns to the table, which is always a much larger task than adding/removing a few rows.
The 2nd option is the usual solution to a problem like this. A safe choice. You can always define an additional foreign key constraint from Schedule(teamID, personID) to PersonTeam to ensure you don't mistakenly assign schedule duty to a person not belonging to the team.
The 3rd option is pretty much equivalent to the 2nd, only you're swapping a composite natural key for PersonTeam for a surrogate simple key. Since the two components of said composite key are already surrogate, there is no advantage (in terms of immutability, etc.) to adding this additional one. Plus it would turn a very simple N-M relationship (PersonTeam) which most DB managers / ORMs will handle nicely into a more complex object which will need management on its own.
By Occam's razor, I'd do away with the additional surrogate key and use your 2nd option.
In my view, the answer may depend on whether the number of teams is fixed and fairly small. Of course, whether the names of the teams are fixed or not, may also matter, but that would probably have more to do with column naming.
More specifically, my view is this:
If the business requirement is to always have a small and fixed number of people (say, three) on call, then it may well be more convenient to allocate three columns in Schedule, one for every team to hold the ID of the appointed person, i.e. like your current structure:
dt OnCall_NY OnCall_MA OnCall_CA
--- --------- --------- ---------
with dt as the primary key.
If the number of teams (in the Team table) is fixed too, you could include teams' names/designators in the column names like you are doing now, but if the number of teams is more than three and it's just the number of teams in Schedule that is limited to three, then you could just use names like OnCallID1, OnCallID2, OnCallID3.
But even if that requirement is fixed, it may only turn out fixed today, and tomorrow your boss says, "We no longer work with a fixed number of teams (on call)", or "We need to extend the number of teams supported to four, and we may need to extend it further in the future". So, a more universal approach would be the one you are considering switching to in your question, that is
dt Team Person
--- ---- ------
where the primary key would now be dt, Team.
That way you could easily extend/reduce the number of people on call on the database level without having to change anything in the schema.
UPDATE
I forgot to address your third option in my original answer (sorry). Here goes.
Your first option (the one actually implemented at the moment) seems to imply that every team can be presented by (no more than) one person only. If you assign surrogate IDs to the Person/Team pairs and use those keys in Schedule instead of separate IDs for Person and Team, you will probably be unable to enforce the mentioned "one person per team in Schedule" requirement (or, at least, that might prove somewhat troublesome) at the database level, while, using separate keys, it would be just enough to set Team to be part of a composite key (dt, Team) and you are done, no more than one team per day now.
Also, you may have difficulties letting a person change the team over time if their presence in the team was fixated in this way, i.e. with a Schedule reference to the Person/Team pair. You would probably have to change the Team reference in the PersonTeam table, which would result in misrepresentation of historical info: when looking at the people on call back on certain day, the person's Team shown would be the one they belong to now, not the one they did then.
Using separate IDs for people and teams in Schedule, on the other hand, would allow you to let people change teams freely, provided you do not make (Schedule.Team, Schedule.Person) a reference to (PersonTeam.Team, PersonTeam.Person), of course.

Setting up a "to-many" relationship value dependency for a transient Core Data attribute

I've got a relatively complicated Core Data relationship structure and I'm trying to figure out how to set up value dependencies (or observations) across various to-many relationships. Let me start out with some basic info. I've got a classroom with students, assignments, and grades (students X assignments). For simplicity's sake, we don't really have to focus much on the assignments yet.
StudentObj <--->> ScoreObj <<---> AssignmentObj
Each ScoreObj has a to-one relation with the StudentObj and the AssignmentObj.
ScoreObj has real attributes for the numerical grade, the turnInDate, and notes.
AssignmentObj.scores is the set of Score objects for that assignment (N = all students).
AssignmentObj has real attributes for name, dueDate, curveFunction, gradeWeight, and maxPoints.
StudentObj.scores is the set of Score objects for that student (N = all assignments).
StudentObj also has real attributes like name, studentID, email, etc.
StudentObj has a transient (calculated, not stored) attribute called gradeTotal.
This last item, gradeTotal, is the real pickle. it calculates the student's overall semester grade using the scores (ScoreObj) from all their assignments, their associated assignment gradeWeights, curves, and maxPoints, and various other things.
This gradeTotal value is displayed in a table column, along with all the students and their individual assignment grades. Determining the value of gradeTotal is a relatively expensive operation, particularly with a large class, therefore I want to run it only when necessary. For simplicity's sake, I'm not storing that gradeTotal value in the core data model. I don't mind caching it somewhere, but I'm having a bitch of a time determining where and how to best update that cache.
I need to run that calculation for each student whenever any value changes that affects their gradeTotal. If this were a simple to-one relationship, I know I could use something like keyPathsForValuesAffectingGradeTotal ... but it's more like a many-to-one-to-many relationship. Does anyone know of an elegant (and KVC correct) solution? I guess I could tear through all those score and assignment objects and tell them to register their students as observers. But this seems like a blunt force approach.
I just postet a project on github which probably solves part of the problem with observings
http://github.com/mbrugger/CoreDataDependentProperties
A more detailed description of the project can be found there.
-(NSArray*) keyPathsForValuesAffecting would not have solved your problem as this only works across to-one relations
In addition you should not make the dependent attribute transient, as it makes your context "dirty" (unsaved changes) already after recalculating all values after loading