Skip to content

feat: add dsp enum parameter for DSP logo overlay (REC-63)#436

Open
recoup-coding-agent wants to merge 1 commit intotestfrom
feature/rec-63-dsp-logo
Open

feat: add dsp enum parameter for DSP logo overlay (REC-63)#436
recoup-coding-agent wants to merge 1 commit intotestfrom
feature/rec-63-dsp-logo

Conversation

@recoup-coding-agent
Copy link
Copy Markdown
Collaborator

@recoup-coding-agent recoup-coding-agent commented Apr 14, 2026

Summary

  • Add dsp parameter (none | spotify | apple) to the content creation pipeline
  • New DSP_VALUES constant and DspValue type in lib/content/dspValues.ts
  • dsp field added to API validation schema, trigger payload, content prompt agent, and Slack mention handler
  • 4 new tests for validation and prompt extraction

Test plan

  • validateCreateContentBody accepts dsp and defaults to none
  • validateCreateContentBody rejects invalid dsp values with 400
  • parseContentPrompt extracts dsp from natural language
  • All 1898 existing API tests still pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added DSP logo overlay selection for content creation. Users can now choose Spotify, Apple Music, or none during content generation; the system infers the selection from prompt text with "none" as the default option.

Add `dsp` parameter ("none" | "spotify" | "apple") to the content
creation pipeline. The parameter flows from API validation through
the Slack bot AI parser to the Trigger.dev task payload.

- Add DSP_VALUES constant and DspValue type
- Add dsp field to createContentBodySchema with "none" default
- Add dsp to content prompt agent schema for Slack bot parsing
- Pass dsp through createContentHandler and triggerCreateContent
- Add 4 new tests for dsp validation and prompt extraction

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 14, 2026

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

Project Deployment Actions Updated (UTC)
recoup-api Ready Ready Preview Apr 14, 2026 8:29pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 14, 2026

📝 Walkthrough

Walkthrough

This pull request adds support for a new dsp (Digital Service Provider) field throughout the content prompt parsing and creation pipeline. The field captures which music streaming service logo—Spotify, Apple Music, or none—should overlay generated content, with the value inferred from prompt text and defaulting to "none".

Changes

Cohort / File(s) Summary
DSP Value Definitions
lib/content/dspValues.ts
Introduced DSP_VALUES readonly tuple and DspValue type alias to define and synchronize allowed DSP values ("none", "spotify", "apple").
Agent Schema & Defaults
lib/agents/content/createContentPromptAgent.ts
Extended contentPromptFlagsSchema with enum-constrained dsp field, updated DEFAULT_CONTENT_PROMPT_FLAGS to include dsp: "none", and refreshed agent instructions to document the new field.
Handler & Payload Propagation
lib/agents/content/handlers/registerOnNewMention.ts, lib/trigger/triggerCreateContent.ts
Updated handler to destructure dsp from parsed prompt flags and pass it through to trigger payload; expanded TriggerCreateContentPayload interface to include required dsp field.
Validation & Normalization
lib/content/validateCreateContentBody.ts, lib/content/createContentHandler.ts
Added dsp field validation with enum constraint and "none" default to request schema; extended ValidatedCreateContentBody type; propagated validated dsp into content handler payload.

Sequence Diagram

sequenceDiagram
    participant Slack as Slack Mention
    participant Handler as registerOnNewMention
    participant Agent as createContentPromptAgent
    participant Validator as validateCreateContentBody
    participant Trigger as triggerCreateContent

    Slack->>Handler: Parse mention with dsp phrase
    Handler->>Agent: Call parseContentPrompt()
    Agent->>Agent: Extract dsp from prompt<br/>(enum: "none"|"spotify"|"apple")
    Agent-->>Handler: Return flags { dsp, ... }
    Handler->>Handler: Destructure { dsp } from flags
    Handler->>Validator: Pass dsp in payload
    Validator->>Validator: Validate dsp against<br/>DSP_VALUES enum
    Validator-->>Handler: Return validated object<br/>{ dsp: DspValue, ... }
    Handler->>Trigger: Invoke triggerCreateContent<br/>with dsp in payload
    Trigger->>Trigger: Forward dsp to task<br/>CREATE_CONTENT_TASK_ID
Loading

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly Related PRs

Suggested Reviewers

  • sweetmantech

Poem

🎵 A DSP field takes flight,
Through schemas, handlers, shining bright,
Spotify, Apple, none so true—
Content overlays, refreshed and new! ✨

🚥 Pre-merge checks | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Solid & Clean Code ⚠️ Warning The dsp type is hardcoded inline in triggerCreateContent.ts instead of importing the centralized DspValue type from dspValues.ts, violating DRY principles. Import DspValue from @/lib/content/dspValues and replace the hardcoded string literal union with DspValue on line 12.

✏️ 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 feature/rec-63-dsp-logo

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.

🧹 Nitpick comments (2)
lib/agents/content/handlers/registerOnNewMention.ts (1)

26-27: Optional: surface dsp in thread details/state for better traceability.

You pass dsp into the task correctly; consider also showing/storing it in thread metadata so operators can confirm what was requested.

Also applies to: 72-72

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

In `@lib/agents/content/handlers/registerOnNewMention.ts` around lines 26 - 27,
The thread metadata/state isn’t recording the parsed dsp value from
parseContentPrompt; update the handler to include dsp in the thread details so
operators can see what DSP was requested. Specifically, after calling
parseContentPrompt(...) (the destructuring that yields dsp) add dsp to the
thread/state object updated by the handler (the same place you set batch,
captionLength, template, etc.), and also ensure any later code paths that create
or update the task (the code around where tasks are enqueued/created) propagate
that dsp into thread details/state so it’s visible in UI/logs (apply the same
change in the other analogous handler location that handles task
creation/update).
lib/trigger/triggerCreateContent.ts (1)

11-12: Reuse DspValue instead of duplicating the DSP union.

Line 12 hardcodes values already defined in lib/content/dspValues.ts, which can drift over time.

♻️ Proposed refactor
 import { tasks } from "@trigger.dev/sdk";
 import { CREATE_CONTENT_TASK_ID } from "@/lib/const";
+import type { DspValue } from "@/lib/content/dspValues";
@@
-  /** Which DSP logo to overlay on the video: "none", "spotify", or "apple". */
-  dsp: "none" | "spotify" | "apple";
+  /** Which DSP logo to overlay on the video. */
+  dsp: DspValue;

As per coding guidelines "Use constants for repeated values" and "Extract shared logic into reusable utilities following Don't Repeat Yourself (DRY) principle".

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

In `@lib/trigger/triggerCreateContent.ts` around lines 11 - 12, The dsp property
in triggerCreateContent.ts currently duplicates the DSP union ("none" |
"spotify" | "apple"); replace this hardcoded union with the shared type DspValue
from lib/content/dspValues.ts by importing DspValue and using it for the dsp
field (e.g., change dsp: "none" | "spotify" | "apple" to dsp: DspValue), and
update any related type references in triggerCreateContent.ts to use DspValue so
the definition stays in sync with the canonical source.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@lib/agents/content/handlers/registerOnNewMention.ts`:
- Around line 26-27: The thread metadata/state isn’t recording the parsed dsp
value from parseContentPrompt; update the handler to include dsp in the thread
details so operators can see what DSP was requested. Specifically, after calling
parseContentPrompt(...) (the destructuring that yields dsp) add dsp to the
thread/state object updated by the handler (the same place you set batch,
captionLength, template, etc.), and also ensure any later code paths that create
or update the task (the code around where tasks are enqueued/created) propagate
that dsp into thread details/state so it’s visible in UI/logs (apply the same
change in the other analogous handler location that handles task
creation/update).

In `@lib/trigger/triggerCreateContent.ts`:
- Around line 11-12: The dsp property in triggerCreateContent.ts currently
duplicates the DSP union ("none" | "spotify" | "apple"); replace this hardcoded
union with the shared type DspValue from lib/content/dspValues.ts by importing
DspValue and using it for the dsp field (e.g., change dsp: "none" | "spotify" |
"apple" to dsp: DspValue), and update any related type references in
triggerCreateContent.ts to use DspValue so the definition stays in sync with the
canonical source.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b73e28ee-1e86-4b1b-be14-92c100025a84

📥 Commits

Reviewing files that changed from the base of the PR and between b9341e3 and daaf8d3.

⛔ Files ignored due to path filters (2)
  • lib/agents/content/__tests__/parseContentPrompt.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/**
📒 Files selected for processing (6)
  • lib/agents/content/createContentPromptAgent.ts
  • lib/agents/content/handlers/registerOnNewMention.ts
  • lib/content/createContentHandler.ts
  • lib/content/dspValues.ts
  • lib/content/validateCreateContentBody.ts
  • lib/trigger/triggerCreateContent.ts

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 8 files

Confidence score: 4/5

  • This PR looks safe to merge overall, with low functional risk; the noted issue is a maintainability/type-consistency concern rather than a clear runtime regression.
  • Most severe issue: lib/trigger/triggerCreateContent.ts duplicates the DSP union instead of reusing DspValue from lib/content/dspValues.ts, which can cause type drift and future mismatches if allowed values change.
  • Given severity 5/10 (high confidence) and no concrete user-facing break described, this is a minor-to-moderate cleanup item rather than a merge blocker.
  • Pay close attention to lib/trigger/triggerCreateContent.ts and lib/content/dspValues.ts - ensure DspValue is the single source of truth to avoid divergence.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="lib/trigger/triggerCreateContent.ts">

<violation number="1" location="lib/trigger/triggerCreateContent.ts:12">
P2: Use the `DspValue` type from `lib/content/dspValues.ts` instead of duplicating the union inline. This PR already introduces `DspValue` as the single source of truth for valid DSP values—using the inline union here creates a second definition that can drift.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant User as User / Client
    participant Slack as Slack Webhook
    participant API as Content Handler
    participant Agent as LLM Agent (ContentPrompt)
    participant Val as Zod Validation
    participant Trigger as Trigger.dev (Task Queue)

    Note over User, Trigger: Content Creation Flow with DSP Logo Selection

    alt Flow A: Natural Language (e.g., Slack)
        User->>Slack: "Make a Spotify editorial video"
        Slack->>API: registerOnNewMention(message)
        API->>Agent: NEW: parseContentPrompt(text)
        Note right of Agent: Extracts dsp: "spotify" from text
        Agent-->>API: Return prompt flags (inc. dsp)
    else Flow B: Structured API Request
        User->>API: POST /api/content { "dsp": "apple" }
        API->>Val: NEW: validateCreateContentBody(body)
        alt Invalid Enum Value (e.g., "tidal")
            Val-->>API: Throw 400 Bad Request
            API-->>User: 400 Error
        else Valid Value or Omitted
            Val-->>API: Return ValidatedCreateContentBody
        end
    end

    API->>Trigger: NEW: triggerCreateContent(payload)
    Note right of Trigger: Payload includes dsp: "none" | "spotify" | "apple"
    
    Trigger->>Trigger: Execute background content generation<br/>with DSP logo overlay logic
Loading

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

/** Controls caption length: "none" skips captions, "short", "medium", or "long". */
captionLength: "none" | "short" | "medium" | "long";
/** Which DSP logo to overlay on the video: "none", "spotify", or "apple". */
dsp: "none" | "spotify" | "apple";
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot Apr 14, 2026

Choose a reason for hiding this comment

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

P2: Use the DspValue type from lib/content/dspValues.ts instead of duplicating the union inline. This PR already introduces DspValue as the single source of truth for valid DSP values—using the inline union here creates a second definition that can drift.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At lib/trigger/triggerCreateContent.ts, line 12:

<comment>Use the `DspValue` type from `lib/content/dspValues.ts` instead of duplicating the union inline. This PR already introduces `DspValue` as the single source of truth for valid DSP values—using the inline union here creates a second definition that can drift.</comment>

<file context>
@@ -8,6 +8,8 @@ export interface TriggerCreateContentPayload {
   /** Controls caption length: "none" skips captions, "short", "medium", or "long". */
   captionLength: "none" | "short" | "medium" | "long";
+  /** Which DSP logo to overlay on the video: "none", "spotify", or "apple". */
+  dsp: "none" | "spotify" | "apple";
   /** Whether to upscale image and video for higher quality. */
   upscale: boolean;
</file context>
Fix with Cubic

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