# Response Approval {#response-approval}



## Workflow States {#workflow-states}


Survey responses follow an approval workflow with three states:

```
Submitted ──► Pending ──► Approved
                  │
                  └──► Rejected
```

| State | Description |
|-------|-------------|
| `pending` | Awaiting review by an approver |
| `approved` | Reviewed and accepted |
| `rejected` | Reviewed and rejected (with reason) |


## Approval Chain {#approval-chain}


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

```python
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 {#single-level}


One approver reviews and approves/rejects.


### Multi-Level {#multi-level}


Responses must pass through multiple levels:

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


## API {#api}


```bash
# 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 {#notifications}


When a response requires approval, notifications are sent:

```python
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 {#audit-events}


All approval actions generate audit events:

| Event | Trigger |
|-------|---------|
| `response.approval_required` | Response submitted with approval config |
| `response.approved` | Approver approved |
| `response.rejected` | Approver rejected |
| `response.approval_escalated` | Escalated to next level |
| `response.approval_reminder` | Reminder sent to approver |


## Frontend {#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.
