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.)
| Concept | Lives in | Changed by | Never changed by |
|---|---|---|---|
| Ownership | device_ownership (one open row per device) | sale, gift, resale, replacement | rebinding, 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 | |
|---|---|
| Ownership | closes the open device_ownership row, opens one for to_user_id |
| Binding | force-unbinds — closes the assignment, publishes unbind_mosque, unit becomes UNBOUND |
lifecycle_status | unchanged — it's a property of the unit, not of who holds it |
| Inventory row | unchanged — same physical asset |
device_secret / broker credentials | rotated, old ones invalidated |
| Preferences | cleared |
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 replacement | Stays 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 + preferences | lifecycle_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.