MishkaBlog.Dashboard.Overview (Mishka Blog v0.0.1)

Copy Markdown View Source

Every number on the blog admin overview page (/admin/dashboard/blog), read from the database.

load/1 gathers the whole page in one pass — the five KPI cards, the eight section cards, the "This Month" panel and the recent-activity list — and calendar/2 reads one month of the editorial calendar. Both are pure reads returning plain numbers and records; every label, delta and abbreviation is the page's business, not this module's.

Every figure is read as user through MishkaBlog.Dashboard.Scope: a master (a user whose site_id is nil) through each resource's master read, counting every site, and a site user through the tenant read under its own site, counting only that one. The resources' policies decide what the viewer reads. The two join resources — MishkaBlog.PostView and MishkaBlog.TeamMember — have no master read and carry no site_id; both viewers read them through :read, which their policies keep to the viewer's site, joined to the post or team they belong to (not is_nil(post.id)), so a row of an archived post or team is not counted by anybody.

What a viewer's figures are read from

Each figure is read only from the blog area the viewer holds (areas/1): posts, views, bloggers, collections, tags, teams and auto posting from admin:dashboard:blog:post, comments from admin:dashboard:blog:comment — the permissions those resources' policies ask for. A read of an area the viewer does not hold is refused and counted as no data, so its counts are zero, its rows are missing from :activity, and an engagement rate — comments over views — is zero unless both are held. The calendar is a post holder's.

Counts are deliberately many small Ash.count/2 calls rather than one hand-written query: each one goes through the resource's own read action, so archival, base filters, multitenancy and policies stay the resources' business. The caller is expected to run this off the render — see MishkaBlogWeb.Live.Admin.Dashboard.Home.Index, which loads it in a start_async/3.

See MishkaBlog.Dashboard.Widgets.DraftsScheduled for the same idiom at widget scale.

Summary

Types

Which blog areas a viewer holds on the dashboard.

Functions

Which blog areas user holds on the dashboard: :post for admin:dashboard:blog:post, :comment for admin:dashboard:blog:comment. nil, or a user holding neither, holds none.

Reads the editorial calendar for the month containing date, as user.

Reads every statistic the overview page shows, as user (see MishkaBlog.Dashboard.Scope).

The day a post belongs on in the calendar — when it went out, or when it is due to.

Types

areas()

@type areas() :: %{post: boolean(), comment: boolean()}

Which blog areas a viewer holds on the dashboard.

Functions

areas(user)

@spec areas(map() | nil) :: areas()

Which blog areas user holds on the dashboard: :post for admin:dashboard:blog:post, :comment for admin:dashboard:blog:comment. nil, or a user holding neither, holds none.

calendar(user, date)

@spec calendar(map(), Date.t()) :: map()

Reads the editorial calendar for the month containing date, as user.

Returns %{month: Date.t(), cells: [cell]} where the cells are the 42 squares of a six-week grid. A cell outside the month carries date: nil and no posts; an in-month cell carries the published posts whose published_at and the scheduled posts whose scheduled_publish_at land on that day.

Only those two states appear: a draft has no place on an editorial calendar even when it carries a leftover published_at, and an archived post has already left it.

load(user)

@spec load(map()) :: map()

Reads every statistic the overview page shows, as user (see MishkaBlog.Dashboard.Scope).

Returns a flat map of numbers plus :activity, the newest few blog records as %{kind, title, status, at} — kind being :post, :comment or :blogger, and status the record's own status where it has one (nil for a blogger) so the page can word the entry without claiming a draft was published.

post_date(arg1)

@spec post_date(map()) :: Date.t() | nil

The day a post belongs on in the calendar — when it went out, or when it is due to.