Skip to main content

Request and approval pattern

Modules NTF plus the requesting module (ATT, LVE, CLM, EXT, TSM, PAY, EMP, IAM) · Release R1 · Spec Notifications & Workflow

Context​

The reference product uses one pattern everywhere: Submitted → Approved or Rejected, rejection needs a reason, the requester edits or deletes while Submitted and cancels approved future items, and manager on-behalf requests are auto-approved [Observed] (see Spryple analysis §3.3, SP-X-03 and SP-X-04). Multi-level approval, delegation and escalation are not documented [Inferred, §20]. Spyrl implements the pattern once, in the NTF engine, and every module plugs in.

Diagram​

Steps​

#ActorActionSystem responseModuleNotifications
1Requester (employee) or initiator (manager on behalf)Submits a requestModule validates (balance, limits, dates); saves as Submitted; reserves balance where relevantRequesting module—
2SystemStarts the workflowInstance pinned to the active definition version; context holds amounts, days, typeNTF—
3SystemEvaluates the next step's conditionSkips steps whose condition is false (e.g. HR step only when days > 5)NTF—
4SystemResolves approversReporting manager, skip-level, role in scope, department head, project manager or counterpart; removes the requester; applies active delegations; falls back to hr_manager at the requester's location when emptyNTF, IAM, EMP—
5SystemChecks on-behalf coverageIn UP_TO_ACTOR_LEVEL mode, a step whose approvers include the initiator is auto-approved and recorded as suchNTFRequester informed that a manager applied for them
6SystemCreates tasksOne task per approver, due by the step's SLANTFPush and in-app to approvers; email digest optional
7Approver or delegateApproves, rejects (reason required) or sends back (comment required); single or bulkAction recorded; ANY mode cancels sibling tasks; ALL mode waits for allNTFRequester informed of each decision
8SystemAdvances or finishesNext step, or final Approved; owning module handler runs and emits <mod>.<entity>.approvedNTF, moduleFinal outcome to requester; FYI to HR when configured
9RequesterWithdraws before final decisionInstance Withdrawn; open tasks cancelled; reservations releasedNTF, moduleApprovers informed
10RequesterAsks to cancel an approved future itemNew cancellation instance using the type's cancellation chain (or self-cancel when policy allows)Module, NTFApprovers informed

Delegation​

RuleDetail
Who can delegateAny approver for themselves; hr_admin for anyone
WhatAll request types or a list, for a date range up to delegation.max_days
EffectNew tasks go to the delegate; existing open tasks are re-pointed when move_existing is chosen
VisibilityTask shows "on behalf of" the original approver; both appear in history
LimitsA delegate cannot approve their own request; chained delegation resolves one hop only
Automatic suggestionWhen an approver has approved leave, the system prompts them to set a delegate

Escalation​

StageDefaultEffect
Reminder24 h after task creationPush and email to the assignee
Escalation level 148 hTask added for the next manager up (or a role); the original stays open
Further levelsEvery 48 h, up to the configured maximumNext level
Timeout actionOffOptional auto-approve or auto-reject after the last level; always recorded as automatic

On-behalf modes​

ModeBehaviourUse when
NONEThe request runs the full chain even when a manager raised itStrict control
UP_TO_ACTOR_LEVEL (default)Steps the initiator could approve are auto-approved; later steps (e.g. HR) still runNormal operations
FULLThe whole chain is auto-approvedParity with the reference product; small tenants

Exception paths​

SituationHandling
Approver has left the companyResolver skips separated employees; fallback approver applies
Requester's manager changes mid-flowOpen tasks stay with the original approver unless HR reassigns (ntf.task.reassign)
Definition changes mid-flowIn-flight instances keep their pinned version
Approver is also the requesterStep skipped to the next resolver; never self-approved
Two approvers act at once in ANY modeFirst action wins; the second receives "already decided"
Bulk approve with mixed validityPer-item results; failures are listed with reasons
Request affects a locked periodModule decides: block, or allow with an adjustment to the next pay run
Notification delivery failsRetries with backoff; in-app inbox always holds the task