Skip to content

agent: @U0AJM7X8FBR API - MPP • actual: using x402 for many endpoints • require#315

Open
sweetmantech wants to merge 2 commits intotestfrom
agent/-u0ajm7x8fbr-api---mpp---actua-1773860354756
Open

agent: @U0AJM7X8FBR API - MPP • actual: using x402 for many endpoints • require#315
sweetmantech wants to merge 2 commits intotestfrom
agent/-u0ajm7x8fbr-api---mpp---actua-1773860354756

Conversation

@sweetmantech
Copy link
Copy Markdown
Contributor

@sweetmantech sweetmantech commented Mar 18, 2026

Automated PR from coding agent.

Prompt: @U0AJM7X8FBR API - MPP
• actual: using x402 for many endpoints
• required: replace those x402 endpoints with MPP
• follow these docs: https://mpp.dev/overview

Summary by CodeRabbit

  • New Features

    • Added MPP (Modern Payment Protocol) support for image generation endpoints, replacing the previous payment method.
    • Added support for webm audio format in transcription processing.
    • Added organization ID parameter to system prompts for improved multi-tenant support.
  • Refactor

    • Migrated from x402-based payment system to MPP-based payment infrastructure.
    • Consolidated image generation to use new MPP-protected endpoints.
  • Documentation

    • Enhanced API documentation with comprehensive JSDoc parameter annotations across multiple modules.

Recoup Agent and others added 2 commits March 18, 2026 18:57
- Remove @coinbase/x402, x402-fetch, x402-next packages; add mppx
- Upgrade viem to 2.47.5 for mppx Tempo chain compatibility
- Create app/api/mpp/image/generate — MPP-protected image endpoint
  using mppx/server tempo.charge() instead of x402 middleware
- Create lib/mpp/{getMppServer, getPayerAddress, fetchWithMppPayment,
  getCreditsForPrice, recoup/mppGenerateImage}
- Remove app/api/x402/ routes and lib/x402/ utilities
- Simplify middleware.ts — no longer needs x402 paymentMiddleware
- Update app/api/image/generate to call mppGenerateImage instead of
  x402GenerateImage
- New env vars: MPP_SECRET_KEY (HMAC challenge), MPP_PAYMENT_KEY
  (private key for Tempo payer account)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
• actual: using x402 for many endpoints
• require
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 18, 2026

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

Project Deployment Actions Updated (UTC)
recoup-api Error Error Mar 18, 2026 7:01pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 18, 2026

📝 Walkthrough

Walkthrough

This PR performs a migration from x402 payment system to MPP (Multi-Protocol Payment), removing x402-related API routes and utility functions while adding new MPP-protected endpoints and payment infrastructure. Additionally, it adds extensive JSDoc parameter documentation across the codebase, introduces an isSupportedContentTemplate validator, extends getSystemPrompt with organization ID support, and adds webm audio format support.

Changes

Cohort / File(s) Summary
API Route Migration: x402 → MPP
app/api/x402/image/generate/route.ts, app/api/mpp/image/generate/route.ts
Removed x402-protected image generation endpoint; added new MPP-protected endpoint with payment charge flow, CORS support, file validation, image upload to Arweave, and moment creation.
Image Generation Handler Updates
app/api/image/generate/route.ts, lib/x402/recoup/x402GenerateImage.ts, lib/mpp/recoup/mppGenerateImage.ts
Updated image generation handler to use new mppGenerateImage instead of x402GenerateImage; removed x402 utility and added MPP-backed equivalent.
MPP Payment Infrastructure
lib/mpp/getMppServer.ts, lib/mpp/fetchWithMppPayment.ts, lib/mpp/getPayerAddress.ts
Added three new MPP utilities: server initialization with Tempo payment method, payment-wrapped fetch with credit deduction, and DID-based payer address extraction from Authorization header.
X402 Payment Infrastructure Removal
lib/x402/fetchWithPayment.ts, lib/x402/getBuyerAccount.ts, lib/x402/getTransferCalls.ts, lib/x402/loadAccount.ts, app/api/x402/session-token/route.ts
Removed entire x402 payment stack: payment-wrapped fetch, buyer account parsing, USDC transfer call construction, account loading, and session token route export.
Core Feature Enhancements
lib/prompts/getSystemPrompt.ts, lib/content/contentTemplates.ts, lib/transcribe/processAudioTranscription.ts
Added optional orgId parameter to system prompt generation; introduced isSupportedContentTemplate(template) validator; extended audio format support to recognize webm extension.
API Route JSDoc Documentation
app/api/accounts/[id]/route.ts, app/api/admins/privy/route.ts, app/api/coding-agent/[platform]/route.ts, app/api/songs/analyze/presets/route.ts, app/api/transcribe/route.ts
Added parameter documentation (@param tags) to route handlers; no functional changes.
Library Function Documentation
lib/admins/privy/*, lib/ai/*, lib/catalog/*, lib/chat/*, lib/chats/*, lib/coding-agent/*, lib/composio/*, lib/content/*, lib/credits/*, lib/emails/*, lib/flamingo/*, lib/github/*, lib/mcp/*, lib/spotify/*, lib/supabase/*, lib/trigger/*, lib/transcribe/*
Extensive JSDoc parameter annotations across utility and domain-specific library functions; no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant MppEndpoint as MPP Image<br/>Generate Endpoint
    participant MppServer as MPP Server
    participant ImageGen as Image Generator
    participant Arweave as Arweave Storage
    participant Database as Database

    Client->>MppEndpoint: GET /api/mpp/image/generate<br/>(prompt, files, Authorization)
    MppEndpoint->>MppServer: Initialize MPP charge<br/>handleMppCharge()
    
    alt 402 Payment Required
        MppServer-->>Client: 402 Challenge
    else Payment Accepted
        MppEndpoint->>MppEndpoint: Validate prompt & files
        
        alt Invalid Input
            MppEndpoint-->>Client: 400 Bad Request
        else Valid
            MppEndpoint->>ImageGen: generateImage(prompt)
            
            alt Generation Success
                ImageGen-->>MppEndpoint: Image Buffer
                MppEndpoint->>Arweave: uploadImage(buffer)
                Arweave-->>MppEndpoint: Arweave TX ID
                
                MppEndpoint->>Database: createMoment(metadata)
                Database-->>MppEndpoint: Moment Record
                
                MppEndpoint-->>Client: 200 JSON<br/>(image data, arweave ID,<br/>moment record, usage)
            else Generation Failed
                ImageGen-->>MppEndpoint: Error
                MppEndpoint-->>Client: 500 Error
            end
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🔄 From x402's chains we break away,
MPP's new dawn lights the day,
Payments flow through Tempo's grace,
JSDoc shines in every place,
Documented, tested, ready to soar—
Clean architecture, now and more! 🚀

🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Solid & Clean Code ⚠️ Warning PR violates SOLID principles: GET handler mixes payment, validation, generation, uploads, and CORS; inconsistent environment validation; error handling returns empty strings; lacks response status checks and credit rollback mechanisms. Extract handler into separate functions per responsibility; add environment validation consistency; implement credit rollback; add response status validation; return null on errors; extract repeated getCorsHeaders() calls into helpers.

✏️ 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 agent/-u0ajm7x8fbr-api---mpp---actua-1773860354756
📝 Coding Plan
  • Generate coding plan for human review comments

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: 14

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/api/transcribe/route.ts (1)

11-33: ⚠️ Potential issue | 🔴 Critical

Derive account identity from auth context, not request body.

This handler trusts account_id from JSON and does not call validateAuthContext(). That allows caller-controlled ownership attribution. Parse body with a Zod validate function, and source ownerAccountId from authenticated context only.

🔧 Suggested patch outline
+const TranscribeRequestSchema = z.object({
+  audio_url: z.string().url(),
+  artist_account_id: z.string().min(1),
+  title: z.string().optional(),
+  include_timestamps: z.boolean().optional(),
+});

 export async function POST(req: NextRequest) {
   try {
-    const body = await req.json();
-    const { audio_url, account_id, artist_account_id, title, include_timestamps } = body;
+    const auth = await validateAuthContext(req);
+    if (auth instanceof NextResponse) return auth;
+    const parsed = TranscribeRequestSchema.parse(await req.json());

-    if (!account_id) {
-      return NextResponse.json({ error: "Missing required field: account_id" }, { status: 400 });
-    }

     const result = await processAudioTranscription({
-      audioUrl: audio_url,
-      ownerAccountId: account_id,
-      artistAccountId: artist_account_id,
-      title,
-      includeTimestamps: include_timestamps,
+      audioUrl: parsed.audio_url,
+      ownerAccountId: auth.accountId,
+      artistAccountId: parsed.artist_account_id,
+      title: parsed.title,
+      includeTimestamps: parsed.include_timestamps,
     });

As per coding guidelines: "Never use account_id in request bodies or tool schemas; always derive the account ID from authentication", "Always use validateAuthContext() for authentication in API routes", and "All API endpoints should use a validate function for input parsing using Zod".

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

In `@app/api/transcribe/route.ts` around lines 11 - 33, Replace trusting
account_id from the request body by validating auth and parsing the body with
Zod: add a Zod schema to validate the incoming body (audio_url, title,
include_timestamps) and use that parsed payload instead of raw req.json(), call
validateAuthContext() to get the authenticated account ID and pass that value as
ownerAccountId into processAudioTranscription (keep artist_account_id only if it
is allowed from body per policy or also derive it if required), and return
errors via NextResponse.json as before; ensure validateAuthContext() is invoked
before calling processAudioTranscription and remove any use of body.account_id.
app/api/image/generate/route.ts (1)

37-42: ⚠️ Potential issue | 🟡 Minor

Add response type validation for mppGenerateImage return value.

The function returns Promise<unknown>, and the response flows directly to NextResponse.json() without type checking. Define a response schema (e.g., using Zod) to validate the MPP endpoint's response shape—this ensures the API contracts are enforced and makes the expected structure explicit to future maintainers.

Consider:

const mppImageResponseSchema = z.object({
  image: z.string(),
  usage: z.record(z.unknown()),
  imageUrl: z.string().optional(),
  arweaveResult: z.unknown().optional(),
  moment: z.unknown().optional(),
  arweaveError: z.unknown().optional(),
});

const data = await mppGenerateImage(...);
const validatedData = mppImageResponseSchema.parse(data);
return NextResponse.json(validatedData, { status: 200, headers: getCorsHeaders() });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/image/generate/route.ts` around lines 37 - 42, The route currently
forwards the unknown result of mppGenerateImage into NextResponse.json; add a
Zod schema (e.g., mppImageResponseSchema) describing the expected shape (image:
string, usage: record, optional imageUrl/arweaveResult/moment/arweaveError) and
call schema.parse or safeParse on the value returned by mppGenerateImage, then
return the validated object to NextResponse.json; on parse failure return a 400
(or appropriate) error response with getCorsHeaders and a clear validation
message. Ensure you update route.ts to import zod and reference
mppGenerateImage, mppImageResponseSchema, and getCorsHeaders so the contract is
enforced before sending the response.
🧹 Nitpick comments (31)
lib/trigger/triggerCreateContent.ts (1)

17-24: LGTM! Clean, single-responsibility function with solid typing.

The function adheres well to SOLID principles:

  • Single Responsibility: Delegates exclusively to tasks.trigger for content task creation
  • Interface Segregation: The TriggerCreateContentPayload interface is well-documented with property-level JSDoc

One minor suggestion: the @param payload tag would be slightly more complete with a brief description, e.g., @param payload - Content creation configuration including account, artist, and template settings. That said, the interface documentation already covers this well, so this is purely optional polish.

,

✨ Optional: Enhanced `@param` description
 /**
  * Triggers the create-content task in Trigger.dev.
  *
- * `@param` payload
+ * `@param` payload - Content creation configuration including account, artist, and template settings
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/trigger/triggerCreateContent.ts` around lines 17 - 24, Update the JSDoc
for the triggerCreateContent function to include a brief description for the
`@param` tag; specifically, in the JSDoc above triggerCreateContent add something
like "@param payload - Content creation configuration including account, artist,
and template settings" so the documentation for the payload passed to
tasks.trigger(CREATE_CONTENT_TASK_ID, payload) is clearer while leaving the
function body (triggerCreateContent) and its use of tasks.trigger unchanged.
lib/admins/privy/getCutoffMs.ts (1)

4-10: JSDoc @param lacks description.

Same pattern as other files in this PR—the @param period tag is present but provides no additional information beyond what TypeScript types already convey.

 /**
  * Returns the cutoff timestamp in milliseconds for a given period.
  * Uses midnight UTC calendar day boundaries to match Privy dashboard behavior.
  * Returns 0 for "all" (no cutoff).
  *
- * `@param` period
+ * `@param` period - The time period to calculate the cutoff for (e.g., "7d", "30d", "all")
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/admins/privy/getCutoffMs.ts` around lines 4 - 10, Update the JSDoc for
getCutoffMs to include a short description for the `@param` period tag (e.g.,
explain accepted string values like "day", "week", "month", "all" and that it
determines the cutoff window) so the documentation is informative beyond the
TypeScript type; edit the comment block above the getCutoffMs function to add
this `@param` description and keep it consistent with other files in the PR.
lib/catalog/getCatalogSongs.ts (1)

28-34: JSDoc block has multiple @param tags without descriptions.

The added JSDoc provides no additional context beyond what the TypeScript signature already conveys. Consider either completing the documentation or removing the empty @param tags:

📝 Suggested JSDoc improvement
 /**
- *
- * `@param` catalogId
- * `@param` pageSize
- * `@param` page
- * `@param` artistName
+ * Fetches a paginated list of songs from a catalog.
+ *
+ * `@param` catalogId - The unique identifier of the catalog
+ * `@param` pageSize - Number of songs per page (default: 100)
+ * `@param` page - Page number to fetch (default: 1)
+ * `@param` artistName - Optional filter by artist name
+ * `@returns` Promise resolving to the catalog songs response with pagination info
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/catalog/getCatalogSongs.ts` around lines 28 - 34, The JSDoc block above
the getCatalogSongs function in lib/catalog/getCatalogSongs.ts contains multiple
empty `@param` tags; either remove the redundant JSDoc entirely (since TypeScript
signatures document parameters) or replace each `@param` with a one-line
description matching the parameter purpose (e.g., catalogId: catalog identifier,
pageSize: items per page, page: page number, artistName: optional filter) so the
comments add real value; update the comment block to reflect the chosen approach
and keep it synchronized with the function parameter names.
lib/emails/processAndSendEmail.ts (1)

31-39: JSDoc @param lacks description.

The @param input tag would benefit from a brief description or a @see reference to the ProcessAndSendEmailInput interface, which is already well-documented via its type definition.

 /**
  * Shared email processing and sending logic used by both the
  * POST /api/notifications handler and the send_email MCP tool.
  *
  * Handles room lookup, footer generation, markdown-to-HTML conversion,
  * and the Resend API call.
  *
- * `@param` input
+ * `@param` input - Email configuration including recipients, subject, and body content
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/emails/processAndSendEmail.ts` around lines 31 - 39, The JSDoc for the
processAndSendEmail function has an incomplete `@param` tag; update the comment so
the `@param` input includes a brief description or a `@see` reference to the
ProcessAndSendEmailInput type (e.g., "@param input - input parameters for
processing and sending email. See ProcessAndSendEmailInput for details" or use
"@see ProcessAndSendEmailInput") so readers can find the documented interface;
locate the JSDoc above the processAndSendEmail function in
lib/emails/processAndSendEmail.ts and update the `@param` accordingly.
lib/catalog/formatCatalogSongsAsCSV.ts (1)

3-7: JSDoc @param lacks description.

Consider adding a description or removing the bare @param songs tag:

 /**
  * Formats catalog songs into the CSV-like format expected by the scorer
  *
- * `@param` songs
+ * `@param` songs - Array of catalog songs to format into CSV rows
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/catalog/formatCatalogSongsAsCSV.ts` around lines 3 - 7, The JSDoc for the
function formatting catalog songs is missing a description for the `@param` tag;
update the JSDoc for formatCatalogSongsAsCSV (or the exported function in
formatCatalogSongsAsCSV.ts) to either remove the bare "@param songs" tag or
replace it with a short description of the parameter (e.g., type/shape of songs
and what the function expects) so the docblock fully describes the input; ensure
the description matches the function signature and any returned value is
documented as well if present.
lib/supabase/files/createFileRecord.ts (1)

26-30: JSDoc @param lacks description.

Per coding guidelines, Supabase database functions should follow the documented pattern with complete JSDoc comments. Consider adding a description:

 /**
  * Create a file record in the database
  *
- * `@param` params
+ * `@param` params - File record parameters including owner, artist, storage key, and metadata
+ * `@returns` Promise resolving to the created FileRecord
+ * `@throws` Error if the database insert fails
  */

Based on learnings: "Supabase database functions should import from @/lib/supabase/serverClient and follow the documented pattern with JSDoc comments, error handling, and return types."

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

In `@lib/supabase/files/createFileRecord.ts` around lines 26 - 30, Update the
JSDoc for the createFileRecord function to follow the Supabase pattern: add a
clear description for the `@param` (describe the params object shape and each
property used), add an `@returns` describing the Promise return type (what the
resolved value contains), and add an `@throws` (or `@throws`) explaining possible
errors; also ensure the module imports the Supabase helper from
"@/lib/supabase/serverClient" and that error handling and return types in
createFileRecord match the documented pattern.
lib/content/validateGetContentEstimateQuery.ts (1)

16-20: JSDoc @param lacks description.

The added @param request tag would be more useful with a description explaining its purpose. Consider either completing it or omitting it entirely, since the function signature already makes the parameter's role clear via TypeScript types.

 /**
  * Validates auth and query params for GET /api/content/estimate.
- *
- * `@param` request
  */

Or provide a meaningful description:

 /**
  * Validates auth and query params for GET /api/content/estimate.
  *
- * `@param` request
+ * `@param` request - The incoming Next.js request containing auth headers and query params
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/content/validateGetContentEstimateQuery.ts` around lines 16 - 20, Update
the JSDoc for validateGetContentEstimateQuery to either remove the redundant
"@param request" tag or add a short descriptive phrase (e.g., "Incoming Express
Request object for GET /api/content/estimate containing auth and query
parameters") so the comment clarifies the parameter's purpose; modify the JSDoc
block above the validateGetContentEstimateQuery function to reflect this change.
lib/transcribe/types.ts (1)

56-61: JSDoc @param lacks description.

The @param error tag would be more informative with a description:

 /**
  * Formats transcription errors into user-friendly messages.
  * Centralizes error message logic to avoid duplication.
  *
- * `@param` error
+ * `@param` error - The caught error (Error instance or unknown) to format
+ * `@returns` Object containing user-friendly message and appropriate HTTP status code
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/transcribe/types.ts` around lines 56 - 61, Update the JSDoc for the
transcription error formatter to add a clear description for the `@param` error
tag: describe that `error` is the Error (or string/unknown) input representing
the transcription failure, include expected types (e.g., Error | string |
unknown) and what the function does with it (formats into a user-facing
message), and optionally note when callers should pass an Error vs a string;
reference the existing JSDoc block for the transcription error formatter and the
`error` parameter so the comment is explicit and actionable.
lib/coding-agent/handleMergeSuccess.ts (1)

6-12: JSDoc @param lacks description.

The existing JSDoc describes the function's behavior well, but the @param state tag provides no additional context:

 /**
  * Handles post-merge cleanup after all PRs merged successfully.
  * Deletes the shared PR state keys for all repos and persists the latest
  * snapshot via upsertAccountSnapshot.
  *
- * `@param` state
+ * `@param` state - The coding agent thread state containing branch, PRs, and snapshot info
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/coding-agent/handleMergeSuccess.ts` around lines 6 - 12, Update the JSDoc
for the function handleMergeSuccess to provide a clear description for the
`@param` state tag: describe that state is the coding agent's current state object
passed into handleMergeSuccess and enumerate the expected pieces used by the
function (e.g., accountId or account info, the snapshot object persisted via
upsertAccountSnapshot, and any repo/shared PR state keys that will be deleted).
Place this description in the existing JSDoc above handleMergeSuccess so someone
reading the docs knows what fields the state object must contain.
app/api/admins/privy/route.ts (2)

18-20: Empty JSDoc block provides no documentation value.

The OPTIONS handler has an empty comment block. Either provide a meaningful description (e.g., "Handles CORS preflight requests") or remove the placeholder entirely.

📝 Proposed fix
-/**
- *
- */
+/**
+ * OPTIONS handler for CORS preflight requests.
+ */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/admins/privy/route.ts` around lines 18 - 20, Remove the empty JSDoc
block above the OPTIONS handler in route.ts or replace it with a concise
description (e.g., "Handles CORS preflight requests for /api/admins/privy") so
the comment either provides meaningful documentation for the OPTIONS handler or
is omitted entirely; update the comment adjacent to the OPTIONS handler function
export to reflect this change.

11-12: Incomplete @param tag on GET handler.

Add a brief description for the request parameter to make the JSDoc useful.

📝 Proposed fix
- *
- * `@param` request
+ * `@param` request - The incoming request with optional period query param
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/admins/privy/route.ts` around lines 11 - 12, The JSDoc for the GET
handler has an incomplete `@param` tag for the request parameter; update the
comment for the GET function (exported async function GET) to include a brief
description like "request — the incoming NextRequest object for this handler"
(or similar) so the `@param` describes the request parameter's purpose and type.
lib/composio/getCallbackUrl.ts (1)

20-23: Redundant @param options entry.

Lines 20–21 already document options.destination and options.roomId with descriptions. Adding a bare @param options afterward is redundant and breaks the conventional JSDoc ordering (parent before children). Remove line 22.

📝 Proposed fix
  * `@param` options.destination - Where to redirect: "chat" or "connectors"
  * `@param` options.roomId - For chat destination, the room ID to return to
- * `@param` options
  * `@returns` Full callback URL with success indicator
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/composio/getCallbackUrl.ts` around lines 20 - 23, Remove the redundant
JSDoc entry for the whole options object in the getCallbackUrl function's
header: delete the bare "@param options" line that follows the documented
"@param options.destination" and "@param options.roomId" entries so the JSDoc
only lists the parent param (if desired) before or omit it entirely and keep the
child params; update the JSDoc block in getCallbackUrl (function name:
getCallbackUrl) accordingly to restore correct ordering and avoid duplication.
lib/ai/isEmbedModel.ts (1)

6-7: Incomplete @param tag—add a description.

The @param m lacks context. A brief description clarifies the input expectation.

📝 Proposed fix
- *
- * `@param` m
+ * `@param` m - Gateway language model entry to evaluate
+ * `@returns` True if the model is an embedding model
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/ai/isEmbedModel.ts` around lines 6 - 7, Update the JSDoc for the
isEmbedModel function to provide a concise description for the `@param` m tag:
explain that m is the model identifier or model object being checked (e.g.,
"model id string or model descriptor to test for embedding capability") and note
expected types/values and that the function returns whether it is an embedding
model; update the comment in lib/ai/isEmbedModel.ts so `@param` m clearly
documents what callers should pass to isEmbedModel.
lib/catalog/getCatalogs.ts (1)

11-14: Incomplete JSDoc—add function and parameter descriptions.

The comment block is effectively empty. Document what the function does and what accountId represents.

📝 Proposed fix
 /**
- *
- * `@param` accountId
+ * Fetches all catalogs associated with the given account.
+ *
+ * `@param` accountId - The account identifier to fetch catalogs for
+ * `@returns` Promise resolving to catalogs response with status and catalog array
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/catalog/getCatalogs.ts` around lines 11 - 14, Add a complete JSDoc for
the getCatalogs function: describe that getCatalogs retrieves the list of
catalogs (or catalog metadata) for a given account, explain what accountId is
(the unique identifier for the account/organization used to scope the query),
mention the return value (e.g., Promise resolving to an array of Catalog objects
or an empty array) and note any thrown errors or side effects; place this JSDoc
immediately above the getCatalogs function declaration and include `@param`
{string} accountId and an `@returns` annotation that matches the function's actual
return type.
lib/transcribe/saveAudioToFiles.ts (1)

5-8: Empty JSDoc provides no value.

The added comment block contains only @param params without any description. Either document what SaveAudioParams properties are expected and what the function does, or remove the empty block—placeholder JSDoc clutters the code without aiding maintainability.

📝 Option A: Meaningful documentation
 /**
- *
- * `@param` params
+ * Uploads an audio blob to storage and creates a corresponding file record.
+ *
+ * `@param` params - Audio save parameters including blob, content type, and owner info
+ * `@returns` The created file record with storage metadata
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/transcribe/saveAudioToFiles.ts` around lines 5 - 8, The JSDoc above
saveAudioToFiles is empty and should be replaced with a meaningful doc or
removed; update the comment to state what saveAudioToFiles does and document the
SaveAudioParams shape (list required properties like fileName,
audioBuffer/stream, format, outputDir, any optional flags) and return value
(e.g., Promise<void> or paths), or delete the placeholder /** `@param` params */
block entirely if you prefer to keep no JSDoc; reference the saveAudioToFiles
function and the SaveAudioParams type when making the change.
lib/admins/privy/toMs.ts (1)

4-5: Incomplete @param tag—add a description.

The @param timestamp lacks a description. Since the function handles both seconds and milliseconds formats from Privy, document the expected input to complement the existing context.

📝 Proposed fix
- *
- * `@param` timestamp
+ * `@param` timestamp - Privy timestamp (may be in seconds or milliseconds)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/admins/privy/toMs.ts` around lines 4 - 5, Update the JSDoc for the toMs
function by adding a clear description to the `@param` timestamp tag stating that
timestamp may be a number or string representing either seconds or milliseconds
from Privy and that the function will normalize it to milliseconds; reference
the toMs function name so the comment is adjacent to its declaration and include
examples like "e.g. 1650000000 (seconds) or 1650000000000 (milliseconds) — both
normalized to ms".
lib/content/validateGetContentValidateQuery.ts (1)

16-17: Incomplete @param tag—add a description.

The @param request lacks a description. Briefly note what the request should contain (e.g., auth headers, artist_account_id query param) to make the documentation actionable.

📝 Proposed fix
- *
- * `@param` request
+ * `@param` request - Next.js request with auth headers and artist_account_id query param
+ * `@returns` Validated query data or NextResponse error
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/content/validateGetContentValidateQuery.ts` around lines 16 - 17, Update
the JSDoc for the function (validateGetContentValidateQuery) to complete the
`@param` tag for request: describe that request is the incoming HTTP request
(e.g., an Express Request) containing authentication headers and the expected
query parameter artist_account_id (and any other required query fields), and
note the shape/required/optional nature of those fields so callers/readers know
what to pass in.
lib/transcribe/saveTranscriptToFiles.ts (1)

5-8: JSDoc block is incomplete.

The documentation has an empty description and the @param tag lacks context. Consider providing meaningful documentation that describes the function's purpose and parameter.

📝 Suggested improvement
 /**
- *
- * `@param` params
+ * Saves a markdown transcript to storage and creates a corresponding file record.
+ *
+ * `@param` params - Configuration object containing markdown content, ownership details, and optional metadata
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/transcribe/saveTranscriptToFiles.ts` around lines 5 - 8, Update the JSDoc
for the saveTranscriptToFiles function to include a concise description of what
the function does and document the params and return value; specifically,
replace the empty block with a summary (e.g., "Write transcript data to one or
more files") and add `@param` entries describing the "params" object (list its
expected properties and types) and an `@returns` tag describing the return type
and any thrown errors. Ensure the JSDoc references the saveTranscriptToFiles
function and documents any options, file paths, or callbacks contained in the
params object so callers know the contract.
lib/content/validateCreateContentBody.ts (1)

43-44: JSDoc @param tag missing description.

The @param request annotation would benefit from a brief description.

📝 Suggested improvement
  /**
   * Validates auth and request body for POST /api/content/create.
   *
-  * `@param` request
+  * `@param` request - The incoming Next.js request object
   */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/content/validateCreateContentBody.ts` around lines 43 - 44, Add a brief
description to the JSDoc `@param` request tag in the validateCreateContentBody
function so the purpose of the parameter is clear; locate the JSDoc block above
the validateCreateContentBody function in
lib/content/validateCreateContentBody.ts and update the `@param` request line with
a short phrase like "the incoming HTTP request body to validate" (or equivalent)
to document what the parameter represents.
lib/catalog/getCatalogDataAsCSV.ts (1)

6-7: JSDoc @param tag missing description.

The @param catalogId annotation would be more helpful with a brief description of what the parameter represents.

📝 Suggested improvement
 /**
  * Gets all catalog songs and formats them as CSV for the scorer
  *
- * `@param` catalogId
+ * `@param` catalogId - The unique identifier of the catalog to fetch songs from
  */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/catalog/getCatalogDataAsCSV.ts` around lines 6 - 7, Add a short
descriptive JSDoc for the catalogId parameter on the getCatalogDataAsCSV
function: update the JSDoc block above getCatalogDataAsCSV to change the bare
"@param catalogId" into something like "@param catalogId - the unique identifier
(e.g., UUID or database id) of the catalog to export as CSV" so readers know
what value to pass and its purpose; ensure the catalogId symbol and the
getCatalogDataAsCSV function name are referenced in the comment.
lib/flamingo/getFlamingoPresetsHandler.ts (1)

13-13: JSDoc @param tag missing description.

The @param request annotation would be more useful with a description.

📝 Suggested improvement
- * `@param` request
+ * `@param` request - The incoming Next.js request object
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/flamingo/getFlamingoPresetsHandler.ts` at line 13, Update the JSDoc for
the getFlamingoPresetsHandler function to add a concise description for the
`@param` request tag: describe the shape or purpose of the request parameter
(e.g., request object containing query/body/auth fields used by
getFlamingoPresetsHandler) so future readers know what is expected and which
properties are used.
lib/admins/privy/countNewAccounts.ts (1)

8-10: JSDoc @param tags missing descriptions.

Both parameter annotations lack descriptions. Adding context would improve developer experience.

📝 Suggested improvement
  /**
   * Counts how many users in the list were created within the cutoff period.
   *
-  * `@param` users
-  * `@param` period
+  * `@param` users - Array of Privy user objects to filter
+  * `@param` period - Time period for the cutoff ("daily", "weekly", or "monthly")
   */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/admins/privy/countNewAccounts.ts` around lines 8 - 10, Add clear
descriptions to the JSDoc `@param` tags for the countNewAccounts function:
document what the users parameter is (e.g., array of user objects or specific
user type and required fields) and what the period parameter represents (e.g.,
start/end dates, duration string, or enum) and any expected formats or units;
update the JSDoc above countNewAccounts to include those descriptions so IDEs
and readers understand expected inputs.
lib/admins/privy/getLatestVerifiedAt.ts (1)

5-10: Use account-oriented naming for parameter/docs.

Please rename user to an account-specific name (for example, privyAccount) in both JSDoc and function parameter for terminology consistency.

♻️ Suggested rename
- * Returns the most recent latest_verified_at (in ms) across all linked_accounts for a Privy user.
+ * Returns the most recent latest_verified_at (in ms) across all linked_accounts for a Privy account.
...
- * `@param` user
+ * `@param` privyAccount
 */
-export function getLatestVerifiedAt(user: User): number | null {
-  const linkedAccounts = user.linked_accounts;
+export function getLatestVerifiedAt(privyAccount: User): number | null {
+  const linkedAccounts = privyAccount.linked_accounts;

As per coding guidelines: "Use 'account' terminology, never 'entity' or 'user'."

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

In `@lib/admins/privy/getLatestVerifiedAt.ts` around lines 5 - 10, Rename the
parameter and its JSDoc to use account-oriented terminology: change the function
signature of getLatestVerifiedAt(user: User) to
getLatestVerifiedAt(privyAccount: User) (or another account-specific name like
privyAccount) and update the JSDoc `@param` tag and description to reference
"account" instead of "user"; ensure all internal references in the function body
are updated to the new parameter name to avoid unused/undefined variable errors.
lib/content/getArtistContentReadiness.ts (1)

26-29: Replace autogenerated root0 JSDoc with a meaningful param name.

root0 is hard to read in API docs. Prefer params and keep nested field docs under that name.

📝 Suggested JSDoc tweak
- * `@param` root0
- * `@param` root0.accountId
- * `@param` root0.artistAccountId
- * `@param` root0.artistSlug
+ * `@param` params
+ * `@param` params.accountId
+ * `@param` params.artistAccountId
+ * `@param` params.artistSlug
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/content/getArtistContentReadiness.ts` around lines 26 - 29, Update the
JSDoc for getArtistContentReadiness by replacing the autogenerated "root0" param
name with a meaningful "params" (or similar) name used by the function's
parameter destructuring, and update the nested `@param` tags to use that root
(e.g., `@param` params.accountId, `@param` params.artistAccountId, `@param`
params.artistSlug) so the generated API docs are readable and match the function
signature.
lib/prompts/getSystemPrompt.ts (1)

16-16: Incomplete JSDoc: Missing description for orgId parameter.

Other parameters have descriptions (e.g., "The ID of the room", "The ID of the artist"), but orgId lacks one. For consistency:

- * `@param` params.orgId
+ * `@param` params.orgId - The ID of the organization, if applicable.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/prompts/getSystemPrompt.ts` at line 16, The JSDoc for getSystemPrompt is
missing a description for the `orgId` parameter; update the JSDoc block in
lib/prompts/getSystemPrompt.ts to add a concise description for `orgId` (e.g.,
"The ID of the organization") so it matches the style of other params and
improves documentation for the getSystemPrompt function. Ensure the `@param
orgId` line is filled in consistently with the existing param descriptions.
lib/mpp/recoup/mppGenerateImage.ts (1)

12-27: Return type Promise<unknown> bypasses type safety.

The function returns Promise<unknown>, forcing callers to handle the response without type guarantees. The calling route (app/api/image/generate/route.ts:37) passes this directly to NextResponse.json(data) without validation.

Define an interface for the expected response shape and validate it, or at minimum provide a typed return.

♻️ Add response type and basic validation
+export interface MppGenerateImageResponse {
+  image: { base64: string; mediaType: string };
+  usage: unknown;
+  imageUrl: string | null;
+  arweaveResult: unknown | null;
+  moment: unknown | null;
+  arweaveError?: string;
+}
+
 export async function mppGenerateImage(
   prompt: string,
   baseUrl: string,
   accountId: string,
   files?: string | null,
-): Promise<unknown> {
+): Promise<MppGenerateImageResponse> {
   const mppUrl = new URL("/api/mpp/image/generate", baseUrl);
   mppUrl.searchParams.set("prompt", prompt);

   if (files) {
     mppUrl.searchParams.set("files", files);
   }

   const response = await fetchWithMppPayment(mppUrl.toString(), accountId);
-  return response.json();
+  const data = await response.json();
+  // Basic validation could be added here with Zod
+  return data as MppGenerateImageResponse;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/recoup/mppGenerateImage.ts` around lines 12 - 27, The function
mppGenerateImage currently returns Promise<unknown>; define a concrete interface
(e.g., MppGenerateImageResponse) that matches the expected API shape and change
the function signature to return Promise<MppGenerateImageResponse>; after
calling fetchWithMppPayment and before returning, perform basic runtime
validation of response.json() (either manual shape checks or via a schema
validator like zod) and throw or return a typed error if validation fails so
callers (including app/api/image/generate/route.ts which forwards the value to
NextResponse.json) receive a correctly typed and validated object.
app/api/mpp/image/generate/route.ts (3)

9-9: Module-level initialization may cause startup failures.

getMppServer() is called at module load time. If it throws (e.g., missing MPP_SECRET_KEY), the entire route module fails to load, causing 500 errors for all requests to this endpoint without clear diagnostics.

Consider lazy initialization or handling the error gracefully.

♻️ Option: Lazy initialization
-const mppx = getMppServer();
+let mppx: ReturnType<typeof getMppServer> | null = null;
+
+function getServer() {
+  if (!mppx) {
+    mppx = getMppServer();
+  }
+  return mppx;
+}

 export async function GET(request: NextRequest) {
   try {
-    const result = await mppx.charge({ amount: "1" })(request);
+    const server = getServer();
+    const result = await server.charge({ amount: "1" })(request);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/mpp/image/generate/route.ts` at line 9, The module currently calls
getMppServer() at top-level which can throw and crash the route; remove the
module-level invocation and replace it with lazy, safe initialization inside the
request handler (or a small cached accessor function) that calls getMppServer()
inside a try/catch, caches the resulting instance on success, and returns a
controlled error (or null) on failure so the handler can return a proper 4xx/5xx
response with diagnostics instead of letting the module fail to load; reference
getMppServer() and the route handler in route.ts and ensure the new accessor
only invokes getMppServer() once and handles missing MPP_SECRET_KEY or other
errors gracefully.

38-50: Manual validation instead of Zod schema.

Per coding guidelines, API endpoints should use Zod for input validation. This route performs manual validation for prompt and files parameters. Consider using a Zod schema for consistency and better error messages.

♻️ Example Zod validation
import { z } from "zod";

const querySchema = z.object({
  prompt: z.string().min(1, "prompt query parameter is required"),
  files: z.string().optional(),
});

// In handler:
const parsed = querySchema.safeParse({
  prompt: searchParams.get("prompt"),
  files: searchParams.get("files"),
});
if (!parsed.success) {
  return result.withReceipt(
    NextResponse.json({ error: parsed.error.issues[0].message }, { status: 400, headers: getCorsHeaders() })
  );
}
const { prompt, files: filesParam } = parsed.data;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/mpp/image/generate/route.ts` around lines 38 - 50, Replace the manual
checks around searchParams.get("prompt") and "files" with a Zod-based validator:
create a querySchema using z.object({ prompt: z.string().min(1, "prompt query
parameter is required"), files: z.string().optional() }), parse the values from
searchParams via schema.safeParse, and if parsing fails return the existing
result.withReceipt NextResponse.json error using parsed.error.issues[0].message
and getCorsHeaders(); on success, pull prompt and filesParam from parsed.data
and continue using those variables (keep existing getPayerAddress(request) and
result.withReceipt usage).

30-103: Missing test coverage for new endpoint.

This is a new API endpoint that handles payment flows and image generation. Based on learnings: "Write tests for new API endpoints covering all success and error paths." Consider adding tests covering:

  • Successful image generation with valid MPP credential
  • 402 response when payment is required
  • 400 responses for missing/invalid prompt and files
  • Error paths (generateImage failure, Arweave upload failure)

Would you like me to help generate test cases for this endpoint?

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

In `@app/api/mpp/image/generate/route.ts` around lines 30 - 103, Add
unit/integration tests for the GET handler in
app/api/mpp/image/generate/route.ts covering all success and error paths: mock
mppx.charge to return a 200 result with withReceipt and a 402 result to assert
the challenge path; test missing prompt by calling GET without the prompt query
and assert the result.withReceipt returns a 400 JSON error; test invalid files
by mocking parseFilesFromQuery to throw and assert 400 JSON error; test
successful flow by mocking generateImage to return {image, usage} and
uploadImageAndCreateMoment to return {arweaveResult, imageUrl, moment,
arweaveError?} and assert the final 200 response contains
image/usage/imageUrl/etc.; and add failure paths by mocking generateImage to
return no image and uploadImageAndCreateMoment to throw or return an
arweaveError and assert proper 500/returned error handling. Ensure tests stub
getPayerAddress and getCorsHeaders as needed and verify mppx.charge is invoked
with {amount: "1"} and request is passed through.
lib/mpp/getPayerAddress.ts (1)

19-24: Missing validation of extracted address format.

The function extracts the last segment of the DID (did:pkh:eip155:<chainId>:<address>) but doesn't validate that it's actually a valid Ethereum address (e.g., starts with 0x, correct length). A malformed DID could result in an invalid address being passed to downstream systems like createImageMoment.

♻️ Add basic address format validation
     if (source) {
       const parts = source.split(":");
-      return parts[parts.length - 1] ?? "";
+      const address = parts[parts.length - 1];
+      // Basic validation: EVM addresses are 42 chars starting with 0x
+      if (address && /^0x[a-fA-F0-9]{40}$/.test(address)) {
+        return address;
+      }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/getPayerAddress.ts` around lines 19 - 24, getPayerAddress currently
takes the last segment from the DID stored in variable source but doesn't
validate it; update getPayerAddress to validate the extracted address (from
parts[parts.length - 1]) against a canonical Ethereum address pattern (e.g.
matches /^0x[a-fA-F0-9]{40}$/) and if it fails validation return an empty string
(or otherwise sanitize) so downstream callers like createImageMoment never
receive a malformed address; keep the existing DID-splitting logic but add this
regex check and fallback.
lib/mpp/fetchWithMppPayment.ts (1)

15-18: Unsafe type cast of environment variable.

The cast as \0x${string}`at line 16 bypasses TypeScript's type checking. IfMPP_PAYMENT_KEYdoesn't start with0x, privateKeyToAccount` will fail with a cryptic error.

♻️ Add format validation
-  const paymentKey = process.env.MPP_PAYMENT_KEY as `0x${string}`;
-  if (!paymentKey) {
+  const paymentKey = process.env.MPP_PAYMENT_KEY;
+  if (!paymentKey || !paymentKey.startsWith("0x")) {
     throw new Error("MPP_PAYMENT_KEY environment variable is required");
+    throw new Error("MPP_PAYMENT_KEY must be a valid hex string starting with 0x");
   }
+  const validatedKey = paymentKey as `0x${string}`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/fetchWithMppPayment.ts` around lines 15 - 18, The function
fetchWithMppPayment currently unsafely casts process.env.MPP_PAYMENT_KEY to
`0x${string}` which can hide malformed keys and cause privateKeyToAccount to
throw; remove the cast and validate the environment value inside
fetchWithMppPayment (read it as string|undefined), check it matches the expected
hex format (e.g. startsWith('0x') and matches /^0x[0-9a-fA-F]{64}$/ or your
project's expected length), and throw a clear Error like "MPP_PAYMENT_KEY must
be a 0x-prefixed 64-hex-char private key" if validation fails before calling
privateKeyToAccount or using paymentKey. Ensure you reference the paymentKey
variable and privateKeyToAccount call so the validation is applied immediately
before usage.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6d79ca86-bbcb-4338-8209-739dfa014403

📥 Commits

Reviewing files that changed from the base of the PR and between 0355d39 and 520f18c.

⛔ Files ignored due to path filters (66)
  • lib/admins/emails/__tests__/validateGetAdminEmailsQuery.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/admins/privy/__tests__/getPrivyLoginsHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/admins/privy/__tests__/validateGetPrivyLoginsQuery.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/ai/__tests__/getAvailableModels.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/ai/__tests__/getModel.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/buildGetArtistsParams.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/checkAccountArtistAccess.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/createArtistInDb.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/createArtistPostHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/validateCreateArtistBody.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/artists/__tests__/validateGetArtistsRequest.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/auth/__tests__/validateAuthContext.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/handleChatCompletion.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/integration/chatEndToEnd.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/saveChatCompletion.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/setupConversation.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/setupToolsForRequest.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/validateChatRequest.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/toolChains/__tests__/getPrepareStepResult.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chats/__tests__/updateChatHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chats/__tests__/validateUpdateChatBody.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/coding-agent/__tests__/handleGitHubWebhook.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/coding-agent/__tests__/onMergeTestToMainAction.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/content/__tests__/validateCreateContentBody.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/credits/__tests__/getCreditUsage.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/credits/__tests__/handleChatCredits.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/evals/callChatFunctions.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/callChatFunctionsWithResult.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/createToolsCalledScorer.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/extractTextFromResult.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/extractTextResultFromSteps.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/getCatalogSongsCountExpected.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/getSpotifyFollowersExpected.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/scorers/CatalogAvailability.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/scorers/QuestionAnswered.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/scorers/ToolsCalled.ts is excluded by !**/evals/** and included by lib/**
  • lib/flamingo/__tests__/getFlamingoPresetsHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/github/__tests__/deleteAccountGithubRepos.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/mcp/__tests__/getMcpTools.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/mcp/__tests__/verifyApiKey.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/mcp/tools/artists/__tests__/registerCreateNewArtistTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/messages/__tests__/convertToUiMessages.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/notifications/__tests__/createNotificationHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/notifications/__tests__/validateCreateNotificationBody.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/organizations/__tests__/canAccessAccount.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/organizations/__tests__/validateOrganizationAccess.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/pulse/__tests__/buildGetPulsesParams.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/pulse/__tests__/getPulsesHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/pulse/__tests__/updatePulsesHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/pulse/__tests__/validateGetPulsesRequest.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/rooms/__tests__/copyRoom.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/account_artist_ids/__tests__/insertAccountArtistId.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/account_artist_ids/__tests__/selectAccountArtistId.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/account_organization_ids/__tests__/selectAccountOrganizationIds.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/account_sandboxes/__tests__/insertAccountSandbox.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/account_workspace_ids/__tests__/selectAccountWorkspaceId.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/accounts/__tests__/selectAccountWithSocials.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/artist_organization_ids/__tests__/selectArtistOrganizationIds.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/pulse_accounts/__tests__/selectPulseAccounts.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/supabase/pulse_accounts/__tests__/upsertPulseAccount.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/tasks/__tests__/deleteTask.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/tasks/__tests__/getTaskRunHandler.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/tasks/__tests__/validateGetTaskRunQuery.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • middleware.ts is excluded by none and included by none
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
📒 Files selected for processing (69)
  • app/api/accounts/[id]/route.ts
  • app/api/admins/privy/route.ts
  • app/api/coding-agent/[platform]/route.ts
  • app/api/image/generate/route.ts
  • app/api/mpp/image/generate/route.ts
  • app/api/songs/analyze/presets/route.ts
  • app/api/transcribe/route.ts
  • app/api/x402/image/generate/route.ts
  • app/api/x402/session-token/route.ts
  • lib/admins/privy/countNewAccounts.ts
  • lib/admins/privy/fetchPrivyLogins.ts
  • lib/admins/privy/getCutoffMs.ts
  • lib/admins/privy/getLatestVerifiedAt.ts
  • lib/admins/privy/toMs.ts
  • lib/ai/getModel.ts
  • lib/ai/isEmbedModel.ts
  • lib/catalog/formatCatalogSongsAsCSV.ts
  • lib/catalog/getCatalogDataAsCSV.ts
  • lib/catalog/getCatalogSongs.ts
  • lib/catalog/getCatalogs.ts
  • lib/chat/toolChains/getPrepareStepResult.ts
  • lib/chats/processCompactChatRequest.ts
  • lib/coding-agent/encodeGitHubThreadId.ts
  • lib/coding-agent/handleMergeSuccess.ts
  • lib/coding-agent/parseMergeActionId.ts
  • lib/coding-agent/parseMergeTestToMainActionId.ts
  • lib/composio/getCallbackUrl.ts
  • lib/content/contentTemplates.ts
  • lib/content/createContentHandler.ts
  • lib/content/getArtistContentReadiness.ts
  • lib/content/getArtistFileTree.ts
  • lib/content/getArtistRootPrefix.ts
  • lib/content/getContentValidateHandler.ts
  • lib/content/isCompletedRun.ts
  • lib/content/persistCreateContentRunVideo.ts
  • lib/content/validateCreateContentBody.ts
  • lib/content/validateGetContentEstimateQuery.ts
  • lib/content/validateGetContentValidateQuery.ts
  • lib/credits/getCreditUsage.ts
  • lib/credits/handleChatCredits.ts
  • lib/emails/processAndSendEmail.ts
  • lib/flamingo/getFlamingoPresetsHandler.ts
  • lib/github/expandSubmoduleEntries.ts
  • lib/github/getRepoGitModules.ts
  • lib/github/resolveSubmodulePath.ts
  • lib/mcp/resolveAccountId.ts
  • lib/mcp/tools/transcribe/registerTranscribeAudioTool.ts
  • lib/mpp/fetchWithMppPayment.ts
  • lib/mpp/getCreditsForPrice.ts
  • lib/mpp/getMppServer.ts
  • lib/mpp/getPayerAddress.ts
  • lib/mpp/recoup/mppGenerateImage.ts
  • lib/prompts/getSystemPrompt.ts
  • lib/spotify/getSpotifyFollowers.ts
  • lib/supabase/account_artist_ids/getAccountArtistIds.ts
  • lib/supabase/account_workspace_ids/getAccountWorkspaceIds.ts
  • lib/supabase/files/createFileRecord.ts
  • lib/supabase/song_artists/insertSongArtists.ts
  • lib/supabase/storage/uploadFileByKey.ts
  • lib/transcribe/processAudioTranscription.ts
  • lib/transcribe/saveAudioToFiles.ts
  • lib/transcribe/saveTranscriptToFiles.ts
  • lib/transcribe/types.ts
  • lib/trigger/triggerCreateContent.ts
  • lib/x402/fetchWithPayment.ts
  • lib/x402/getBuyerAccount.ts
  • lib/x402/getTransferCalls.ts
  • lib/x402/loadAccount.ts
  • lib/x402/recoup/x402GenerateImage.ts
💤 Files with no reviewable changes (7)
  • lib/x402/getBuyerAccount.ts
  • lib/x402/recoup/x402GenerateImage.ts
  • app/api/x402/image/generate/route.ts
  • lib/x402/getTransferCalls.ts
  • lib/x402/fetchWithPayment.ts
  • app/api/x402/session-token/route.ts
  • lib/x402/loadAccount.ts

Comment on lines 25 to 27
* @param request - The request object
* @param params.params
* @param params - Route params containing the account ID
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

Incorrect and redundant @param entry.

Line 26 adds @param params.params which is malformed—there's no params.params in the function signature. The existing line 27 already documents the params parameter correctly. Remove the erroneous line.

📝 Proposed fix
  * `@param` request - The request object
- * `@param` params.params
  * `@param` params - Route params containing the account ID
📝 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
* @param request - The request object
* @param params.params
* @param params - Route params containing the account ID
* `@param` request - The request object
* `@param` params - Route params containing the account ID
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/accounts/`[id]/route.ts around lines 25 - 27, Remove the malformed
JSDoc entry "@param params.params" from the comment block above the account
route handler (the doc that currently lists "@param request" and "@param
params"); the function signature only has "params" so keep the correct "@param
params - Route params containing the account ID" line and delete the
redundant/malformed "@param params.params" line so the JSDoc matches the
handler's parameters.

Comment on lines 12 to 14
* @param request - The incoming verification request
* @param params.params
* @param params - Route params containing the platform name
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

Remove duplicate/incorrect @param entry.

The @param params.params on line 13 is syntactically incorrect and redundant—@param params on line 14 already documents the route parameters. This appears to be an erroneous addition.

🧹 Suggested fix
  * `@param` request - The incoming verification request
- * `@param` params.params
  * `@param` params - Route params containing the platform name
📝 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
* @param request - The incoming verification request
* @param params.params
* @param params - Route params containing the platform name
* `@param` request - The incoming verification request
* `@param` params - Route params containing the platform name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/coding-agent/`[platform]/route.ts around lines 12 - 14, Remove the
erroneous duplicate JSDoc param entry by deleting the incorrect "@param
params.params" line in the route handler's comment block (the one documenting
the function that takes request and params); keep the correct "@param request"
and "@param params" entries so the route.ts JSDoc documents the incoming
verification request and the route params consistently.

Comment on lines 37 to 39
* @param request - The incoming webhook request
* @param params.params
* @param params - Route params containing the platform name
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

Same issue: remove duplicate/incorrect @param entry.

The @param params.params on line 38 should be removed for the same reason as above.

🧹 Suggested fix
  * `@param` request - The incoming webhook request
- * `@param` params.params
  * `@param` params - Route params containing the platform name
📝 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
* @param request - The incoming webhook request
* @param params.params
* @param params - Route params containing the platform name
* `@param` request - The incoming webhook request
* `@param` params - Route params containing the platform name
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/coding-agent/`[platform]/route.ts around lines 37 - 39, Remove the
duplicate/incorrect JSDoc entry "@param params.params" from the route handler's
comment block in app/api/coding-agent/[platform]/route.ts; keep the single
correct "@param params - Route params containing the platform name" line and
ensure the JSDoc only documents the actual parameters used by the exported route
function (e.g., the request and params objects referenced in the route handler).

const { searchParams } = new URL(request.url);
const prompt = searchParams.get("prompt");
const filesParam = searchParams.get("files");
const account = getPayerAddress(request);
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

Payer address not validated after extraction.

getPayerAddress(request) can return an empty string if the Authorization header is missing or malformed. This empty string is passed to uploadImageAndCreateMoment, which silently skips moment creation (see lib/arweave/uploadImageAndCreateMoment.ts:48). Payment attribution is lost without any indication.

🛡️ Add validation for account
     const account = getPayerAddress(request);

+    if (!account) {
+      return result.withReceipt(
+        NextResponse.json(
+          { error: "Could not extract payer address from Authorization header" },
+          { status: 401, headers: getCorsHeaders() },
+        ),
+      );
+    }
+
     if (!prompt) {
📝 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 account = getPayerAddress(request);
const account = getPayerAddress(request);
if (!account) {
return result.withReceipt(
NextResponse.json(
{ error: "Could not extract payer address from Authorization header" },
{ status: 401, headers: getCorsHeaders() },
),
);
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/mpp/image/generate/route.ts` at line 41, The extracted payer address
from getPayerAddress(request) can be an empty string and should be validated
before calling uploadImageAndCreateMoment; update the handler in route.ts to
check the returned account (from getPayerAddress) and if it's falsy/empty,
return a 400/unauthorized response (or throw an appropriate error) with a clear
message instead of passing the empty string into uploadImageAndCreateMoment;
reference the variables/function names getPayerAddress, account, and
uploadImageAndCreateMoment so the check is added immediately after const account
= getPayerAddress(request).

Comment on lines +68 to +77
const { image, usage } = await generateImage(prompt, files);

if (!image) {
return result.withReceipt(
NextResponse.json(
{ error: "Failed to generate image" },
{ status: 500, headers: getCorsHeaders() },
),
);
}
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 | 🔴 Critical

Destructuring before null check causes potential runtime error.

Line 68 destructures { image, usage } from generateImage(prompt, files), but generateImage can return null (per lib/ai/generateImage.ts). The null check at line 70 happens after destructuring, which would throw a TypeError if generateImage returns null.

🐛 Proposed fix
-    const { image, usage } = await generateImage(prompt, files);
+    const result = await generateImage(prompt, files);

-    if (!image) {
+    if (!result) {
       return result.withReceipt(
         NextResponse.json(
           { error: "Failed to generate image" },
           { status: 500, headers: getCorsHeaders() },
         ),
       );
     }

+    const { image, usage } = result;
+
     const {
📝 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 { image, usage } = await generateImage(prompt, files);
if (!image) {
return result.withReceipt(
NextResponse.json(
{ error: "Failed to generate image" },
{ status: 500, headers: getCorsHeaders() },
),
);
}
const imageResponse = await generateImage(prompt, files);
if (!imageResponse) {
return result.withReceipt(
NextResponse.json(
{ error: "Failed to generate image" },
{ status: 500, headers: getCorsHeaders() },
),
);
}
const { image, usage } = imageResponse;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/api/mpp/image/generate/route.ts` around lines 68 - 77, The code
destructures { image, usage } directly from generateImage(prompt, files) but
generateImage can return null, causing a TypeError; change the flow to first
assign the raw result (e.g., const genResult = await generateImage(prompt,
files)), check if genResult is null and handle the error via
result.withReceipt/NextResponse.json with getCorsHeaders, then safely extract
genResult.image and genResult.usage (or destructure after the null check) and
continue.

Comment on lines +21 to +30
const creditsToDeduct = getCreditsForPrice(IMAGE_GENERATE_PRICE);
await deductCredits({ accountId, creditsToDeduct });

const account = privateKeyToAccount(paymentKey);
const mppx = Mppx.create({
methods: [tempo({ account })],
polyfill: false,
});

return mppx.fetch(url, { method: "GET" });
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

Credits deducted before fetch with no rollback on failure.

Credits are deducted at line 22 before mppx.fetch executes at line 30. If the fetch fails (network error, server error, etc.), the user loses credits without receiving the service. According to lib/credits/deductCredits.ts, there's no built-in rollback mechanism.

Consider wrapping in a try-catch with credit restoration on failure, or deferring deduction until after confirmed success.

🛡️ Proposed fix with rollback on failure
+import { restoreCredits } from "@/lib/credits/restoreCredits";
+
 export async function fetchWithMppPayment(url: string, accountId: string): Promise<Response> {
   const paymentKey = process.env.MPP_PAYMENT_KEY as `0x${string}`;
   if (!paymentKey) {
     throw new Error("MPP_PAYMENT_KEY environment variable is required");
   }

   const creditsToDeduct = getCreditsForPrice(IMAGE_GENERATE_PRICE);
   await deductCredits({ accountId, creditsToDeduct });

   const account = privateKeyToAccount(paymentKey);
   const mppx = Mppx.create({
     methods: [tempo({ account })],
     polyfill: false,
   });

-  return mppx.fetch(url, { method: "GET" });
+  try {
+    return await mppx.fetch(url, { method: "GET" });
+  } catch (error) {
+    // Restore credits on fetch failure
+    await restoreCredits({ accountId, creditsToRestore: creditsToDeduct });
+    throw error;
+  }
 }

Note: You'll need to implement restoreCredits or use an existing mechanism.

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

In `@lib/mpp/fetchWithMppPayment.ts` around lines 21 - 30, Credits are being
deducted before the MPP fetch so users lose credits if mppx.fetch fails; modify
the flow in fetchWithMppPayment by either deferring calling deductCredits({
accountId, creditsToDeduct }) until after mppx.fetch succeeds, or wrap the
mppx.fetch call in a try-catch and call a restoreCredits(accountId,
creditsToDeduct) on any failure; locate the code around
getCreditsForPrice(IMAGE_GENERATE_PRICE), deductCredits, privateKeyToAccount,
Mppx.create and mppx.fetch and implement the chosen rollback/defer approach
(ensure restoreCredits exists or add it) so credits are only final on successful
fetch.

Comment on lines +10 to +18
export function getMppServer() {
return Mppx.create({
methods: [
tempo({
recipient: SMART_ACCOUNT_ADDRESS,
}),
],
secretKey: process.env.MPP_SECRET_KEY,
});
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

Missing validation for MPP_SECRET_KEY environment variable.

Unlike fetchWithMppPayment.ts which validates MPP_PAYMENT_KEY and throws a descriptive error if missing, this function passes process.env.MPP_SECRET_KEY directly to Mppx.create without validation. If the variable is unset, this could cause cryptic failures downstream.

🛡️ Proposed fix to add validation
 export function getMppServer() {
+  const secretKey = process.env.MPP_SECRET_KEY;
+  if (!secretKey) {
+    throw new Error("MPP_SECRET_KEY environment variable is required");
+  }
+
   return Mppx.create({
     methods: [
       tempo({
         recipient: SMART_ACCOUNT_ADDRESS,
       }),
     ],
-    secretKey: process.env.MPP_SECRET_KEY,
+    secretKey,
   });
 }
📝 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
export function getMppServer() {
return Mppx.create({
methods: [
tempo({
recipient: SMART_ACCOUNT_ADDRESS,
}),
],
secretKey: process.env.MPP_SECRET_KEY,
});
export function getMppServer() {
const secretKey = process.env.MPP_SECRET_KEY;
if (!secretKey) {
throw new Error("MPP_SECRET_KEY environment variable is required");
}
return Mppx.create({
methods: [
tempo({
recipient: SMART_ACCOUNT_ADDRESS,
}),
],
secretKey,
});
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/getMppServer.ts` around lines 10 - 18, getMppServer currently passes
process.env.MPP_SECRET_KEY straight into Mppx.create without verifying it; add a
validation step at the start of getMppServer to check process.env.MPP_SECRET_KEY
and throw a clear, descriptive error if it's missing (matching the pattern used
in fetchWithMppPayment.ts), then pass the validated value to Mppx.create
(referencing the getMppServer function, MPP_SECRET_KEY env var, and
Mppx.create).

Comment on lines +10 to +28
export function getPayerAddress(request: NextRequest): string {
const authHeader = request.headers.get("Authorization");
if (!authHeader) return "";
try {
// The MPP credential is base64-encoded JSON in the Authorization header
// Format: "Payment <base64>"
const base64 = authHeader.replace(/^Payment\s+/i, "");
const decoded = Buffer.from(base64, "base64").toString("utf-8");
const credential = JSON.parse(decoded);
// source is a DID: "did:pkh:eip155:4217:0x..."
const source: string = credential?.source ?? "";
if (source) {
const parts = source.split(":");
return parts[parts.length - 1] ?? "";
}
} catch {
// ignore parse errors
}
return "";
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

Silent failure pattern may cause undetected payment attribution loss.

Returning an empty string on parsing failures creates a silent failure path. According to the context in app/api/mpp/image/generate/route.ts:41, getPayerAddress(request) is called but never validated. When extraction fails:

  • uploadImageAndCreateMoment silently skips moment creation (see lib/arweave/uploadImageAndCreateMoment.ts:48)
  • Payment attribution via createImageMoment is lost without any indication

Consider either:

  1. Throwing an error for invalid/missing credentials (fail-fast)
  2. Returning null instead of "" to make the failure state explicit and type-checkable
  3. Adding validation in the calling route
🛡️ Option 1: Return null for explicit failure state
-export function getPayerAddress(request: NextRequest): string {
+export function getPayerAddress(request: NextRequest): string | null {
   const authHeader = request.headers.get("Authorization");
-  if (!authHeader) return "";
+  if (!authHeader) return null;
   try {
     const base64 = authHeader.replace(/^Payment\s+/i, "");
     const decoded = Buffer.from(base64, "base64").toString("utf-8");
     const credential = JSON.parse(decoded);
     const source: string = credential?.source ?? "";
     if (source) {
       const parts = source.split(":");
-      return parts[parts.length - 1] ?? "";
+      return parts[parts.length - 1] || null;
     }
   } catch {
     // ignore parse errors
   }
-  return "";
+  return null;
 }
📝 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
export function getPayerAddress(request: NextRequest): string {
const authHeader = request.headers.get("Authorization");
if (!authHeader) return "";
try {
// The MPP credential is base64-encoded JSON in the Authorization header
// Format: "Payment <base64>"
const base64 = authHeader.replace(/^Payment\s+/i, "");
const decoded = Buffer.from(base64, "base64").toString("utf-8");
const credential = JSON.parse(decoded);
// source is a DID: "did:pkh:eip155:4217:0x..."
const source: string = credential?.source ?? "";
if (source) {
const parts = source.split(":");
return parts[parts.length - 1] ?? "";
}
} catch {
// ignore parse errors
}
return "";
export function getPayerAddress(request: NextRequest): string | null {
const authHeader = request.headers.get("Authorization");
if (!authHeader) return null;
try {
// The MPP credential is base64-encoded JSON in the Authorization header
// Format: "Payment <base64>"
const base64 = authHeader.replace(/^Payment\s+/i, "");
const decoded = Buffer.from(base64, "base64").toString("utf-8");
const credential = JSON.parse(decoded);
// source is a DID: "did:pkh:eip155:4217:0x..."
const source: string = credential?.source ?? "";
if (source) {
const parts = source.split(":");
return parts[parts.length - 1] || null;
}
} catch {
// ignore parse errors
}
return null;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/getPayerAddress.ts` around lines 10 - 28, Change getPayerAddress to
return an explicit failure value (null) instead of an empty string and update
its signature to return string | null so callers can detect parse failures;
inside getPayerAddress (function name) keep the same parsing logic but return
null on missing Authorization or JSON/parse errors rather than ""; then update
the callers (the route that calls getPayerAddress in
app/api/mpp/image/generate/route.ts and uploadImageAndCreateMoment /
createImageMoment usages in lib/arweave/uploadImageAndCreateMoment.ts) to
validate for null and either fail-fast (throw/return an error response) or
handle attribution absence explicitly. Ensure tests/type checks are updated to
reflect the new return type.

Comment on lines +25 to +26
const response = await fetchWithMppPayment(mppUrl.toString(), accountId);
return response.json();
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

Missing error handling for non-OK responses.

The function assumes fetchWithMppPayment always returns a successful response. If the MPP endpoint returns a 4xx/5xx status, response.json() may fail or return an error object that doesn't match expected shape.

🛡️ Add response status check
   const response = await fetchWithMppPayment(mppUrl.toString(), accountId);
+  if (!response.ok) {
+    const errorBody = await response.text();
+    throw new Error(`MPP image generation failed: ${response.status} - ${errorBody}`);
+  }
   return response.json();
 }
📝 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 response = await fetchWithMppPayment(mppUrl.toString(), accountId);
return response.json();
const response = await fetchWithMppPayment(mppUrl.toString(), accountId);
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`MPP image generation failed: ${response.status} - ${errorBody}`);
}
return response.json();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/mpp/recoup/mppGenerateImage.ts` around lines 25 - 26, The function
mppGenerateImage currently calls fetchWithMppPayment and directly returns
response.json() without checking HTTP status; update it to check response.ok (or
response.status) after the fetchWithMppPayment call and handle non-2xx responses
by parsing the error body (e.g., await response.text() or response.json()) and
throwing or returning a structured error; ensure callers of mppGenerateImage
receive a consistent error shape. Locate the call site using the symbol
fetchWithMppPayment and the surrounding function (mppGenerateImage) to add the
status check and error handling before returning the JSON.

Comment on lines +9 to 10
* @param songArtists
*/
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

Complete the @param JSDoc description.

@param songArtists is currently undocumented; add a short description so the contract is explicit for callers and tooling.

Suggested update
 /**
  * Inserts song-artist relationships, skipping duplicates.
  *
- * `@param` songArtists
+ * `@param` songArtists Array of song-artist join rows to validate, deduplicate, and upsert.
  */

As per coding guidelines: lib/supabase/**/*.ts functions should follow the documented pattern with JSDoc comments.

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

In `@lib/supabase/song_artists/insertSongArtists.ts` around lines 9 - 10, Add a
short JSDoc description for the `songArtists` parameter on the
`insertSongArtists` function: describe that `songArtists` is the array (or
single item if applicable) of SongArtist records/objects to be inserted into the
song_artists table (include expected shape or model name, e.g., SongArtist or
Partial<SongArtist>), and note whether it may be empty/null and how the function
handles that; update the `@param songArtists` line to a one-sentence description
following the existing JSDoc style used in lib/supabase files.

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