Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Jgk2k4/eng 84 import data from platforms#150

Closed
george-bobby wants to merge 2 commits intomainfrom
jgk2k4/eng-84-import-data-from-platforms
Closed

Jgk2k4/eng 84 import data from platforms#150
george-bobby wants to merge 2 commits intomainfrom
jgk2k4/eng-84-import-data-from-platforms

Conversation

@george-bobby
Copy link
Member

Recordings

📹 View Recording

Code Quality

  • Performed a proper self-review of my own code
  • My changes generate no new warnings or errors
  • All the AI slop has been removed using /deslop
  • I have ran bun type and ensured type safety
  • I have ran bun check and passed biome checks

Performance & Security

  • I have checked for potential performance impacts
  • I have updated Convex schema if needed
  • I have considered security implications
  • I have not introduced any console.log or debug code
  • I have handled errors appropriately
  • I have not added unnecessary dependencies
  • I have run bun i after adding dependencies

PR Comments

  • All CodeRabbitAI review comments have been resolved
  • All Copilot review comments have been resolved
  • All DeepSource static analysis comments have been resolved
  • All Vercel build and deployment comments have been addressed

Reviewer Checklist:

  • Code quality and style
  • Performance considerations
  • Security implications

Copilot AI review requested due to automatic review settings February 27, 2026 04:07
@linear
Copy link

linear bot commented Feb 27, 2026

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Cache: Disabled due to Reviews > Disable Cache setting

📥 Commits

Reviewing files that changed from the base of the PR and between 17efb96 and 3370167.

⛔ Files ignored due to path filters (1)
  • convex/_generated/api.d.ts is excluded by !**/_generated/**
📒 Files selected for processing (48)
  • README.md
  • convex/assistant/agent.ts
  • convex/assistant/context.ts
  • convex/assistant/errorHandling.test.ts
  • convex/assistant/errorHandling.ts
  • convex/assistant/tools/composioTools.ts
  • convex/assistant/tools/index.ts
  • convex/assistant/tools/internalTools.ts
  • convex/assistantChat.ts
  • convex/assistantComposioTools.ts
  • convex/assistantTools.ts
  • convex/chatbot.ts
  • convex/http.ts
  • convex/importIntegrations.ts
  • convex/importPipeline.ts
  • convex/integrations.ts
  • convex/linearImportProvider.ts
  • convex/onesignal.ts
  • convex/ragchat.ts
  • convex/schema.ts
  • convex/slackImportProvider.ts
  • convex/testComposio.ts
  • convex/todoistImportProvider.ts
  • convex/tsconfig.json
  • src/app/api/assistant/chatbot/route.ts
  • src/app/api/assistant/chatbot/stream/route.ts
  • src/app/api/assistant/composio/tools/route.ts
  • src/app/api/import/linear/callback/route.ts
  • src/app/api/import/todoist/callback/route.ts
  • src/app/workspace/[workspaceId]/manage/page.tsx
  • src/features/dashboard/components/dashboard-chatbot.tsx
  • src/features/imports/api/use-initiate-linear-oauth.ts
  • src/features/imports/api/use-initiate-todoist-oauth.ts
  • src/features/imports/api/use-start-linear-import.ts
  • src/features/imports/api/use-start-todoist-import.ts
  • src/features/manage/import-data-management.tsx
  • src/lib/ai-cache.ts
  • src/lib/ai-confirmation-logic.ts
  • src/lib/ai-multi-step-planner.ts
  • src/lib/ai-query-classifier.ts
  • src/lib/ai-tool-selector.ts
  • src/lib/assistant-orchestration.ts
  • src/lib/unified-tool-manager.ts
  • src/middleware.ts
  • tests/test-assistant-message.ts
  • tests/test-assistant.ts
  • tests/test-message.ts
  • tests/test-tool-schemas.ts

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for Todoist and Linear imports alongside Slack
    • Implemented real-time notifications for import completion via push and in-app alerts
    • Added AI-driven confirmation prompts for tool actions before execution
    • Expanded import configuration options per platform with customizable filters
  • Improvements

    • Enhanced OAuth callback handling for improved reliability
    • Updated workspace admin interface to reflect new AI integration capabilities
  • Documentation

    • Corrected Next.js development server URL in setup instructions

Walkthrough

This PR introduces multi-provider import capabilities for Linear and Todoist alongside existing Slack support, adds comprehensive OAuth flows, implements a reusable import pipeline infrastructure, expands the assistant agent with additional tools and context, and includes new database tables for tracking imported data across platforms.

Changes

Cohort / File(s) Summary
Core Import Infrastructure
convex/importPipeline.ts
Introduces foundational import pipeline types and interfaces (ImportProvider, ImportContext, ImportConfig, RateLimiter, retry logic) supporting cross-platform import integrations with pagination, rate limiting, and idempotency utilities.
Import Integrations API
convex/importIntegrations.ts
Adds OAuth initiation mutations (initiateTodoistOAuth, initiateLinearOAuth), import start mutations for Todoist and Linear, token storage mutations, result/channel/message/file storage mutations, and import job processing with multi-provider support and OneSignal notifications.
Import Provider Implementations
convex/linearImportProvider.ts, convex/todoistImportProvider.ts, convex/slackImportProvider.ts
Implements platform-specific import providers with GraphQL/REST API integration, data fetching, rate limiting, retry logic, idempotent storage, and end-to-end import orchestration for Linear, Todoist, and Slack platforms.
Database Schema Updates
convex/schema.ts
Adds three new metadata tables (import_channel_metadata, import_message_metadata, import_file_metadata) for tracking external-to-internal ID mappings; expands import_jobs.config with platform-specific options.
OAuth Callback Routes
src/app/api/import/linear/callback/route.ts, src/app/api/import/todoist/callback/route.ts
Implements Next.js API routes for Linear and Todoist OAuth callbacks with code exchange, state validation, error handling, and redirect logic.
Convex HTTP Callbacks
convex/http.ts
Adds backend OAuth callback handlers for Todoist and Linear; updates Slack callback to support flexible siteUrl resolution with fallback defaults.
Notifications Integration
convex/onesignal.ts
Adds sendImportNotification and sendInAppImportNotification server actions for OneSignal push and in-app notifications on import completion.
Assistant Agent Enhancements
convex/assistant/agent.ts, convex/assistant/context.ts, convex/assistant/tools/internalTools.ts, convex/assistant/tools/composioTools.ts, convex/assistant/tools/index.ts
Reorders imports, adds tools and stepCountIs configuration to agent initialization, expands BASE_INSTRUCTIONS, adds userId to AssistantCtx type, and reformats tool descriptions.
Assistant Core Logic
convex/assistantChat.ts
Adds imports for openai and AI toolkit; minor formatting adjustments in tool logging and mutation calls; preserves public API signatures.
AI Confirmation and Classification
src/app/api/assistant/chatbot/route.ts, src/lib/ai-confirmation-logic.ts, src/lib/ai-query-classifier.ts
Integrates AI-driven action confirmation, query classification, and user confirmation parsing into chatbot route; updates schema formatting and error handling logic.
Import UI Components and Hooks
src/features/imports/api/use-initiate-*.ts, src/features/imports/api/use-start-*.ts, src/features/manage/import-data-management.tsx
Adds React hooks for Linear and Todoist OAuth and import initiation (useInitiateLinearOAuth, useInitiateTodoistOAuth, useStartLinearImport, useStartTodoistImport); expands ImportDataManagement component with multi-platform support and per-platform configuration options.
Tool Selection and Orchestration
src/lib/ai-tool-selector.ts, src/lib/unified-tool-manager.ts, src/lib/assistant-orchestration.ts
Expands AI tool selection prompt with additional guidelines; minor formatting adjustments in tool caching and retrieval logic.
Middleware and Routing
src/middleware.ts
Adds OAuth callback paths (Slack, Todoist, Linear) to auth bypass list in middleware.
Minor Formatting and Cleanup
README.md, convex/assistantComposioTools.ts, convex/assistantTools.ts, convex/chatbot.ts, convex/errorHandling.ts, convex/errorHandling.test.ts, convex/ragchat.ts, convex/testComposio.ts, convex/integrations.ts, convex/tsconfig.json, src/app/api/assistant/composio/tools/route.ts, src/app/api/assistant/chatbot/stream/route.ts, src/features/dashboard/components/dashboard-chatbot.tsx, src/lib/ai-cache.ts, src/lib/ai-multi-step-planner.ts, tests/test-assistant-message.ts, tests/test-assistant.ts, tests/test-message.ts, tests/test-tool-schemas.ts
String formatting, whitespace adjustments, import reordering, unused parameter naming (e.g., _ctx), and minor refactoring without functional changes.

Sequence Diagram(s)

sequenceDiagram
    participant User as User/Browser
    participant NextApp as Next.js App
    participant OAuth as OAuth Provider<br/>(Linear/Todoist)
    participant ConvexHTTP as Convex HTTP<br/>Callback
    participant ConvexMutation as Convex<br/>Mutation

    User->>NextApp: Click "Connect [Platform]"
    NextApp->>ConvexMutation: Call initiate[Platform]OAuth<br/>(workspaceId)
    ConvexMutation->>ConvexMutation: Validate workspace membership<br/>Load credentials
    ConvexMutation->>ConvexMutation: Build redirect URI + CSRF state
    ConvexMutation-->>NextApp: Return OAuth URL
    NextApp->>OAuth: Redirect to OAuth flow
    OAuth->>User: Show consent screen
    User->>OAuth: Grant permissions
    OAuth->>NextApp: Redirect with code + state
    NextApp->>ConvexHTTP: GET /import/[platform]/callback<br/>?code=...&state=...
    ConvexHTTP->>OAuth: Exchange code for token
    OAuth-->>ConvexHTTP: Return access/refresh tokens
    ConvexHTTP->>ConvexMutation: Call store[Platform]Connection<br/>(tokens, metadata)
    ConvexMutation->>ConvexMutation: Persist connection record
    ConvexMutation-->>ConvexHTTP: Success
    ConvexHTTP->>NextApp: 302 Redirect to workspace
    NextApp->>User: Connection complete
Loading
sequenceDiagram
    participant User as User
    participant UI as UI Component
    participant ConvexMutation as Convex<br/>start[Platform]Import
    participant BackendJob as Background<br/>Job Runner
    participant Provider as [Platform]<br/>ImportProvider
    participant Storage as Storage &<br/>Database
    participant Notify as OneSignal<br/>Notifications

    User->>UI: Click "Start Import"<br/>+ configuration
    UI->>ConvexMutation: Call start[Platform]Import<br/>(workspaceId, config)
    ConvexMutation->>ConvexMutation: Validate member<br/>Load connection
    ConvexMutation->>Storage: Create import job record<br/>with config
    ConvexMutation-->>UI: Return jobId
    UI->>User: "Import started..."

    BackendJob->>Provider: process[Platform]Import(jobId)
    Provider->>Provider: Validate connection
    Provider->>Provider: Fetch workspace metadata
    Provider->>Provider: Fetch users, channels/projects
    Provider->>Storage: Store imported channels<br/>with external ID mapping
    Provider->>Provider: Fetch messages (paginated)
    Provider->>Storage: Store imported messages<br/>with idempotency keys
    Provider->>Storage: Update progress<br/>& job status
    BackendJob->>Notify: sendImportNotification<br/>(status, counts)
    Notify-->>User: Push notification<br/>Import complete!
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jgk2k4/eng-84-import-data-from-platforms

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds multi-platform data import support (Todoist + Linear alongside Slack) by introducing a reusable Convex import pipeline, wiring OAuth callback routes, and exposing new UI controls to connect/start imports from the workspace manage area.

Changes:

  • Introduces a reusable Convex import pipeline and new import providers for Slack/Todoist/Linear.
  • Adds OAuth callback handling (Next.js + Convex HTTP routes) and updates middleware to allow callback routes.
  • Expands import UI and schema to support platform-specific import configuration and metadata tracking.

Reviewed changes

Copilot reviewed 48 out of 49 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
tests/test-tool-schemas.ts Formatting/cleanup in tool schema test output.
tests/test-message.ts Minor formatting + template literal cleanup for test conversation IDs.
tests/test-assistant.ts Import order + formatting changes in assistant test harness.
tests/test-assistant-message.ts Formatting cleanup for test client + separator output.
src/middleware.ts Allows OAuth callback routes to bypass auth middleware.
src/lib/unified-tool-manager.ts Refactors typings/import order and formatting; minor logging formatting.
src/lib/assistant-orchestration.ts Formats connected-app tool policy prompt generation.
src/lib/ai-tool-selector.ts Formatting + minor refactors for caching/filtering/tool catalog prompt.
src/lib/ai-query-classifier.ts Formatting + minor refactors; keeps AI classification + fallback behavior.
src/lib/ai-multi-step-planner.ts Formatting + minor refactors for planning/execution logging and loops.
src/lib/ai-confirmation-logic.ts Formatting + minor refactors for prompt building and fallbacks.
src/lib/ai-cache.ts Formats periodic cache eviction interval setup.
src/features/manage/import-data-management.tsx Enables Todoist/Linear in UI, adds config toggles, and wires new connect/import hooks.
src/features/imports/api/use-start-todoist-import.ts New hook to start Todoist import via Convex mutation.
src/features/imports/api/use-start-linear-import.ts New hook to start Linear import via Convex mutation.
src/features/imports/api/use-initiate-todoist-oauth.ts New hook to initiate Todoist OAuth via Convex mutation.
src/features/imports/api/use-initiate-linear-oauth.ts New hook to initiate Linear OAuth via Convex mutation.
src/features/dashboard/components/dashboard-chatbot.tsx Minor formatting / prop ordering tweak.
src/app/workspace/[workspaceId]/manage/page.tsx Renames “Integrations” tab label to “AI Integrations”.
src/app/api/import/todoist/callback/route.ts New Next.js route that redirects OAuth callback params to Convex handler.
src/app/api/import/linear/callback/route.ts New Next.js route that redirects OAuth callback params to Convex handler.
src/app/api/assistant/composio/tools/route.ts Minor formatting; adjusts import order and tool fetch call formatting.
src/app/api/assistant/chatbot/stream/route.ts Import ordering/formatting and minor response formatting for streaming route.
src/app/api/assistant/chatbot/route.ts Import ordering/formatting and minor response formatting for non-stream route.
convex/tsconfig.json Formatting-only adjustments.
convex/todoistImportProvider.ts New Todoist import provider + executor using shared import pipeline.
convex/testComposio.ts Minor cleanup (unused ctx) + formatting.
convex/slackImportProvider.ts New Slack import provider + executor using shared import pipeline.
convex/schema.ts Adds import config fields + new import metadata tables (channel/message/file).
convex/ragchat.ts Formatting-only changes in semantic reranking logic.
convex/onesignal.ts Adds OneSignal notification internal actions (push + placeholder in-app).
convex/linearImportProvider.ts New Linear import provider + executor using shared import pipeline.
convex/integrations.ts Removes noisy debug logs and formats workspace account query.
convex/importPipeline.ts Introduces shared import pipeline types/utilities (rate limiting, retry, idempotency, etc.).
convex/http.ts Adds Convex HTTP OAuth callbacks for Todoist/Linear; adjusts site URL sourcing.
convex/chatbot.ts Formatting-only changes to tool selection/external audit logging.
convex/assistantTools.ts Formatting-only tweaks in date range filters.
convex/assistantComposioTools.ts Formatting-only changes + minor cleanup of unused catch vars.
convex/assistantChat.ts Formatting-only changes and minor log formatting adjustments.
convex/assistant/tools/internalTools.ts Formatting-only changes to zod tool argument schemas.
convex/assistant/tools/index.ts Import order tweak for tool exports.
convex/assistant/tools/composioTools.ts Import ordering/formatting changes.
convex/assistant/errorHandling.ts Formatting-only changes for long error message string.
convex/assistant/errorHandling.test.ts Formatting-only changes in assertions.
convex/assistant/context.ts Removes unused imports + formats mapping of recent tools.
convex/assistant/agent.ts Import order/formatting for agent construction.
convex/_generated/api.d.ts Updated generated API typings for newly added Convex modules.
README.md Updates local dev URL in setup instructions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +723 to +725
disabled={
startSlackImport.isPending || startTodoistImport.isPending
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The “Start Import” button is disabled for Slack/Todoist pending states but not for Linear. This allows duplicate Linear import submissions while startLinearImport is in-flight. Include startLinearImport.isPending in the disabled condition (and ideally gate based on selectedPlatform).

Copilot uses AI. Check for mistakes.
const siteUrl =
process.env.NEXT_PUBLIC_APP_URL ||
process.env.SITE_URL ||
"https://localhost:3000";
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Defaulting siteUrl to https://localhost:3000 is likely incorrect for local development (most dev servers run on http://localhost:3000). This affects OAuth redirect URIs and can break the auth flow locally. Prefer http://localhost:3000 as the fallback (or require NEXT_PUBLIC_APP_URL/SITE_URL to be set).

Suggested change
"https://localhost:3000";
"http://localhost:3000";

Copilot uses AI. Check for mistakes.

5. **Run the app**
- Terminal 1 (Next.js): `bun next` → open [http://localhost:3000](http://localhost:3000)
- Terminal 1 (Next.js): `bun next` → open [https://localhost:3000](https://localhost:3000)
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The README instructs opening https://localhost:3000, but the dev server is typically http://localhost:3000 unless TLS is configured. This can confuse contributors and break OAuth redirect assumptions in local dev.

Suggested change
- Terminal 1 (Next.js): `bun next` → open [https://localhost:3000](https://localhost:3000)
- Terminal 1 (Next.js): `bun next` → open [http://localhost:3000](http://localhost:3000)

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +34
// Get user's OneSignal player ID from preferences or external player table
// For now, we'll broadcast to all users in the workspace
// In production, you'd store player IDs per user
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

This comment says “broadcast to all users in the workspace”, but the payload targets include_aliases.external_user_id for a single userId and sets include_player_ids to an empty array. Either update the comment to match the current behavior or implement actual workspace-wide targeting (e.g., by maintaining and supplying player IDs / tags / segments).

Suggested change
// Get user's OneSignal player ID from preferences or external player table
// For now, we'll broadcast to all users in the workspace
// In production, you'd store player IDs per user
// Target this notification to the specific user via OneSignal aliasing
// (external_user_id). Workspace-wide broadcasting would require
// maintaining player IDs / tags / segments for all workspace members.

Copilot uses AI. Check for mistakes.
Comment on lines +698 to +703
const _messageId = await ctx.runMutation<string>(
internal.importIntegrations.storeImportedMessage,
{
workspaceId: ctx.workspaceId,
memberId: ctx.memberId,
channelId: "" as any, // Not needed for replies
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

storeImportedMessage requires a valid channelId (Convex validator is v.id("channels")), but comment replies are being stored with channelId: "" as any. This will fail at runtime and also loses the channel association for replies. Pass the parent task's channelId (projectMap lookup) when storing comments, or change the storage API to accept optional channelId for replies and derive it from the parent message.

Suggested change
const _messageId = await ctx.runMutation<string>(
internal.importIntegrations.storeImportedMessage,
{
workspaceId: ctx.workspaceId,
memberId: ctx.memberId,
channelId: "" as any, // Not needed for replies
// Derive the channelId from the Todoist project associated with this comment
// so that replies are stored in the same channel as their parent task.
const projectChannel: ExternalChannel | undefined =
ctx.projectMap && comment.project_id
? ctx.projectMap.get(comment.project_id)
: undefined;
if (!projectChannel || !projectChannel.channelId) {
throw new Error(
`Missing channel mapping for Todoist project ${comment.project_id} when storing comment ${comment.id}`
);
}
const _messageId = await ctx.runMutation<string>(
internal.importIntegrations.storeImportedMessage,
{
workspaceId: ctx.workspaceId,
memberId: ctx.memberId,
channelId: projectChannel.channelId,

Copilot uses AI. Check for mistakes.
Comment on lines +193 to +210
const url = "https://api.todoist.com/rest/v2/projects";
console.log("[TodoistValidate] Calling URL:", url);
console.log("[TodoistValidate] Token present:", !!ctx.accessToken);

try {
await ctx.log("info", "Validating Todoist connection");
// Test the connection by fetching projects (lightweight validation)
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${ctx.accessToken}`,
},
});

console.log("[TodoistValidate] Response status:", response.status);

if (!response.ok) {
const errorText = await response.text();
console.log("[TodoistValidate] Error response:", errorText);
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

validateConnection contains multiple console.log statements (URL, token presence, response status, error text, exception). This will be noisy in production Convex logs and may leak operational details. Prefer ctx.log with appropriate level, and avoid logging token presence/error bodies unless explicitly needed for debugging behind a flag.

Copilot uses AI. Check for mistakes.

constructor() {
this.rateLimiter = new RateLimiter({
minDelay: 100, // Todoist allows ~50 requests per minute
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

The rate limiter configuration is internally inconsistent: minDelay: 100ms implies up to ~600 requests/minute, but the comment says Todoist allows ~50 requests/minute. Either increase minDelay (e.g., ~1200ms) or update the comment so it matches the intended request rate to avoid accidental 429s and confusion.

Suggested change
minDelay: 100, // Todoist allows ~50 requests per minute
minDelay: 1200, // ~50 requests per minute

Copilot uses AI. Check for mistakes.
{
workspaceId: ctx.workspaceId,
memberId: ctx.memberId,
channelId: "" as any,
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

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

Comment replies are stored with channelId: "" as any, but storeImportedMessage validates channelId as v.id("channels"). This will throw at runtime. Replies should carry the same channelId as the parent issue/team channel (look it up when calling storeComment, or include it in the function signature).

Suggested change
channelId: "" as any,
channelId: ctx.channelId as any,

Copilot uses AI. Check for mistakes.
@deepsource-io
Copy link
Contributor

deepsource-io bot commented Feb 27, 2026

DeepSource Code Review

We reviewed changes in 17efb96...3370167 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

Code Review Summary

Analyzer Status Updated (UTC) Details
JavaScript Feb 27, 2026 4:11a.m. Review ↗

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.

3 participants