← back to Designer Wallcoverings

DW-Agents/dw-agents/HOOKS-API-ARCHITECTURE.md

571 lines

# Shared Hooks API - Architecture & Integration

## System Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│                        DW-Agents Ecosystem                      │
└─────────────────────────────────────────────────────────────────┘
                                 │
                    ┌────────────┴────────────┐
                    │                         │
        ┌───────────▼──────────┐  ┌──────────▼─────────┐
        │   Agent 1 (9800)     │  │  Agent 2 (9850)    │
        │   Marketing          │  │  E-commerce        │
        ├──────────────────────┤  ├────────────────────┤
        │ import { hooks }     │  │ import { hooks }   │
        │ setupHooksAPI(app)   │  │ setupHooksAPI(app) │
        └──────────┬───────────┘  └──────────┬─────────┘
                   │                         │
                   └────────┬────────────────┘
                            │
                   ┌────────▼─────────┐
                   │  shared-hooks-   │
                   │     api.ts       │
                   │                  │
                   │ - setupHooksAPI  │
                   │ - executeHook    │
                   │ - hooks.*        │
                   │ - HooksClient    │
                   └────────┬─────────┘
                            │
          ┌─────────────────┼─────────────────┐
          │                 │                 │
    ┌─────▼─────┐   ┌──────▼──────┐   ┌─────▼─────┐
    │  Gmail    │   │   Slack     │   │  Shopify  │
    │   Hook    │   │   Hook      │   │   Hook    │
    └───────────┘   └─────────────┘   └───────────┘
         │                 │                 │
    ┌────▼────┐      ┌─────▼─────┐     ┌────▼────┐
    │ Gmail   │      │  Slack    │     │Shopify  │
    │  API    │      │   API     │     │  API    │
    └─────────┘      └───────────┘     └─────────┘
```

## Data Flow

### 1. REST API Flow

```
User Request
    │
    ▼
┌─────────────────────────┐
│ POST /api/hooks/slack   │
│ { params: {...} }       │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ setupHooksAPI()         │
│ - Parse request         │
│ - Validate params       │
│ - Build args string     │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ executeHook()           │
│ - Sanitize hook name    │
│ - Build command         │
│ - Execute with timeout  │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ node slack-hook.js      │
│ - Connect to Slack API  │
│ - Send message          │
│ - Return result         │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ HookResult              │
│ {                       │
│   success: true,        │
│   output: "...",        │
│   executionTime: 1234   │
│ }                       │
└─────────────────────────┘
```

### 2. Programmatic Flow

```
Agent Code
    │
await hooks.slack.send('general', 'Hello')
    │
    ▼
┌─────────────────────────┐
│ Convenience Wrapper     │
│ hooks.slack.send()      │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ executeHook()           │
│ ('slack', 'send ...')   │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ Hook Execution          │
└───────────┬─────────────┘
            │
            ▼
┌─────────────────────────┐
│ Return HookResult       │
└─────────────────────────┘
```

## Integration Patterns

### Pattern 1: Basic Integration

```typescript
// Minimal setup
import express from 'express';
import { setupHooksAPI } from '../shared-hooks-api';

const app = express();
app.use(express.json());
setupHooksAPI(app);  // Done! REST API ready
app.listen(9800);
```

**Result:**
- GET /api/hooks (list all)
- POST /api/hooks/:hookName (execute any hook)

### Pattern 2: Programmatic Integration

```typescript
import { hooks, executeHook } from '../shared-hooks-api';

// In any route or function
app.post('/api/orders', async (req, res) => {
  // Use convenience wrappers
  await hooks.slack.send('orders', 'New order');
  await hooks.gmail.send('team@co.com', 'Order', 'Details');

  // Or direct execution
  await executeHook('order-processing', req.body.id);

  res.json({ success: true });
});
```

### Pattern 3: Type-Safe Client

```typescript
import { HooksClient } from '../shared-hooks-api';

const client = new HooksClient(60000);

// Full type safety and IntelliSense
await client.gmail('send', to, subject, body);
await client.healthCheck('web');
await client.notifyError('critical', 'Down');
```

### Pattern 4: Error Handling

```typescript
import { executeHook, hooks } from '../shared-hooks-api';

try {
  await riskyOperation();
} catch (error) {
  // Multi-channel error notification
  await hooks.errors.notify('critical', error.message);
  await hooks.slack.send('alerts', `ERROR: ${error.message}`);
  await hooks.twilio.sms('+1234567890', 'ALERT: System error');
}
```

### Pattern 5: Health Monitoring

```typescript
import { HooksClient } from '../shared-hooks-api';

const client = new HooksClient();

setInterval(async () => {
  const services = ['web', 'gmail', 'slack', 'shopify'];

  for (const service of services) {
    const result = await client.healthCheck(service);

    if (!result.success) {
      await client.notifyError('critical', `${service} down`);
    }
  }
}, 5 * 60 * 1000); // Every 5 minutes
```

## Module Structure

### Core Module (`shared-hooks-api.ts`)

```typescript
┌──────────────────────────────────────┐
│         shared-hooks-api.ts          │
├──────────────────────────────────────┤
│                                      │
│  Interface HookResult                │
│    - success: boolean                │
│    - output?: string                 │
│    - error?: string                  │
│    - timestamp: string               │
│    - executionTime?: number          │
│                                      │
├──────────────────────────────────────┤
│                                      │
│  executeHook(name, args, timeout)    │
│    - Sanitize hook name              │
│    - Build command path              │
│    - Execute with timeout            │
│    - Return HookResult               │
│                                      │
├──────────────────────────────────────┤
│                                      │
│  setupHooksAPI(app, basePath)        │
│    - GET /api/hooks                  │
│    - GET /api/hooks/:hookName        │
│    - POST /api/hooks/:hookName       │
│                                      │
├──────────────────────────────────────┤
│                                      │
│  hooks { }                           │
│    - gmail { send, read, search }    │
│    - slack { send, listChannels }    │
│    - twilio { sms, call }            │
│    - health { check, agents }        │
│    - orders { process }              │
│    - errors { notify }               │
│                                      │
├──────────────────────────────────────┤
│                                      │
│  class HooksClient                   │
│    - execute(hook, args)             │
│    - gmail(action, ...params)        │
│    - slack(action, ...params)        │
│    - healthCheck(service)            │
│    - processOrder(id)                │
│    - notifyError(severity, msg)      │
│                                      │
└──────────────────────────────────────┘
```

## API Endpoints

### GET /api/hooks

```json
{
  "success": true,
  "hooks": {
    "gmail": {
      "description": "Gmail API operations",
      "examples": ["send to@test.com 'Subject' 'Body'"]
    },
    "slack": { ... },
    ...
  },
  "usage": { ... }
}
```

### GET /api/hooks/:hookName

```json
{
  "success": true,
  "hook": "gmail",
  "info": {
    "description": "Gmail API operations",
    "examples": [...]
  }
}
```

### POST /api/hooks/:hookName

**Request:**
```json
{
  "action": "send to@test.com 'Subject' 'Body'",
  "timeout": 60000
}
```

**Or:**
```json
{
  "params": {
    "to": "test@test.com",
    "subject": "Subject",
    "body": "Body"
  }
}
```

**Response:**
```json
{
  "success": true,
  "output": "Email sent successfully",
  "timestamp": "2025-11-12T20:30:00.000Z",
  "hookName": "gmail",
  "executionTime": 1234
}
```

## Security Model

```
┌──────────────────────────────────┐
│      Agent Request               │
└────────────┬─────────────────────┘
             │
             ▼
┌──────────────────────────────────┐
│  Agent Authentication            │
│  (requireAuth middleware)        │
└────────────┬─────────────────────┘
             │
             ▼
┌──────────────────────────────────┐
│  Rate Limiting                   │
│  (express-rate-limit)            │
└────────────┬─────────────────────┘
             │
             ▼
┌──────────────────────────────────┐
│  shared-hooks-api                │
│  - Input sanitization            │
│  - Hook name validation          │
│  - Timeout protection            │
└────────────┬─────────────────────┘
             │
             ▼
┌──────────────────────────────────┐
│  Hook Execution                  │
│  (sandboxed child process)       │
└────────────┬─────────────────────┘
             │
             ▼
┌──────────────────────────────────┐
│  Result with execution metrics   │
└──────────────────────────────────┘
```

## Performance Characteristics

| Metric | Value | Notes |
|--------|-------|-------|
| Function Call Overhead | <5ms | Negligible |
| Hook Execution | Varies | Depends on hook and external API |
| Default Timeout | 60s | Configurable per call |
| Max Buffer | 10MB | For hook output |
| Concurrent Calls | Unlimited | No artificial limits |
| Memory Footprint | Minimal | Stateless design |

## Migration Path

### Phase 1: Add Module (No Breaking Changes)

```typescript
// Keep existing code
// Add new module alongside
import { setupHooksAPI } from '../shared-hooks-api';
setupHooksAPI(app);
```

### Phase 2: Start Using (Gradual)

```typescript
// Replace one function at a time
// OLD:
await sendSlackMessage('general', 'Hello');
// NEW:
await hooks.slack.send('general', 'Hello');
```

### Phase 3: Full Migration

```typescript
// Remove all old hook code
// Use only shared-hooks-api
import { hooks } from '../shared-hooks-api';
```

### Phase 4: Cleanup

```typescript
// Delete old helper functions
// Update documentation
// Verify all agents use new module
```

## Testing Strategy

### Unit Tests

```typescript
describe('executeHook', () => {
  it('should execute valid hook', async () => {
    const result = await executeHook('slack', 'send general "Test"');
    expect(result.success).toBe(true);
  });

  it('should handle errors', async () => {
    const result = await executeHook('invalid', 'args');
    expect(result.success).toBe(false);
    expect(result.error).toBeDefined();
  });

  it('should timeout long operations', async () => {
    const result = await executeHook('slow-hook', '', 100);
    expect(result.success).toBe(false);
  });
});
```

### Integration Tests

```bash
# Test REST API
curl http://localhost:9800/api/hooks

# Test hook execution
curl -X POST http://localhost:9800/api/hooks/slack \
  -d '{"params": {"channel": "test", "message": "Test"}}'

# Test error handling
curl -X POST http://localhost:9800/api/hooks/invalid
```

### End-to-End Tests

```typescript
// Test full workflow
app.post('/test/workflow', async (req, res) => {
  // 1. Process order
  const order = await hooks.orders.process(req.body.id);

  // 2. Notify team
  await hooks.slack.send('orders', `Order ${req.body.id}`);

  // 3. Email customer
  await hooks.gmail.send(req.body.email, 'Confirmed', 'Details');

  // 4. Update agents
  await executeHook('inter-agent-chat', `broadcast "Order processed"`);

  res.json({ success: true });
});
```

## Monitoring & Observability

### Built-in Logging

```javascript
[Hooks API] Executing: node /root/DW-MCP/DW-Hooks/slack-hook.js send general "Hello"
[Hooks API] Success: 1234ms
```

### Metrics to Track

- Hook execution count per hook
- Average execution time per hook
- Success/failure rate
- Timeout frequency
- Error patterns

### Dashboard Integration

```typescript
app.get('/api/hooks/metrics', (req, res) => {
  res.json({
    totalExecutions: 12345,
    successRate: 0.98,
    avgExecutionTime: 1234,
    topHooks: [
      { name: 'slack', count: 5000 },
      { name: 'gmail', count: 3000 },
      { name: 'order-processing', count: 2000 }
    ]
  });
});
```

## Best Practices

### 1. Always Handle Errors

```typescript
const result = await executeHook('gmail', '...');
if (!result.success) {
  await hooks.errors.notify('high', `Failed: ${result.error}`);
}
```

### 2. Use Convenience Wrappers

```typescript
// Good
await hooks.slack.send('general', 'Hello');

// Okay
await executeHook('slack', 'send general "Hello"');
```

### 3. Set Appropriate Timeouts

```typescript
// Short timeout for fast operations
await executeHook('health-check', 'web', 5000);

// Long timeout for complex operations
await executeHook('product-import', 'large-file', 300000);
```

### 4. Add Rate Limiting

```typescript
import rateLimit from 'express-rate-limit';

app.use('/api/hooks', rateLimit({
  windowMs: 60000,
  max: 30
}));
```

### 5. Protect Endpoints

```typescript
app.use('/api/hooks', requireAuth);
setupHooksAPI(app);
```

## Troubleshooting Guide

| Symptom | Cause | Solution |
|---------|-------|----------|
| "Hook not found" | Typo in hook name | Check spelling, use GET /api/hooks |
| Timeout errors | Slow operation | Increase timeout parameter |
| Permission denied | Not executable | chmod +x hooks/*.js |
| Module not found | Missing deps | npm install |
| Type errors | Wrong import | Use correct import path |
| Empty output | Hook failed silently | Check hook's own logs |

---

**Last Updated:** 2025-11-12
**Version:** 1.0.0
**Status:** Production Ready