- Shipped
- September 23, 2026 at 11:04 AM UTC
- Author
- Kamo
- Commit
- be57082
**************** resolved the caller's role against a CLIENT-SUPPLIED subjectMemberId (resolveRole -> EMPLOYEE whenever actor==subject) but never forwarded that id or the resolved role downstream. TimecardService loaded the punch by punchId and checked only the org, so an enrolled employee could pass subjectMemberId=self (trivially authorized) together with a colleague's real punchId and edit or void someone else's punch. Both values now travel on the relay, the same way approvalAct already forwards role: subjectMemberId lets TimecardService (the one holding the punch row) confirm punchId actually belongs to the member this caller was authorized against, and role lets it enforce the approval-chain lock (see the paired timecard-service fix). Also: resolveRole ran isManagerOf's reporting-line query (an org-wide employment scan before this change) on every self-view before checking actor==subject, even though nobody is their own manager. actor==subject is now checked first, so a self-view never touches the reporting line, and the remaining cross-member lookup uses **************** instead of an unfiltered findAll().
