CRUD for bookable services and their availability rules.
Every mutation logs an Activity entry (actor via opts[:actor_uuid],
passed down from the LiveView layer) and broadcasts
{:bookings_service_changed, service_uuid} on services_topic/0 so
admin lists and public pickers stay live.
Summary
Functions
Adds one availability rule. service_uuid is stamped explicitly — never
cast from attrs.
Counts services per status — powers the admin tabs.
Non-trashed services owned by a user (the self-service cap check).
Creates a service. opts[:owner_uuid] stamps the owning user (nil = a
site-wide service) — deliberately an option, never cast from attrs.
Permanent delete — Trash view only. Cascades to availability rules and
bookings (DB ON DELETE CASCADE).
Deletes a unit; its past bookings keep history via ON DELETE SET NULL.
The service's effective capacity: the active-unit count when any units
exist (unit-tracked service), else the pooled seats.
Fetches an ACTIVE service by public slug (the public booking path).
Fetches a service by UUID; nil on miss or forged id.
Active units only — the capacity-defining set.
Active services for the public listing.
Rules of a service, overrides first, then weekly rules.
Lists services. Trashed rows are excluded unless status: "trashed" or
include_trashed: true is passed. Options: :status,
:include_trashed, :owner_uuid (only services owned by that user —
Policy.visible_services/2 uses this for base-permission holders).
All units of a service, active first, then by name.
PubSub topic announcing service config changes.
Controlled status flip (active / inactive).
Soft-delete (workspace status-sentinel convention).
A unit's display name; nil for a deleted/unknown unit.
Unit names keyed by uuid — batch lookup for admin lists.
Functions
Adds one availability rule. service_uuid is stamped explicitly — never
cast from attrs.
Counts services per status — powers the admin tabs.
Non-trashed services owned by a user (the self-service cap check).
Creates a service. opts[:owner_uuid] stamps the owning user (nil = a
site-wide service) — deliberately an option, never cast from attrs.
Permanent delete — Trash view only. Cascades to availability rules and
bookings (DB ON DELETE CASCADE).
Deletes a unit; its past bookings keep history via ON DELETE SET NULL.
The service's effective capacity: the active-unit count when any units
exist (unit-tracked service), else the pooled seats.
Fetches an ACTIVE service by public slug (the public booking path).
Fetches a service by UUID; nil on miss or forged id.
Active units only — the capacity-defining set.
Active services for the public listing.
Rules of a service, overrides first, then weekly rules.
Lists services. Trashed rows are excluded unless status: "trashed" or
include_trashed: true is passed. Options: :status,
:include_trashed, :owner_uuid (only services owned by that user —
Policy.visible_services/2 uses this for base-permission holders).
All units of a service, active first, then by name.
PubSub topic announcing service config changes.
Controlled status flip (active / inactive).
Soft-delete (workspace status-sentinel convention).
A unit's display name; nil for a deleted/unknown unit.
Unit names keyed by uuid — batch lookup for admin lists.