Skip to content

nucamp/soloai

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Multi-Tenant SvelteKit Application

A dynamic multi-tenant SvelteKit application that supports unlimited brands/tenants through configuration. This codebase demonstrates a scalable architecture for building SaaS applications with tenant-specific branding, features, and configurations.

Featured Tenants

  • LupinLearn: An AI-powered educational platform for creating lessons, quizzes, and personalized learning experiences
  • BSOS (Be Smart On Social): An AI browser extension for social media content generation

The architecture is extensible - you can add new tenants without modifying the core codebase.

Tech Stack

  • Framework: SvelteKit with Svelte 5
  • Styling: Tailwind CSS 4 + DaisyUI 5
  • Database: MySQL with Prisma ORM
  • Authentication: Better Auth
  • AI Services: OpenAI and Anthropic APIs
  • Payment: Stripe integration + Lemon Squeezy support
  • i18n: Paraglide for internationalization
  • Testing: Vitest (unit) + Playwright (integration)
  • Build Tools: Vite

Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js (v18 or higher)
  • npm (v9 or higher)
  • MySQL (v8.0 or higher)
  • Git

Getting Started

1. Clone the Repository

git clone <Insert your repository URL here>
cd soloaiversion

2. Install Dependencies

npm install

3. Set Up Your Database

Create a MySQL database for your application:

CREATE DATABASE your_app_name;

4. Configure Environment Variables

Copy the example environment file and configure it for your tenant:

# For LupinLearn development
cp .env.example .env.lupinlearn.development

# For BSOS development
cp .env.example .env.bsos.development

# Or create your own tenant
cp .env.example .env.yourtenant.development

Edit your .env.[tenant].development file and fill in all required values:

  • Database credentials (MySQL host, user, password, database name)
  • API keys (OpenAI, Anthropic, Stripe, etc.)
  • OAuth credentials (Google, Microsoft, Apple)
  • Better Auth secrets (generate with: openssl rand -base64 32)

See .env.example for a complete list of required environment variables.

5. Generate Prisma Client

npx prisma generate

6. Create Initial Database Migration

Since this is a fresh setup, create your first migration:

npx prisma migrate dev --name init

This will create the database schema from prisma/schema.prisma.

7. Start Development Server

Choose the tenant you want to develop:

# LupinLearn development
npm run dev:lupin

# BSOS development
npm run dev:bsos

The application will be available at http://localhost:5173

Project Structure

├── src/
│   ├── routes/              # SvelteKit routes
│   │   ├── (marketing)/    # Public marketing pages
│   │   ├── app/           # Authenticated app pages
│   │   ├── auth/          # Authentication flows
│   │   └── api/           # API endpoints
│   ├── lib/
│   │   ├── components/    # Shared components
│   │   ├── services/      # Business logic and external integrations
│   │   ├── tenant/        # Multi-tenant configuration
│   │   │   ├── configs/   # Tenant-specific configs
│   │   │   └── registry.ts # Tenant registry
│   │   ├── tenants/       # Tenant-specific components
│   │   └── paraglide/     # Generated i18n files (auto-generated)
│   ├── extension/         # Browser extension code
│   └── chatbot/          # Embeddable chatbot widget
├── prisma/
│   └── schema.prisma      # Database schema
├── .env.example           # Environment variables template
└── package.json           # Dependencies and scripts

Multi-Tenant Architecture

How It Works

The application uses a tenant registry system that automatically discovers and loads tenant configurations:

  1. Tenant Configs: Each tenant has a configuration file in src/lib/tenant/configs/
  2. Environment Files: Each tenant has dedicated environment files (.env.[tenant-id].development, .env.[tenant-id].production)
  3. Dynamic Loading: The tenant is determined at build time via the APP environment variable
  4. Component Overrides: Tenants can provide custom components in src/lib/tenants/[tenant-id]/

Adding a New Tenant

  1. Create a tenant config file: src/lib/tenant/configs/yourtenant.ts
import type { TenantConfig } from '../types';

export const config: TenantConfig = {
  id: 'yourtenant',
  name: 'yourtenant',
  displayName: 'Your Tenant Name',
  domain: '<Insert your production domain here>',
  contactEmail: '<Insert your contact email here>',
  // ... more configuration
};
  1. Create environment files:

    • .env.yourtenant.development
    • .env.yourtenant.production
  2. Add npm scripts to package.json:

{
  "scripts": {
    "dev:yourtenant": "APP=yourtenant npm run dev",
    "build:yourtenant": "APP=yourtenant npm run build"
  }
}
  1. (Optional) Add custom components: src/lib/tenants/yourtenant/

Tenant-Specific Features

Use the tenant store to conditionally render features:

<script>
  import { tenant } from '$lib/tenant/store';
</script>

{#if tenant.isTenant('lupinlearn')}
  <LupinLearnFeature />
{/if}

{#if tenant.hasFeature('chatbot')}
  <ChatbotWidget />
{/if}

Development Commands

Testing

# Run all tests
npm test

# Unit tests only
npm run test:unit

# Integration tests only
npm run test:integration

Code Quality

# Type checking
npm run check

# Linting
npm run lint

# Formatting
npm run format

Building

# Build LupinLearn
npm run build:lupin

# Build BSOS
npm run build:bsos

# Build browser extension
npm run build:extension:dev   # Development
npm run build:extension:prod  # Production

# Build chatbot widget
npm run build:chatbot

Database Management

# Open Prisma Studio (database GUI)
npx prisma studio

# Create a new migration
npx prisma migrate dev --name your_migration_name

# Reset database (WARNING: deletes all data)
npx prisma migrate reset

Translations

# Generate Paraglide translations
npm run translate-paraglide

# Generate Handsontable translations
npm run translate-handsontable

Svelte 5 Usage

This project uses Svelte 5 with the new Runes API. Key patterns:

<script>
  // Props
  let { propName } = $props();

  // State
  let count = $state(0);

  // Derived values
  let doubled = $derived(count * 2);

  // Effects
  $effect(() => {
    console.log('Count changed:', count);
  });
</script>

Avoid legacy Svelte 4 syntax ($:, export let, etc.)

Deployment

Environment Variables

Before deploying, ensure all environment variables are properly configured in your production environment files (.env.[tenant].production).

GitHub Actions

The repository includes GitHub Actions workflows for automated deployment:

  • .github/workflows/deploy-lupinlearn.yml
  • .github/workflows/deploy-bsos.yml

Important: Customize the deployment steps in these workflows for your specific server environment.

Manual Deployment

  1. Build the project:
npm run build:[tenant-name]
  1. The built files will be in the build/ directory

  2. Deploy to your hosting provider (Vercel, Netlify, self-hosted Node.js server, etc.)

Security Considerations

  • Never commit .env files - they contain sensitive credentials
  • Use environment variables for all API keys and secrets
  • Rotate secrets regularly for production environments
  • Enable CORS protection in production
  • Keep dependencies updated to patch security vulnerabilities

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

Support

For questions or issues:

  • Open an issue on GitHub
  • Check the documentation in CLAUDE.md
  • Review the .github/design-guidelines.md for design standards

Acknowledgments

Built with:


Note: This is a template project. Replace all placeholder values (marked with <Insert your ...>) with your actual configuration before deploying to production.