feat: Add app_id parameter to engagement functions for proper routing
All engagement functions (like, truth vote, share, view, comment) now accept app_id in addition to guid. This enables the backend to route requests to the correct system based on app_id. - news-global → routes to news-app (ES-based) - no app_id → routes to native post system (PostgreSQL/YCQL) Future apps can be routed based on their app_id. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5d5fae63c5
commit
cd9ab30ab7
|
|
@ -415,10 +415,11 @@ export async function fetchPostTruth(postId) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function votePostTruth(postId, vote, guid = null) {
|
||||
export async function votePostTruth(postId, vote, guid = null, appId = null) {
|
||||
if (!postId && !guid) throw new Error("post_id or guid required");
|
||||
const payload = { post_id: postId, vote };
|
||||
if (guid) payload.guid = guid;
|
||||
if (appId) payload.app_id = appId;
|
||||
const body = JSON.stringify(payload);
|
||||
const res = await fetch(`${apiBase()}/post/truth-vote`, {
|
||||
method: "POST",
|
||||
|
|
@ -778,11 +779,12 @@ export async function fetchProfile(username = "") {
|
|||
}
|
||||
}
|
||||
|
||||
export async function recordPostView(postId, guid = null) {
|
||||
export async function recordPostView(postId, guid = null, appId = null) {
|
||||
if (!postId && !guid) return { ok: false };
|
||||
try {
|
||||
const body = { post_id: postId };
|
||||
if (guid) body.guid = guid;
|
||||
if (appId) body.app_id = appId;
|
||||
const res = await fetch(`${apiBase()}/post/view`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
|
@ -796,11 +798,12 @@ export async function recordPostView(postId, guid = null) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function togglePostLike(postId, like = true, guid = null) {
|
||||
export async function togglePostLike(postId, like = true, guid = null, appId = null) {
|
||||
if (!postId && !guid) return { ok: false };
|
||||
try {
|
||||
const body = { post_id: postId, like };
|
||||
if (guid) body.guid = guid;
|
||||
if (appId) body.app_id = appId;
|
||||
const res = await fetch(`${apiBase()}/post/like`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", ...authHeaders() },
|
||||
|
|
@ -814,11 +817,12 @@ export async function togglePostLike(postId, like = true, guid = null) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function recordPostShare(postId, guid = null) {
|
||||
export async function recordPostShare(postId, guid = null, appId = null) {
|
||||
if (!postId && !guid) return { ok: false };
|
||||
try {
|
||||
const body = { post_id: postId };
|
||||
if (guid) body.guid = guid;
|
||||
if (appId) body.app_id = appId;
|
||||
const res = await fetch(`${apiBase()}/post/share`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
|
@ -832,11 +836,12 @@ export async function recordPostShare(postId, guid = null) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function fetchPostComments(postId, limit = 20, guid = null) {
|
||||
export async function fetchPostComments(postId, limit = 20, guid = null, appId = null) {
|
||||
if (!postId && !guid) return [];
|
||||
const qs = new URLSearchParams();
|
||||
qs.set("post_id", String(postId));
|
||||
if (guid) qs.set("guid", guid);
|
||||
if (appId) qs.set("app_id", appId);
|
||||
if (limit) qs.set("limit", String(limit));
|
||||
try {
|
||||
const res = await fetch(`${apiBase()}/post/comments?${qs.toString()}`, {
|
||||
|
|
@ -850,12 +855,13 @@ export async function fetchPostComments(postId, limit = 20, guid = null) {
|
|||
}
|
||||
}
|
||||
|
||||
export async function createPostComment(postId, body, guid = null) {
|
||||
export async function createPostComment(postId, body, guid = null, appId = null) {
|
||||
if (!postId && !guid) return { ok: false };
|
||||
if (!body) return { ok: false };
|
||||
try {
|
||||
const reqBody = { post_id: postId, body };
|
||||
if (guid) reqBody.guid = guid;
|
||||
if (appId) reqBody.app_id = appId;
|
||||
const res = await fetch(`${apiBase()}/post/comment`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", ...authHeaders() },
|
||||
|
|
|
|||
|
|
@ -1812,7 +1812,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
|
||||
if ((postID > 0 || postData?.guid) && !modalWrap.__swViewed) {
|
||||
modalWrap.__swViewed = true;
|
||||
recordPostView(postID, postData?.guid).then((res) => {
|
||||
recordPostView(postID, postData?.guid, postData?.app_id).then((res) => {
|
||||
const counts = res?.counts;
|
||||
if (counts) {
|
||||
updateStat(modalWrap, "views", counts.view_count);
|
||||
|
|
@ -1858,7 +1858,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
}
|
||||
trackEvent("post_like_click", { post_id: postID, context: "map" });
|
||||
likeBtn.disabled = true;
|
||||
const res = await togglePostLike(postID, !liked);
|
||||
const res = await togglePostLike(postID, !liked, postData?.guid, postData?.app_id);
|
||||
if (res?.ok) {
|
||||
liked = !!res.liked;
|
||||
likeBtn.textContent = liked ? "Liked" : "Like";
|
||||
|
|
@ -1889,7 +1889,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
await navigator.clipboard.writeText(shareUrl);
|
||||
}
|
||||
} catch {}
|
||||
const res = await recordPostShare(postID, postData?.guid);
|
||||
const res = await recordPostShare(postID, postData?.guid, postData?.app_id);
|
||||
const counts = res?.counts;
|
||||
if (counts) {
|
||||
updateStat(modalWrap, "views", counts.view_count);
|
||||
|
|
@ -1945,7 +1945,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
|
||||
try {
|
||||
trackEvent("truth_vote_click", { post_id: postID || postData?.guid, vote, context: "map" });
|
||||
const stats = await votePostTruth(postID, vote, postData?.guid);
|
||||
const stats = await votePostTruth(postID, vote, postData?.guid, postData?.app_id);
|
||||
if (stats) {
|
||||
currentVote = vote;
|
||||
updateButtonStyles();
|
||||
|
|
@ -2188,7 +2188,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
|
||||
const commentsBody = modalWrap.querySelector(".sw-livechat-body");
|
||||
if (commentsBody && postID > 0) {
|
||||
fetchPostComments(postID, 20).then((items) => renderComments(commentsBody, items));
|
||||
fetchPostComments(postID, 20, postData?.guid, postData?.app_id).then((items) => renderComments(commentsBody, items));
|
||||
}
|
||||
if (commentBtn && commentInput && postID > 0) {
|
||||
commentBtn.addEventListener("click", async () => {
|
||||
|
|
@ -2200,10 +2200,10 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
|
|||
if (!body) return;
|
||||
trackEvent("post_comment_submit", { post_id: postID, context: "map" });
|
||||
commentBtn.disabled = true;
|
||||
const res = await createPostComment(postID, body, postData?.guid);
|
||||
const res = await createPostComment(postID, body, postData?.guid, postData?.app_id);
|
||||
if (res?.ok) {
|
||||
commentInput.value = "";
|
||||
const existing = await fetchPostComments(postID, 20, postData?.guid);
|
||||
const existing = await fetchPostComments(postID, 20, postData?.guid, postData?.app_id);
|
||||
renderComments(commentsBody, existing);
|
||||
const counts = res?.counts;
|
||||
if (counts) {
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
// Initial data fetch
|
||||
useEffect(() => {
|
||||
if (!postId) return;
|
||||
recordPostView(postId, post?.guid).then(res => {
|
||||
recordPostView(postId, post?.guid, post?.app_id).then(res => {
|
||||
if (res?.counts) setCounts(c => ({ ...c, views: res.counts.view_count || c.views, likes: res.counts.like_count || c.likes }));
|
||||
});
|
||||
fetchPostLikeState(postId).then(res => { if (res?.liked !== undefined) setLiked(res.liked); });
|
||||
|
|
@ -690,18 +690,18 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
const newLiked = !liked;
|
||||
setLiked(newLiked);
|
||||
setCounts(c => ({ ...c, likes: c.likes + (newLiked ? 1 : -1) }));
|
||||
const res = await togglePostLike(postId, newLiked, post?.guid);
|
||||
const res = await togglePostLike(postId, newLiked, post?.guid, post?.app_id);
|
||||
if (res?.counts) setCounts(c => ({ ...c, likes: res.counts.like_count ?? c.likes }));
|
||||
}, [postId, liked, post?.guid]);
|
||||
}, [postId, liked, post?.guid, post?.app_id]);
|
||||
|
||||
const handleShare = useCallback(async () => {
|
||||
if (!postId) return;
|
||||
const shareUrl = `${window.location.origin}/p/${postId}`;
|
||||
if (navigator.share) { try { await navigator.share({ title: post?.title, url: shareUrl }); } catch {} }
|
||||
else { navigator.clipboard?.writeText(shareUrl); }
|
||||
const res = await recordPostShare(postId, post?.guid);
|
||||
const res = await recordPostShare(postId, post?.guid, post?.app_id);
|
||||
if (res?.counts) setCounts(c => ({ ...c, shares: res.counts.share_count ?? c.shares }));
|
||||
}, [postId, post?.title, post?.guid]);
|
||||
}, [postId, post?.title, post?.guid, post?.app_id]);
|
||||
|
||||
const handleTruthVote = useCallback(async (vote) => {
|
||||
if (!postId) return;
|
||||
|
|
@ -709,9 +709,9 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
window.dispatchEvent(new CustomEvent("sociowire:auth-required"));
|
||||
return;
|
||||
}
|
||||
const res = await votePostTruth(postId, vote, post?.guid);
|
||||
const res = await votePostTruth(postId, vote, post?.guid, post?.app_id);
|
||||
if (res) setTruth({ score: res.truth_score ?? res.user_score ?? truth.score, count: res.vote_count ?? truth.count });
|
||||
}, [postId, truth, token, post?.guid]);
|
||||
}, [postId, truth, token, post?.guid, post?.app_id]);
|
||||
|
||||
const handleComment = useCallback(async () => {
|
||||
const body = commentInput.trim();
|
||||
|
|
@ -727,7 +727,7 @@ export default function PostDetailModal({ post, onClose, onPostUpdated, onPostDe
|
|||
// Retry logic - try up to 3 times with delay
|
||||
let res = null;
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
res = await createPostComment(postId, body, post?.guid);
|
||||
res = await createPostComment(postId, body, post?.guid, post?.app_id);
|
||||
if (res?.ok) break;
|
||||
if (attempt < 2) await new Promise(r => setTimeout(r, 500)); // wait before retry
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue