
Ragboost
Multi-Tenant SaaS AI Chatbots Platform
Overview
Context
The AI chatbot market is growing, but enterprise solutions are expensive for SMBs. Companies face high costs per message and storage, technical complexity to integrate RAG, generic widgets that don't represent the brand, lack of team collaboration, and isolated data that isn't leveraged. The opportunity: create an affordable alternative with advanced features for companies of all sizes.
Solution
Development of a complete SaaS platform that democratizes access to AI chatbots with affordable pricing, simplifies assistant creation without coding, scales with robust multi-tenant architecture, and monetizes with flexible plans via Stripe. The platform allows companies to create virtual assistants contextualized with their own documents using RAG (Retrieval-Augmented Generation) technology, with team collaboration system featuring complete RBAC and support for 4 languages.
My Role
As founder and full stack developer, I designed and implemented the entire system architecture. On the backend, I developed Clean Architecture with Either Monad, Use Case Pattern, and Domain Events. On the frontend, I implemented TanStack Query with Optimistic Updates, cross-subdomain authentication system, and file-based routing with TanStack Router. I also did all UI/UX design and integrations with Stripe, open source RAG service, and email system.
Tech Stack
Frontend
Backend
Projects
Backend API
Multi-Tenant REST API with Clean Architecture
Robust REST API with clean architecture, 10 domain modules, granular permissions system (RBAC) with 50+ permissions, Stripe integration for billing, and Domain Events for cross-module communication.
Features
Clean Architecture
Layer separation: routes → controllers → use-cases → repositories → entities
Either Monad
Functional error handling with Either<Error, Success> in all use cases
Multi-Tenancy
Complete data isolation per tenant via subdomain with context middleware
Granular RBAC
50+ permissions across 4 role levels (owner, admin, curator, user)
Domain Events
Asynchronous communication between modules for decoupling
Webhook Service
Handlers for Stripe events (checkout, subscription, invoice) with signature verification
Factory Pattern
Manual dependency injection without container, easy to test and debug
Zod + OpenAPI
Schema validation with automatic Swagger documentation generation
Dual JWT
Access token (15min) + refresh token (7d) in httpOnly cookie
Rate Limiting
Endpoint protection with limits per IP and user
RAG Integration
Connection with open source service for document processing and semantic search
Invitation System
Email invitations with tracking, expiration and assignable roles
Subscription with Addons
Flexible Stripe plans system with modular addons (extra seats, storage, API calls)
Complete Billing
Checkout sessions, customer portal, invoices, proration, trial periods, cancellation
Design Patterns
Testing Strategy
Unit Tests
Complete use cases60+ files testing use cases and domain logic with 18+ In-Memory Repositories and 7 In-Memory Providers (hash, token, email, ragflow, stripe, etc.)
Tools: Node.js Test Runner, In-Memory Repositories/Providers
E2E Tests
All routes40+ files testing controllers with Prisma Test Environment (isolated database), automatic plan seeding, unique data helpers (generateUniqueEmail, generateUniqueSlug)
Tools: Node.js Test Runner, Prisma Test Environment, Supertest
Technical Decisions
Fastify vs Express vs NestJS
2x faster than Express, native schema validation, modular plugin system
Either Monad vs throw/catch
Type-safe errors, explicit flow, controller knows exactly what errors to expect
Factory Pattern vs DI Container
Zero magic, tree-shakeable, pure TypeScript without decorators, easy to test
PostgreSQL + Prisma vs MongoDB
ACID compliance, complex relations, type-safety, migrations, native RLS
Challenges & Solutions
Multi-Tenant Isolation
Middleware injects tenant context in all queries via X-Tenant-Subdomain header
50+ Granular Permissions
Roles → permissions matrix, CheckPermissionUseCase reused in all use cases
Stripe Webhook with Raw Body
Custom middleware to preserve raw body before Fastify bodyParser
Isolated E2E Tests
Prisma test environment with isolated database, helpers to generate unique data
Frontend Dashboard
React 19 SPA with Multi-Tenant via Subdomain
Administrative dashboard SPA with React 19 and TanStack Router. Cross-subdomain authentication system via cookies, sophisticated cache with TanStack Query, internationalization in 4 languages, and 31 shadcn/ui components.
Features
Multi-Tenant via Subdomain
Automatic tenant detection via hostname (tenant1.ragboost.app)
Cross-Subdomain Auth
Cookies shared between subdomains via Domain=.ragboost.app
TanStack Query Cache
staleTime, gcTime, refetchOnMount/WindowFocus configured per query
Optimistic Updates
onMutate → snapshot → rollback with instant feedback
File-Based Routing
TanStack Router with complete type-safety and beforeLoad for guards
Axios Interceptors
Automatic token refresh, retry with exponential backoff, i18n error handling
Frontend RBAC
useCurrentUserRole() with canManageTeam, canEditChatbots, etc.
Validated Forms
React Hook Form + Zod with shared schemas frontend/backend
Design System
31 shadcn/ui + Radix UI components with Tailwind CSS 4
Complete i18n
4 languages (PT, EN, FR, ES) with lazy-loaded namespaces
Dashboard Analytics
Charts with Recharts for usage metrics
Team Management
Invitations, roles, member removal with optimistic updates
Subscription Management
Current plan view, addons, usage, upgrade/downgrade with Stripe Customer Portal
Addon Selector
Interface to add/remove addons (seats, storage, API calls) with price preview
Design Patterns
Technical Decisions
React 19 SPA vs Next.js
Dashboard doesn't need SSR, Vite instant HMR, 10x faster builds
TanStack Query vs Redux
Automatic cache, mutations with optimistic updates, less boilerplate
TanStack Router vs React Router
Complete type-safety, file-based routing, beforeLoad for guards
Cookie Auth vs localStorage
Cross-subdomain sharing impossible with localStorage
Challenges & Solutions
Cross-Subdomain Auth
Cookie with Domain=.localhost (dev) / .ragboost.app (prod) shared between tenants
Transparent Token Refresh
Interceptor detects 401, calls /refresh-token, retries original request
Complex State Management
TanStack Query for server state, useCurrentTenant() for context, zero Redux
Multi-Environment Subdomain Detection
Support for lvh.me (dev), localhost, and multisaas.app (prod) with same logic