Generator for MishkaDocument resources.
- Test functions (no prefix): simple, deterministic — used by factory and tests.
- Dev functions (dev_ prefix): realistic, rich data — used by dev seeds.
Every generator takes the tenant (where the resource is site-scoped) and the actor as trailing
optional arguments. The actor matters beyond authorization: MishkaDocument.EventLog persists it
as actor_id, and MishkaDocument.Resources.Calculations.WorkspaceMaintainers derives a
workspace's maintainer list purely from those event rows, so a create without an actor produces a
workspace nobody appears to maintain.
status: :archived on workspace_version/3 is a plain label — MishkaDocument.WorkspaceVersion
has no AshArchival and its :destroy is a hard delete, so the label is the only way to express an
archived version. It is deliberately absent from workspace/3: MishkaDocument.Workspace carries
archived_at, and a workspace holding only the status label renders as archived while still
sitting in the Active tab.
Summary
Functions
Creates a note draft through the master action, which is the only path that can attach the draft
to a section_draft_id.
Tracks one page view of a section.
Functions
Creates a note draft through the master action, which is the only path that can attach the draft
to a section_draft_id.
The tenant :create action resolves the parent section draft with
Ash.get(MishkaDocument.SectionDraft, id, authorize?: false) and passes no tenant, so on a
global? false resource that lookup always fails and the create is rejected with "Section draft
not found". :master_create performs the same lookup through :master_get, which bypasses
multitenancy. Note drafts hanging off a real section take note_draft/3 instead.
Tracks one page view of a section.
MishkaDocument.SectionView is not site-scoped and takes no tenant. The view belongs to actor,
and a nil actor with a distinct ip_address is a guest view. The create action upserts on
{section_id, user_id, ip_address}, so repeated rows collapse instead of failing.