Post view counting over core migration V159's
phoenix_kit_publishing_post_views — one (post_uuid, view_date) row per
day, incremented in place. Totals are SUM(count).
What counts as a view
A public post-page render for a group with views_enabled on, where:
- the visitor's User-Agent doesn't look like a bot/CLI (
bot_ua?/1), and - the visitor's session hasn't already viewed this post today — dedup
rides the Phoenix session cookie (
mark_viewed/2), so there is no server-side visitor state and no reader PII: the DB only ever stores accepted counts. A cookieless client (most bots) still passes the session check every time, which is why the UA filter runs first.
Recording is fire-and-forget (Task.Supervisor under core's
PhoenixKit.TaskSupervisor) — a slow or failing insert never delays or
crashes the page.
Summary
Functions
True when the User-Agent looks like a bot/CLI (or is absent).
Records a view for post_uuid unless the request is a bot or this session
already viewed the post today. Returns the (possibly updated) conn —
callers thread it so the dedup marker lands in the session cookie.
Increments today's rollup row for a post (upsert). Safe under concurrency —
the conflict target is the primary key and the update is an atomic
count = count + 1.
A group's top posts by views in the trailing days window:
[{post_uuid, views}], most-viewed first, capped at limit.
All-time view total for one post.
All-time view totals for a list of post uuids: %{post_uuid => total}.
Functions
True when the User-Agent looks like a bot/CLI (or is absent).
Records a view for post_uuid unless the request is a bot or this session
already viewed the post today. Returns the (possibly updated) conn —
callers thread it so the dedup marker lands in the session cookie.
Increments today's rollup row for a post (upsert). Safe under concurrency —
the conflict target is the primary key and the update is an atomic
count = count + 1.
A group's top posts by views in the trailing days window:
[{post_uuid, views}], most-viewed first, capped at limit.
All-time view total for one post.
All-time view totals for a list of post uuids: %{post_uuid => total}.