Skip to content

feat(integrations): add Ramp integration with spend, receipts, and bill tools#4982

Open
waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-ramp-integration
Open

feat(integrations): add Ramp integration with spend, receipts, and bill tools#4982
waleedlatif1 wants to merge 3 commits into
stagingfrom
worktree-ramp-integration

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Add Ramp integration with 25 tools covering transactions, users, cards, spend limits, reimbursements, bills, departments, vendors, entities, spend programs, business info/balance, and receipts
  • Receipt upload goes through an internal route (/api/tools/ramp/upload-receipt) with contract validation, internal auth, file access checks, and the documented Ramp multipart format (metadata as form-data parts, file as an attachment part named receipt)
  • Register Ramp as an OAuth provider (authorization code + refresh token via Basic auth) with centralized scopes, scope descriptions, env vars, and token refresh config
  • Add Ramp block with operation-conditional subBlocks, basic/advanced canonical pairs for credential and file, timestamp wand configs, shared pagination (start cursor surfaced as nextStart), BlockMeta templates and skills
  • Generate docs page with a manual intro section; add RampIcon (brand bg #E4F222)

Type of Change

  • New feature

Testing

Typecheck clean, biome clean, check:api-validation:strict passes, block/tool registry test suites pass (162 tests). All endpoints, params, scopes, and response shapes cross-checked against Ramp's OpenAPI spec.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jun 11, 2026 11:59pm

Request Review

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@gitguardian

gitguardian Bot commented Jun 11, 2026

Copy link
Copy Markdown

️✅ There are no secrets present in this pull request anymore.

If these secrets were true positive and are still valid, we highly recommend you to revoke them.
While these secrets were previously flagged, we no longer have a reference to the
specific commits where they were detected. Once a secret has been leaked into a git
repository, you should consider it compromised, even if it was deleted immediately.
Find here more information about risks.


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor

cursor Bot commented Jun 11, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches OAuth/auth and a server route that forwards bearer tokens and user files to Ramp; scope is additive but finance data and file handling warrant careful review.

Overview
Adds a Ramp finance integration so workflows can automate corporate spend via OAuth and 25 tools (transactions, users, cards, limits, reimbursements, bills, vendors, departments, receipts, business balance, etc.).

Wires Ramp OAuth (RAMP_CLIENT_ID / RAMP_CLIENT_SECRET, Basic-auth token refresh, business-scoped getUserInfo) and registers the Ramp block with operation-specific UI, pagination (nextStart), receipt file upload, templates/skills, docs (ramp.mdx), icons, and integrations.json catalog entry. Most API calls use shared Ramp tool helpers; receipt upload is proxied through /api/tools/ramp/upload-receipt with contract validation, internal auth, file access checks, and Ramp’s multipart format.

Reviewed by Cursor Bugbot for commit eceb558. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d72df32. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a complete Ramp integration with 25 tools covering transactions, users, cards, spend limits, reimbursements, bills, departments, vendors, entities, spend programs, business info/balance, and receipts. It registers Ramp as an OAuth provider (authorization code + refresh token via Basic auth), adds the Ramp block, and routes file uploads through an internal proxy endpoint that handles multipart/form-data construction.

  • 25 tools all follow the established ToolConfig pattern with accessToken marked visibility: 'hidden' (correct per codebase convention for OAuth-injected tokens) and direct Ramp API calls via buildRampHeaders/buildRampUrl helpers.
  • Receipt upload goes through /api/tools/ramp/upload-receipt which validates the caller with checkInternalAuth, enforces file access with assertToolFileAccess, then constructs a sanitized multipart body before forwarding to Ramp; field values, filename, and Content-Type are all stripped of CR/LF characters.
  • OAuth registration in auth.ts follows the identical pattern used by 40+ other generic OAuth providers (non-deterministic providerAccountId per authorization, getUserInfo fetches /business to synthesize a stable identity from the business ID).

Confidence Score: 5/5

This PR is safe to merge; it adds a self-contained new integration with no changes to existing logic paths.

All 25 tools follow the established codebase patterns for OAuth-backed integrations. The receipt upload route correctly validates the caller, checks file ownership, and sanitizes CR/LF characters in all user-controlled fields before embedding them in the multipart body. OAuth registration mirrors the existing 40+ provider convention. No existing code paths are modified beyond additive registration entries.

No files require special attention. The upload-receipt route is the most complex new path and it handles auth, file access, and multipart construction correctly.

Important Files Changed

Filename Overview
apps/sim/app/api/tools/ramp/upload-receipt/route.ts New internal proxy endpoint for receipt uploads; correctly validates caller auth, checks file ownership, sanitizes CR/LF in field values/filename/Content-Type, and constructs a compliant multipart body before forwarding to Ramp.
apps/sim/tools/ramp/upload_receipt.ts Client-side tool definition that routes receipt uploads through the internal proxy; accessToken correctly marked hidden (OAuth-injected), file and userId correctly required.
apps/sim/lib/auth/auth.ts Adds Ramp genericOAuth provider; getUserInfo fetches /business and synthesizes identity from business ID following the same non-deterministic providerAccountId convention used by all 40+ other workflow-credential providers.
apps/sim/lib/oauth/oauth.ts Registers Ramp as an OAuth provider with full scope set and Basic-auth token refresh; correctly uses getProviderAuthConfig case for Ramp with useBasicAuth: true and supportsRefreshTokenRotation: true.
apps/sim/tools/ramp/utils.ts Shared utilities: buildRampHeaders (guards against missing token), buildRampUrl (omits empty params), extractRampError (handles error_v2 and legacy message fields), extractNextStart (parses next-page cursor from page.next URL).
apps/sim/lib/api/contracts/tools/ramp.ts Zod contract for the receipt upload route; validates accessToken, userId, optional transactionId (nullish), and file via FileInputSchema; success response schema uses z.literal(true) consistent with codebase pattern.
apps/sim/blocks/blocks/ramp.ts Block definition with 25 operation dropdown entries and conditional subBlocks; operation-conditional visibility for all resource-ID fields is correctly configured, and RAMP_LIST_OPERATIONS drives pagination subBlock visibility.
apps/sim/tools/ramp/types.ts Comprehensive type definitions for all 25 operations; RampCurrencyAmount is correctly documented as integer in smallest denomination; all list response types include optional nextStart cursor.
apps/sim/tools/ramp/list_transactions.ts List transactions tool with comprehensive filters (user, card, department, merchant, state, amount range, date range, pagination); all params correctly typed and mapped to Ramp API query parameter names.
apps/sim/tools/ramp/create_department.ts Create department tool using POST /departments with JSON body; Content-Type header correctly added alongside Authorization header; follows the same mutation pattern as other tools in the codebase.

Sequence Diagram

sequenceDiagram
    participant Client as Client Tool (upload_receipt.ts)
    participant Internal as /api/tools/ramp/upload-receipt
    participant Storage as File Storage
    participant Ramp as Ramp API

    Client->>Internal: "POST JSON {accessToken, userId, transactionId?, file}"
    Internal->>Internal: checkInternalAuth()
    Internal->>Internal: parseRequest (Zod validation)
    Internal->>Internal: processFilesToUserFiles()
    Internal->>Internal: assertToolFileAccess(key, userId)
    Internal->>Storage: downloadFileFromStorage(userFile)
    Storage-->>Internal: fileBuffer
    Internal->>Internal: buildReceiptMultipartBody(boundary, fields, file)
    Internal->>Ramp: POST /receipts multipart/form-data
    Ramp-->>Internal: "{id} or error"
    Internal-->>Client: "{success, output: {receiptId}} or {success: false, error}"
Loading

Reviews (3): Last reviewed commit: "fix(ramp): sanitize multipart field valu..." | Re-trigger Greptile

Comment thread apps/sim/lib/auth/auth.ts
Comment thread apps/sim/app/api/tools/ramp/upload-receipt/route.ts Outdated
@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a full Ramp integration — 25 tools covering transactions, users, cards, spend limits, reimbursements, bills, departments, vendors, entities, spend programs, business info/balance, and receipts — along with an OAuth provider registration, a custom internal upload route for the multipart Ramp receipts endpoint, a block with conditional sub-blocks and wand configs, and docs.

  • OAuth & auth: Ramp is registered as a provider with Basic-auth token refresh. getUserInfo synthesises a stable business identity following the established random-suffix ID pattern used by every other provider in this file.
  • Receipt upload route (/api/tools/ramp/upload-receipt): Builds the Ramp-specific multipart body with idempotency_key, user_id, optional transaction_id, and the file; internal auth + assertToolFileAccess guard the endpoint before the Ramp call.
  • Block & tools: The block cleanly maps 25 operations to conditional sub-blocks, correctly converts pageSize/amounts to numbers, and normalises the file input. All read tools follow the shared buildRampUrl + buildRampHeaders + extractRampError utilities, and list tools use the extractNextStart cursor helper.

Confidence Score: 4/5

The integration is well-structured and the receipt upload route is properly guarded by internal auth and file-access checks; the two findings are both hardening suggestions with no realistic attack surface today.

The implementation follows the established patterns for OAuth providers, block definitions, and tool utilities consistently across 46 files. The only actionable findings are a missing CRLF strip on multipart field values (inconsistent with the filename sanitization already present) and generic scope-description keys that could silently collide with future provider registrations. Neither represents a current breakage.

apps/sim/app/api/tools/ramp/upload-receipt/route.ts (multipart field sanitization) and apps/sim/lib/oauth/utils.ts (generic scope key names)

Important Files Changed

Filename Overview
apps/sim/app/api/tools/ramp/upload-receipt/route.ts New internal route that proxies receipt file uploads to Ramp's multipart API; field values in the multipart body lack CRLF sanitization unlike the filename.
apps/sim/lib/auth/auth.ts Registers Ramp as an OAuth provider with getUserInfo synthesizing a stable business identity; follows the established random-suffix ID pattern used by other providers.
apps/sim/lib/oauth/oauth.ts Adds Ramp to OAUTH_PROVIDERS and getProviderAuthConfig with correct Basic-auth token refresh configuration.
apps/sim/lib/oauth/utils.ts Adds Ramp-specific scope descriptions using generic flat-key names (e.g., business:read, transactions:read); could collide with future providers using the same scope strings.
apps/sim/blocks/blocks/ramp.ts Comprehensive block definition with 25 operations, conditional subBlocks, file-upload handling, wand configs for timestamps, and BlockMeta templates — all look correct.
apps/sim/tools/ramp/utils.ts Clean utility helpers for URL building, auth headers, error extraction, and pagination cursor parsing.
apps/sim/tools/ramp/upload_receipt.ts Tool wrapper that delegates receipt upload to the internal route; correctly uses hidden accessToken and JSON body proxy.
apps/sim/lib/api/contracts/tools/ramp.ts Zod contract for receipt upload body and response; correctly uses FileInputSchema and validates required fields.
apps/sim/tools/ramp/types.ts Well-structured TypeScript interfaces for all 25 Ramp tools covering transactions, users, cards, limits, receipts, and the union RampResponse type.
apps/sim/lib/core/config/env.ts Adds optional RAMP_CLIENT_ID and RAMP_CLIENT_SECRET env vars with correct Zod schema.

Sequence Diagram

sequenceDiagram
    participant User as User / Workflow
    participant Block as Ramp Block
    participant ToolExecutor as Tool Executor
    participant InternalRoute as /api/tools/ramp/upload-receipt
    participant Storage as File Storage
    participant RampAPI as Ramp API

    User->>Block: configure operation + inputs
    Block->>ToolExecutor: resolve tool (e.g. ramp_list_transactions)

    alt Read / list / create tool
        ToolExecutor->>RampAPI: GET/POST https://api.ramp.com/developer/v1/...
        RampAPI-->>ToolExecutor: JSON response
        ToolExecutor-->>Block: transformed output
    end

    alt Upload Receipt
        ToolExecutor->>InternalRoute: POST /api/tools/ramp/upload-receipt
        InternalRoute->>InternalRoute: checkInternalAuth + parseRequest
        InternalRoute->>InternalRoute: processFilesToUserFiles + assertToolFileAccess
        InternalRoute->>Storage: downloadFileFromStorage
        Storage-->>InternalRoute: file buffer
        InternalRoute->>InternalRoute: buildReceiptMultipartBody
        InternalRoute->>RampAPI: POST /developer/v1/receipts (multipart/form-data)
        RampAPI-->>InternalRoute: "{ id: receiptId }"
        InternalRoute-->>ToolExecutor: "{ success: true, output: { receiptId } }"
        ToolExecutor-->>Block: receiptId
    end

    alt OAuth Token Refresh
        ToolExecutor->>RampAPI: POST /developer/v1/token (Basic auth)
        RampAPI-->>ToolExecutor: new access_token + refresh_token
    end
Loading

Reviews (2): Last reviewed commit: "feat(integrations): add Ramp integration..." | Re-trigger Greptile

Comment thread apps/sim/app/api/tools/ramp/upload-receipt/route.ts
Comment thread apps/sim/lib/oauth/utils.ts
@waleedlatif1 waleedlatif1 force-pushed the worktree-ramp-integration branch from 4e6f901 to eceb558 Compare June 11, 2026 23:54
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit eceb558. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant