Commit 72f84be
authored
Feat/aggregator (#1322)
* feat(db): add content aggregator schema and Reddit-style voting
- Add feed_source, aggregated_article, and aggregated_article_vote tables
- Add ContentReport table for moderation with reason tags
- Add post_vote table for Reddit-style upvote/downvote on posts
- Add upvotes/downvotes columns to Post table
- Migrate existing post likes to upvotes with data migration SQL
- Update seed data for new content types
* feat(api): add feed, content, and voting API routers
- Add feed router with getFeed, vote, bookmark, getCategories procedures
- Add content router for unified content management
- Add discussion router with Reddit-style upvote/downvote
- Add report router for content moderation queue
- Update admin router with getStats, getUsers, getBannedUsers
- Update post router with vote mutation and trending algorithm
- Add hot score calculation for trending sort (recency + votes)
- Update sidebarData to return upvotes/downvotes instead of likes
* feat(feed): add curated developer content feed with RSS aggregation
- Add FeedFilters, FeedItemAggregated, FeedItemLoading components
- Add feed pages with source profiles and article detail views
- Add RSS fetcher Lambda for content aggregation
- Update Algolia indexer for feed content
- Add og-image utility for Open Graph metadata
- Support upvote/downvote, bookmarking, and external link tracking
* feat(components): add unified Content card and Discussion voting
- Add ContentCard component for rendering all content types
- Add ContentMenu with report, share, and edit options
- Update Discussion component with upvote/downvote
- Update ReportModal with reason tag selector (spam, harassment, etc.)
- Add loading skeletons for content cards
* feat(admin): add admin dashboard, moderation queue, and user management
- Add admin dashboard with platform stats overview
- Add moderation queue for reviewing reported content
- Add user management with search, ban/unban functionality
- Display ban reasons and reviewer info
- Filter reports by status (pending, actioned, dismissed)
* feat(articles): unify filters and add Reddit-style voting UX
- Replace article page sidebar with bottom action bar
- Add ArticleActionBar with upvote/downvote, bookmark, share, report
- Update articles list to use FeedFilters component
- Add trending sort option with hot score algorithm
- Unify filter dropdowns between feed and articles pages
- Map sort options: recent/trending/popular
* fix(seo): update branding from Codu to Codú in metadata
* chore(deps): update dependencies and Next.js types
* chore(deps): update dependencies and add RSS fetch utility
- Update package dependencies
- Add local fetch-rss.ts script for testing RSS feeds without Lambda
* feat(db): add unified content system and sponsor inquiry schemas
Consolidate migrations into unified content table supporting posts and
aggregated links. Add sponsor inquiry schema for advertiser contact form.
* feat(api): update routers for unified content and voting system
Add sponsor inquiry router, update content/feed routers for unified
content table, and add Reddit-style voting endpoints.
* feat(components): add content detail, sponsorship, and unified content components
Add ContentDetail components for article/link display, DiscussionEditor
for rich text discussions, SavedItemCard, Sponsorship page sections,
and UnifiedContentCard for the feed.
* refactor(components): update components for unified content system
Update existing components to support unified content table, add voting
UI to feed items, and update sidebar/trending posts for new data model.
* feat(pages): update pages for unified content and sponsorship
Add advertise page, content detail pages for links/articles, update feed
and article pages for unified content system, remove alpha sponsorship.
* feat(utils): add content sync script and sponsor email template
Add sync-content-table script for migrating data to unified content
table, useCreateContent hook, and sponsor inquiry email template.
* chore(config): update site config, sitemap, and RSS feed for unified content
* feat(cdk): update lambdas for unified content indexing
Update Algolia indexer and RSS fetcher lambdas to support unified
content table structure.
* chore(db): remove old incremental migrations
* refactor: simplify component file names by removing redundant prefixes
Rename verbose component files where folder context already provides clarity:
- ContentDetail/: Layout, TypeBadge, MetaHeader, ActionBar
- DiscussionEditor/: Editor, Toolbar, useEditor
- Feed/: AggregatedItem, ItemLoading, Filters
* feat: enhance article and source profile components with inline source info and author bios
* refactor(votes): remove manual count updates, rely on DB triggers
Database triggers (tr_post_vote_counts, tr_comment_vote_counts) now
handle all vote count updates. Removing duplicate manual updates
eliminates double-counting risk.
* fix(votes): migrate components from feed.vote to content.vote
Components were using api.feed.vote which lacked proper count updates.
Migrated to api.content.vote for consistent behavior.
* feat(scripts): add vote count reconciliation script
Adds safety net script to verify and fix vote count discrepancies.
Run with: npm run votes:reconcile (or votes:reconcile:dry for dry run)
* feat(cdk): add daily vote reconciliation Lambda
Scheduled Lambda runs at 5 AM UTC daily to reconcile vote counts,
ensuring DB triggers are working correctly. Runs before Algolia
indexing to ensure accurate counts before re-indexing.
* feat(auth): auto-grant admin role based on ADMIN_EMAILS env var
* feat(db): link feed sources to user profiles for author attribution
* feat(db): add migrations for legacy Post/Comment data to new schema
* refactor(feed): update RSS fetchers and sitemap to use source user profiles
* chore: remove redundant inline comments from vote mutations
* test(e2e): comprehensive test coverage for unified content system
- Update articles.spec.ts for new feed URLs and voting UI
- Create feed.spec.ts with 15 tests for filters, voting, bookmarks
- Create saved.spec.ts with 6 tests for bookmark management
- Create admin.spec.ts with 13 tests for admin dashboard
- Add data-testid attributes to VoteButtons, Filters, ContentCard, DiscussionArea
- Update e2e setup with admin user and new posts table schema
- Add loggedInAsAdmin utility for admin test authentication
Total: 63 passing e2e tests
* Fixes for linting/prettier
* chore: remove console logs and unused success messages from content creation hooks
* refactor: optimize state management and error handling across components
* fix: update redirect method and adjust sitemap routes for consistency
* fix: update slug handling in metadata generation and comments area styling
* fix: handle potential migration issues for feed sources and articles in sitemap generation
* fix: adjust class order for HeartIcon in CommentsArea component
* fix: add revalidation period for sitemap regeneration1 parent 1bdefc7 commit 72f84be
File tree
146 files changed
+27026
-2701
lines changed- app
- (app)
- [username]
- [slug]
- admin
- moderation
- sources
- users
- advertise
- alpha/sponsorship
- articles
- [slug]
- company/[slug]
- feed
- [sourceSlug]
- [shortId]
- my-posts
- saved
- sponsorship
- (editor)/create/[[...paramsArr]]
- api/admin/sync-feeds
- feed.xml
- cdk
- lambdas
- algoliaIndex
- rssFetcher
- voteReconcile
- lib
- components
- ArticleActionBar
- ArticleMenu
- ArticlePreview
- Comments
- ContentDetail
- Content
- Discussion
- DiscussionEditor
- extensions
- hooks
- Feed
- ReportModal
- SavedItemCard
- SideBar
- Sponsorship
- TrendingPosts
- UnifiedContentCard
- config
- drizzle
- meta
- e2e
- constants
- utils
- hooks
- lib
- schema
- scripts
- server
- api/router
- db
- lib
- utils
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
146 files changed
+27026
-2701
lines changedLarge diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | | - | |
| 23 | + | |
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| |||
127 | 127 | | |
128 | 128 | | |
129 | 129 | | |
130 | | - | |
131 | | - | |
| 130 | + | |
| 131 | + | |
132 | 132 | | |
133 | 133 | | |
134 | | - | |
| 134 | + | |
135 | 135 | | |
136 | | - | |
137 | | - | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
142 | | - | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | | - | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
160 | 162 | | |
161 | 163 | | |
162 | 164 | | |
| |||
0 commit comments