Spheres
Purpose
The platform-level taxonomy root. A sphere is a coarse-grained domain like “Cinema”, “Gym”, “Restaurants”, “Education” — every Activity and Category must belong to exactly one. Spheres exist because category trees alone are not enough: the same word (“Class”) means very different things across spheres, and we need a single root for browsing and search filters that doesn’t break when a new vertical is added.
Spheres are owned by super-admin only. Companies and clients see them but cannot mutate them. Every change is audited via Sphere audit log.
Boundaries
- In: the taxonomy root + an immutable audit trail.
- Out:
- Categories under a sphere live in Catalog.
- Sphere-aware filtering on the client side is implemented per-feature (catalog, search) — not owned here.
Entities
| ID | Entity | Role in this context |
|---|---|---|
| ENT-037 | Sphere | The taxonomy root row |
| ENT-038 | Sphere audit log | Append-only record of super-admin sphere mutations |
Backend implementation
- Module:
libs/features/spheres/ - Surface routing: the only context mounted on all three surfaces —
spheres-client.module.ts,spheres-admin.module.ts,spheres-super-admin.module.ts. Client and business get read-only DTOs; super-admin owns mutations. - Drizzle schema: Tables live in
libs/shared/data-access-db/src/lib/schema/activities.schema.ts(withinpgSchema('activities')).
Cross-context relationships
- This context owns
activities.spheresandactivities.sphere_audit_log. - This context is referenced by Catalog — every
activity.sphereIdandcategory.sphereIdis NOT NULL FK toactivities.spheres.id(intra-schema FK, allowed). - This context references nothing from elsewhere. Super-admin identity lives in a separate Supabase project; the audit log stores the super-admin actor id as a bare string with no FK.
Open questions
- OPEN: what’s the deletion policy for a sphere with linked activities/categories? Schema-level FK has no
ON DELETEclause (defaults to NO ACTION) — Postgres will refuse the delete. Confirm whether super-admin UI offers a “force re-link” workflow.