A feed schema that only supports a single activity type (post) cannot evolve to include likes, comments, follows, or shares without a full schema migration. When type support is added ad-hoc through if/else chains in the renderer, each new type adds a branch, tests, and cognitive overhead — the component becomes a maintenance liability under ISO 25010:2011. More concretely, the absence of a type discriminator on the Activity model means you cannot query or filter by activity type, which blocks every notification and analytics feature that depends on distinguishing activity kinds.
Medium because the maintainability impact is indirect — code still works for the single type — but adding any second activity type without this structure triggers a disruptive schema migration.
Add a type discriminator field to your activity or post schema, then replace branching renderer logic with a component factory in components/feed/ActivityRenderer.tsx.
// Prisma schema
model Activity {
id String @id @default(cuid())
type String // 'post' | 'like' | 'comment' | 'follow'
userId String
targetId String?
content String?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id])
}
// components/feed/ActivityRenderer.tsx
const renderers: Record<string, React.FC<{ activity: Activity }>> = {
post: PostActivity,
like: LikeActivity,
comment: CommentActivity,
follow: FollowActivity
}
export function ActivityRenderer({ activity }: { activity: Activity }) {
const Component = renderers[activity.type]
return Component ? <Component activity={activity} /> : null
}
This pattern lets you add new activity types by registering a new entry in renderers without touching the router or switch logic.
ID: community-social-engagement.activity-feeds.polymorphic-feed-items
Severity: medium
What to look for: Enumerate all relevant files and Examine feed components and the Post/Activity schema. Check for support of multiple activity types: posts, comments, likes, shares, follows, reactions, etc. Look for either: (a) a type discriminator field (e.g., activity_type, kind), (b) a component factory pattern that routes render logic, or (c) a schema with different tables per activity type. Verify the component avoids excessive if statements for each type.
Pass criteria: At least 1 implementation must be present. Multiple activity types are supported by the schema (evidenced by a type field, separate tables, or extensible design). Components use a factory or discriminator pattern to render different activity types cleanly.
Fail criteria: Only one activity type (posts) is supported, or the rendering component is a giant if/else block with hardcoded logic for each type.
Skip (N/A) when: Feed only shows posts (single activity type).
Detail on fail: "Post table has no type field; feed only supports post activities" or "FeedItem component has 20+ if/else branches for different activity types"
Remediation: Use a polymorphic schema and factory component:
// Prisma schema
model Activity {
id String @id
type String // 'post', 'like', 'comment', 'follow'
userId String
targetId String? // Post ID if type is 'like'/'comment'
content String?
createdAt DateTime
user User @relation(fields: [userId], references: [id])
}
// Component factory
function ActivityRenderer({ activity }) {
switch (activity.type) {
case 'post':
return <PostActivity activity={activity} />
case 'like':
return <LikeActivity activity={activity} />
case 'comment':
return <CommentActivity activity={activity} />
default:
return null
}
}