Skip to content

feat(ai-integrations): cursor usage polling pipeline#2923

Open
subomi wants to merge 6 commits into
mainfrom
cursor-usage-polling-stack
Open

feat(ai-integrations): cursor usage polling pipeline#2923
subomi wants to merge 6 commits into
mainfrom
cursor-usage-polling-stack

Conversation

@subomi
Copy link
Copy Markdown
Contributor

@subomi subomi commented May 19, 2026

Summary

  • Adds an org-level AI Integrations product surface (CRUD service, settings UI, audit) with Cursor as the first provider — encrypted API-key storage, write-only key reads, soft delete.
  • Adds an hourly AIIntegrationUsageSyncWorkflow that polls the Cursor Admin API per org/provider with bounded concurrency, rate-limit-aware paging, in-memory dedupe by SHA-256 event hash, and a single bulk insert into ClickHouse telemetry_logs.
  • Updates the dashboard cost surfaces to reflect Cursor + Claude Code coverage and adds an employee-level cost card.

Test plan

  • Backend unit tests pass (aiintegrations, background workflow/activities, audit, Cursor HTTP client)
  • Dashboard type-check + lint
  • Local end-to-end: save Cursor API key in org settings → trigger workflow → confirm rows in ClickHouse with auto-resolved gram_project_id
  • Verify watermark advances on success and does NOT advance on mid-poll failure
  • Verify 429 handling: simulated Retry-After causes activity sleep + heartbeat + resume
  • Verify workflow-ID mutex: concurrent coordinators don't spawn duplicate child workflows for the same provider + org
  • Verify dashboard cost queries include Cursor polling rows alongside hook data

🤖 Generated with Claude Code

Introduces an org-level AI Integrations product surface, with Cursor as the
first provider. Adds CRUD endpoints + dashboard settings UI for managing
provider integrations, an hourly Temporal workflow that polls the Cursor
Admin API for token/cost usage events, and ClickHouse ingestion via the
existing telemetry_logs schema so cost data shows up uniformly alongside
Claude Code hook data on the dashboard.

- New aiintegrations Goa service: getConfig / upsertConfig / deleteConfig
- ai_integration_configs + ai_integration_syncs tables with encrypted
  API key storage (AES-256-GCM) and high-water-mark polling
- AIIntegrationUsageSyncWorkflow coordinator + per-org/provider child
  workflow with stable workflow-ID mutex and 50min run budget
- Cursor HTTP client with rate-limit-aware paging (429 Retry-After)
- SHA-256 event hashing stored on each row for duplicate audit
- Dashboard: AIIntegrationsSection in org settings, cost copy +
  employee-level cost card
- SDK regenerated for the new endpoints

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@subomi subomi requested review from a team as code owners May 19, 2026 14:43
@vercel
Copy link
Copy Markdown

vercel Bot commented May 19, 2026

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

Project Deployment Actions Updated (UTC)
gram-docs-redirect Ready Ready Preview, Comment May 19, 2026 3:37pm

Request Review

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 19, 2026

🦋 Changeset detected

Latest commit: 7a0f895

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
server Minor
dashboard Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@subomi subomi added the preview Spawn a preview environment label May 19, 2026
@speakeasybot
Copy link
Copy Markdown
Collaborator

speakeasybot commented May 19, 2026

🚀 Preview Environment (PR #2923)

Preview URL: https://pr-2923.dev.getgram.ai

Component Status Details Updated (UTC)
✅ Database Ready Existing database reused 2026-05-20 12:00:01.
✅ Images Available Container images ready 2026-05-20 11:58:22.

Gram Preview Bot

aiIntegrationUsageSyncWorkflowID = "v1:ai-integration-usage-sync"
aiIntegrationUsageSyncScheduleID = "v1:ai-integration-usage-sync-schedule"
aiIntegrationUsageSyncScheduledWorkflowID = aiIntegrationUsageSyncScheduleID + "/scheduled"
aiIntegrationUsageSyncInterval = time.Hour
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Based on my initial reading, I think this workflow isn't set up quite right. Right now the schedule triggers a single workflow every hour. That one workflow them loops over every org and triggers a sync. This means that when I add in my cursor api key, it might take up to an hour before any data actually appears.

What should happen instead:

  • The schedule should trigger the workflow every ~5 minutes (or something)
  • The lastPolledAt should determine which orgs actually get syncs run in that particular job. This has the advantage of staggering load
  • The workflow should be triggerable outside the schedule for a certain org, e.g. whenever a new api key is created trigger the workflow for JUST that org. Or if we add a manual button to the UI

}
}

for len(active) < aiIntegrationUsageSyncConcurrency {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This feels like the kind of thing that should be handled natively by temporal. Is that not possible?

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

Labels

preview Spawn a preview environment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants