feat(views): anonymous daily view counter with social-proof badge
- New table symbol_views_daily(code, view_date, views) via migration 004.
- POST /api/views/{code} UPSERTs and returns today_views; GET returns
today + last_7d + trend (last 7 days).
- Client dedupes via localStorage (views:logged map keyed by KST date) so a
given browser counts once per day per code; refresh/extra tabs don't inflate.
- PriceHero shows "오늘 N명이 봤어요" pill when viewsToday > 0.
Read-only social proof — Toss 의 종목 상세에서 익명 카운트로 진입 신호를 주는 패턴.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -352,4 +352,28 @@ export const api = {
|
||||
getJson<OrderbookResponse>(`/api/orderbook/${encodeURIComponent(code)}`),
|
||||
fundamentals: (code: string) =>
|
||||
getJson<FundamentalsResponse>(`/api/fundamentals/${encodeURIComponent(code)}`),
|
||||
recordView: (code: string) =>
|
||||
getJson<RecordViewResponse>(`/api/views/${encodeURIComponent(code)}`, {
|
||||
method: "POST",
|
||||
}),
|
||||
views: (code: string) =>
|
||||
getJson<ViewsResponse>(`/api/views/${encodeURIComponent(code)}`),
|
||||
};
|
||||
|
||||
export type RecordViewResponse = {
|
||||
ok: boolean;
|
||||
code?: string;
|
||||
today_views: number;
|
||||
};
|
||||
|
||||
export type ViewsTrendPoint = {
|
||||
date: string;
|
||||
views: number;
|
||||
};
|
||||
|
||||
export type ViewsResponse = {
|
||||
code: string;
|
||||
today_views: number;
|
||||
last_7d_views: number;
|
||||
trend: ViewsTrendPoint[];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user