Developer Documentation

    Complete technical guide for building on Nino360

    ArchitectureAPI ReferenceDatabaseAuthentication

    Platform Overview

    Nino360 is a multi-tenant enterprise SaaS platform built on modern web technologies with AI-powered features across 18 business modules.

    Tech Stack
    • • Next.js 16 (App Router)
    • • React 19.2 (Server Components)
    • • TypeScript 5.x
    • • Tailwind CSS v4
    • • Supabase (PostgreSQL + Auth)
    • • Vercel AI SDK v5
    Key Stats
    • • 219 Pages Implemented
    • • 114 API Route Handlers
    • • 364 Database Tables
    • • 18 Business Modules
    • • 25+ AI-Powered Features
    • • 10,000+ Concurrent Users

    Architecture

    Multi-Tenant Architecture

    Complete tenant isolation at database level with URL-based resolution.

    # Subdomain Pattern
    https://acme.nino360.com/crm/dashboard
    # Tenant: acme
    # Path Pattern
    https://app.nino360.com/acme/crm/dashboard
    # Tenant: acme

    API Architecture

    RESTful API design with structured responses and tenant isolation.

    // Standard API Response Format
    interface ApiResponse<T> {
      data?: T
      error?: string
    }
    
    // Example Usage
    export async function GET() {
      const data = await fetchData()
      return Response.json({ data })
    }
    
    // Error Handling
    export async function POST() {
      try {
        const result = await createRecord()
        return Response.json({ data: result })
      } catch (error) {
        return Response.json(
          { error: error.message },
          { status: 400 }
        )
      }
    }

    Database Architecture

    PostgreSQL via Supabase with Row Level Security (RLS) policies.

    36 Schemas
    app, crm, hrms, ats, finance, proj, vms, bench, analytics, audit, etc.
    364 Tables
    All with RLS policies for tenant isolation and RBAC enforcement
    Real-time Subscriptions
    WebSocket-based updates for live data sync across clients

    API Reference

    Authentication Middleware

    import { withAuth } from "@/lib/api/handlers"
    
    export const GET = withAuth(
      async (req, { session, supabase }) => {
        // Access authenticated session
        const userId = session.user.id
        
        // Use authenticated supabase client
        const { data } = await supabase
          .from('users')
          .select('*')
          .eq('id', userId)
        
        return Response.json({ data })
      }
    )

    Tenant Context

    import { getTenantContext } from "@/lib/auth/tenant-context"
    
    export async function GET() {
      const context = await getTenantContext()
      
      if (!context) {
        return Response.json(
          { error: "Unauthorized" },
          { status: 401 }
        )
      }
      
      const { tenantId, userId, roles } = context
      
      // Query with tenant isolation
      const { data } = await supabase
        .from('crm_leads')
        .select('*')
        .eq('tenant_id', tenantId)
      
      return Response.json({ data })
    }

    Permission Checks

    import { hasPermission } from "@/lib/auth/tenant-context"
    
    export async function POST(req: Request) {
      // Check permission
      if (!await hasPermission('crm:write')) {
        return Response.json(
          { error: 'Forbidden' },
          { status: 403 }
        )
      }
      
      // Continue with protected operation
      const body = await req.json()
      // ... create lead
      
      return Response.json({ data: result })
    }

    AI Integration

    import { generateText } from 'ai'
    
    export async function POST(req: Request) {
      const { prompt } = await req.json()
      
      // Use Vercel AI SDK with AI Gateway
      const { text } = await generateText({
        model: 'openai/gpt-4.1',
        prompt: prompt,
        temperature: 0.7
      })
      
      return Response.json({ data: { text } })
    }
    
    // Supported models via AI Gateway:
    // - openai/gpt-4
    // - anthropic/claude-sonnet-4.5
    // - xai/grok-4-fast
    // - And more...

    Database Schema

    Core Tables

    app.tenants
    id: uuid (PK)
    name: text
    slug: text (unique)
    status: text
    created_at: timestamp
    app.tenant_members
    user_id: uuid (FK → auth.users)
    tenant_id: uuid (FK → app.tenants)
    role: text
    role_id: uuid (FK → app.roles)
    status: text
    joined_at: timestamp
    app.roles
    id: uuid (PK)
    tenant_id: uuid (FK → app.tenants)
    key: text
    name: text
    description: text
    app.permissions
    id: uuid (PK)
    key: text (unique)
    name: text
    description: text
    category: text

    Row Level Security (RLS)

    All tables have RLS policies enforcing tenant isolation:

    -- Example RLS Policy
    CREATE POLICY tenant_isolation_policy ON crm_leads
      USING (tenant_id = current_tenant_id());
    
    -- Policy ensures users can only access
    -- data belonging to their tenant

    Authentication & Security

    Supabase Auth Integration

    Client-Side Auth
    import { createClient } from '@/lib/supabase/client'
    
    const supabase = createClient()
    
    // Sign in
    const { data, error } = await supabase.auth.signInWithPassword({
      email,
      password
    })
    
    // Sign out
    await supabase.auth.signOut()
    Server-Side Auth
    import { createServerClient } from '@/lib/supabase/server'
    
    const supabase = await createServerClient()
    
    // Get current user
    const { data: { user } } = await supabase.auth.getUser()
    
    // Check session
    const { data: { session } } = await supabase.auth.getSession()

    RBAC Implementation

    Role-based access control with fine-grained permissions.

    Permission Keys
    • tenant:read/write
    • users:read/write
    • roles:read/write
    • crm:read/write
    • hrms:read/write
    • finance:read/write
    • projects:read/write
    • admin:all

    Environment Variables

    # Supabase Configuration
    NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
    NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
    SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
    
    # Development
    NEXT_PUBLIC_DEV_SUPABASE_REDIRECT_URL=http://localhost:3000
    
    # AI (Optional - AI Gateway handles by default)
    OPENAI_API_KEY=sk-...
    XAI_API_KEY=xai-...
    
    # Nino360 API
    NINO360_API_KEY=your_api_key

    Best Practices

    1. Always use RLS policies
    Never bypass Row Level Security - it ensures tenant isolation
    2. Check permissions in API routes
    Use withAuth or manual permission checks on all protected endpoints
    3. Use server components when possible
    Sensitive data should be fetched on the server, not the client
    4. Verify tenant membership
    Always check user belongs to tenant before allowing access to tenant data
    5. Implement proper error handling
    Use try-catch blocks and return meaningful error messages