WELIFE Docs Swagger Admin Web

Luồng Social / Reels — Like · Bình luận · Chia sẻ · Thống kê

Domain: D-SOCIAL · WP: WP-SOC-ENGAGE-01 Surfaces: CON (Expo) + API (NestJS) Ngày: 2026-08-19 Status: IMP

Tài liệu này mô tả cách dữ liệu chạy khi người dùng thả tim, bình luận, lưu, chia sẻ trên Luồng (Social) và Reels (Video) — từ icon UI → REST → Postgres → số đếm trên màn hình.


1. Hai bề mặt, một bảng bài viết

Reels và bài tường không phải hai hệ thống. Cả hai đọc/ghi SocialPost (social_posts).

Tab CON Màn Nguồn feed Kind bài điển hình
Social SocialFeedScreen · tab Luồng GET /social/posts/feed hoặc /posts/following STATUS · NEWS · PHOTO · VIDEO · REEL
Social tab Video Cùng list, lưới VideoExploreTile Có mediaUrls
Reels ReelsFeedScreen GET /social/reels/feed hoặc /reels/following VIDEO / REEL (filter phía BE)

Đăng từ CreatePostScreen → POST /social/posts (ảnh/video đã gỡ EXIF ở POST /upload/single, WP-MEDIA-STRIP-01).

flowchart LR
  subgraph CON["App khách"]
    Luong["Luồng SocialPostCard"]
    Reels["Reels ReelPage"]
    Sheet["CommentsSheet"]
  end
  subgraph API["NestJS /social"]
    Feed["feed / following"]
    Act["like save comment share"]
  end
  subgraph DB["Postgres"]
    P["social_posts"]
    L["post_likes"]
    C["post_comments"]
    S["post_shares"]
    B["post_saves"]
  end
  Luong --> Feed
  Reels --> Feed
  Luong --> Act
  Reels --> Act
  Sheet --> Act
  Feed --> P
  Act --> L
  Act --> C
  Act --> S
  Act --> B
  Act --> P

2. Bộ đếm trên mỗi bài (SocialPost)

Field Ý nghĩa Tăng khi Giảm khi
likeCount Số tim POST .../like (lần đầu) Unlike (toggle lần 2)
commentCount Số bình luận (kể cả reply) POST .../comments Soft-delete comment (nếu có)
shareCount Số lần chia sẻ đã ghi POST .../share sau OS share sheet Không giảm
saveCount Số bookmark POST .../save Bỏ lưu
viewCount Lượt xem chi tiết GET /posts/:id hoặc /reels/:id Không

Cờ theo viewer đang login:

Flag Nguồn
liked Có dòng post_likes (postId, userId)
saved Có dòng post_saves (postId, userId)

Feed serialize (SocialService.serializePost) trả đủ 5 số + 2 cờ để UI không đoán.


3. Icon trên UI ↔ hành vi

3.1 Luồng (SocialPostCard)

Hàng action (trái → phải): tim → bình luận → chia sẻ · spacer · bookmark.

Icon Gesture API Cập nhật UI
Tim (heart) Tap POST /social/posts/:id/like Optimistic liked + likeCount ±1; sync res.liked
Bình luận Tap Mở CommentsSheet GET /posts/:id/comments · gửi POST .../comments
Chia sẻ Tap OS Share.share rồi POST /posts/:id/share { channel: "native" } shareCount từ response
Bookmark Tap POST /social/posts/:id/save saved + saveCount

Số dưới icon: formatReelCount (1.2K / 1.2M).

3.2 Reels (ReelPage)

Rail phải: avatar+follow · tim · bình luận · bookmark · chia sẻ · đĩa nhạc.

Gesture Hành vi
Tap 1 lần video Pause / play
Double-tap video Tim + animation trái tim (DoubleTapHeart) → cùng like API
Tap tim Toggle like
Tap bình luận Sheet giống luồng (postId = id reel = id SocialPost)
Tap chia sẻ Cùng sharePostToSheet

3.3 Sheet bình luận


4. REST (tag Swagger social)

Cùng postId dùng được cho bài tường và reel (alias /reels/:id/... gọi cùng service).

Method Path Auth Side effect
GET /social/posts/feed optional JWT List + liked/saved nếu có token
GET /social/posts/following JWT Chỉ author đang follow
GET /social/reels/feed optional Filter video/reel
GET /social/reels/following JWT
POST /social/posts/:id/like JWT Toggle PostLike; trả { liked, postId, likeCount }
POST /social/posts/:id/save JWT Toggle PostSave; { saved, postId, saveCount }
POST /social/posts/:id/share JWT WP-SOC-ENGAGE-01 · PostShare + shareCount++
POST /social/reels/:id/share JWT Cùng share()
POST /social/posts/:id/comments JWT PostComment + commentCount++ + notif social.comment
GET /social/posts/:id/comments optional List + liked từng comment
POST /social/comments/:id/like JWT Toggle tim comment
POST /social/follow/:userId JWT Follow

Like bài → notif social.like cho tác giả (không tự notif chính mình).


5. Luồng runtime (ví dụ: thả tim)

sequenceDiagram
  participant U as User
  participant FE as SocialPostCard / ReelPage
  participant API as POST /posts/:id/like
  participant DB as post_likes + social_posts
  U->>FE: tap / double-tap tim
  FE->>FE: optimistic liked + likeCount
  FE->>API: JWT
  API->>DB: tồn tại PostLike?
  alt đã like
    DB-->>API: xóa like, likeCount-1
    API-->>FE: liked=false, likeCount
  else chưa like
    DB-->>API: tạo like, likeCount+1
    API-->>FE: liked=true, likeCount
    API-->>DB: AppNotification social.like
  end
  FE->>FE: set liked theo server (rollback nếu lỗi)

Chia sẻ

  1. Mở sheet hệ thống (Zalo / Messages / copy…).
  2. Nếu user không huỷ (Share.dismissedAction) → SocialApi.share(postId, "native").
  3. BE ghi post_shares.channel = native và tăng shareCount.
  4. FE gán shareCounts[id] = res.shareCount.

6. Thống kê — công thức & chỗ hiện

Chỉ số Công thức Hiện ở
Tim bài COUNT(post_likes) ≈ likeCount (denormalized) Card luồng · rail Reels
Bình luận COUNT(post_comments WHERE deletedAt IS NULL) ≈ commentCount Card · rail · title sheet
Tim comment comment.likeCount Trái tim nhỏ mỗi dòng
Chia sẻ COUNT(post_shares) ≈ shareCount Card · rail Reels
Lưu COUNT(post_saves) ≈ saveCount Bookmark Reels (+ card)
Xem viewCount Overlay lưới explore / profile cell (viewCount ?? likeCount)
Followers SocialProfile.followerCount SocialProfileScreen

Lưu ý denormalize: số trên SocialPost.*Count tăng/giảm trong cùng transaction với bảng event. Không scan COUNT mỗi lần render feed.

Explore tile hiện viewCount ?? likeCount (play badge) — không phải lượt play realtime.


7. File đụng (WP-SOC-ENGAGE-01)

Layer File
BE api/src/modules/social/social.controller.ts · social.service.ts
FE API mobile/src/services/api.ts (SocialApi.share, counts)
Helper mobile/src/features/social/sharePost.ts
UI SocialPostCard · SocialFeedScreen · ReelPage · ReelsFeedScreen · CommentsSheet

8. Cách kiểm tra nhanh

  1. Login CON → Social → Luồng → tim (icon đỏ, số +1) → tim lại (trừ).
  2. Bình luận → sheet → gửi → số comment trên card tăng; tim comment.
  3. Chia sẻ → chọn app hoặc copy → số share tăng (nếu huỷ sheet thì không ghi BE).
  4. Reels → double-tap video = tim; rail comment/share/save cùng postId.
  5. Swagger /docs tag social: POST /posts/{id}/share.

Restart API nếu process cũ chưa load route share bài tường.