# `Sigra.Organizations.Query`
[🔗](https://github.com/sztheory/sigra/blob/v1.20.0/lib/sigra/organizations/query.ex#L1)

Tenant-scoping query helpers for organization-aware schemas.

`for_org/2` is the primary enforcement layer against cross-tenant data
leaks (Pitfall O-1). `maybe_enforce_org_scope/4` provides defense-in-depth
via the generated Repo's `prepare_query/3` callback (D-14).

# `for_org`

```elixir
@spec for_org(Ecto.Queryable.t(), map() | binary()) :: Ecto.Query.t()
```

Scopes a queryable to a specific organization.

Accepts either a map with an `active_organization` key that has an `id`
field (such as a `%Scope{}`), or a raw binary organization ID. Raises
`ArgumentError` if the schema does not have an `:organization_id` field.

## Examples

    Sigra.Organizations.Query.for_org(Post, scope)
    Sigra.Organizations.Query.for_org(Post, "org-uuid-here")

# `maybe_enforce_org_scope`

```elixir
@spec maybe_enforce_org_scope(atom(), Ecto.Query.t(), keyword(), map()) ::
  {Ecto.Query.t(), keyword()}
```

Defense-in-depth tenant enforcement for `prepare_query/3` delegation.

Checks that queries on enforced schemas include an `organization_id`
WHERE clause. Called from the generated Repo's `prepare_query/3` callback.

Skips enforcement for:
- `skip_org_check: true` in opts (explicit escape hatch)
- `:ecto_query` values `:preload` or `:schema_migration`
- Non-query operations (`:insert`, `:insert_all`, `:delete`, `:delete_all`, `:update`, `:update_all`)
- Schemas not in the enforced list

Returns `{query, opts}` (the `prepare_query/3` return shape).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
