feat: add anonymous view counter with most-read sidebar

- node:sqlite storage in $DATA_DIR/views.db (no native deps)
- POST /api/views/<slug>/ counts once per visitor per 24h via
  daily-salted hash; IPs are never stored, bots are skipped
- GET /api/views/top/ feeds the sidebar's featured list, falling back
  to frontmatter-featured and latest posts when unavailable

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-16 01:15:05 +03:00
parent 809f89af08
commit c1c57c4f85
7 changed files with 178 additions and 30 deletions
+2 -2
View File
@@ -59,10 +59,10 @@ export function tagCounts(posts: Post[]): TagCount[] {
return [...map.values()].sort((a, b) => b.count - a.count || a.tag.localeCompare(b.tag, 'tr'));
}
/** Fallback "featured" list: frontmatter `featured`, else the latest posts. */
/** Fallback "featured" list: frontmatter `featured` first, topped up with the latest posts. */
export function featuredPosts(posts: Post[], limit = 3): Post[] {
const featured = posts.filter((p) => p.data.featured);
return (featured.length ? featured : posts).slice(0, limit);
return [...featured, ...posts.filter((p) => !p.data.featured)].slice(0, limit);
}
/** prev = older post, next = newer post. */