Skip to main content

Ownership

:::info Status Implemented. Source: docs/device-management-module-architecture.md §1, §3, §4, §5a-iii. :::

Ownership answers: which user owns this unit right now, and who owned it before? It applies only to stream players — a transmitter is an Azan360-owned, mosque-installed asset with no owning member, and therefore never gets a device_ownership row at all. ("Not applicable" is the correct answer for a transmitter here, not an empty join to be misread as a data gap.)

ConceptLives inChanged byNever changed by
Ownershipdevice_ownership (one open row per device)sale, gift, resale, replacementrebinding, membership changes, approval

Why ownership and binding are separate tables

Ownership (who owns it) and mosque binding (which mosque it currently follows) change at very different rates — a gift changes ownership without touching binding; moving between mosques changes binding without touching ownership; a warranty replacement changes the underlying inventory row under a stable owner and binding. Each is one open row, enforced by a unique partial index (ended_at IS NULL / unassigned_at IS NULL) — never more than one active owner or one active mosque binding at a time.

Ownership transfer — Super Admin only in V1

POST /devices/{id}/transfer-ownership { to_user_id, reason, note }

One transaction:

Effect
Ownershipcloses the open device_ownership row, opens one for to_user_id
Bindingforce-unbinds — closes the assignment, publishes unbind_mosque, unit becomes UNBOUND
lifecycle_statusunchanged — it's a property of the unit, not of who holds it
Inventory rowunchanged — same physical asset
device_secret / broker credentialsrotated, old ones invalidated
Preferencescleared

Binding deliberately does not follow ownership — carrying the previous owner's mosque across would fail the new owner's membership check on the next request and produce a confusing MEMBERSHIP_LAPSED instead of an honest UNBOUND. Credentials rotate because the previous owner had physical access to the unit.

Self-service transfer is explicitly out of scope for V1: it's a fraud surface ("I sold it" as a way to launder a stolen unit) that would need a two-sided consent handshake the data model already supports for later, per docs/device-management-architecture-summary.md's frozen-decisions table — see Design Decisions for the recorded rationale.

Replacement — a special case

A warranty replacement is a different physical asset (own serial, MAC, inventory row) — not the old inventory_id reused. What travels to the replacement vs. what stays with the retired unit:

Travels to the replacementStays with the old unit
Ownership (device_ownership)Its own device_inventory row (the failed asset)
Mosque binding (device_assignments)Its serial, MAC, device_uid, audit history
Config + preferenceslifecycle_status, which becomes RETIRED

Full endpoint and transaction-ordering detail: Device Management module.

Where ownership feeds authorization

A stream player's device authorization chain checks for an open ownership row as a precondition for becoming ACTIVE, and a stream player's playback entitlement depends on the owner's membership status at the bound mosque — ownership itself grants nothing on its own.