Skip to content

Conversation

@sweetmantech
Copy link
Contributor

@sweetmantech sweetmantech commented Dec 13, 2025

Summary by CodeRabbit

Release Notes

  • New Features
    • AI-powered audience segmentation generation based on fan data
    • Knowledge base creation and management for artist profiles
    • Artist profile updates including image, instructions, and social links
    • Web search functionality
    • Text file generation and decentralized storage
    • Spotify integration for artist and album discovery
    • YouTube authentication support

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Dec 13, 2025

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

Project Deployment Review Updated (UTC)
recoup-api Ready Ready Preview Dec 13, 2025 9:15pm

@coderabbitai
Copy link

coderabbitai bot commented Dec 13, 2025

Caution

Review failed

Failed to post review comments

Walkthrough

This PR introduces comprehensive artist profile management with knowledge base uploads to Arweave, fan segment generation using AI, social media link management, and artist-facing data enrichment. It implements web search via Perplexity API and Spotify data integration. It refactors MCP tool response handling with standardized wrappers and adds extensive Supabase database utilities to support the new features. It also adds YouTube authentication token management.

Changes

Cohort / File(s) Summary
Artist Profile & Knowledge Management
lib/artist/createKnowledgeBase.ts, lib/artist/updateArtistProfile.ts, lib/artist/updateArtistSocials.ts
New functions to create and manage artist knowledge bases with Arweave uploads, update artist profile with image/instruction/label and deduplicated knowledge entries, and update artist social links with platform detection and record reuse.
Segment Generation Pipeline
lib/ai/generateArray.ts, lib/segments/createSegments.ts, lib/segments/createSegmentResponses.ts, lib/segments/generateSegments.ts, lib/segments/getAnalysisPrompt.ts, lib/segments/getFanSegmentsToInsert.ts, lib/segments/consts.ts
New modules implementing AI-driven segment generation from fan social data, including response helpers, analysis prompt construction, and segment-to-fan association building.
Artist Segment Querying Updates
lib/artist/getArtistSegments.ts, lib/artist/mapArtistSegments.ts
Updated to use new selectArtistSegmentsWithDetails function for enhanced joined data retrieval.
MCP Response Utilities
lib/mcp/getCallToolResult.ts, lib/mcp/getToolResultError.ts, lib/mcp/getToolResultSuccess.ts
New standardized response construction helpers for MCP tool handlers, replacing inline content payloads across all tool registrations.
MCP Tool Registrations – Artist & Account
lib/mcp/tools/artistSocials/*, lib/mcp/tools/registerUpdateAccountInfoTool.ts, lib/mcp/tools/registerCreateSegmentsTool.ts
New and updated tool registrations for artist socials management, account profile updates, and segment creation with aggregated registration entry points.
MCP Tool Registrations – Web Search & Files
lib/mcp/tools/registerSearchWebTool.ts, lib/mcp/tools/files/*, lib/mcp/tools/catalogs/register*Tool.ts, lib/mcp/tools/images/register*Tool.ts, lib/mcp/tools/tasks/register*Tool.ts
New web search tool registration and file management tools (knowledge base, TXT generation); existing catalog, image, and task tools refactored to use standardized response wrappers.
MCP Tool Registrations – Spotify Integration
lib/mcp/tools/spotify/*
Complete new Spotify toolkit with search, artist data, albums, and deep research tools; aggregated registration entry point.
MCP Tool Registrations – Media & Other
lib/mcp/tools/youtube/*, lib/mcp/tools/registerContactTeamTool.ts, lib/mcp/tools/registerGetLocalTimeTool.ts, lib/mcp/tools/sora2/register*Tool.ts, lib/mcp/tools/index.ts
New YouTube login tool, refactored miscellaneous tools to use standardized responses, and updated main tool registry to wire new aggregators.
Perplexity Web Search API
lib/perplexity/config.ts, lib/perplexity/searchPerplexity.ts, lib/perplexity/formatSearchResultsAsMarkdown.ts
New Perplexity API integration with configuration, search execution, and Markdown formatting for search results.
Arweave & File Storage
lib/arweave/uploadTextToArweave.ts, lib/files/generateAndStoreTxtFile.ts
New functions to upload text and generate TXT files with metadata storage on Arweave.
Supabase Database Helpers – Account & Profile
lib/supabase/accounts/*, lib/supabase/account_info/*, lib/supabase/account_socials/*
New database helpers for account selection, account info updates, and social link management.
Supabase Database Helpers – Segments & Fans
lib/supabase/segments/*, lib/supabase/artist_segments/*, lib/supabase/fan_segments/*, lib/supabase/social_fans/selectSocialFans.ts
New and refactored segment and fan segment insertion/deletion; new detailed segment query with joined data; new social fan selection with ordering and filtering support.
Supabase Database Helpers – Socials & Tokens
lib/supabase/socials/insertSocials.ts, lib/supabase/socials/selectSocials.ts, lib/supabase/youtube_tokens/selectYouTubeTokens.ts
New socials insertion helper, updated socials selection with profile URL filtering, and new YouTube token retrieval.
Supporting Infrastructure
lib/youtube/isTokenExpired.ts
New utility to check YouTube token expiration with 1-minute safety buffer.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant MCP Server
    participant createSegments
    participant generateSegments
    participant generateArray
    participant Supabase
    participant Arweave
    
    Client->>MCP Server: Call create_segments tool<br/>(artist_account_id, prompt)
    MCP Server->>createSegments: createSegments(args)
    createSegments->>Supabase: selectAccounts(artist_account_id)
    Supabase-->>createSegments: account + artist name
    createSegments->>Supabase: selectSocialFans(artist_account_id)
    Supabase-->>createSegments: fans with social details
    createSegments->>generateSegments: generateSegments({fans, prompt})
    generateSegments->>generateArray: generateArray(SYSTEM_PROMPT, analysis_prompt)
    generateArray-->>generateSegments: [GenerateArrayResult]
    generateSegments-->>createSegments: segment definitions
    createSegments->>Supabase: deleteSegments(artist_account_id)
    Supabase-->>createSegments: deleted segments
    createSegments->>Supabase: insertSegments(segment_definitions)
    Supabase-->>createSegments: inserted segments with IDs
    createSegments->>Supabase: insertArtistSegments(associations)
    Supabase-->>createSegments: artist_segments records
    createSegments->>Supabase: insertFanSegments(fan_associations)
    Supabase-->>createSegments: fan_segments records
    createSegments-->>MCP Server: successResponse(data)
    MCP Server-->>Client: success + segment results

Loading
sequenceDiagram
    participant Client
    participant MCP Server
    participant updateArtistProfile
    participant Arweave
    participant Supabase
    
    Client->>MCP Server: Call update_account_info tool<br/>(artistId, image, name, etc.)
    MCP Server->>updateArtistProfile: updateArtistProfile(fields)
    updateArtistProfile->>Supabase: selectAccounts(artistId)
    Supabase-->>updateArtistProfile: artist account
    alt Account not found
        updateArtistProfile-->>MCP Server: error
    end
    updateArtistProfile->>Supabase: updateAccount(name)
    Supabase-->>updateArtistProfile: updated account
    updateArtistProfile->>Supabase: selectAccountInfo(accountId)
    Supabase-->>updateArtistProfile: existing account_info or null
    alt account_info exists
        updateArtistProfile->>Supabase: updateAccountInfo(fields, deduped knowledges)
    else account_info not found
        updateArtistProfile->>Supabase: insertAccountInfo(new record)
    end
    Supabase-->>updateArtistProfile: updated/inserted account_info
    updateArtistProfile->>Supabase: selectAccountInfo + selectAccounts (concurrent)
    Supabase-->>updateArtistProfile: merged ArtistProfile
    updateArtistProfile-->>MCP Server: ArtistProfile
    MCP Server-->>Client: success + updated profile

Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Segment generation flow (lib/segments/createSegments.ts, lib/segments/generateSegments.ts) – orchestrates multiple Supabase queries, AI model calls, and data transformations; verify deduplication logic and fan-to-segment association correctness
  • MCP response refactoring – all MCP tool registrations updated to use new standardized wrappers; spot-check a few tool handlers to ensure response structure integrity
  • Artist profile updates (lib/artist/updateArtistProfile.ts) – handles knowledge deduplication by URL and conditional account_info insert/update; verify edge cases with missing/null knowledge fields
  • Arweave integration (lib/arweave/uploadTextToArweave.ts, lib/files/generateAndStoreTxtFile.ts) – tolerates upload failures but logs; verify error handling paths do not silently fail
  • Supabase selectArtistSegmentsWithDetails – new complex join query with pagination; verify pagination range math and null-handling for joined fields
  • Perplexity API integration – new external API; verify error handling, rate limiting, and API key validation paths

Possibly related PRs

Poem

🐰 Segments spring from fan hearts true,
Knowledge on Arweave, profiles made new,
Spotify harmonies, searches so keen,
Artists empowered—the best we've seen! 🎵✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title references the primary change—YouTube login MCP tool registration—but uses a jira-ticket-style format that is somewhat unclear. The format 'Sweetmantech/myc 3742 mcp youtube login' mixes a branch prefix with a ticket number, making it less clear than a direct description. Consider rephrasing to a more direct format like 'Add MCP YouTube login tool registration' or 'Implement YouTube authentication MCP tool' for better clarity and scannability.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sweetmantech/myc-3742-mcp-youtube_login

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.

@sweetmantech sweetmantech changed the base branch from main to test December 13, 2025 21:19
Copy link

@vercel vercel bot left a comment

Choose a reason for hiding this comment

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

Additional Suggestions:

  1. The updateAccountInfo function call is not checked for errors. If the update fails, the error is silently logged but the function continues and returns the old profile data, making it appear as if the update succeeded.
View Details
📝 Patch Details
diff --git a/lib/artist/updateArtistProfile.ts b/lib/artist/updateArtistProfile.ts
index 9c7cbd0..df874aa 100644
--- a/lib/artist/updateArtistProfile.ts
+++ b/lib/artist/updateArtistProfile.ts
@@ -68,16 +68,22 @@ export async function updateArtistProfile(
       infoUpdate.label = label === "" ? null : label;
     }
 
-    await updateAccountInfo(artistId, infoUpdate);
+    const updatedAccountInfo = await updateAccountInfo(artistId, infoUpdate);
+    if (!updatedAccountInfo) {
+      throw new Error("Failed to update account info");
+    }
   } else {
     // Create new account_info
-    await insertAccountInfo({
+    const newAccountInfo = await insertAccountInfo({
       image: image || null,
       instruction: instruction || null,
       knowledges: knowledges || null,
       label: label === "" ? null : label || null,
       account_id: artistId,
     });
+    if (!newAccountInfo) {
+      throw new Error("Failed to create account info");
+    }
   }
 
   // Fetch and return the latest account and account_info

Analysis

Silent data loss in updateArtistProfile when database operations fail

What fails: The updateArtistProfile() function in lib/artist/updateArtistProfile.ts does not check the return values of updateAccountInfo() (line 71) and insertAccountInfo() (line 76). When these database operations fail, they return null but the function continues execution, refetches the old/unchanged data, and returns it as if the update succeeded.

How to reproduce:

  1. Call updateArtistProfile(artistId, image, name, instruction, label, knowledges) where the account_info record exists
  2. Inject a failure in the Supabase database layer (or simulate network failure) causing updateAccountInfo to fail
  3. The function logs the error to console but continues execution
  4. selectAccountInfo is called at line 85 and returns the OLD (unchanged) data from the database
  5. Function returns success: true with old data

Result: The caller receives the old profile data with no indication that the update failed. Changes are not persisted to the database, but the caller believes they succeeded.

Expected behavior: Per the pattern established in lines 46-49 where updateAccount is checked with if (!updatedAccount) throw new Error(), the updateAccountInfo call should also check its return value and throw an error on failure, preventing the function from returning false success.

Root cause: Unchecked return values on database operation functions that can fail and return null:

  • updateAccountInfo() returns Tables<"account_info"> | null
  • insertAccountInfo() returns Tables<"account_info"> | null

Both log errors but do not throw, requiring the caller to check the return value. The updateArtistProfile function failed to do this check, creating a silent failure scenario.

2. The `deleteAccountSocial` and `insertAccountSocial` function calls don\'t check return values\. If these database operations fail\, the errors are silently logged but the function continues\, returning a success response with potentially inconsistent data\.
View Details
📝 Patch Details
diff --git a/lib/artist/updateArtistSocials.ts b/lib/artist/updateArtistSocials.ts
index 12fc25c..0671f21 100644
--- a/lib/artist/updateArtistSocials.ts
+++ b/lib/artist/updateArtistSocials.ts
@@ -32,7 +32,12 @@ export async function updateArtistSocials(
 
     // Delete existing social for this platform type if it exists
     if (existingSocial && existingSocial.social?.id) {
-      await deleteAccountSocial(artistId, existingSocial.social.id);
+      const deleteSuccess = await deleteAccountSocial(artistId, existingSocial.social.id);
+      if (!deleteSuccess) {
+        throw new Error(
+          `Failed to delete existing account social for artist ${artistId} and social ${existingSocial.social.id}`,
+        );
+      }
     }
 
     // Insert new social if URL provided
@@ -43,7 +48,12 @@ export async function updateArtistSocials(
           (as: AccountSocialWithSocial) => as.social_id === social.id,
         );
         if (!existing) {
-          await insertAccountSocial(artistId, social.id);
+          const insertResult = await insertAccountSocial(artistId, social.id);
+          if (!insertResult) {
+            throw new Error(
+              `Failed to insert account social for artist ${artistId} and social ${social.id}`,
+            );
+          }
         }
       } else {
         // Create new social record
@@ -54,7 +64,12 @@ export async function updateArtistSocials(
           },
         ]);
         if (newSocials.length > 0) {
-          await insertAccountSocial(artistId, newSocials[0].id);
+          const insertResult = await insertAccountSocial(artistId, newSocials[0].id);
+          if (!insertResult) {
+            throw new Error(
+              `Failed to insert account social for artist ${artistId} and social ${newSocials[0].id}`,
+            );
+          }
         }
       }
     }

Analysis

Unchecked database operation failures in updateArtistSocials allows inconsistent responses

What fails: updateArtistSocials() ignores return values from deleteAccountSocial() and insertAccountSocial(), logging errors but continuing execution and returning a success response even when database operations fail.

How to reproduce:

  • Call updateArtistSocials() with artistId and profileUrls to update artist socials
  • When deleteAccountSocial() or insertAccountSocial() encounters a database error (e.g., due to constraint violation, permission error, or connection issue), the function returns false/null respectively
  • The error is logged to console but the function continues execution
  • updateArtistSocials() completes and returns the current state of socials from the database
  • The MCP tool (registerUpdateArtistSocialsTool) receives the data and returns success: true with the incomplete/unchanged social relationships
  • Caller believes the update succeeded when it actually failed

Result: The database operation failures are silently ignored. If deleteAccountSocial fails, the old social isn't removed. If insertAccountSocial fails, the new social isn't linked. The caller receives a success response with data that doesn't reflect what was requested.

Expected: When deleteAccountSocial or insertAccountSocial fail, an error should be thrown and propagated to the caller, preventing the function from returning a false success response.

References:

  • deleteAccountSocial returns boolean with false on error (lib/supabase/account_socials/deleteAccountSocial.ts line 19)
  • insertAccountSocial returns null on error (lib/supabase/account_socials/insertAccountSocial.ts line 22)
  • Three locations in updateArtistSocials where return values are not checked (lines 35, 46, 57)
  • Similar pattern in other codebase functions like insertAccount (lib/supabase/accounts/insertAccount.ts) which properly throw errors on failure

@sweetmantech sweetmantech merged commit a967d38 into test Dec 13, 2025
3 checks passed
This was referenced Dec 15, 2025
Merged
Merged
@coderabbitai coderabbitai bot mentioned this pull request Jan 6, 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.

2 participants