PhoenixKitKnowledgeBase.Places (PhoenixKitKnowledgeBase v0.1.0)

Copy Markdown View Source

Where a drop-in notes panel's notes live.

A panel is given a path — ["CRM", "Clients", "Acme"]. The first segment names the vault, the rest the folder chain inside it, and the panel shows that folder and everything under it. Nothing exists until it is needed: the first note or folder creates the vault and the chain (ensure/2).

Two kinds of place share a path:

  • :shared ("everyone here") — an organisation vault of that name, so the admin pages, its managers and its members work on it as on any other. Who may use it through a panel is the host's call: the :authorize hook.
  • :private ("only me") — the person's own personal vault of that name. Only they can reach it; the hook is not asked and cannot widen it.

A vault is found by path_key (the slugified first segment), which only a vault created here carries — an organisation vault that merely happens to be called "CRM" is not adopted. Names are not unique and slugs are unique across everyone's vaults, so neither could say which vault a path means.

Notes are kept by path: a path built from something that changes (a client's name) points at a new, empty folder after the change, and the old notes stay where they were. Hosts should put something stable in the path.

Access

config :phoenix_kit_knowledge_base, :authorize, {MyApp.Notes, :can?}

can?(action, user, path), with action :view or :edit and path the panel's path, is asked about shared places only. Unconfigured, any signed-in user may use a shared place, as with boards. A hook that raises, throws, exits or answers anything but a boolean is a no — logged without its arguments. It grants access through a panel, under its path; the admin pages keep their own rules.

Summary

Types

t()

A parsed panel path. folder is "" for the vault root.

Functions

Whether user may action (:view / :edit) the place. See "Access".

The place's vault and folder chain, created as needed. Asks authorize/3 for :edit first.

The vault a place lives in, if it has been created. No side effects — this is what a panel shows before anyone has written anything.

Validates a panel's path and visibility.

Whether relative_path (a note's folder or a folder) sits inside the place's folder — the fence every panel event checks, so a crafted event cannot reach the rest of the vault.

Types

action()

@type action() :: :view | :edit

t()

@type t() :: %PhoenixKitKnowledgeBase.Places{
  folder: String.t(),
  key: String.t(),
  path: [String.t()],
  vault_name: String.t(),
  visibility: visibility()
}

A parsed panel path. folder is "" for the vault root.

visibility()

@type visibility() :: :shared | :private

Functions

authorize(action, user, arg3)

@spec authorize(action(), PhoenixKit.Users.Auth.User.t() | nil, t()) :: boolean()

Whether user may action (:view / :edit) the place. See "Access".

ensure(place, user)

@spec ensure(t(), PhoenixKit.Users.Auth.User.t() | nil) ::
  {:ok, PhoenixKitKnowledgeBase.Schemas.Vault.t()} | {:error, term()}

The place's vault and folder chain, created as needed. Asks authorize/3 for :edit first.

Two people writing the first note at once both reach the insert; the second loses on the unique index, re-reads, and uses the first one's vault.

locate(places, arg2)

The vault a place lives in, if it has been created. No side effects — this is what a panel shows before anyone has written anything.

parse(path, visibility)

@spec parse(term(), term()) :: {:ok, t()} | {:error, term()}

Validates a panel's path and visibility.

Every segment must be usable as a file or directory name (Storage.validate_filename/1): a segment is user-visible text and a directory on disk. An invalid one is a developer error, reported, never written.

within?(arg1, relative_path)

@spec within?(t(), String.t() | nil) :: boolean()

Whether relative_path (a note's folder or a folder) sits inside the place's folder — the fence every panel event checks, so a crafted event cannot reach the rest of the vault.