mostly android
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 03. Blog Route With DB Integration, Featured Post, And Chronological Feed
|
||||
|
||||
meta:
|
||||
id: landing-pages-and-admin-03
|
||||
feature: landing-pages-and-admin
|
||||
priority: P1
|
||||
depends_on: [landing-pages-and-admin-02]
|
||||
tags: [implementation, routes, blog, database, tRPC]
|
||||
|
||||
objective:
|
||||
- Refactor the `/blog` route to fetch posts from the database via tRPC instead of hardcoded data, support a featured post display at the top, and show remaining posts in chronological order with tag filtering and pagination.
|
||||
|
||||
deliverables:
|
||||
- Rewritten `/web/src/routes/blog.tsx` with database-backed data
|
||||
- tRPC query `blog.list` for fetching posts with filtering, pagination, and featured flag
|
||||
- Featured post hero section at top of blog listing
|
||||
- Chronological feed with tag filtering and pagination
|
||||
- Updated `/web/src/routes/blog/[slug].tsx` to fetch from database
|
||||
- tRPC query `blog.bySlug` for fetching individual post
|
||||
- tRPC mutation `blog.incrementViews` for tracking view counts
|
||||
|
||||
steps:
|
||||
- Create tRPC router procedure `blog.list`:
|
||||
- Accept optional `tag`, `limit`, `offset` parameters
|
||||
- Query `blogPosts` table for published posts only
|
||||
- Order by `publishedAt` descending (chronological)
|
||||
- Return posts with all fields including `featured` flag
|
||||
- Create tRPC router procedure `blog.bySlug`:
|
||||
- Accept `slug` parameter
|
||||
- Query `blogPosts` table for published post by slug
|
||||
- Increment `viewCount` on each view
|
||||
- Return post with related posts (same tags, excluding current)
|
||||
- Create tRPC router procedure `blog.tags`:
|
||||
- Return all unique tags from published posts with counts
|
||||
- Refactor `/blog.tsx`:
|
||||
- Replace hardcoded `blogPosts` array with tRPC query
|
||||
- Add featured post section at top (large card with full excerpt, shown only if a post is marked featured)
|
||||
- Show remaining posts in chronological grid below featured post
|
||||
- Preserve tag filtering UI (fetch tags from database)
|
||||
- Preserve pagination ("Load More Posts" button)
|
||||
- Add loading states and error handling
|
||||
- Refactor `/blog/[slug].tsx`:
|
||||
- Replace hardcoded data with tRPC query by slug
|
||||
- Preserve markdown rendering, author sidebar, related posts, social sharing
|
||||
- Add 404 handling for non-existent slugs
|
||||
- Track view count on page load
|
||||
- Add database migration for `featured` column on `blogPosts` table
|
||||
- Ensure `publishedAt` is properly set on all existing posts
|
||||
|
||||
tests:
|
||||
- Unit: tRPC queries return correct data shapes
|
||||
- Integration: Blog list page loads posts from database
|
||||
- Integration: Featured post displays at top when one is marked featured
|
||||
- Integration: Tag filtering correctly filters posts
|
||||
- Integration: Pagination loads next batch of posts
|
||||
- Integration: Individual post page loads by slug and increments view count
|
||||
- Integration: 404 shown for non-existent slug
|
||||
|
||||
acceptance_criteria:
|
||||
- `/blog` fetches posts from `blogPosts` database table (no hardcoded data)
|
||||
- One post can be marked as `featured` and displays prominently at the top of the blog listing
|
||||
- Remaining posts display in chronological order (newest first)
|
||||
- Tag filtering works with tags sourced from the database
|
||||
- Pagination ("Load More") loads additional posts in batches
|
||||
- `/blog/[slug]` fetches individual post from database
|
||||
- View count increments each time a post is viewed
|
||||
- Related posts section shows posts with matching tags
|
||||
- 404 page shown for non-existent blog slugs
|
||||
- Loading states displayed while data is being fetched
|
||||
|
||||
validation:
|
||||
- `cd /Users/mike/Code/Kordant/web && pnpm dev` then navigate to `/blog`
|
||||
- Verify posts load from database (not hardcoded)
|
||||
- Mark a post as featured via admin and verify it appears at top
|
||||
- Test tag filtering by clicking different tag buttons
|
||||
- Click "Load More" and verify additional posts load
|
||||
- Navigate to individual post and verify content renders correctly
|
||||
- Refresh post page and verify view count increments
|
||||
- Navigate to non-existent slug and verify 404
|
||||
|
||||
notes:
|
||||
- Current blog schema in `marketing.ts` has: id, slug, title, excerpt, content, authorName, coverImageUrl, tags (JSON), published, publishedAt, viewCount
|
||||
- Need to add `featured` boolean column (default: false)
|
||||
- `publishedAt` should be used for chronological ordering
|
||||
- `tags` is stored as JSON array in database
|
||||
- Existing markdown parser in `[slug].tsx` should be preserved
|
||||
- Related posts logic: find other published posts sharing at least one tag
|
||||
- Use `createQuery` from `@trpc/client` (SolidJS adapter) for data fetching
|
||||
- Consider server-side rendering for initial blog list (SolidStart supports this)
|
||||
Reference in New Issue
Block a user