Skip to content

feat: track web or api too#97

Merged
techeng322 merged 5 commits intomainfrom
techengme/myc-4487-track-channel-including-web-api
Mar 25, 2026
Merged

feat: track web or api too#97
techeng322 merged 5 commits intomainfrom
techengme/myc-4487-track-channel-including-web-api

Conversation

@techeng322
Copy link
Copy Markdown
Collaborator

@techeng322 techeng322 commented Mar 25, 2026

Summary by CodeRabbit

  • New Features

    • Requests now detect and propagate a channel (web, api, sms, telegram) so created moments and notifications reflect origin.
  • Behavior Changes

    • Success notifications use channel-aware URL paths; Telegram handlers post simplified success messages without extra logging/triggering.
    • Moment creation triggers downstream messaging for non-SMS channels.
  • Bug Fixes

    • Background task failures are caught and no longer break flows.
  • Tests

    • Added/updated tests for channel detection, URL parsing, notification behavior, and moment processing.
  • Chores

    • Database enum extended with new client channel values.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 25, 2026

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

Project Deployment Actions Updated (UTC)
in-process-api Ready Ready Preview Mar 25, 2026 2:50pm

Request Review

@supabase
Copy link
Copy Markdown

supabase Bot commented Mar 25, 2026

Updates to Preview Branch (techengme/myc-4487-track-channel-including-web-api) ↗︎

Deployments Status Updated
Database Wed, 25 Mar 2026 14:49:33 UTC
Services Wed, 25 Mar 2026 14:49:33 UTC
APIs Wed, 25 Mar 2026 14:49:33 UTC

Tasks are run on every commit but only new migration files are pushed.
Close and reopen this PR if you want to apply changes from existing seed or migration files.

Tasks Status Updated
Configurations Wed, 25 Mar 2026 14:49:35 UTC
Migrations Wed, 25 Mar 2026 14:49:35 UTC
Seeding Wed, 25 Mar 2026 14:49:35 UTC
Edge Functions Wed, 25 Mar 2026 14:49:35 UTC

View logs for this Workflow Run ↗︎.
Learn more about Supabase for Git ↗︎.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dc800037-3158-4ce7-87db-9488435497bb

📥 Commits

Reviewing files that changed from the base of the PR and between c878284 and 0060247.

📒 Files selected for processing (1)
  • src/lib/phones/createMomentFromMedia.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/phones/createMomentFromMedia.ts

📝 Walkthrough

Walkthrough

Adds channel detection and propagation into moment creation and messaging flows: origin-based channel inference, new processMessageMoment to log and conditionally trigger tasks, schema and DB enum updates for new client values, and multiple test updates and simplifications.

Changes

Cohort / File(s) Summary
Docs & Schema
CLAUDE.md, src/lib/schema/createMomentSchema.ts
Added guidance text to CLAUDE.md; extended createMoment schema with optional `channel: 'sms'
API Route
src/app/api/moment/create/route.ts
POST handler now derives channel from request headers and calls createMoment with { ...data, channel }.
Channel Detection
src/lib/moment/getChannelFromReqHeader.ts, src/lib/moment/__tests__/getChannelFromReqHeader.test.ts
New helper maps Origin header to 'web' or 'api'; tests added.
Moment Core & Orchestration
src/lib/moment/createMoment.ts, src/lib/moment/processMessageMoment.ts, src/lib/moment/__tests__/processMessageMoment.test.ts
createMoment now invokes new processMessageMoment which logs a success message and conditionally triggers process-message-moment (errors caught); tests added.
Message Logging & Types
src/lib/messages/logMessage.ts, src/lib/supabase/types.ts, src/lib/supabase/migrations/...extend_message_client_enum.sql
Expanded message client union to include 'web' and 'api'; updated TS types/constants and DB enum migration.
Message Parsing & Tests
src/lib/messages/getMomentFromMessage.ts, src/lib/messages/__tests__/getMomentFromMessage.test.ts, src/lib/messages/__tests__/logMessage.test.ts
Simplified URL regex to match path-only patterns, lowercased addresses; added/updated parsing and client-forwarding tests.
Removed/Refactored Message Flow
src/lib/messages/processMomentMessage.ts (deleted), related tests
Removed legacy messages/processMomentMessage implementation and adjusted dependent tests.
Phones Integration
src/lib/phones/createMomentFromMedia.ts, src/lib/phones/processMmsMedia.ts
createMomentFromMedia now supplies channel: 'sms'; MMS flow sends SMS directly (uses SITE_ORIGINAL_URL/IS_TESTNET) instead of calling removed helper.
Telegram Integration & Handlers
src/lib/telegram/chat/..., src/lib/telegram/chat/__tests__/*
createMomentFromTelegramAttachment supplies channel: 'telegram'; handleMomentSuccess signature simplified (dropped artistAddress) and posts /collect/ URL; call sites and tests updated.
Trigger.dev Handling
src/lib/trigger.dev/triggerMuxMigration.ts, src/lib/trigger.dev/__tests__/triggerMuxMigration.test.ts
Wrapped tasks.trigger in try/catch and log failures; tests adjusted to expect no throw.
Tests Added/Removed
src/lib/messages/__tests__/processMomentMessage.test.ts (deleted), new tests under src/lib/moment/* and other updates
Deleted one legacy test file; added suites for channel detection and processMessageMoment; updated many tests to reflect new signatures/behavior.

Sequence Diagram

sequenceDiagram
    participant Client
    participant API as API Route<br/>/api/moment/create
    participant GetChannel as getChannelFromReqHeader
    participant CreateMoment as createMoment
    participant ProcessMsg as processMessageMoment
    participant LogMsg as logMessage
    participant TaskTrigger as tasks.trigger

    Client->>API: POST /api/moment/create (with Origin)
    API->>GetChannel: getChannelFromReqHeader(req)
    GetChannel-->>API: channel ('web' / 'api' / default)
    API->>CreateMoment: createMoment({...data, channel})
    CreateMoment-->>API: { contractAddress, tokenId }
    CreateMoment->>ProcessMsg: processMessageMoment({contractAddress, tokenId, artistAddress, channel})
    ProcessMsg->>LogMsg: logMessage(message, 'assistant', artistAddress, channel)
    LogMsg-->>ProcessMsg: messageId (or null)
    alt messageId exists
        ProcessMsg->>TaskTrigger: tasks.trigger('process-message-moment', { messageId })
        TaskTrigger-->>ProcessMsg: (success or error caught)
    end
    ProcessMsg-->>CreateMoment: (resolves)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇
I hopped through headers, sniffed the breeze,
Mapped web and SMS with nimble ease,
I logged a moment, nudged a task,
Errors caught, no questions asked,
A tidy hop — then back to meadows!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: track web or api too' directly describes the main change: extending message tracking/logging to support 'web' and 'api' channels in addition to 'sms' and 'telegram'.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch techengme/myc-4487-track-channel-including-web-api

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
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (3)
src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts (1)

28-34: Consider removing this redundant test case.

This test is essentially a subset of the first test—if thread.post is called with the correct arguments (verified in the first test), it will also be called exactly once. The two tests exercise the same code path with identical inputs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts` around lines 28
- 34, Remove the redundant test "still posts the success message even when
thread.post is called once" from
src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts; it duplicates the
first test's assertions because verifying thread.post was called with the
correct arguments already implies it was called once. Locate the test by its
description and references to makeThread(), handleMomentSuccess, and
thread.post, and delete that entire it(...) block to avoid duplicate coverage.
src/lib/moment/__tests__/processMessageMoment.test.ts (1)

23-43: Consider adding a test case for undefined channel.

The channel parameter is optional in processMessageMoment. Adding a test case where channel is omitted would help verify the default behavior and ensure the type cast doesn't cause issues.

it('handles undefined channel gracefully', async () => {
  await processMessageMoment({
    contractAddress: CONTRACT,
    tokenId: '7',
    artistAddress: ARTIST,
    // channel omitted
  });

  expect(logMessage).toHaveBeenCalledWith(
    expect.any(Array),
    'assistant',
    ARTIST,
    expect.anything() // or the expected default
  );
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/moment/__tests__/processMessageMoment.test.ts` around lines 23 - 43,
Add a unit test that calls processMessageMoment without the optional channel to
verify default handling and avoid the type cast issue: create a new it block
that calls processMessageMoment({ contractAddress: CONTRACT, tokenId: '7',
artistAddress: ARTIST }) and assert that logMessage was invoked with the
expected message array, 'assistant', ARTIST, and either the concrete default
channel value or expect.anything()/expect.any(String) for the channel; reference
processMessageMoment and logMessage to locate where to add the test.
src/lib/moment/processMessageMoment.ts (1)

19-19: Consider lowercasing contractAddress in the URL.

The coding guidelines specify normalizing addresses to lowercase. While the Address type from viem may already be checksummed, lowercasing it in the URL ensures consistency with other parts of the codebase (e.g., the test file getMomentFromMessage.test.ts verifies that parsed addresses are lowercased).

♻️ Proposed fix
- const successMessage = `✅ Moment created! ${SITE_ORIGINAL_URL}/${path}/${chain}:${contractAddress}/${tokenId}`;
+ const successMessage = `✅ Moment created! ${SITE_ORIGINAL_URL}/${path}/${chain}:${contractAddress.toLowerCase()}/${tokenId}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/moment/processMessageMoment.ts` at line 19, The success URL embeds
contractAddress without normalizing case; update the successMessage construction
in processMessageMoment (the line building successMessage using
SITE_ORIGINAL_URL, path, chain, contractAddress, tokenId) to use a lowercased
contract address (e.g., replace contractAddress with
contractAddress.toLowerCase()) so the emitted URL is normalized to lowercase
like other parts of the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/moment/createMoment.ts`:
- Around line 85-90: The call to processMessageMoment is passing input.channel
which may be undefined and later is unsafely cast inside processMessageMoment
(see logMessage usage in processMessageMoment.ts), so change the call site
(createMoment -> processMessageMoment) or the log invocation to provide a safe
default channel (e.g., 'api' or 'web') when input.channel is undefined; update
references around processMessageMoment and logMessage to use the fallback value
(instead of blind casting) so the type is always one of 'sms' | 'telegram' |
'web' | 'api'.

In `@src/lib/moment/getChannelFromReqHeader.ts`:
- Around line 3-9: getChannelFromReqHeader currently classifies requests as
'web' only if origin includes 'inprocess.world' or 'stayinprocess.vercel.app',
missing the testnet frontend origin and causing misclassification; update
getChannelFromReqHeader (function) to also check for
'in-process-git-test-sweetmantechs-projects.vercel.app' OR refactor to reuse the
existing trusted-origin constant/pattern (e.g., SITE_ORIGINAL_URL or the
constant defined in src/lib/consts.ts) so the testnet domain is included in the
trusted domains check and requests from testnet are returned as 'web'.

In `@src/lib/moment/processMessageMoment.ts`:
- Around line 21-26: The code unsafely casts the optional channel to the union
type when calling logMessage; instead, validate and normalize channel before
calling logMessage (e.g., check if channel is one of
'sms'|'telegram'|'web'|'api' and otherwise fall back to the default 'sms'), then
pass that validated value to logMessage (referencing the channel variable and
the logMessage call where messageId is created) so the function never receives
undefined or an unexpected string.

In `@src/lib/schema/createMomentSchema.ts`:
- Line 58: The channel field currently allows any string; replace
z.string().optional() in the moment schema (e.g., createMomentSchema /
MomentSchema) with a constrained enum like
z.enum(['sms','telegram','web','api']).optional() so only supported channels
pass validation, and if you need custom logic add a .superRefine() on the schema
to emit a clear validation error for unsupported values or cross-field checks.

In `@src/lib/trigger.dev/__tests__/triggerMuxMigration.test.ts`:
- Line 84: The test currently asserts await
expect(triggerMuxMigration(baseInput)).resolves.not.toThrow(), which is
semantically wrong for a Promise<void>; update the assertion to await
expect(triggerMuxMigration(baseInput)).resolves.toBeUndefined() so the test
checks the resolved value of the Promise returned by triggerMuxMigration (use
the same baseInput and test file triggerMuxMigration.test.ts and the
triggerMuxMigration import to locate the test).

---

Nitpick comments:
In `@src/lib/moment/__tests__/processMessageMoment.test.ts`:
- Around line 23-43: Add a unit test that calls processMessageMoment without the
optional channel to verify default handling and avoid the type cast issue:
create a new it block that calls processMessageMoment({ contractAddress:
CONTRACT, tokenId: '7', artistAddress: ARTIST }) and assert that logMessage was
invoked with the expected message array, 'assistant', ARTIST, and either the
concrete default channel value or expect.anything()/expect.any(String) for the
channel; reference processMessageMoment and logMessage to locate where to add
the test.

In `@src/lib/moment/processMessageMoment.ts`:
- Line 19: The success URL embeds contractAddress without normalizing case;
update the successMessage construction in processMessageMoment (the line
building successMessage using SITE_ORIGINAL_URL, path, chain, contractAddress,
tokenId) to use a lowercased contract address (e.g., replace contractAddress
with contractAddress.toLowerCase()) so the emitted URL is normalized to
lowercase like other parts of the codebase.

In `@src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts`:
- Around line 28-34: Remove the redundant test "still posts the success message
even when thread.post is called once" from
src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts; it duplicates the
first test's assertions because verifying thread.post was called with the
correct arguments already implies it was called once. Locate the test by its
description and references to makeThread(), handleMomentSuccess, and
thread.post, and delete that entire it(...) block to avoid duplicate coverage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f69c2167-d95e-486e-8ec1-34bb422bf66a

📥 Commits

Reviewing files that changed from the base of the PR and between 9e50b42 and a6ef146.

📒 Files selected for processing (29)
  • CLAUDE.md
  • src/app/api/moment/create/route.ts
  • src/lib/messages/__tests__/getMomentFromMessage.test.ts
  • src/lib/messages/__tests__/logMessage.test.ts
  • src/lib/messages/__tests__/processMomentMessage.test.ts
  • src/lib/messages/getMomentFromMessage.ts
  • src/lib/messages/logMessage.ts
  • src/lib/messages/processMomentMessage.ts
  • src/lib/moment/__tests__/createMoment.test.ts
  • src/lib/moment/__tests__/getChannelFromReqHeader.test.ts
  • src/lib/moment/__tests__/processMessageMoment.test.ts
  • src/lib/moment/createMoment.ts
  • src/lib/moment/getChannelFromReqHeader.ts
  • src/lib/moment/processMessageMoment.ts
  • src/lib/phones/createMomentFromMedia.ts
  • src/lib/phones/processMmsMedia.ts
  • src/lib/schema/createMomentSchema.ts
  • src/lib/supabase/migrations/20260325000000_extend_message_client_enum.sql
  • src/lib/supabase/types.ts
  • src/lib/telegram/chat/__tests__/createMomentFromTelegramAttachment.test.ts
  • src/lib/telegram/chat/__tests__/handleMomentSuccess.test.ts
  • src/lib/telegram/chat/__tests__/processTelegramMedia.test.ts
  • src/lib/telegram/chat/createMomentFromTelegramAttachment.ts
  • src/lib/telegram/chat/handleMomentSuccess.ts
  • src/lib/telegram/chat/handlers/__tests__/onNewMention.test.ts
  • src/lib/telegram/chat/handlers/onNewMention.ts
  • src/lib/telegram/chat/processTelegramMedia.ts
  • src/lib/trigger.dev/__tests__/triggerMuxMigration.test.ts
  • src/lib/trigger.dev/triggerMuxMigration.ts

Comment on lines +85 to +90
await processMessageMoment({
contractAddress,
tokenId,
artistAddress: input.account,
channel: input.channel,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify how processMessageMoment handles undefined channel
cat src/lib/moment/processMessageMoment.ts

Repository: sweetmantech/In-Process-API

Length of output: 1091


Unsafe type cast when channel is undefined.

input.channel can be undefined (per createMomentSchema), but line 25 of processMessageMoment.ts casts it directly to 'sms' | 'telegram' | 'web' | 'api' without null/undefined handling. While the function defensively checks channel === 'sms' for path logic, it unsafely casts the value when passing to logMessage.

Default to a fallback channel to ensure type safety:

Proposed fix
  await processMessageMoment({
    contractAddress,
    tokenId,
    artistAddress: input.account,
-   channel: input.channel,
+   channel: input.channel ?? 'api',
  });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await processMessageMoment({
contractAddress,
tokenId,
artistAddress: input.account,
channel: input.channel,
});
await processMessageMoment({
contractAddress,
tokenId,
artistAddress: input.account,
channel: input.channel ?? 'api',
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/moment/createMoment.ts` around lines 85 - 90, The call to
processMessageMoment is passing input.channel which may be undefined and later
is unsafely cast inside processMessageMoment (see logMessage usage in
processMessageMoment.ts), so change the call site (createMoment ->
processMessageMoment) or the log invocation to provide a safe default channel
(e.g., 'api' or 'web') when input.channel is undefined; update references around
processMessageMoment and logMessage to use the fallback value (instead of blind
casting) so the type is always one of 'sms' | 'telegram' | 'web' | 'api'.

Comment on lines +3 to +9
const getChannelFromReqHeader = (req: NextRequest): string => {
const origin = req.headers.get('origin') ?? '';
const isWeb =
origin.includes('inprocess.world') ||
origin.includes('stayinprocess.vercel.app');
return isWeb ? 'web' : 'api';
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing testnet origin in trusted domains check.

The testnet frontend URL (in-process-git-test-sweetmantechs-projects.vercel.app per src/lib/consts.ts) is not included in the origin check. Requests from testnet will be misclassified as 'api' instead of 'web'.

Proposed fix
 const getChannelFromReqHeader = (req: NextRequest): string => {
   const origin = req.headers.get('origin') ?? '';
   const isWeb =
     origin.includes('inprocess.world') ||
-    origin.includes('stayinprocess.vercel.app');
+    origin.includes('stayinprocess.vercel.app') ||
+    origin.includes('in-process-git-test-sweetmantechs-projects.vercel.app');
   return isWeb ? 'web' : 'api';
 };

Alternatively, consider extracting the trusted origins to a constant or reusing the SITE_ORIGINAL_URL pattern for consistency.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/moment/getChannelFromReqHeader.ts` around lines 3 - 9,
getChannelFromReqHeader currently classifies requests as 'web' only if origin
includes 'inprocess.world' or 'stayinprocess.vercel.app', missing the testnet
frontend origin and causing misclassification; update getChannelFromReqHeader
(function) to also check for
'in-process-git-test-sweetmantechs-projects.vercel.app' OR refactor to reuse the
existing trusted-origin constant/pattern (e.g., SITE_ORIGINAL_URL or the
constant defined in src/lib/consts.ts) so the testnet domain is included in the
trusted domains check and requests from testnet are returned as 'web'.

Comment on lines +21 to +26
const messageId = await logMessage(
[{ type: 'text', text: successMessage }],
'assistant',
artistAddress,
channel as 'sms' | 'telegram' | 'web' | 'api'
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Unsafe type cast when channel is undefined or unexpected value.

When channel is undefined (the parameter is optional) or an unexpected string value, casting it directly to 'sms' | 'telegram' | 'web' | 'api' will pass an invalid value to logMessage. The logMessage function has a default of 'sms' for the client parameter, but passing undefined explicitly bypasses that default.

🛡️ Proposed fix to handle undefined channel
+ const client = (['sms', 'telegram', 'web', 'api'] as const).includes(channel as any)
+   ? (channel as 'sms' | 'telegram' | 'web' | 'api')
+   : 'sms';
+
  const messageId = await logMessage(
    [{ type: 'text', text: successMessage }],
    'assistant',
    artistAddress,
-   channel as 'sms' | 'telegram' | 'web' | 'api'
+   client
  );
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const messageId = await logMessage(
[{ type: 'text', text: successMessage }],
'assistant',
artistAddress,
channel as 'sms' | 'telegram' | 'web' | 'api'
);
const client = (['sms', 'telegram', 'web', 'api'] as const).includes(channel as any)
? (channel as 'sms' | 'telegram' | 'web' | 'api')
: 'sms';
const messageId = await logMessage(
[{ type: 'text', text: successMessage }],
'assistant',
artistAddress,
client
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/moment/processMessageMoment.ts` around lines 21 - 26, The code
unsafely casts the optional channel to the union type when calling logMessage;
instead, validate and normalize channel before calling logMessage (e.g., check
if channel is one of 'sms'|'telegram'|'web'|'api' and otherwise fall back to the
default 'sms'), then pass that validated value to logMessage (referencing the
channel variable and the logMessage call where messageId is created) so the
function never receives undefined or an unexpected string.

Comment thread src/lib/schema/createMomentSchema.ts Outdated
await expect(triggerMuxMigration(baseInput)).rejects.toThrow(
'Trigger.dev unavailable'
);
await expect(triggerMuxMigration(baseInput)).resolves.not.toThrow();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the test file
fd "triggerMuxMigration.test.ts" --type f

Repository: sweetmantech/In-Process-API

Length of output: 128


🏁 Script executed:

# Read the test file around line 84 to understand context
cat -n src/lib/trigger.dev/__tests__/triggerMuxMigration.test.ts | sed -n '70,95p'

Repository: sweetmantech/In-Process-API

Length of output: 979


🏁 Script executed:

# Find the triggerMuxMigration function implementation
fd "triggerMuxMigration" --type f | grep -v ".test"

Repository: sweetmantech/In-Process-API

Length of output: 113


🌐 Web query:

Vitest resolves.toThrow() vs resolves.toBeUndefined() Promise assertion API

💡 Result:

In Vitest, resolves.toThrow and resolves.toBeUndefined are part of the Promise assertion API for testing asynchronous code. expect(promise).resolves.toThrow asserts that the promise resolves (does NOT reject) AND the resolved value is a function that throws an error when called. This is primarily for Jest compatibility when passing async functions that throw, like expect(async => { throw new Error }).resolves.toThrow. However, there are known inconsistencies: .resolves does not auto-unwrap functions like .rejects does, leading to errors like "You must provide a Promise to expect when using .resolves, not 'function'" in some cases. expect(promise).resolves.toBeUndefined asserts that the promise resolves to the primitive value undefined. This is useful for functions expected to return no value asynchronously, e.g., await expect(someAsyncFn).resolves.toBeUndefined. Key differences: - toThrow after resolves expects the resolved value to be a throwable function (uncommon for direct promises). - toBeUndefined expects the resolved value to be undefined (common for void async functions). For expecting a promise to reject with a thrown error, use expect(promise).rejects.toThrow instead, which unwraps the rejection reason. All must be awaited. Official docs emphasize .resolves unwraps resolved values for chaining matchers, and .rejects unwraps rejection reasons.

Citations:


🏁 Script executed:

# Read the triggerMuxMigration implementation to understand return type
cat -n src/lib/trigger.dev/triggerMuxMigration.ts | head -50

Repository: sweetmantech/In-Process-API

Length of output: 1076


🏁 Script executed:

# Check the full function signature and return type
ast-grep --pattern $'export $$$function triggerMuxMigration($$$) {
  $$$
}'

Repository: sweetmantech/In-Process-API

Length of output: 53


Use a resolved-value matcher instead of resolves.not.toThrow.

triggerMuxMigration returns Promise<void>, which resolves to undefined. The toThrow matcher is for testing if a function throws; for a resolved Promise, use resolves.toBeUndefined() instead. This avoids semantically incorrect assertions.

Suggested fix
-    await expect(triggerMuxMigration(baseInput)).resolves.not.toThrow();
+    await expect(triggerMuxMigration(baseInput)).resolves.toBeUndefined();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await expect(triggerMuxMigration(baseInput)).resolves.not.toThrow();
await expect(triggerMuxMigration(baseInput)).resolves.toBeUndefined();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/trigger.dev/__tests__/triggerMuxMigration.test.ts` at line 84, The
test currently asserts await
expect(triggerMuxMigration(baseInput)).resolves.not.toThrow(), which is
semantically wrong for a Promise<void>; update the assertion to await
expect(triggerMuxMigration(baseInput)).resolves.toBeUndefined() so the test
checks the resolved value of the Promise returned by triggerMuxMigration (use
the same baseInput and test file triggerMuxMigration.test.ts and the
triggerMuxMigration import to locate the test).

@techeng322 techeng322 merged commit 9a2fa93 into main Mar 25, 2026
4 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 9, 2026
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