Skip to content

feat(api): add feed sentiment backend support#3596

Open
Daily-Dave wants to merge 2 commits intomainfrom
eng-720-add-sentiment-popup-to-feed
Open

feat(api): add feed sentiment backend support#3596
Daily-Dave wants to merge 2 commits intomainfrom
eng-720-add-sentiment-popup-to-feed

Conversation

@Daily-Dave
Copy link

This PR implements backend infrastructure for capturing and storing user feed sentiment feedback to support the frontend sentiment popup feature.

Changes

  • FeedSentiment Entity: Created TypeORM entity to store user sentiment feedback (good/neutral/bad)
  • GraphQL Mutation: Added submitFeedSentiment mutation with rate limiting (5 submissions/hour)
  • Database Migration: Added feed_sentiment table with indexes on userId, sentiment, and createdAt
  • Validation: Sentiment value validation with proper GraphQL error handling using ValidationError

Key Decisions

  • Rate limit set to 5 submissions per hour to prevent abuse while allowing legitimate feedback
  • Foreign key constraint with CASCADE delete ensures data cleanup when users are deleted
  • Used ValidationError for GraphQL validation errors per best practices
  • Avoided barrel file imports (User entity imported directly from './user/User')

Closes ENG-720


Created by Huginn 🐦‍⬛

Daily-Dave and others added 2 commits February 17, 2026 11:04
Implement backend infrastructure for capturing and storing user feed sentiment feedback.

**Features:**
- FeedSentiment entity with TypeORM
- GraphQL mutation submitFeedSentiment with rate limiting
- Database migration for feed_sentiment table
- Foreign key constraint to user table with CASCADE delete
- Indexes on userId, sentiment, and createdAt for efficient querying

**Technical Details:**
- Rate limited to 5 submissions per hour per user
- Validates sentiment values (good, neutral, bad)
- Registered in GraphQL schema with typeDefs and resolvers
- Migration: 1771326220000-AddFeedSentimentTable.ts

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
**Critical Fixes:**
- Fix User import path from './user' to './user/User' (CLAUDE.md compliance)
- Use ValidationError instead of Error for GraphQL validation
- Remove unnecessary comments per CLAUDE.md guidelines

**Changes:**
- FeedSentiment.ts: Corrected import path to avoid barrel file
- feedSentiment.ts: Added ValidationError import from apollo-server-errors
- feedSentiment.ts: Use ValidationError for invalid sentiment values
- Removed redundant comments that restate code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ rebelchris
❌ Daily-Dave
You have signed the CLA already but the status is still pending? Let us recheck it.

@pulumi
Copy link

pulumi bot commented Feb 17, 2026

🍹 The Update (preview) for dailydotdev/api/prod (at e6b1bcd) was successful.

Resource Changes

    Name                                                       Type                           Operation
+   vpc-native-api-db-migration-9aabb55d                       kubernetes:batch/v1:Job        create
~   vpc-native-generate-search-invites-cron                    kubernetes:batch/v1:CronJob    update
~   vpc-native-sync-subscription-with-cio-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-daily-digest-cron                               kubernetes:batch/v1:CronJob    update
~   vpc-native-calculate-top-readers-cron                      kubernetes:batch/v1:CronJob    update
~   vpc-native-deployment                                      kubernetes:apps/v1:Deployment  update
~   vpc-native-check-analytics-report-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-personalized-digest-deployment                  kubernetes:apps/v1:Deployment  update
~   vpc-native-update-achievement-rarity-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-update-highlighted-views-cron                   kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-opportunities-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-user-profile-updated-sync-cron                  kubernetes:batch/v1:CronJob    update
+   vpc-native-api-clickhouse-migration-9aabb55d               kubernetes:batch/v1:Job        create
~   vpc-native-validate-active-users-cron                      kubernetes:batch/v1:CronJob    update
~   vpc-native-user-profile-analytics-history-clickhouse-cron  kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tag-recommendations-cron                 kubernetes:batch/v1:CronJob    update
~   vpc-native-user-profile-analytics-clickhouse-cron          kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-images-cron                        kubernetes:batch/v1:CronJob    update
~   vpc-native-expire-super-agent-trial-cron                   kubernetes:batch/v1:CronJob    update
-   vpc-native-api-clickhouse-migration-ab5b80e1               kubernetes:batch/v1:Job        delete
~   vpc-native-ws-deployment                                   kubernetes:apps/v1:Deployment  update
~   vpc-native-personalized-digest-cron                        kubernetes:batch/v1:CronJob    update
~   vpc-native-generic-referral-reminder-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-public-threshold-cron             kubernetes:batch/v1:CronJob    update
~   vpc-native-post-analytics-clickhouse-cron                  kubernetes:batch/v1:CronJob    update
~   vpc-native-update-source-tag-view-cron                     kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-user-companies-cron                kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-gifted-plus-cron                          kubernetes:batch/v1:CronJob    update
~   vpc-native-update-trending-cron                            kubernetes:batch/v1:CronJob    update
~   vpc-native-user-posts-analytics-refresh-cron               kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-zombie-users-cron                         kubernetes:batch/v1:CronJob    update
~   vpc-native-clean-stale-user-transactions-cron              kubernetes:batch/v1:CronJob    update
~   vpc-native-bg-deployment                                   kubernetes:apps/v1:Deployment  update
~   vpc-native-update-current-streak-cron                      kubernetes:batch/v1:CronJob    update
-   vpc-native-api-db-migration-ab5b80e1                       kubernetes:batch/v1:Job        delete
~   vpc-native-update-views-cron                               kubernetes:batch/v1:CronJob    update
~   vpc-native-update-tags-str-cron                            kubernetes:batch/v1:CronJob    update
~   vpc-native-post-analytics-history-day-clickhouse-cron      kubernetes:batch/v1:CronJob    update
~   vpc-native-hourly-notification-cron                        kubernetes:batch/v1:CronJob    update
~   vpc-native-private-deployment                              kubernetes:apps/v1:Deployment  update
~   vpc-native-temporal-deployment                             kubernetes:apps/v1:Deployment  update
... and 2 other changes

unknown,
BaseContext
>({
Mutation: {
Copy link
Contributor

Choose a reason for hiding this comment

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

this could be in existing feed schema

Copy link
Contributor

Choose a reason for hiding this comment

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

It should just be frontend mock for now I think.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah but still, no need to create whole new gql schema for this?

export * from './campaign';
export * from './PersonalAccessToken';
export * from './Feedback';
export * from './FeedSentiment';
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't use barrel files, so this needs to be removed, its in AGENTS.md but agent ignored it...

Comment on lines +29 to +32
const validSentiments = ['good', 'neutral', 'bad'];
if (!validSentiments.includes(sentiment)) {
throw new ValidationError('Invalid sentiment value');
}
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be validated with zod

Comment on lines +33 to +37
const feedSentimentRepo = ctx.con.getRepository(FeedSentiment);
await feedSentimentRepo.save({
userId: ctx.userId,
sentiment,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

So user can add single sentiment? since user can have multiple feeds maybe better to also add feedId, but not blocking more of a expansion opportunity

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.

4 participants