Skip to content

Add content_type support for fiction vs cartoon storylines#1216

Merged
realproject7 merged 2 commits into
mainfrom
task/1212-content-type-foundation
May 16, 2026
Merged

Add content_type support for fiction vs cartoon storylines#1216
realproject7 merged 2 commits into
mainfrom
task/1212-content-type-foundation

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • Adds content_type column (fiction | cartoon, default fiction) to storylines table via migration
  • /api/index/storyline accepts and validates contentType param, rejects invalid values with 400
  • /api/storyline/update allows admin-only updates to content_type
  • Story cards and detail page display a "Cartoon" badge for cartoon storylines
  • Updated Supabase types, added CONTENT_TYPES constant, unit tests for badge and validation

Closes #1212

Test plan

  • TypeScript typecheck passes
  • ESLint passes (no new errors)
  • Unit tests pass (StoryCard Cartoon badge, content-type validation)
  • RE1/RE2 review: verify migration applies cleanly
  • Verify default fiction for existing rows after migration
  • Test indexing a cartoon storyline via API
  • Test invalid contentType rejection (400)
  • Test admin-only update restriction (403 for non-admin)

🤖 Generated with Claude Code

Adds a content_type column to storylines (default 'fiction') to distinguish
fiction from cartoon content. The index endpoint validates the field, the
update endpoint allows admin changes, and story cards/detail pages display
a Cartoon badge when applicable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 16, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored May 16, 2026 10:56pm

Request Review

Copy link
Copy Markdown
Owner Author

@realproject7 realproject7 left a comment

Choose a reason for hiding this comment

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

RE2 Review: ✅ Approve

Clean implementation — migration is safe (NOT NULL DEFAULT won't break existing rows), API validation is correct with shared CONTENT_TYPES constant, admin-only gate on updates is properly enforced with 403, and badge rendering follows existing patterns.

Minor non-blocking note: no CHECK constraint on the column, so direct DB inserts could bypass validation. This is consistent with how genre/language are handled in the codebase, so not a blocker.

CI: lint-and-typecheck green, e2e pending at time of review.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: REQUEST CHANGES

Summary

The PR implements the main API/UI wiring for content_type, but the allowed value contract is not fully enforced. Invalid supplied values can still silently become fiction, and the database does not protect the foundational storylines.content_type column from out-of-band invalid writes.

Findings

  • [medium] Invalid non-string/falsy contentType values are accepted as the default fiction instead of being rejected with 400.

    • File: src/app/api/index/storyline/route.ts:49
    • Suggestion: Validate based on property presence, not truthiness. For example, when contentType is present, require it to be a string and one of CONTENT_TYPES; only default to fiction when the field is absent.
  • [medium] The migration adds content_type without a database constraint, so the stated allowed values are not enforced at the source of truth.

    • File: supabase/migrations/00039_add_content_type.sql:2
    • Suggestion: Add a CHECK constraint such as content_type IN ('fiction', 'cartoon'), ideally named, so admin SQL, service-role jobs, or future endpoints cannot persist unsupported content types.

Decision

Requesting changes because #1212 defines content_type as the foundation for downstream cartoon work. That field needs strict value enforcement before later tickets depend on it. Note: lint/typecheck is green, but e2e was still pending at review time.

…aint

- Reject non-string/invalid contentType with 400 when field is present
- Add CHECK constraint to migration ensuring only fiction/cartoon persisted

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

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

Verdict: APPROVE

Summary

The requested fixes are in place. contentType is now rejected when present but non-string/invalid, and the migration adds a named CHECK constraint enforcing fiction/cartoon at the database layer.

Findings

  • None blocking.

Decision

Approved. The prior RE1 findings are resolved. lint-and-typecheck is green on the updated commit; e2e was still pending at approval time and should be verified before merge.

Copy link
Copy Markdown
Owner Author

@realproject7 realproject7 left a comment

Choose a reason for hiding this comment

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

RE2 Re-review: ✅ Approve

Both fixes correctly address RE1's findings:

  1. Strict validation — uses "contentType" in body for presence check, rejects non-string/invalid with 400, only defaults to fiction when field is absent.
  2. CHECK constraint added to migration — DB-level enforcement now in place.

lint-and-typecheck green. e2e pending. No further concerns from RE2.

@realproject7 realproject7 merged commit c416820 into main May 16, 2026
4 checks passed
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.

Add content_type support for fiction vs cartoon stories

2 participants