Backend requirements
Backend requirements
What the backend must provide for nuxt-x-tenancy to work. The layer ships no server code; it composes nuxt-x-auth-better on the identity side and expects a tenant-aware API on the data side. This page summarizes the package's BACKEND-REQUIREMENTS.md — read that file in the repo for the authoritative contract.
1. Identity: better-auth with the organization plugin
The consumer runs a better-auth server with the organization plugin enabled (see nuxt-x-auth-better's integration guide). The layer uses exactly these client endpoints:
| Endpoint | Used for |
|---|---|
GET {baseUrl}{authPath}/get-session | Session + session.activeOrganizationId |
GET {baseUrl}{authPath}/organization/list | tenants + slug → org resolution (resolveBySlug) |
GET {baseUrl}{authPath}/organization/get-full-organization | Active tenant (no params — returns the session's active org) |
POST {baseUrl}{authPath}/organization/set-active | switchTenant(id) |
GET {baseUrl}{authPath}/organization/get-active-member | (via auth-better) member role |
organization/list response, notget-full-organization?organizationSlug= — better-auth's client (≤1.6.5) drops that method's GET query params, so server-side slug lookup is unreliable. See Resolution chain.2. ID contract
tenant id === better-auth organization id. The layer never mints its own ids. Per-tenant rows in any backend should key on the organization id, so nuxt-x-app-admin's per-tenant views and this layer's X-Tenant-ID header refer to the same identifier without translation.
3. Data API: the X-Tenant-ID header
Tenant-scoped API endpoints must:
- Read the tenant id from the
X-Tenant-IDrequest header (name configurable viaxTenancy.headerName). - Authorize: the session user must be a member of that organization — the header is a selector, never a proof of membership.
- Filter all rows by that tenant id.
The layer injects the header client-side into every $fetch request that doesn't already set it (opt out: xTenancy.injectHeader: false), and exposes $tenantHeaders() for SSR/custom clients. Requests without the header should be treated as unscoped — reject or return nothing for tenant-scoped resources; never fall back to "all tenants".
4. Subdomain strategy (optional)
When xTenancy.strategy: 'subdomain': wildcard DNS / vhost for *.{rootDomain} routes to the Nuxt app; the left-most host label is the organization slug, activated via the standard set-active endpoint. No extra backend work beyond §1.
AI Context
guide: backend-requirements
package: "@xenterprises/nuxt-x-tenancy"
use-when: >
Implementing the backend for a tenancy consumer. better-auth with the
organization plugin for identity; tenant id === organization id; data
APIs read X-Tenant-ID (selector, not proof of membership) and filter
rows by it. Subdomain strategy needs only wildcard DNS.
Components
XTTenantSwitcher and XTTenantResolver — the XT* tenant UI components of nuxt-x-tenancy.
nuxt-x-billing
Stripe billing layer for Nuxt 4 — useBilling() composable, plan/feature gating (XBBillingGate), and billing container components wired against a consumer-owned backend contract. The layer never talks to Stripe directly.
