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:
19
backend/app/db/migrations/004_symbol_views.sql
Normal file
19
backend/app/db/migrations/004_symbol_views.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
-- Phase 5: 종목 페이지 익명 조회 카운터.
|
||||
-- (code, view_date) PK 로 일 단위 집계. Redis/KV 없이 PG 만으로 충분 — 쓰기 빈도가
|
||||
-- 낮고(페이지 진입 시 클라이언트 측에서 하루 1회로 dedupe), UPSERT 1회 비용은 무시 가능.
|
||||
-- symbols(code) FK 는 일부러 안 걺 — 삭제된/오타 코드 방문에도 카운터가 죽지 않게.
|
||||
|
||||
\set ON_ERROR_STOP on
|
||||
|
||||
CREATE TABLE IF NOT EXISTS symbol_views_daily (
|
||||
code TEXT NOT NULL,
|
||||
view_date DATE NOT NULL,
|
||||
views INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (code, view_date)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS symbol_views_daily_date_idx
|
||||
ON symbol_views_daily (view_date DESC);
|
||||
|
||||
COMMENT ON TABLE symbol_views_daily IS
|
||||
'Phase 5: 종목 페이지 익명 조회 카운터. 일 단위 UPSERT(+1). 클라이언트가 localStorage 로 dedupe.';
|
||||
Reference in New Issue
Block a user