> ## Documentation Index
> Fetch the complete documentation index at: https://alguna.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Approval Workflows Setup Guide

> Step-by-step guide to configuring approval workflows

# Approval Workflows Setup Guide

This guide walks you through setting up approval workflows from scratch. By the end, you'll have a working approval system that enforces your business rules for discounts, pricing, and deal terms.

***

## Prerequisites

Before setting up approvals, ensure you have:

* Admin access to your Alguna organization
* At least one product configured
* Team members with user accounts

***

## Step 1: Plan Your Approval Strategy

Before creating rules, define your approval requirements:

### Common Approval Scenarios

| Scenario             | Trigger                | Typical Threshold |
| -------------------- | ---------------------- | ----------------- |
| Large discounts      | Discount exceeds X%    | 15-25%            |
| Enterprise deals     | Deal value over \$X    | \$50,000+         |
| Multi-year contracts | Contract term > 1 year | 2+ years          |
| Non-standard terms   | Custom legal terms     | Any deviation     |
| Product-specific     | Certain products       | Premium products  |

### Define Approver Hierarchy

```
Level 1: Sales Manager
  - Discounts up to 20%
  - Deals up to $25,000

Level 2: VP of Sales
  - Discounts up to 35%
  - Deals up to $100,000

Level 3: CFO
  - Any discount over 35%
  - Deals over $100,000
```

***

## Step 2: Create Approver Groups

Groups define who can approve requests.

### Via Dashboard

1. Go to **Settings → Approvals → Groups**
2. Click **Create Group**
3. Add group details:
   * Name: "Sales Managers"
   * Members: Select team members
   * Strategy: Choose approval requirement

### Via API

```javascript theme={null}
const group = await alguna.approvals.groups.create({
  name: 'Sales Managers',
  description: 'Regional sales managers',
  members: [
    { userId: 'user_sarah', role: 'approver' },
    { userId: 'user_mike', role: 'approver' },
    { userId: 'user_alex', role: 'backup' },
  ],
  strategy: 'any',
  settings: {
    notifyOnRequest: true,
    autoEscalateAfter: '48h',
    escalateTo: 'group_vp_sales',
  },
});
```

### Group Strategies

| Strategy  | Behavior                       | Use Case            |
| --------- | ------------------------------ | ------------------- |
| `All`     | Every member must approve      | High-risk decisions |
| `Any`     | One member approval sufficient | Standard approvals  |
| `Minimum` | Specified number must approve  | Committee decisions |

#### All Strategy

All group members must approve:

```javascript theme={null}
{
  strategy: 'All'
}
```

**Example:** CFO *and* Legal both must approve enterprise contracts.

#### Any Strategy

Any single member can approve:

```javascript theme={null}
{
  strategy: 'Any'
}
```

**Example:** Any sales manager can approve moderate discounts.

#### Minimum Strategy

Specified number of approvals required:

```javascript theme={null}
{
  strategy: 'Minimum',
  minimumApprovers: 2
}
```

**Example:** At least 2 of 5 committee members must approve.

***

## Step 3: Create Approval Rules

Rules define when approval is required.

### Via Dashboard

1. Go to **Settings → Approvals → Rules**
2. Click **Create Rule**
3. Configure:
   * Name and description
   * Conditions (triggers)
   * Approver groups
   * Priority

### Via API

```javascript theme={null}
const rule = await alguna.approvals.rules.create({
  name: 'Large Discount Approval',
  description: 'Discounts over 20% require manager approval',
  enabled: true,
  priority: 10, // Lower = higher priority
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 20, // 20% or more
    },
  ],
  approvers: [
    { groupId: 'group_sales_managers' },
  ],
  settings: {
    expiresAfter: '7d',
    allowSelfApproval: false,
    requireComment: true,
  },
});
```

***

## Step 4: Configure Rule Conditions

Conditions determine when a rule triggers.

### Condition Types

#### ProductPresence

Trigger when specific products are included:

```javascript theme={null}
{
  type: 'ProductPresence',
  productIds: ['prod_enterprise', 'prod_premium_support'],
  operator: 'any' // 'any' or 'all'
}
```

**Use cases:**

* Enterprise products require executive approval
* Add-ons need finance review
* Custom products need legal approval

#### AnyProductDiscountThreshold

Trigger when any line item exceeds discount threshold:

```javascript theme={null}
{
  type: 'AnyProductDiscountThreshold',
  threshold: 25, // Percentage
  operator: 'greater_than' // or 'greater_than_or_equal'
}
```

**Use cases:**

* Large discounts need manager approval
* Tiered approval based on discount level

#### SpecificProductDiscountThreshold

Trigger for discounts on specific products:

```javascript theme={null}
{
  type: 'SpecificProductDiscountThreshold',
  productId: 'prod_flagship',
  threshold: 15,
  operator: 'greater_than_or_equal'
}
```

**Use cases:**

* Premium products have stricter discount controls
* Different thresholds per product line

### Combining Conditions

Rules can have multiple conditions (AND logic):

```javascript theme={null}
{
  conditions: [
    {
      type: 'ProductPresence',
      productIds: ['prod_enterprise']
    },
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 10
    }
  ]
}
```

This triggers when Enterprise product has >10% discount.

***

## Step 5: Set Rule Priority

Rules are evaluated in priority order (lower number = higher priority).

```javascript theme={null}
// Rule priority examples
const rules = [
  { name: 'CFO Approval', priority: 1, threshold: 50 },    // Checked first
  { name: 'VP Approval', priority: 10, threshold: 30 },    // Checked second
  { name: 'Manager Approval', priority: 20, threshold: 15 } // Checked third
];
```

### Priority Best Practices

1. **Highest restrictions first** - CFO approval rules at priority 1-5
2. **Mid-level approvals** - VP/Director rules at priority 10-15
3. **Standard approvals** - Manager rules at priority 20+
4. **Catch-all rules** - Default rules at priority 100+

### Reorder via API

```javascript theme={null}
await alguna.approvals.rules.reorder({
  ruleIds: [
    'rule_cfo_approval',
    'rule_vp_approval',
    'rule_manager_approval'
  ]
});
```

***

## Step 6: Configure Notifications

Set up notifications for approval workflows.

### Email Notifications

```javascript theme={null}
await alguna.approvals.settings.update({
  notifications: {
    onRequestCreated: {
      enabled: true,
      recipients: ['approvers'], // or specific emails
      template: 'tmpl_approval_request',
    },
    onRequestApproved: {
      enabled: true,
      recipients: ['requester', 'approvers'],
    },
    onRequestRejected: {
      enabled: true,
      recipients: ['requester'],
    },
    reminderSchedule: {
      enabled: true,
      intervals: ['24h', '48h', '72h'],
    },
  },
});
```

### Slack Integration

```javascript theme={null}
await alguna.approvals.settings.update({
  integrations: {
    slack: {
      enabled: true,
      channelId: 'C0123DEALS',
      notifyOn: ['created', 'approved', 'rejected', 'expired'],
    },
  },
});
```

***

## Step 7: Test Your Setup

Before going live, test your approval workflow.

### Create Test Scenario

```javascript theme={null}
// Create a subscription that should trigger approval
const subscription = await alguna.subscriptions.create({
  accountId: 'acc_test_customer',
  planId: 'plan_enterprise',
  lineItems: [
    {
      productId: 'prod_enterprise',
      quantity: 1,
      discount: {
        type: 'percentage',
        value: 30, // Should trigger approval
      },
    },
  ],
});

// Check if approval was required
console.log('Requires approval:', subscription.requiresApproval);
console.log('Approval request:', subscription.approvalRequest);
```

### Verify Rule Matching

```javascript theme={null}
// Preview which rules would match
const preview = await alguna.approvals.preview({
  subscriptionId: subscription.id,
});

console.log('Matched rules:', preview.matchedRules);
console.log('Required approvers:', preview.requiredApprovers);
```

### Process Test Approval

```javascript theme={null}
// Approve the test request
await alguna.approvals.requests.approve({
  requestId: preview.requestId,
  comment: 'Test approval - verified workflow working',
});
```

***

## Step 8: Enable for Production

Once tested, enable approval workflows.

### Gradual Rollout

```javascript theme={null}
// Start with high-threshold rules only
await alguna.approvals.rules.update('rule_large_discount', {
  enabled: true,
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 40, // Start high
    },
  ],
});

// Monitor for a week, then lower threshold
await alguna.approvals.rules.update('rule_large_discount', {
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 25, // Production threshold
    },
  ],
});
```

### Monitor Approval Metrics

```javascript theme={null}
const metrics = await alguna.approvals.analytics.get({
  period: '30d',
});

console.log('Total requests:', metrics.totalRequests);
console.log('Approved:', metrics.approved);
console.log('Rejected:', metrics.rejected);
console.log('Avg time to approval:', metrics.avgApprovalTime);
console.log('By rule:', metrics.byRule);
```

***

## Complete Setup Example

Here's a complete example setting up a tiered approval system:

```javascript theme={null}
// 1. Create approver groups
const salesManagers = await alguna.approvals.groups.create({
  name: 'Sales Managers',
  members: [
    { userId: 'user_sarah' },
    { userId: 'user_mike' },
  ],
  strategy: 'Any',
});

const vpSales = await alguna.approvals.groups.create({
  name: 'VP Sales',
  members: [
    { userId: 'user_jennifer' },
  ],
  strategy: 'All',
});

const executive = await alguna.approvals.groups.create({
  name: 'Executive Team',
  members: [
    { userId: 'user_cfo' },
    { userId: 'user_ceo' },
  ],
  strategy: 'Any',
});

// 2. Create tiered approval rules
await alguna.approvals.rules.create({
  name: 'Manager Discount Approval',
  priority: 30,
  enabled: true,
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 15,
    },
  ],
  approvers: [{ groupId: salesManagers.id }],
});

await alguna.approvals.rules.create({
  name: 'VP Discount Approval',
  priority: 20,
  enabled: true,
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 30,
    },
  ],
  approvers: [{ groupId: vpSales.id }],
});

await alguna.approvals.rules.create({
  name: 'Executive Discount Approval',
  priority: 10,
  enabled: true,
  conditions: [
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 45,
    },
  ],
  approvers: [{ groupId: executive.id }],
});

// 3. Create product-specific rule
await alguna.approvals.rules.create({
  name: 'Enterprise Product Approval',
  priority: 5,
  enabled: true,
  conditions: [
    {
      type: 'ProductPresence',
      productIds: ['prod_enterprise'],
    },
    {
      type: 'AnyProductDiscountThreshold',
      threshold: 10,
    },
  ],
  approvers: [
    { groupId: vpSales.id },
    { groupId: executive.id },
  ],
});

// 4. Configure notifications
await alguna.approvals.settings.update({
  notifications: {
    onRequestCreated: { enabled: true },
    onRequestApproved: { enabled: true },
    onRequestRejected: { enabled: true },
    reminderSchedule: {
      enabled: true,
      intervals: ['24h', '48h'],
    },
  },
});

console.log('Approval workflow configured successfully!');
```

***

## Troubleshooting

### Rule Not Triggering

1. Check rule is enabled
2. Verify condition thresholds
3. Check rule priority (higher priority rules may match first)
4. Review the preview endpoint for debugging

```javascript theme={null}
const debug = await alguna.approvals.debug({
  subscriptionId: 'sub_123',
  verbose: true,
});
console.log(debug.ruleEvaluation);
```

### Approval Stuck

1. Check approver group has active members
2. Verify notification delivery
3. Check escalation settings

```javascript theme={null}
const request = await alguna.approvals.requests.get('req_123');
console.log('Status:', request.status);
console.log('Pending approvers:', request.pendingApprovers);
console.log('Escalation due:', request.escalationDueAt);
```

### Notifications Not Sending

1. Verify email configuration
2. Check notification settings are enabled
3. Review email logs

```javascript theme={null}
const logs = await alguna.approvals.notifications.logs({
  requestId: 'req_123',
});
```

***

## Best Practices

<CardGroup cols={2}>
  <Card title="Start Conservative" icon="shield">
    Begin with high thresholds and lower gradually based on data.
  </Card>

  <Card title="Document Rules" icon="file-lines">
    Add clear descriptions explaining why each rule exists.
  </Card>

  <Card title="Set Escalations" icon="clock">
    Configure auto-escalation to prevent deals getting stuck.
  </Card>

  <Card title="Review Regularly" icon="calendar">
    Audit approval metrics monthly and adjust rules as needed.
  </Card>
</CardGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Approval Rules" icon="list-check" href="/approvals/approval-rules">
    Deep dive into rule configuration.
  </Card>

  <Card title="Approval Flows" icon="diagram-project" href="/approvals/approval-flows">
    Learn about approval request lifecycle.
  </Card>
</CardGroup>
