Response Approval

Response approval workflow covering states, approval chains, notifications, and audit events

Workflow States

Survey responses follow an approval workflow with three states:

Submitted ──► Pending ──► Approved
                  │
                  └──► Rejected
StateDescription
pendingAwaiting review by an approver
approvedReviewed and accepted
rejectedReviewed and rejected (with reason)

Approval Chain

Approval can be configured as single-step or multi-level:

class ApprovalConfig(BaseModel):
    mode: Literal["single", "multi"]  # Single or multi-level
    required_approvers: int = 1        # How many approvers needed
    levels: Optional[List[Level]]      # Hierarchical levels

Single-Level

One approver reviews and approves/rejects.

Multi-Level

Responses must pass through multiple levels:

levels = [
    {"name": "Supervisor", "roles": ["supervisor"]},
    {"name": "Manager", "roles": ["manager"]},
]

API

# Approve a response
POST /responses/{id}/approve
{"comment": "Data verified against source documents"}

# Reject a response
POST /responses/{id}/reject
{"reason": "Incomplete data", "comment": "Please fill missing fields"}

Notifications

When a response requires approval, notifications are sent:

async def notify_approvers(response, tenant_id):
    await notification_service.send(
        channel="email",
        recipients=approver_emails,
        template="response_approval_required",
        data={"response_id": response.id, "survey": response.survey_name}
    )

Audit Events

All approval actions generate audit events:

EventTrigger
response.approval_requiredResponse submitted with approval config
response.approvedApprover approved
response.rejectedApprover rejected
response.approval_escalatedEscalated to next level
response.approval_reminderReminder sent to approver

Frontend

The frontend displays approval status in the response list and detail views, with dedicated approve/reject buttons for users with the response:approve permission.