Ok, if I now understood you correctly, this sort of thing can be implemented on the authorization side, but it’s currently tricky on the privacy/visibility side as changes to the group/role have to be propagated through to the (immutable) contracts that such changes affect.
Ignoring visibility issues, we could implement this:
template TradeApproverGroup
with
admins : Set Party
members : Set Party
groupName : Text
where
signatory admins
observer members
key (admins, groupName) : (Set Party, Text)
maintainer key._1
choice AddMember ...
choice RemoveMember ...
choice PromoteMember ...
choice DemoteAdmin ...
template TradeApprovalRequest
with
group : TradeApproverGroup
requester : Party
where
signatory requester
observer group.members
choice Accept : ContractId TradeApproval
with
approver : Party
do
(groupCid, actualGroup) <- fetchByKey @TradeApproverGroup (group.admins, group.name)
assert (approver /= requester && group == actualGroup)
create TradeApproval with ..
The problem in the above is: If the group gets updated whilst there is an outstanding TradeApprovalRequest, how do you update the group on the request?
A proposed solution is to allocate parties for such groups:
template TradeApproverGroup
with
admins : Set Party
groupParty : Party
members : Set Party
where
signatory admins, groupParty
observer members
key groupParty : Party
maintainer key
choice AddMember ...
choice RemoveMember ...
choice PromoteMember ...
choice DemoteAdmin ...
template TradeApprovalRequest
with
group : Party
requester : Party
where
signatory requester
observer group
choice Accept : ContractId TradeApproval
with
approver : Party
do
(groupCid, actualGroup) <- fetchByKey @TradeApproverGroup group
assert (approver /= requester && approver `elem` actualGroup.members)
create TradeApproval with ..
The feature that’s missing to make that work is for all members to be able to read as the group party over the API so that they can see the TradeApprovalRequest
. Sadly, this is not possible yet so for now one has to keep the membership relatively stable, or propagate changes through to the observers.