Skip to content

Feat/#37/search component and function#48

Merged
pich-reamrachna merged 10 commits intomainfrom
feat/#37/search-component-and-function
Apr 5, 2026
Merged

Feat/#37/search component and function#48
pich-reamrachna merged 10 commits intomainfrom
feat/#37/search-component-and-function

Conversation

@pich-reamrachna
Copy link
Copy Markdown
Owner

@pich-reamrachna pich-reamrachna commented Apr 5, 2026

Summary by CodeRabbit

  • New Features

    • Profile pages lazy-load liked posts when the tab is selected.
  • Performance

    • Session cookie caching to reduce auth work and backend load.
    • Batched like-detection queries for faster feed loading.
  • Bug Fixes

    • Fixed share count display (was hardcoded to zero); counts now reflect stored values.
  • Improvements

    • Like/unlike actions return updated like counts and update UI state immediately without full refresh.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
social-media Ready Ready Preview, Comment Apr 5, 2026 11:57am

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: afa054b2-48b6-43d0-9916-e31e61932507

📥 Commits

Reviewing files that changed from the base of the PR and between a31d388 and 3ee4bf7.

📒 Files selected for processing (1)
  • src/hooks.server.ts

📝 Walkthrough

Walkthrough

The PR adds route-aware session loading in the server hook with dev diagnostics, enables a 5-minute cookie cache in auth config, adds like_count and share_count to the post table, changes like-related queries to batched lookups and atomic count updates, and implements optimistic like updates and lazy-loading of profile liked posts.

Changes

Cohort / File(s) Summary
Server hooks & auth
src/hooks.server.ts, src/lib/server/auth.ts
Added route-based logic to conditionally call auth.api.getSession, request normalization, dev-only timing/logging, and storing session/user on event.locals only when obtained. Enabled session.cookieCache with 5-minute maxAge and refresh in auth config.
Database schema
src/lib/server/db/post.ts
Added like_count and share_count integer columns (not null, default 0) and imported integer.
Home page (server + client)
src/routes/home/+page.server.ts, src/routes/home/+page.svelte
Replaced per-post eager-loaded likes with a batched liked-posts query for viewer; derive is_liked_by_user via a Set. Use post.likeCount / post.shareCount for counts. toggleLike now validates post existence, updates post.likeCount atomically, and returns { post_id, is_liked, likes }. Client applies optimistic updates from the response instead of invalidating.
Profile page (server + client)
src/routes/profile/[username]/+page.server.ts, src/routes/profile/[username]/+page.svelte
Refactored load into helpers, limited and simplified includes, replaced eager relation counts with separate viewer-like lookup, added actions.loadLikedPosts for lazy fetching, and updated toggleLike to mirror home-side atomic count updates. Frontend lazily loads liked posts with loading flags and tab-triggered fetch.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Hook as Server Hook\n(src/hooks.server.ts)
  participant AuthAPI as Auth API\n(auth.api.getSession)
  participant Svelte as SvelteKit Handler

  Client->>Hook: HTTP request
  Hook->>Hook: normalizeUrl -> pathname, label, cookie header
  alt shouldLoadSession(pathname)
    Hook->>AuthAPI: auth.api.getSession(request)
    AuthAPI-->>Hook: session (or null)
    Hook->>Hook: set event.locals.session / .user if session
  else skip session
    Hook-->>Hook: skip getSession (dev log)
  end
  Hook->>Svelte: call svelteKitHandler(event)
  Svelte-->>Hook: Response
  Hook->>Hook: dev logs (timings, set-cookie presence)
  Hook-->>Client: Response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Nethphorn

Poem

🐰 I hopped through routes to check who’s the one,
I cached a cookie for five minutes’ fun.
Counts now tally where likes used to hide,
Tabs wake liked posts only when you slide.
🥕 Happy hopping — code and carrots, side by side!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Title check ⚠️ Warning The pull request title references a search component and function, but the changeset focuses on auth session optimization, database schema updates for like/share counts, and refactoring post/profile pages to batch queries and lazy-load liked posts—no search functionality is present. Update the title to accurately reflect the main changes: consider something like 'Optimize session handling and refactor post/profile pages with batched queries' or similar that describes the actual changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#37/search-component-and-function

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/routes/profile/[username]/+page.svelte (1)

49-77: Solid lazy-loading implementation, but failures are silent.

The loading guard pattern (line 50) and state management are well-implemented. However, on failure (line 72-73), the user receives no feedback—the tab simply shows empty. Consider adding a toast or error indicator:

Optional: Add user feedback on failure
 		} catch {
 			profile_liked_posts = []
+			// Optionally show error feedback to user
+			console.error('Failed to load liked posts')
 		} finally {
 			is_liked_posts_loading = false
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/profile/`[username]/+page.svelte around lines 49 - 77, The
ensure_liked_posts_loaded function currently swallows all errors and leaves the
UI silent; modify it to surface failures by setting an error state and/or
invoking the app's toast/notification utility when the fetch or deserialization
fails. Specifically, inside the catch block for ensure_liked_posts_loaded (which
currently just sets profile_liked_posts = []), set a boolean like
liked_posts_load_error (or call the existing toast function) and include a
short, user-facing message; keep the existing guards (has_loaded_liked_posts,
is_liked_posts_loading) and finally block unchanged so loading state is still
cleared.
src/routes/home/+page.server.ts (1)

250-255: Same stale count issue as profile route; consider DRY extraction.

The returned likes value is calculated from the pre-update current_post.likeCount, not the actual post-update value. Additionally, this toggleLike logic is nearly identical to src/routes/profile/[username]/+page.server.ts. Consider extracting to a shared utility in $lib/server/ to reduce duplication.

Proposed shared utility location
// $lib/server/actions/toggle-like.ts
export async function toggleLike(userId: string, postId: string) {
  // Shared implementation with RETURNING clause
}

Then import and use in both route actions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/home/`+page.server.ts around lines 250 - 255, The likes value is
computed from the stale pre-update current_post.likeCount and duplicates logic
used in the profile route; change the route action to call a shared server
utility (e.g. export async function toggleLike(userId, postId) in
$lib/server/actions/toggle-like.ts) that performs the DB toggle and returns the
actual updated likeCount and the new liked state (use a DB UPDATE/INSERT/DELETE
with RETURNING to get the new count), then replace the inline calculation of
is_liked and likes (which currently uses existing_like and
current_post.likeCount) with the values returned from toggleLike and import that
utility into both +page.server.ts files to remove duplication.
src/hooks.server.ts (1)

6-12: Share the auth-route matcher with src/routes/+layout.server.ts.

AUTH_ROUTES, PROTECTED_ROUTE_PREFIXES, and is_protected_route() are now a second copy of the auth-route policy already defined in src/routes/+layout.server.ts, Lines 4-12. If one side changes without the other, hooks can skip session hydration while the layout still enforces redirects, which sends authenticated users back to /login. Export a single matcher/constants module and reuse it in both places.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks.server.ts` around lines 6 - 12, The auth-route logic is
duplicated—AUTH_ROUTES, PROTECTED_ROUTE_PREFIXES, and is_protected_route()—so
extract those three symbols into a single shared module and export them, then
replace the local definitions in both places with imports of AUTH_ROUTES,
PROTECTED_ROUTE_PREFIXES, and is_protected_route; ensure the exported
is_protected_route function preserves the same semantics (checking equality or
startsWith(`${prefix}/`) for each prefix) and update any import sites to use the
shared module so both the hook and the layout use the exact same matcher.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/hooks.server.ts`:
- Around line 28-33: Normalize the pathname before matching auth routes: replace
direct uses of event.url.pathname in the should_load_session check with a
normalized path (use normalizeUrl from `@sveltejs/kit`) so that SvelteKit internal
suffixes like "__data.json" are stripped; update the logic around
should_load_session, AUTH_ROUTES lookups and any callsites that rely on
event.url.pathname (e.g., where getSession() is conditionally invoked) to use
the normalized pathname to ensure exact matches (e.g., "/login") succeed and
locals.user is populated for guard checks.

In `@src/routes/profile/`[username]/+page.server.ts:
- Around line 222-230: The code reads current_post via db.query.post.findFirst
and uses current_post.likeCount later to compute the returned likes, which can
be stale under concurrent updates; instead perform the like/unlike update using
a database update call with a RETURNING clause to fetch the post's updated
likeCount (e.g., replace the separate findFirst + later computation with a
single update that returns likeCount), then use that returned likeCount in the
response; reference the existing symbols current_post, db.query.post.findFirst,
post_id and likeCount when locating and replacing the logic so the response uses
the updated DB value rather than the pre-read value.

---

Nitpick comments:
In `@src/hooks.server.ts`:
- Around line 6-12: The auth-route logic is duplicated—AUTH_ROUTES,
PROTECTED_ROUTE_PREFIXES, and is_protected_route()—so extract those three
symbols into a single shared module and export them, then replace the local
definitions in both places with imports of AUTH_ROUTES,
PROTECTED_ROUTE_PREFIXES, and is_protected_route; ensure the exported
is_protected_route function preserves the same semantics (checking equality or
startsWith(`${prefix}/`) for each prefix) and update any import sites to use the
shared module so both the hook and the layout use the exact same matcher.

In `@src/routes/home/`+page.server.ts:
- Around line 250-255: The likes value is computed from the stale pre-update
current_post.likeCount and duplicates logic used in the profile route; change
the route action to call a shared server utility (e.g. export async function
toggleLike(userId, postId) in $lib/server/actions/toggle-like.ts) that performs
the DB toggle and returns the actual updated likeCount and the new liked state
(use a DB UPDATE/INSERT/DELETE with RETURNING to get the new count), then
replace the inline calculation of is_liked and likes (which currently uses
existing_like and current_post.likeCount) with the values returned from
toggleLike and import that utility into both +page.server.ts files to remove
duplication.

In `@src/routes/profile/`[username]/+page.svelte:
- Around line 49-77: The ensure_liked_posts_loaded function currently swallows
all errors and leaves the UI silent; modify it to surface failures by setting an
error state and/or invoking the app's toast/notification utility when the fetch
or deserialization fails. Specifically, inside the catch block for
ensure_liked_posts_loaded (which currently just sets profile_liked_posts = []),
set a boolean like liked_posts_load_error (or call the existing toast function)
and include a short, user-facing message; keep the existing guards
(has_loaded_liked_posts, is_liked_posts_loading) and finally block unchanged so
loading state is still cleared.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 69321eaf-8c96-4f55-91cc-023a5635e924

📥 Commits

Reviewing files that changed from the base of the PR and between ea3e96d and a31d388.

📒 Files selected for processing (7)
  • src/hooks.server.ts
  • src/lib/server/auth.ts
  • src/lib/server/db/post.ts
  • src/routes/home/+page.server.ts
  • src/routes/home/+page.svelte
  • src/routes/profile/[username]/+page.server.ts
  • src/routes/profile/[username]/+page.svelte

Comment thread src/hooks.server.ts
Comment on lines +222 to +230
const current_post = await db.query.post.findFirst({
where: eq(post.id, post_id),
columns: {
likeCount: true
}
})
if (!current_post) {
return fail(404, { message: 'Post not found' })
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Returned likes count may be stale under concurrent updates.

The current_post.likeCount is read at line 222-227 before the update occurs. The returned likes (line 254) is calculated from this pre-read value, not the actual database value after the update. Under concurrent like/unlike operations, the client receives a potentially incorrect count.

Consider using RETURNING to get the actual post-update value:

Proposed fix using RETURNING clause
 			if (existing_like) {
 				await db.delete(like).where(and(eq(like.postId, post_id), eq(like.userId, viewer.id)))
-				await db
+				const [updated] = await db
 					.update(post)
 					.set({
 						likeCount: sql`greatest(${post.likeCount} - 1, 0)`
 					})
 					.where(eq(post.id, post_id))
+					.returning({ likeCount: post.likeCount })
+				return { success: true, is_liked: false, likes: updated?.likeCount ?? 0 }
 			} else {
 				await db.insert(like).values({ userId: viewer.id, postId: post_id })
-				await db
+				const [updated] = await db
 					.update(post)
 					.set({
 						likeCount: sql`${post.likeCount} + 1`
 					})
 					.where(eq(post.id, post_id))
+					.returning({ likeCount: post.likeCount })
+				return { success: true, is_liked: true, likes: updated?.likeCount ?? 0 }
 			}
-		} catch {
+		} catch (err) {
+			console.error('toggleLike database error:', err)
 			return fail(500, { message: 'Failed to update like' })
 		}
-
-		return { success: true }

Also applies to: 250-254

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routes/profile/`[username]/+page.server.ts around lines 222 - 230, The
code reads current_post via db.query.post.findFirst and uses
current_post.likeCount later to compute the returned likes, which can be stale
under concurrent updates; instead perform the like/unlike update using a
database update call with a RETURNING clause to fetch the post's updated
likeCount (e.g., replace the separate findFirst + later computation with a
single update that returns likeCount), then use that returned likeCount in the
response; reference the existing symbols current_post, db.query.post.findFirst,
post_id and likeCount when locating and replacing the logic so the response uses
the updated DB value rather than the pre-read value.

@pich-reamrachna
Copy link
Copy Markdown
Owner Author

The main problems were:

  1. Session lookup was slow
  • getSession() was often falling back to a database-backed lookup on protected routes
  • that made navigation slow before the page load even finished
  1. Page loads were doing too much database work
  • home/profile were recalculating likes/shares during page load
  • profile also eagerly loaded liked posts and full relations
  1. Some interactions were reloading too much
  • invalidateAll() after a like caused a full page refresh instead of updating one post.

So the short answer is:

  • auth session retrieval was unstable and expensive
  • route data loading was heavier than necessary
  • some client actions were triggering unnecessary full-page reloads

@pich-reamrachna pich-reamrachna merged commit c897f25 into main Apr 5, 2026
4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Apr 7, 2026
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.

1 participant