16
🏛️

Tenancy & Identity — Forms

Multi-tenant registry · branches · memberships · auth

Tenancy & Identity — Forms & Input Specification

Status: LIVE since Alembic 0005 (deployed 2026-04-28). This document describes forms already implemented. Slug: tenancy · Module #14 · 5 sub-modules

The substrate that makes Aayojana a multi-tenant SaaS. Every other module's data is scoped via these tables.


Sub-module 1: SaaS Sign-up (LIVE)

Form 1.1 — Tenant Registration (PUBLIC, no login)

Purpose: A new institution registers and the founding admin account is created atomically. Lives at: /admin/register

Field Type Required Options / Validation Default Help
Trust / Organisation Name Text Yes — — e.g. "Sri Datta Gnana Bodha Sabha"
Org Code Text Yes Lowercase alphanumeric + hyphen, 3-20 chars, unique — Short identifier like sgsdatta
Subdomain Text No URL-safe, unique (from code) Becomes <sub>.aayojana.dharmaposhanam.in
Admin Username Text Yes Unique — First admin account
Admin Email Email Yes Unique — —
Admin Password Password Yes Min 8 chars — (Email-link auth coming; password is provisional)

Submit action: Atomically creates organisations row + first users row + memberships row with role=tenant-admin, status=active. Sets JWT cookie; redirects to /admin/select-modules.


Sub-module 2: Login (LIVE)

Form 2.1 — Login

Purpose: Existing tenant admin signs in. Lives at: /admin/login

Field Type Required Options / Validation Default Help
Username or Email Text Yes — — —
Password Password Yes — — —
Next URL Hidden No — /admin/dashboard Where to redirect after login

Submit action: Validates credentials → JWT cookie → redirect.


Sub-module 3: Branch Registry (schema live; admin UI partial)

Form 3.1 — Branch Setup (planned admin UI — schema in place)

Purpose: Tenant adds a physical centre.

Field Type Required Options / Validation Default Help
Branch Name Text Yes Unique within tenant — e.g. "Mysuru Ashrama"
Description Textarea No — — —
Country Text No — India —
State Text No — — —
City Text No — — —
Address Textarea No — — —
Pincode Text No — — —
Contact Email Email No — — —
Contact Phone Phone No — — —
Active? Checkbox Yes — ☑ —

Submit action: Inserts into branches. Available immediately as scope for other modules.


Sub-module 4: Memberships (schema live; invite UI planned)

Form 4.1 — Invite User

Purpose: Tenant-admin invites a new user with a specific role.

Field Type Required Options / Validation Default Help
Email Email Yes — — If user exists, role is added; else invite is sent
Role Dropdown Yes tenant-admin · branch-admin · module-admin · member · devotee · candidate member —
Branch Dropdown Conditional If role=branch-admin — —
Module Scope Multi-select Conditional If role=module-admin — Which modules they can admin
Invitation Note Textarea No — — Personal message

Submit action: Creates memberships row in pending status; emails invite link.

Purpose: Recipient clicks the invite link and joins.

Field Type Required Options / Validation Default Help
Invitation Token URL token Yes One-time — —
Set Password (if new user) Password Conditional — — —
Display Name Text Yes — — —

Submit action: Status flips to active; JWT cookie issued; redirect to dashboard.


Form 5.1 — Google Sign-in Button (planned)

Purpose: One-click sign-in with Google. No form fields — just the OAuth button.

Purpose: For users without Google accounts (archakas, older staff).

Field Type Required Options / Validation Default Help
Email Email Yes — — A magic link is mailed; one click signs in

Submit action: Generates token, hashes for storage, emails the raw token in a one-time URL valid 15 min.


Workflow

A new tenant flow: Sign-up (Form 1.1) → Auto-login → Module Selection (separate UI) → Branch Setup (Form 3.1) → Invite Users (Form 4.1). After that, each user logs in (Form 2.1 today; Forms 5.1/5.2 once those land). Every other Aayojana module's queries are scoped by the JWT's tenant_id claim, so users see only their organisation's data.