Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ Recurring research, cron jobs, and webhook delivery.
| Recipe | Description | APIs | Stack | Demo |
| --- | --- | --- | --- | --- |
| [**Daily Insights**](typescript-recipes/parallel-daily-insights) | Cron-triggered daily research feed — runs Tasks on a schedule, persists to KV, publishes a public data feed. Includes a `SPEC.md` showing the task spec used. | `Task` `Webhooks` `Cron` | Cloudflare Workers · KV | – |
| [**Procurement Vendor Risk (n8n)**](typescript-recipes/parallel-procurement-n8n) | n8n-orchestrated daily Deep Research + V1 event-stream monitors across six risk dimensions per vendor, with deterministic scoring, cited audit log, and severity routing into Slack. Ships an optional Next.js + Supabase BYOK dashboard. | `Task` `Deep Research` `Monitors` `Webhooks` | n8n · TypeScript · Next.js · Supabase | – |

### Deep Research & Notebooks

Expand Down
42 changes: 42 additions & 0 deletions typescript-recipes/parallel-procurement-n8n/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# ── Required ────────────────────────────────────────────────────────────────

# Parallel AI API key (https://platform.parallel.ai)
PARALLEL_API_KEY=your-parallel-api-key-here

# Google Sheets document ID for vendor registry
GOOGLE_SHEET_ID=your-google-sheet-id-here

# Slack incoming webhook URL for alert delivery
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/your/webhook/url

# Shared token gating the dashboard-snapshot webhook
# (workflow-combined.json region 7). Without this, anyone who knows the URL
# can dump the entire vendor registry. Set the same value here, as an n8n
# workflow variable, and as a Vercel env var on the dashboard.
PROCUREMENT_SNAPSHOT_TOKEN=replace-with-a-random-32+char-string

# ── Optional (defaults shown) ──────────────────────────────────────────────

# Parallel API base URL
# PARALLEL_BASE_URL=https://api.parallel.ai

# Cron schedules (UTC)
# RESEARCH_CRON=0 6 * * *
# SYNC_CRON=0 0 * * *

# Processing
# BATCH_SIZE=50
# RESEARCH_PROCESSOR=ultra8x

# Monitor cadence by priority
# MONITOR_CADENCE_HIGH=daily
# MONITOR_CADENCE_STD=weekly

# Monitors per vendor by priority
# MONITORS_PER_VENDOR_HIGH=5
# MONITORS_PER_VENDOR_STD=2

# Slack channel routing (optional — uses webhook default if unset)
# SLACK_CHANNEL_CRITICAL=#procurement-critical
# SLACK_CHANNEL_ALERT=#procurement-alerts
# SLACK_CHANNEL_DIGEST=#procurement-digest
10 changes: 10 additions & 0 deletions typescript-recipes/parallel-procurement-n8n/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
node_modules/
dist/
coverage/
.next/
.vercel/
.env
.env.local
*.local
*.tsbuildinfo
.DS_Store
38 changes: 38 additions & 0 deletions typescript-recipes/parallel-procurement-n8n/DEPLOY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Deploying the dashboard

The recipe ships two deployable pieces:

1. The **n8n workflow JSON** in [`n8n-workflows/`](n8n-workflows/) — import into n8n Cloud (or a self-hosted instance). The full walkthrough is in [SETUP.md](SETUP.md).
2. The optional **Next.js + Supabase dashboard** in [`dashboard/`](dashboard/) — a multi-tenant BYOK control plane that uses the same Parallel APIs the n8n flow does.

This document covers the dashboard. For the n8n side, see SETUP.md.

## One-click Vercel deploy

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fparallel-web%2Fparallel-cookbook%2Ftree%2Fmain%2Ftypescript-recipes%2Fparallel-procurement-n8n%2Fdashboard&project-name=parallel-procurement-dashboard&repository-name=parallel-procurement-dashboard)

The Vercel project should target the `dashboard/` subdirectory. The full step-by-step (Supabase provisioning, env vars, cron schedule, smoke test) lives in [`dashboard/README.md`](dashboard/README.md#deploying-to-vercel).

## Required environment variables

All values live in Vercel **Project Settings → Env Vars** (Production + Preview). No Parallel, Slack, or Resend keys are configured at the platform level — every user brings their own at sign-in.

| Variable | How to generate |
|---|---|
| `NEXT_PUBLIC_APP_URL` | Public URL of the deployment |
| `SUPABASE_URL` / `SUPABASE_SERVICE_ROLE_KEY` | Supabase **Project Settings → API** |
| `SESSION_SECRET` | `openssl rand -base64 32` |
| `APP_ENCRYPTION_KEY` | `openssl rand -hex 32` (must decode to 32 bytes) |
| `PARALLEL_WEBHOOK_SECRET` | Any 32+ char random string |
| `CRON_SECRET` | Bearer auth required by `/api/cron/*` endpoints |

See [`dashboard/.env.example`](dashboard/.env.example) for the full list and inline notes.

## What the cron jobs do

`dashboard/vercel.json` schedules:

- `/api/cron/sweep` (daily 05:00 UTC) — reconciles in-flight task groups whose webhooks were dropped.
- `/api/cron/research-due` (daily 06:00 UTC) — runs deep research for any vendor whose `next_research_date` has elapsed, using each account's BYOK Parallel key.

Vercel Hobby is limited to one cron per day per project; upgrade to Pro if you want the hourly sweep cadence noted in the dashboard README.
21 changes: 21 additions & 0 deletions typescript-recipes/parallel-procurement-n8n/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Shapley AI, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
99 changes: 99 additions & 0 deletions typescript-recipes/parallel-procurement-n8n/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Procurement Vendor Risk Monitor (n8n)

Continuous vendor risk monitoring built on [Parallel](https://parallel.ai)'s Task and Monitor APIs, orchestrated by n8n, with Slack-routed alerts and a cited audit log. Live demo: _video walkthrough coming with the public release_.

See [DEPLOY.md](DEPLOY.md) for the optional Next.js + Supabase dashboard that ships with the recipe.

## What it shows

- Driving the Parallel **Task Group** API from an n8n cron flow to research every vendor across six risk dimensions on a daily cadence.
- Deploying a portfolio of **V1 event-stream monitors** per vendor (sized to priority) and resolving events via `client.monitor.events`.
- Wiring monitor webhooks back into the same scoring chain that handles deep-research output, so live events and daily research share a code path.
- Lifting the top citation from `output.basis` so every alert and audit row carries a source URL.
- Severity-based routing into Slack (`#procurement-critical` / `#alerts` / `#digest`) plus a `/vendor-research` slash command for ad-hoc reports.

## Architecture

```
Google Sheets (Vendors tab)
|
Vendor Sync (every 6h) -----> Deploy Monitors (V1 event_stream)
| |
Deep Research (daily 2 AM) Monitor Events (real-time webhooks)
| |
+--------> Risk Scoring <-------+
|
Route by severity
/ | | \
CRITICAL HIGH MEDIUM LOW
| | | |
#critical #alerts #digest (log only)
|
Audit Log (with top_citation_url, confidence)
```

One combined n8n workflow contains all five flows (50 nodes total). Every Parallel API call — daily Task Group, per-vendor monitor create, event resolution — runs on the official [`parallel-web`](https://www.npmjs.com/package/parallel-web) SDK against the V1 surfaces.

## Quick Start

1. Clone the cookbook and enter the recipe.
```bash
git clone https://github.com/parallel-web/parallel-cookbook.git
cd parallel-cookbook/typescript-recipes/parallel-procurement-n8n
```
2. Install dependencies.
```bash
npm ci
```
3. Copy `.env.example` to `.env` and fill in `PARALLEL_API_KEY`, `GOOGLE_SHEET_ID`, `SLACK_WEBHOOK_URL`, and `PROCUREMENT_SNAPSHOT_TOKEN`.
4. Run the test suite to verify the local install.
```bash
npm test
```
5. Generate the importable n8n workflow JSON.
```bash
npx tsx src/workflows/generate-all.ts ./n8n-workflows
```
6. Import `n8n-workflows/workflow-combined.json` into n8n Cloud, wire your Google Sheets and Slack credentials, and set `NODE_FUNCTION_ALLOW_EXTERNAL=parallel-web` so the Code nodes can `require()` the SDK at runtime. The full walkthrough is in [SETUP.md](SETUP.md).

Optional: the [`dashboard/`](dashboard/) folder is a Next.js + Supabase BYOK app that consumes the same Parallel APIs. See [DEPLOY.md](DEPLOY.md) for Vercel + Supabase setup.

## How it works

**Vendor sync diffs the source of truth, not the world.** The cron flow reads the Google Sheet, compares it to the persisted registry, and only deploys or cancels monitors where the row actually changed — so a re-run is cheap and idempotent. Monitor cancellation is irreversible per the V1 contract, so the self-healing path recreates a fresh monitor with the same settings rather than mutating in place.

**Daily research uses Task Groups, monitors stream events.** Each batch of due vendors becomes a Task Group of six per-dimension specs (financial, legal/regulatory, cybersecurity, leadership, ESG, adverse events). The same vendors also carry persistent V1 monitors (`type: "event_stream"`, nested `settings`, `processor: "lite" | "base"`) sized to priority: HIGH gets 5 monitors at `1d` cadence, MEDIUM gets 3 at `1d`, LOW gets 2 at `7d`. Cyber and legal monitors on HIGH vendors use the `base` processor for higher recall.

**Scoring is deterministic, citations are not.** The cascade is fixed (any CRITICAL → CRITICAL; any HIGH → HIGH; 3+ MEDIUM across 2+ categories → MEDIUM-adverse; otherwise MEDIUM or LOW), with overrides for active breaches, government litigation, and a spreadsheet `risk_tier_override` floor. The interesting part is what comes back from `output.basis`: every assessment carries reasoning, confidence, and citation URLs per field. The scorer groups basis entries by dimension, picks the highest-confidence citation per triggered dimension, and writes them as `top_citation_url` / `top_citation_title` / `confidence` on the audit row and as a `Sources:` block in the Slack alert.

**One workflow, five flows.** Combining the flows in a single n8n workflow means the monitor webhook and the daily Task Group fan into the exact same scoring chain — there is one risk-scoring path, not two that can drift. The five entry points (vendor sync cron, deep-research cron, monitor-deploy webhook, monitor-event webhook, Slack slash command) all share `src/services/risk-scorer.ts`.

For the data model, processor selection rationale, and a full walkthrough of the scoring overrides, see [`parallel_procurement.md`](parallel_procurement.md). For a 15-vendor sample run with screenshots, see [`sample-setup.md`](sample-setup.md).

## Configuration

| Variable | Required | Default | Notes |
|---|---|---|---|
| `PARALLEL_API_KEY` | Yes | – | Parallel API key |
| `GOOGLE_SHEET_ID` | Yes | – | Google Sheets document ID |
| `SLACK_WEBHOOK_URL` | Yes | – | Slack incoming webhook |
| `PROCUREMENT_SNAPSHOT_TOKEN` | Yes | – | Bearer token for the snapshot endpoint (any 32+ char random string) |
| `N8N_WEBHOOK_BASE_URL` | Yes | – | Your n8n instance URL |
| `BATCH_SIZE` | No | `50` | Vendors per Task Group batch |
| `RESEARCH_PROCESSOR` | No | `ultra8x` | Parallel processor tier |
| `MONITOR_CADENCE_HIGH` / `_STD` | No | `1d` / `7d` | Override the default monitor cadences |
| `SLACK_CHANNEL_CRITICAL` / `_ALERT` / `_DIGEST` | No | see `.env.example` | Per-severity Slack routing |

The dashboard takes additional Supabase / encryption / webhook secrets; see [`dashboard/.env.example`](dashboard/.env.example) and [DEPLOY.md](DEPLOY.md).

## Tests

```bash
npm test
```

46 Vitest suites covering every service and model, n8n workflow JSON structure (combined + per-flow generators), full pipeline integration (research → score → route → audit), vendor lifecycle across sync cycles, nine error scenarios, and a scale simulation (200 vendors / 4 batches, 3000 vendors / 15-day rotation).

## License

MIT — see [LICENSE](LICENSE). Copyright (c) 2026 Shapley AI, Inc.
Loading