feat: show last 5 recently generated stories on dashboard - #54
Conversation
- Add GET /api/stories/recent endpoint that lists stories from KV sorted by updatedAt - Add getRecentStories() method to StoryService - Display recent stories as cards below the story generator form - Auto-refresh recent stories after generating a new story - Show loading skeleton while fetching recent stories Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
commitstory | 6136627 | Commit Preview URL Branch Preview URL |
Jul 16 2026, 05:22 PM |
📝 WalkthroughWalkthroughAdds a recent-stories API backed by a KV index, a typed client method, and dashboard story cards that load on initialization and refresh after story generation. It also removes GitHub authentication services, routes, session types, and related configuration. ChangesRecent Stories
Authentication Removal
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant DashboardComponent
participant StoryService
participant handleRecentStories
participant STORY_KV
DashboardComponent->>StoryService: getRecentStories(5)
StoryService->>handleRecentStories: GET /api/stories/recent?limit=5
handleRecentStories->>STORY_KV: Read recent stories index
STORY_KV-->>handleRecentStories: Indexed story entries
handleRecentStories-->>StoryService: RecentStoriesResponse
StoryService-->>DashboardComponent: Update recent stories
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install timed out. The project may have too many dependencies for the sandbox. Comment |
OAuth login/logout/session infrastructure is no longer used. This removes: Server: - SESSION_SECRET, GITHUB_CLIENT_ID/SECRET/CALLBACK_URL from Env - SessionUser, SessionData interfaces - Signed cookie session helpers (encode/decode/get/apply) - OAuth route handlers (handleGitHubAuth, handleGitHubCallback, handleLogout, handleAuthUser) - Auth route registration and session cookie management in entry point - redirect() helper (only used by OAuth) Frontend: - AuthService and AuthGuard - Login page component - UserProfile interface from activity.models (only used by AuthService) - session.d.ts express-session type augmentation Config: - Legacy OAuth secret references from wrangler.toml, .dev.vars.example, .env.example ShareService updated to remove AuthService dependency. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@yourstory/src/app/pages/dashboard/dashboard.component.ts`:
- Around line 939-947: Update loadRecentStories and the refresh flow around its
caller so overlapping requests cannot let an older response or catchError
fallback overwrite the newest recentStories result. Track request freshness or
use a switchMap-based stream, and ensure isLoadingRecentStories finalization is
likewise limited to the active request.
In `@yourstory/src/server.ts`:
- Line 1177: Update the limit parsing expression in the server request handler
to preserve a parsed zero so Math.max clamps it to the minimum value of 1;
replace the falsy fallback that converts zero to 5, while retaining 5 only for
missing or invalid limit values and the existing upper bound of 20.
- Around line 1181-1209: Replace the STORY_KV.list-based scan in the story-feed
handler with an indexed recent-story feed that retrieves only the required
recent entries, avoiding the single-page 1,000-key limit and per-story get()
fanout. Update the surrounding story parsing and sorting flow to consume the
index while preserving the existing response fields and image-key handling.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: d10714c0-4b7c-4d07-a61e-5d3c1b890696
📒 Files selected for processing (3)
yourstory/src/app/core/services/story.service.tsyourstory/src/app/pages/dashboard/dashboard.component.tsyourstory/src/server.ts
- Replace KV list() scan with indexed recent-story feed to avoid 1000-key limit and per-story get() fanout - Prevent stale loads from overwriting post-generation refresh via request ID tracking - Fix limit parsing to clamp zero to minimum instead of default Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes Applied SuccessfullyFixed 2 file(s) based on 3 unresolved review comment(s). Files modified:
Commit: The latest autofix changes are on the |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@yourstory/src/app/pages/dashboard/dashboard.component.ts`:
- Around line 946-957: Update the recent-stories stream in the dashboard
component so catchError does not emit an empty stories list on fetch failure;
return EMPTY or otherwise preserve the existing recentStories value. Keep
successful responses replacing the list and retain the existing requestId guard
and finalize loading-state behavior.
In `@yourstory/src/server.ts`:
- Around line 945-948: Update the recent-stories retrieval flow around
RECENT_STORIES_INDEX_KEY so namespaces without an index are backfilled from
existing KV story entries before serving results. Implement cursor-paginated
migration that excludes metadata keys, or retain a temporary legacy fallback
until backfill completes, ensuring pre-existing stories appear in the feed.
- Around line 1146-1157: Replace the read-modify-write handling of
RECENT_STORIES_INDEX_KEY with a strongly consistent coordinator/store shared by
story creation, image flag updates, and /api/stories/recent. Update the index
logic at yourstory/src/server.ts lines 1146-1157, 1064-1073, and 945-959 so
concurrent operations preserve all entries and hasImage changes without stale
reads.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 5abc2897-8ef6-4aec-9c8a-d06065a1b084
📒 Files selected for processing (2)
yourstory/src/app/pages/dashboard/dashboard.component.tsyourstory/src/server.ts
| const raw = await env.STORY_KV.get(RECENT_STORIES_INDEX_KEY); | ||
| let index: RecentStoryEntry[] = raw ? JSON.parse(raw) : []; | ||
| // Remove existing entry for same handle+genre | ||
| index = index.filter( | ||
| (e) => !(e.handle === entry.handle && e.genre === entry.genre), | ||
| ); | ||
| // Prepend new entry and cap | ||
| index.unshift(entry); | ||
| if (index.length > RECENT_STORIES_MAX_ENTRIES) { | ||
| index = index.slice(0, RECENT_STORIES_MAX_ENTRIES); | ||
| } | ||
| await env.STORY_KV.put(RECENT_STORIES_INDEX_KEY, JSON.stringify(index)); |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the relevant structure first.
ast-grep outline yourstory/src/server.ts --view expanded > /tmp/server_outline.txt
sed -n '1,220p' /tmp/server_outline.txt
# Inspect the three cited regions with line numbers.
echo '--- 930-980 ---'
sed -n '930,980p' yourstory/src/server.ts | cat -n
echo '--- 1048-1085 ---'
sed -n '1048,1085p' yourstory/src/server.ts | cat -n
echo '--- 1138-1170 ---'
sed -n '1138,1170p' yourstory/src/server.ts | cat -n
# Locate the shared key/type definitions and any other readers/writers.
echo '--- recent-story symbols ---'
rg -n "RECENT_STORIES_INDEX_KEY|RecentStoryEntry|RECENT_STORIES_MAX_ENTRIES|hasImage|storys? index|recent stories" yourstory/src/server.tsRepository: santoshyadavdev/commitstory
Length of output: 9266
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo '--- 860-920 ---'
sed -n '860,920p' yourstory/src/server.ts | cat -n
echo '--- 920-940 ---'
sed -n '920,940p' yourstory/src/server.ts | cat -n
echo '--- 1-80 ---'
sed -n '1,80p' yourstory/src/server.ts | cat -nRepository: santoshyadavdev/commitstory
Length of output: 6482
Avoid mutating the shared recent-stories KV blob from multiple paths. Story creation and image flag updates both rewrite RECENT_STORIES_INDEX_KEY, so concurrent requests can drop entries or hasImage updates, and /api/stories/recent can read stale data. Move this index to a strongly consistent coordinator/store instead.
📍 Affects 1 file
yourstory/src/server.ts#L1146-L1157(this comment)yourstory/src/server.ts#L1064-L1073yourstory/src/server.ts#L945-L959
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@yourstory/src/server.ts` around lines 1146 - 1157, Replace the
read-modify-write handling of RECENT_STORIES_INDEX_KEY with a strongly
consistent coordinator/store shared by story creation, image flag updates, and
/api/stories/recent. Update the index logic at yourstory/src/server.ts lines
1146-1157, 1064-1073, and 945-959 so concurrent operations preserve all entries
and hasImage changes without stale reads.
- Add legacy KV list() fallback for namespaces without index so
pre-existing stories still appear in the feed
- Use EMPTY instead of of({ stories: [] }) in catchError to preserve
existing feed on transient fetch failures
- Skipped concurrent mutation concern: KV is eventually consistent by
design and story generation is user-initiated with low concurrency
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes Applied SuccessfullyFixed 2 file(s) based on 3 unresolved review comment(s). Files modified:
Issues addressed:
Commit: The latest autofix changes are on the |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
yourstory/src/server.ts (1)
902-911: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winPreserve an existing story’s image state.
A cached result with
imageUrlskips image generation inDashboardComponent, so the image endpoint never restores this forcedhasImage: false. Regenerating such a story removes its cover from Recent Stories. Merge the prior entry’shasImageduring index deduplication, or derive it from persisted image metadata.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@yourstory/src/server.ts` around lines 902 - 911, Update the recent-story index update flow around updateRecentStoriesIndex to preserve the existing entry’s hasImage value during deduplication instead of always passing false. Reuse the prior indexed entry’s image state, or derive it from persisted image metadata, so regenerating cached stories does not remove their covers from Recent Stories.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@yourstory/src/server.ts`:
- Around line 902-911: Update the recent-story index update flow around
updateRecentStoriesIndex to preserve the existing entry’s hasImage value during
deduplication instead of always passing false. Reuse the prior indexed entry’s
image state, or derive it from persisted image metadata, so regenerating cached
stories does not remove their covers from Recent Stories.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 4e346be0-ad61-405b-b1fb-2e573fd2cbcd
📒 Files selected for processing (2)
yourstory/src/app/pages/dashboard/dashboard.component.tsyourstory/src/server.ts
Why
Users currently have no way to see stories that have already been generated. Adding a "Recent Stories" section gives visitors a sense of what the app produces and makes it easy to revisit previous stories without re-generating them.
Approach
New API endpoint --
GET /api/stories/recent?limit=5lists keys from theSTORY_KVnamespace, fetches each entry, sorts byupdatedAtdescending, and returns the most recent stories (default 5, max 20). Image-metadata keys (*:imageKey) are filtered out.StoryService -- added
getRecentStories()and supportingRecentStory/RecentStoriesResponseinterfaces.Dashboard UI -- a responsive card grid (1/2/3 columns) appears below the story generator form when in the "story" view mode. Each card shows the genre badge, username, title, a two-line story preview, and the cover image when available. Cards link to the shareable story page. A loading skeleton is shown while fetching, and the list auto-refreshes after a new story is generated.
Notes
window.matchMediainThemeService) is unrelated to these changes.Summary by CodeRabbit