Sigra.Plug.LoadActiveOrganization (Sigra v1.20.0)

Copy Markdown View Source

Hydrates scope.active_organization and scope.membership from the caller's %Sigra.Session{} (read from conn.private[:sigra_session], stashed by Sigra.Plug.FetchSession).

This is a Fetch plug in the phx.gen.auth sense: it mutates conn.assigns[:current_scope] and conn.private[:sigra_session], but NEVER halts the pipeline. Missing, invalid, or stale pointers resolve to a nil active_organization (or a reassigned one after hybrid recovery) and the request continues. Downstream Sigra.Plug.RequireMembership is responsible for halting when an active org is required.

Stale-pointer recovery

On {:error, :not_a_member} or {:error, :org_not_found} from Sigra.Scope.Hydration.hydrate/3, the plug:

  1. Clears the session row's active_organization_id via SessionStore.update_active_organization/3.
  2. Calls Sigra.Organizations.select_active_organization/3 with previous_active_organization_id: nil (the stale pointer is NOT resumed — D-14).
  3. Writes the result (or leaves the session at nil) via the same store callback and assigns the final scope.
  4. Emits one audit event via Sigra.Audit.log_safe/2: "organization.active_auto_reassigned", with %{from: stale_id, to: new_id_or_nil} in metadata.

No Plug session cookie writes. No halts. Phase 14 D-03, D-04, D-14, D-17.

Options

  • :organizations — required. The host's use Sigra.Organizations module, exposing __sigra_org_config__/0 (the Phase 14 accessor added for the plug/on_mount consumers).

  • :session_store — required. The module implementing Sigra.SessionStore. Typically read from Sigra.Config at the call site but passed explicitly so the plug stays fully dependency-injected.

  • :session_store_opts — optional keyword list forwarded to the store callback (e.g. [repo: MyApp.Repo, session_schema: MyApp.Accounts.UserSession]). Defaults to [].

  • :audit_opts — optional keyword list forwarded to Sigra.Audit.log_safe/2 (e.g. [audit_schema: MyApp.AuditEvent, repo: MyApp.Repo]). Defaults to []. When empty, the plug auto-derives [repo: config.repo, audit_schema: config.audit_schema] from the host's __sigra_org_config__/0 so the documented "organization.active_auto_reassigned" audit event is written out-of-the-box whenever the host org config declares an :audit_schema. If the host org config has audit_schema: nil (the default), log_safe/2 remains a no-op (by design).