Rebuild project like flow#108
Conversation
|
@greptile review |
Greptile SummaryThis PR replaces per-card AJAX like reads with server-rendered counts and state from annotated querysets, and consolidates writes into a single authenticated toggle endpoint. The Stimulus controller is simplified from ~200 lines to ~110 by reading from Stimulus value attributes instead of firing API calls on
Confidence Score: 5/5Safe to merge — the change eliminates N+1 API reads on page load, all views route through the new annotation helper, and the new toggle endpoint is tested end-to-end. The concerns flagged in earlier review rounds (unconditional existing_like query, analytics reporting pre-request state, invisible heart icon before hydration, silent error handling) are all addressed in the current revision. The with_like_metadata helper is correct: distinct=True in the COUNT keeps results accurate when the outer queryset introduces additional joins, and the authenticated Exists subquery is gated properly. No new logic issues were found. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Browser
participant Django as Django (SSR)
participant DB as Database
participant Stimulus as Stimulus Controller
participant API as ProjectLikeToggleAPIView
Browser->>Django: GET /projects/
Django->>DB: with_like_metadata(queryset, user) annotate(like_count, user_has_liked)
DB-->>Django: Projects + counts + viewer state
Django-->>Browser: "HTML with data-like-*-value attrs + pre-rendered heart icon and count"
Note over Browser,Stimulus: JS hydrates — connect() reads values, calls render() (idempotent)
Browser->>Stimulus: User clicks heart
Stimulus->>API: "POST /api/v1/projects/{id}/like/ {like: true/false}"
API->>DB: update_or_create Like
DB-->>API: like row
API->>DB: "COUNT(like=True) for project"
DB-->>API: like_count
API-->>Stimulus: "{like: bool, like_count: int}"
Stimulus->>Stimulus: Update likedValue, countValue then render()
Stimulus->>Stimulus: trackChange(serverLiked, prevCount)
Reviews (6): Last reviewed commit: "Show like toggle errors" | Re-trigger Greptile |
Greptile SummaryThis PR replaces the old per-card API read approach for project likes with server-side annotation (
Confidence Score: 3/5The list and detail views are correct, but the home page will show 0 likes for all projects because its queryset skips the new annotation step. The three views covered by the PR work correctly and are well-tested. However, HomeView in pages/views.py fetches projects with a plain queryset that does not call with_like_metadata, while the shared project-card.html template now reads site.like_count and site.user_has_liked as server-rendered values. Every project displayed on the home page will show a like count of 0 and an unliked heart, which is a visible regression for the most prominent page on the site. pages/views.py — HomeView's project queryset needs with_like_metadata applied before the [:6] slice Important Files Changed
Sequence DiagramsequenceDiagram
participant Browser
participant Django as Django View
participant DB as Database
participant Stimulus as like_controller.js
participant API as ProjectLikeToggleAPIView
note over Django,DB: Page load
Django->>DB: Project.objects.filter() + with_like_metadata(user)
DB-->>Django: Projects annotated with like_count, user_has_liked
Django-->>Browser: HTML with data-like-count-value, data-like-liked-value
Browser->>Stimulus: connect() → render()
note over Stimulus: Sets heart icon class and count from server values
note over Browser,API: User clicks Like (authenticated)
Browser->>Stimulus: modify()
Stimulus->>Stimulus: setPending(true), compute nextLiked
Stimulus->>API: "POST /api/v1/projects/{id}/like/ {like: nextLiked}"
API->>DB: "update_or_create(author, project, like=like_value)"
API->>DB: "Count likes where like=True"
DB-->>API: like_count
API-->>Stimulus: "{like, like_count}"
Stimulus->>Stimulus: update likedValue, countValue, render()
Stimulus->>Stimulus: setPending(false)
Reviews (2): Last reviewed commit: "Address like review feedback" | Re-trigger Greptile |
|
@greptile review |
|
@greptile review |
|
@greptile review |
|
@greptile review |
Summary
Production/backfill notes
Verification