The requireApproval Pattern

The core feature of OK!Gotcha is the ability to wrap functions with approval requirements. This is done using the requireApproval decorator (Python) or higher-order function (TypeScript), which transforms regular functions into approval-gated functions.

import { OkGotcha } from '@okgotcha/sdk';

const ok = OkGotcha();

// Original function
const transferFunds = async (fromAccount: string, toAccount: string, amount: number): Promise<boolean> => {
  // Transfer implementation
  return true;
};

// Approval-gated function
const secureTransferFunds = ok.requireApproval({
  title: "Fund Transfer",
  description: "Transfer funds between accounts",
  approvers: ["finance-team"]
})(transferFunds);

How It Works

When a function is wrapped with requireApproval:

  1. Calling the function creates an approval request instead of executing immediately
  2. The function’s parameters are captured and serialized
  3. Approvers are notified through configured channels
  4. The function remains pending until approved or rejected
  5. Upon approval, the original function executes with the captured parameters
  6. Results are returned to the original caller (if using await/async patterns)

OK!Gotcha handles all the complexities of managing approval state, notifications, and execution flow, allowing you to focus on your business logic.

Approval Configuration Options

The requireApproval function accepts a configuration object with the following properties:

title
string
required

A short, descriptive title for the approval request.

description
string

A detailed description of what the approval request is for.

approvers
string[]
required

An array of approver IDs or teams who can approve or reject the request.

expiresIn
number

Time in seconds until the approval request expires (defaults to 24 hours).

minApprovals
number

Minimum number of approvals required (defaults to 1).

metadata
object

Additional custom data to store with the approval request.

Advanced Usage

Conditional Approval Requirements

You can dynamically determine if approval is required based on the function parameters:

const transferFunds = ok.requireApprovalIf({
  title: "High-Value Fund Transfer",
  description: "Transfer of funds exceeding $10,000",
  approvers: ["finance-team", "security-team"],
  condition: (fromAccount, toAccount, amount) => amount > 10000
})(async (fromAccount, toAccount, amount) => {
  // Transfer implementation
  return true;
});

Custom Approval Handlers

You can provide custom logic for handling approvals with the onApproved and onRejected callbacks:

const secureAction = ok.requireApproval({
  title: "Sensitive Action",
  description: "Perform a sensitive operation",
  approvers: ["security-team"],
  onApproved: (result) => {
    // Custom logic when approved
    logAudit("Action approved and executed successfully");
    return result;
  },
  onRejected: (reason) => {
    // Custom logic when rejected
    notifyAdmin(`Action rejected: ${reason}`);
    throw new Error(`Action rejected: ${reason}`);
  }
})(performSensitiveAction);

Next Steps