Tenants & Subdomain Routing

AutoCom is multi-tenant: every customer ("tenant") gets their own subdomain, their own database (via Stancl Tenancy multi-database mode), and their own isolated world. This section covers how tenants come into existence, how their subdomains are chosen, and how an incoming HTTP request ends up connected to the right tenant's data.

What's in this section

  • Onboarding flows — the three paths into the system (public signup, reseller referral, install wizard), what subdomain each produces, and where the applicant has control.
  • Subdomain routing — how acme.autocom.app becomes tenant = "acme" inside Laravel, end-to-end. Covers browser → ingress → nginx → Stancl middleware → DB.
  • Local dev setup — how *.localhost works without any DNS configuration, why Chrome/Firefox/Safari all "just resolve" it, and how to test subdomain flows on your Mac.
  • Production k8s wildcard setup — step-by-step guide to wildcard DNS + wildcard TLS + a single wildcard-host ingress. One-time setup that makes every new tenant zero-infra.
  • Preferred subdomain feature — how applicants can propose their own subdomain during the reseller onboarding flow, and the fallback rules when the name is taken.

Quick reference

Path Subdomain source
Public signup (currently disabled) POST /api/v1/auth/tenants User picks, validated alpha_dash|max:63|unique
Reseller onboarding (active) POST /api/v1/reseller-register/apply Auto-generated 8-char random ID + optional applicant-chosen alias (preferred_domain)
Install wizard (first tenant) POST /api/v1/install/owner User picks organization_slug

Key invariants

  1. Every tenant has at least two domain rows: the random 8-char ID (never changes) and at least one human-readable alias.
  2. Subdomains are case-insensitive and stored lowercase. All normalization happens at the application boundary.
  3. Stancl Tenancy is in multi-database mode: each tenant gets a separate Postgres database named tenant<id>. The central DB holds tenants, users, domains, module_installations.
  4. The central DB is the authority for domain ↔ tenant mapping. Any cache in nginx, cert-manager, or Next.js is best-effort and falls back to the central DB.