관리자 유입 통계 추가 v1.5.35
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
# 업데이트 요약
|
||||
|
||||
## v1.5.35
|
||||
|
||||
- 관리자 대시보드에 방문자 유입 정보, 디바이스 통계, 유입 키워드 영역을 추가했다.
|
||||
- 인기 게시물 목록에서 월간 조회수와 작성일을 함께 확인할 수 있게 했다.
|
||||
- 페이지뷰 통계가 유입원과 디바이스를 일별 축약 집계하도록 개선했다.
|
||||
|
||||
## v1.5.34
|
||||
|
||||
- 공개 404/오류 페이지를 추가했다.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 배포 가이드
|
||||
|
||||
> 로컬 기준 v1.5.34에서 `npm run lint`, `npm run build` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다.
|
||||
> 로컬 기준 v1.5.35에서 `npm run lint`, `npm run build` 검증을 통과했다. NAS 실제 컨테이너 기동과 도메인/프록시 접속 검증은 운영 배포 단계에서 진행한다.
|
||||
|
||||
## 빌드 유형
|
||||
|
||||
@@ -68,6 +68,12 @@ docker exec sori-studio-db pg_isready -U sori_studio -d sori_studio
|
||||
docker exec sori-studio-db psql -U sori_studio -d sori_studio -c 'SELECT count(*) AS posts_count FROM posts;'
|
||||
```
|
||||
|
||||
### v1.5.35 마이그레이션
|
||||
|
||||
- `045_analytics_traffic_sources.sql`: 방문자 유입원·디바이스·검색 키워드 일별 축약 집계 테이블과 중복 방문 제거용 컬럼을 추가한다.
|
||||
- 적용 이후부터 수집되는 페이지뷰에 대해서만 유입 정보가 쌓인다. 과거 방문 데이터는 소급 집계하지 않는다.
|
||||
- 검색 키워드는 검색엔진이 referrer query를 전달한 경우에만 표시된다.
|
||||
|
||||
### v1.5.34 마이그레이션
|
||||
|
||||
- `044_site_settings_custom_code.sql`: `site_settings`에 `ads_txt`, `custom_head_code`, `custom_footer_code` 컬럼을 추가한다.
|
||||
@@ -261,6 +267,7 @@ docker compose --env-file .env.production up -d --build
|
||||
### 통계 데이터 보관 정책
|
||||
|
||||
- `site_analytics_daily`, `post_analytics_daily`: 사이트 전체 방문자와 게시물별 조회수의 누적 원본이므로 자동 삭제하지 않는다.
|
||||
- `analytics_traffic_daily`: 유입원·디바이스·키워드 축약 집계 원본이므로 자동 삭제하지 않는다.
|
||||
- `analytics_daily_visitors`: 일별 중복 방문 제거용 해시만 담으므로 32일 초과 행은 통계 수집·관리자 조회 흐름에서 주기적으로 삭제한다.
|
||||
- `analytics_active_sessions`: 현재 접속자 목록용 임시 데이터이며 90초 초과 행은 조회·수집 시 삭제한다.
|
||||
- 관리자 대시보드 차트는 최대 365일 범위를 조회하며, 차트 범위를 넘는 집계도 누적 통계 원본으로 보관한다.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-06-02 v1.5.35 — 유입 분석은 축약 집계로 시작한다
|
||||
|
||||
관리자 대시보드는 방문자가 어디서 들어왔는지, 어떤 기기로 보는지, 검색 키워드가 있는지 정도를 빠르게 파악할 수 있어야 한다. 다만 원문 referrer나 IP를 오래 저장하면 운영 부담과 개인정보 리스크가 커지므로, 페이지뷰 요청 시 서버가 즉시 검색·SNS·직접·기타, 디바이스·OS, 키워드로 축약해 일별 집계만 남긴다. 검색 키워드는 검색엔진이 referrer query를 전달한 경우에만 수집되며, 숨겨진 키워드는 소급하거나 추정하지 않는다.
|
||||
|
||||
## 2026-06-02 v1.5.34 — 사이트 검증 코드는 설정으로 관리한다
|
||||
|
||||
AdSense의 `ads.txt`나 헤더 검증 스크립트는 테마 파일을 직접 고치기보다 운영 설정에서 바꾸는 편이 안전하다. 그래서 사이트 설정에 ads.txt, 헤더 코드, 푸터 코드를 별도 카드로 두고, 공개 HTML 응답과 루트 `/ads.txt`에서만 반영한다. 관리자 화면과 API 응답에는 삽입하지 않아 관리 도구가 외부 광고·검증 스크립트에 영향을 받지 않게 했다. gethomepage 연동은 아직 표시 항목이 확정되지 않았으므로 기존 통계 집계에서 바로 만들 수 있는 오늘 방문자·페이지뷰·현재 접속자·평균 체류시간을 반환하는 커스텀 API 틀로 시작한다.
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
| lib/markdown-slash-commands.js | 관리자 Markdown-first 에디터 슬래시 명령 목록과 삽입 줄 정의 |
|
||||
| lib/analytics-shared.js | 통계 추적 경로 필터·체류/스크롤 상수(클라이언트·서버 공용) |
|
||||
| lib/analytics.js | 서버 전용 visitor/session hash(`node:crypto`) |
|
||||
| lib/analytics-traffic.js | referrer·User-Agent 기반 유입원·디바이스·검색 키워드 축약 분류 |
|
||||
|
||||
## Nuxt 모듈
|
||||
|
||||
@@ -128,7 +129,7 @@
|
||||
|
||||
| 파일 | 화면 |
|
||||
|------|------|
|
||||
| pages/admin/index.vue | 대시보드(상단 요약: 현재 접속자·오늘 접속자·게시물 수, 기간 선택형 방문자수·평균 체류·50% 스크롤 차트, 접속자 목록, 인기 게시물·인기 페이지 참여 지표) |
|
||||
| pages/admin/index.vue | 대시보드(상단 요약: 현재 접속자·오늘 접속자·게시물 수, 기간 선택형 방문자수·평균 체류·50% 스크롤 차트, 방문자 유입 정보·디바이스·유입 키워드, 접속자 목록, 인기 게시물 월간 조회수·작성일, 인기 페이지 참여 지표) |
|
||||
| pages/admin/login.vue | 관리자 로그인, 일반 로그인과 같은 다크 인증 스타일·우측 배치 및 내부 오른쪽 정렬 폼, 이메일·비밀번호 모두 입력 시에만 제출 버튼 활성 |
|
||||
| pages/admin/posts/index.vue | 글 목록, 헤더 우측에 검색·필터(상태·태그·추천·정렬)와 «새 글»을 한 줄 배치, 예약/초안/발행/멤버십/비공개 텍스트 상태, 추천 표시와 제목 사이 대표 이미지 썸네일, 제목 옆 댓글 수, 첫 번째 태그 색상 대표 배지, 화면 기준 행 more vert 메뉴(추천·삭제) |
|
||||
| pages/admin/posts/new.vue | 글 작성, Ghost 스타일 작성 폼, 초안 `POST` 디바운스 자동 저장·이탈 직전 플러시, 저장 토스트 |
|
||||
@@ -267,7 +268,7 @@
|
||||
| server/repositories/post-import-repository.js | 게시물 Export ZIP Import 저장소(frontmatter·자산 재매핑·게시물 생성) |
|
||||
| server/repositories/member-repository.js | 회원 조회/생성 저장소 |
|
||||
| server/repositories/comment-repository.js | 댓글 조회/생성 저장소 |
|
||||
| server/repositories/analytics-repository.js | 방문·게시물 통계 집계·관리자 요약 조회·방문자 해시 보관 정리 |
|
||||
| server/repositories/analytics-repository.js | 방문·게시물·유입 통계 집계·관리자 요약 조회·방문자 해시 보관 정리 |
|
||||
| server/utils/analytics-pageview-input.js | `POST /api/analytics/pageview` 검증·기록 |
|
||||
| server/utils/zip-writer.js | 게시물 Export ZIP 생성 유틸리티 |
|
||||
| server/utils/zip-reader.js | 게시물 Import ZIP 읽기 유틸리티 |
|
||||
@@ -278,6 +279,7 @@
|
||||
| server/routes/admin/api/analytics/posts.get.js | 관리자 인기 게시물 API |
|
||||
| server/routes/admin/api/analytics/pages.get.js | 관리자 인기 페이지 API |
|
||||
| server/routes/admin/api/analytics/realtime.get.js | 관리자 실시간 접속자 API |
|
||||
| server/routes/admin/api/analytics/traffic.get.js | 관리자 유입원·디바이스·키워드 통계 API |
|
||||
| plugins/site-analytics.client.js | 공개 라우트 pageview·heartbeat·read 클라이언트 전송 |
|
||||
|
||||
## 데이터베이스
|
||||
@@ -318,6 +320,7 @@
|
||||
| db/migrations/042_post_export_date_range.sql | 게시물 Export 날짜 범위 컬럼 추가 |
|
||||
| db/migrations/043_post_export_size_and_error_detail.sql | 게시물 Export 목표 용량·실패 상세 로그 컬럼 추가 |
|
||||
| db/migrations/044_site_settings_custom_code.sql | 사이트 설정 ads.txt·공통 헤더 코드·공통 푸터 코드 컬럼 추가 |
|
||||
| db/migrations/045_analytics_traffic_sources.sql | 방문자 유입원·디바이스·키워드 일별 집계 테이블 추가 |
|
||||
|
||||
## 설정/배포
|
||||
|
||||
|
||||
14
docs/spec.md
14
docs/spec.md
@@ -447,17 +447,22 @@ components/content/
|
||||
| site_analytics_daily | day, page_views, visitors, engaged_views, total_engaged_seconds | 사이트 일별 페이지뷰·방문자·체류 집계 |
|
||||
| post_analytics_daily | day, post_id, views, reads, visitors, engaged_views, total_engaged_seconds, scroll_25~100 | 게시물 일별 조회·읽음·스크롤 구간 |
|
||||
| page_analytics_daily | day, page_id, views, visitors, engaged_views, total_engaged_seconds, scroll_25~100 | 페이지 일별 조회·방문자·스크롤 구간 |
|
||||
| analytics_daily_visitors | day, scope(`site`/`post`/`page`), post_id?, page_id?, visitor_hash | 일별 방문자 해시 등록(중복 방문 제거용) |
|
||||
| analytics_traffic_daily | day, source_group, source_name, device_type, os_name, keyword, page_views, visitors | 유입원·디바이스·키워드 일별 축약 집계 |
|
||||
| analytics_daily_visitors | day, scope(`site`/`post`/`page`/`traffic`), post_id?, page_id?, visitor_hash, source_group?, source_name?, device_type?, os_name?, keyword? | 일별 방문자 해시 등록(중복 방문 제거용) |
|
||||
| analytics_active_sessions | session_hash, user_id?, path, post_id?, post_slug, page_id?, page_slug, duration_seconds, max_scroll_ratio, last_seen_at | 실시간 접속 세션(TTL 90초) |
|
||||
|
||||
- 추적 대상: 공개 경로만. `/admin`, `/signin`, `/signup`, `/forgot-password`, `/settings`는 제외.
|
||||
- 봇 User-Agent는 서버에서 무시.
|
||||
- 페이지뷰 수집은 탭 최초 referrer와 현재 URL을 서버로 보내며, 서버는 원문 referrer를 저장하지 않고 검색·SNS·직접·기타, 디바이스·OS, 검색 키워드로 축약해 `analytics_traffic_daily`에 집계한다.
|
||||
- 검색 유입은 네이버·다음·구글·줌·빙을 우선 분류하고, SNS 유입은 카카오톡·페이스북·인스타그램·트위터/X·유튜브를 우선 분류한다. 검색 키워드는 referrer query에 남아 있는 경우만 표시한다.
|
||||
- 게시물 `reads`는 클라이언트에서 15초 이상 체류·50% 이상 스크롤 후 별도 전송.
|
||||
- `POST /api/analytics/heartbeat`는 20초 간격으로 체류시간·스크롤·현재 경로를 전송한다. 로그인 사용자는 서버 세션으로 `user_id`를 연결한다.
|
||||
- 관리자 대시보드는 `GET /admin/api/analytics/realtime`으로 현재 접속자 목록(닉네임·아바타·게시물 제목·접속 유지시간)을 조회한다.
|
||||
- 관리자 대시보드 **통계 추이**는 `trends` 데이터를 3개 막대 차트(방문자수·평균 체류시간·50% 스크롤 도달)로 표시한다. 7일은 일자별로 표시하고, 30일 이상은 선택 기간에 따라 7일·14일·30일 단위로 묶어 카드 폭을 넘지 않게 한다. 막대 hover/focus 시 기간과 정확한 값을 툴팁으로 표시하며, 표(table)나 외부 차트 라이브러리는 사용하지 않는다.
|
||||
- 관리자 대시보드 **방문자 유입 정보**는 선택 기간 기준 검색·SNS·기타(직접 포함) 유입원, 디바이스/OS, 유입 키워드를 표시한다.
|
||||
- 관리자 대시보드 **인기 게시물**은 선택 기간 조회수와 함께 최근 30일 월간 조회수, 작성일을 표시한다.
|
||||
- 관리자 차트는 최대 365일 범위를 조회한다.
|
||||
- `site_analytics_daily`, `post_analytics_daily`는 사이트 전체 방문자와 게시물별 조회수 누적 원본이므로 자동 삭제하지 않는다.
|
||||
- `site_analytics_daily`, `post_analytics_daily`, `analytics_traffic_daily`는 사이트 전체 방문자와 게시물별 조회수, 유입 통계 누적 원본이므로 자동 삭제하지 않는다.
|
||||
- `analytics_daily_visitors`는 일별 중복 방문 제거용이며, 수집·조회 흐름에서 32일보다 오래된 행을 주기적으로 삭제한다.
|
||||
- `analytics_active_sessions`는 현재 접속자 목록용이며, 90초보다 오래된 행을 삭제한다.
|
||||
|
||||
@@ -490,7 +495,7 @@ components/content/
|
||||
- `GET /api/search?q=` - 통합 검색(태그 `name`·`slug`, 게시물 `title`·`excerpt`·`content` 부분 일치, 각 최대 12건, 발행 게시물만)
|
||||
- `GET /api/site-settings` - 공개 사이트 설정(어나운스 바·홈 커버 등 포함)
|
||||
- `GET /api/homepage-widget` - gethomepage customapi용 사이트 요약. `title`, `updatedAt`, `todayVisitors`, `todayPageViews`, `onlineNow`, `loggedInNow`, `avgEngagedSeconds`, `items[]`를 반환한다.
|
||||
- `POST /api/analytics/pageview` - 공개 방문·게시물·페이지 조회/읽음 집계. 본문: `path`(필수), `postSlug`(게시물일 때), `pageSlug`(페이지일 때), `read`(읽음 이벤트). 발행된 게시물과 공개 페이지만 개별 집계한다. 응답 `{ ok: true }`. HTML 문서 모드 페이지는 Nuxt 클라이언트 플러그인을 거치지 않으므로 서버 미들웨어가 GET 요청 시 페이지 조회를 직접 기록한다.
|
||||
- `POST /api/analytics/pageview` - 공개 방문·게시물·페이지 조회/읽음 집계. 본문: `path`(필수), `postSlug`(게시물일 때), `pageSlug`(페이지일 때), `referrer`, `currentUrl`, `read`(읽음 이벤트). 발행된 게시물과 공개 페이지만 개별 집계한다. 응답 `{ ok: true }`. HTML 문서 모드 페이지는 Nuxt 클라이언트 플러그인을 거치지 않으므로 서버 미들웨어가 GET 요청 시 페이지 조회를 직접 기록한다.
|
||||
- `POST /api/analytics/heartbeat` - 실시간 세션·체류·스크롤 집계. 본문: `path`, `postSlug`, `pageSlug`, `clientSessionId`, `durationSeconds`(최대 1800), `maxScrollRatio`(0~1). 로그인 시 서버가 회원 세션으로 사용자 연결.
|
||||
- `GET /api/navigation` - 공개 네비게이션(`primary`는 트리·`footer`·`recommended`는 평면, 상세는 위 메뉴/네비게이션 절)
|
||||
- `GET /ads.txt` - 사이트 설정의 ads.txt 본문을 `text/plain`으로 반환한다. 값이 없으면 빈 본문을 반환한다.
|
||||
@@ -525,9 +530,10 @@ components/content/
|
||||
- `POST /admin/api/auth/logout` - 로그아웃
|
||||
- `GET /admin/api/auth/me` - 현재 관리자 세션 조회
|
||||
- `GET /admin/api/analytics/summary?days=30` - 통계 요약(오늘/7일 방문, 30일 조회, 현재 접속자, 평균 체류, 50% 스크롤 도달, 일자별 `trends`). `days`는 대시보드에서 7/30/90/180/365로 전환한다.
|
||||
- `GET /admin/api/analytics/posts?days=30&limit=5` - 기간 내 인기 게시물(조회·읽음·평균 체류·스크롤 구간)
|
||||
- `GET /admin/api/analytics/posts?days=30&limit=5` - 기간 내 인기 게시물(조회·최근 30일 월간 조회·작성일·읽음·평균 체류·스크롤 구간)
|
||||
- `GET /admin/api/analytics/pages?days=30&limit=5` - 기간 내 인기 페이지(조회·방문자·평균 체류·스크롤 구간)
|
||||
- `GET /admin/api/analytics/realtime?limit=20` - 현재 접속자 요약·목록(로그인 사용자 닉네임·아바타 포함)
|
||||
- `GET /admin/api/analytics/traffic?days=30` - 기간 내 유입원·디바이스·유입 키워드 통계
|
||||
- `GET /admin/api/posts` - 글 목록
|
||||
- `POST /admin/api/posts` - 글 작성
|
||||
- `GET /admin/api/posts/:id` - 글 상세
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# 업데이트 이력
|
||||
|
||||
## v1.5.35
|
||||
|
||||
- 관리자 대시보드: 검색·SNS·직접·기타 유입 정보 카드 추가.
|
||||
- 관리자 대시보드: 디바이스·OS별 방문 집계와 유입 키워드 목록 추가.
|
||||
- 관리자 대시보드: 인기 게시물에 월간 조회수와 작성일 표시 추가.
|
||||
- Analytics: 페이지뷰 수집 시 referrer·현재 URL을 받아 유입원과 키워드를 집계하도록 추가.
|
||||
- DB: `analytics_traffic_daily`와 유입 중복 방문자 집계 컬럼 추가.
|
||||
|
||||
## v1.5.34
|
||||
|
||||
- 공개 화면: Nuxt 전역 404/오류 페이지 추가.
|
||||
|
||||
Reference in New Issue
Block a user