I have the following entity relationship.
A {state: ON | OFF} => B {state: ON | OFF} => C {state: ON | OFF}
So, in this case, B is a child of A, and C is a child of B. Moreover, they all share a property called state that can be either ON or OFF and defaults to OFF.
Domain rules
A child must inherit the state of the parent when setting the values, but it must leave the current value if it was set explicitly.
When I set the state to the parent, this value needs to be inherited by the children. Assuming a default state of OFF if my Operation is set-state(ON, B), this should set the state to entities B and C (but not A since this is the parent) so the resulting state should be:
A {state: OFF} => B {state: ON} => C {state: ON}
So when someone reads the state of C, it should return ON.
Examples
Initial state:
A {state: OFF} => B {state: OFF} => C {state: OFF}
reading values:
read(state, A) => OFF
read(state, B) => OFF
read(state, C) => OFF
Operation1 set-state(ON, B)
resulting state:
A {state: OFF} => B {state: ON} => C {state: ON}
reading values:
read(state, A) => OFF
read(state, B) => ON
read(state, C) => ON
Operation2 set-state(ON, A)
resulting state:
A {state: ON} => B {state: ON} => C {state: ON}
reading values:
read(state, A) => ON
read(state, B) => ON
read(state, C) => ON
Operation3 set-state(ON, C)
resulting state:
A {state: ON} => B {state: ON} => C {state: ON}
reading values:
read(state, A) => ON
read(state, B) => ON
read(state, C) => ON
Operation4 set-state(OFF, B)
resulting state:
(since operation 3 set the state to ON on C it leaves it ON)
A {state: ON} => B {state: OFF} => C {state: ON}
reading values:
read(state, A) => ON
read(state, B) => OFF
read(state, C) => ON
Operation5 set-state(OFF, A)
resulting state:
A {state: OFF} => B {state: OFF} => C {state: ON}
reading values:
read(state, A) => OFF
read(state, B) => OFF
read(state, C) => ON
Problem
Someone can set the state of C to ON explicitly set-state(ON, C), and since C is already assigned to ON, this should result in a NOOP since C is already assigned to ON however if B goes back to OFF it usually should set its child(C) back to OFF as well. Still, since there was an explicit operation on C to ON, it should leave it to ON. In this state, a read operation of state of C should return ON (This behavior must be extended to A as well)
Potential Solution
I can add a field to each property to track its explicit and implicit states. However, I am crowdsourcing this problem to see if there is a more clever/elegant way to handle it, maybe using the value or something else I could be missing.