---
name: workflow-feature
description: Multi-step approval/state-machine workflow with assignees + notifications. Models portal-platform's ApprovalRequest.
---

# Blueprint: Workflow Feature

## Frontend

- Routes: `/approvals` (inbox), `/approvals/:id` (detail+actions), `/approvals/new` (submit).
- Components: step timeline, action buttons (Approve / Reject / Reassign / Comment).
- Real-time updates when a step transitions.

## Backend

- States: `DRAFT → SUBMITTED → IN_REVIEW → APPROVED|REJECTED|CANCELLED`. Each transition is a MediatR command with FluentValidation guards (only the current step's approver can decide).
- Steps: ordered list; advance to next on Approve; halt on Reject.
- Emit a notification on transition (`em-notifications`).

## Database

- `ApprovalRequest` (status, submitterId, payload JSON, decidedAt/By).
- `ApprovalStep` (order, approverId nullable, decision enum, comment, decidedAt).

## API contract

- `submitApprovalSchema`, `decideStepSchema`, `approvalDetailSchema`.

## UI

- Show the current step + who's the assignee.
- Disable actions when the user isn't the active approver.

## Validation

- Only the current step's approver can decide.
- Can't decide on a decided step.
- Comment required on Reject.

## Testing

- State-machine tests for every transition + every illegal transition.
- Authz: a non-approver decision returns 403.

## Observability

- Audit every transition.
- Metric: time-to-decide per step.

## Security

- Permission: `approvals.read` (list/detail), `approvals.approve` (act).
- Tenant scoped; submitters see their own; approvers see what's assigned.
