Skip to content

Krosebrook/thundercloud

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

7 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Thundercloud - AI Website Builder

Generate production-quality websites in minutes using Claude Sonnet 4.5.

🎯 What is Thundercloud?

Thundercloud is an AI-powered website builder that creates professional, SEO-optimized, accessible websites using advanced AI. Unlike template-based builders, Thundercloud generates custom code tailored to your specific needs.

Key Features (MVP)

  • βœ… AI Website Generation - Claude Sonnet 4.5 creates custom HTML/CSS
  • βœ… Quality Validation - 50+ automated quality checks (SEO, accessibility, performance)
  • βœ… Real-time Preview - See your site on mobile, tablet, desktop
  • βœ… One-Click Deployment - Publish instantly with preview URL
  • βœ… Type-Safe API - End-to-end TypeScript with tRPC
  • βœ… Secure by Default - Row-level security (RLS) on all data

πŸš€ Quick Start

Prerequisites

  • Node.js 20+ and npm
  • Supabase account (free tier works)
  • Anthropic API key (Claude)

1. Clone & Install

git clone <your-repo-url> thundercloud-app
cd thundercloud-app
npm install

2. Environment Setup

Create .env.local:

# Supabase (get from https://supabase.com/dashboard)
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key

# Anthropic (get from https://console.anthropic.com/)
ANTHROPIC_API_KEY=sk-ant-...

3. Database Setup

  1. Go to Supabase Dashboard β†’ SQL Editor
  2. Copy contents of supabase/schema.sql
  3. Run the SQL script
  4. Verify tables created (21 tables total)

4. Run Development Server

npm run dev

Open http://localhost:3000

5. Create Your First Website

  1. Sign up at /signup
  2. Go to Dashboard
  3. Click "Create Website"
  4. Fill in details, click "Generate"
  5. Wait 30-60 seconds
  6. Preview and save!

πŸ“ Project Structure

thundercloud-app/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/                    # Next.js 15 App Router
β”‚   β”‚   β”œβ”€β”€ (auth)/            # Auth pages (login, signup)
β”‚   β”‚   β”œβ”€β”€ (dashboard)/       # Dashboard pages
β”‚   β”‚   β”œβ”€β”€ api/trpc/          # tRPC API routes
β”‚   β”‚   β”œβ”€β”€ layout.tsx         # Root layout
β”‚   β”‚   └── page.tsx           # Landing page
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ ui/                # shadcn/ui components
β”‚   β”‚   β”œβ”€β”€ auth/              # Auth components
β”‚   β”‚   └── websites/          # Website components
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ supabase/          # Supabase clients
β”‚   β”‚   β”œβ”€β”€ ai/                # AI generation & validation
β”‚   β”‚   β”œβ”€β”€ trpc/              # tRPC client setup
β”‚   β”‚   └── utils.ts           # Utilities
β”‚   └── server/
β”‚       β”œβ”€β”€ trpc.ts            # tRPC setup
β”‚       └── routers/           # API routers
β”œβ”€β”€ public/                     # Static files
β”œβ”€β”€ supabase/
β”‚   └── schema.sql             # Database schema
└── package.json

πŸ”‘ Environment Variables

Variable Required Description
NEXT_PUBLIC_SUPABASE_URL βœ… Your Supabase project URL
NEXT_PUBLIC_SUPABASE_ANON_KEY βœ… Supabase anonymous key (public)
ANTHROPIC_API_KEY βœ… Claude API key (secret)

Security Notes:

  • βœ… NEXT_PUBLIC_* vars are safe in browser (public)
  • ⚠️ ANTHROPIC_API_KEY is server-only (never exposed)
  • βœ… All database access protected by RLS

πŸ—οΈ Tech Stack

Layer Technology Why?
Frontend Next.js 15 + React 19 Server Components, App Router
Backend tRPC + Next.js API Type-safe APIs, no codegen
Database Supabase (PostgreSQL) Managed DB + Auth + RLS
AI Anthropic Claude Sonnet 4.5 Best-in-class code generation
Auth Supabase Auth JWT + RLS
Styling Tailwind CSS Utility-first CSS
UI shadcn/ui Accessible components
Deployment Vercel Zero-config, edge functions

πŸ“Š Database Schema

Core Tables

user_profiles - User accounts

- id (uuid, PK)
- email (text)
- full_name (text)
- role (text) - 'user' | 'admin'
- subscription_tier (text) - 'free' | 'pro' | 'agency'
- created_date (timestamp)

websites - Generated websites

- id (uuid, PK)
- user_id (uuid, FK β†’ user_profiles)
- title (text)
- description (text)
- slug (text, unique)
- html_content (text) - Full HTML output
- quality_score (integer) - 0-100
- seo_score (integer) - 0-100
- is_published (boolean)
- created_date (timestamp)

See supabase/schema.sql for complete schema (21 tables).

πŸ” Security

Authentication

  • JWT tokens via Supabase Auth
  • 30-day session expiry
  • PKCE flow for OAuth (future)

Authorization

  • Row Level Security (RLS) on all tables
  • Users can only access their own data
  • Policy: auth.uid() = user_id

Input Validation

  • Zod schemas on all API inputs
  • SQL injection prevention (parameterized queries)
  • XSS prevention (DOMPurify on HTML output)

Rate Limiting

  • 100 API requests/hour per user
  • 10 website generations/hour per user
  • Enforced at API gateway

πŸ§ͺ Testing

Run Type Checking

npm run type-check

Run Linter

npm run lint

Test API Endpoints (Manual)

  1. Start dev server: npm run dev
  2. Test generation:
    • Go to /dashboard/websites/new
    • Fill form, click "Generate"
    • Check console for errors
    • Verify website saved to dashboard

πŸš€ Deployment

Deploy to Vercel

  1. Push code to GitHub:
git add .
git commit -m "Initial commit"
git push origin main
  1. Import to Vercel:

    • Go to vercel.com
    • Click "Import Project"
    • Select your repo
    • Add environment variables
    • Deploy!
  2. Configure environment variables in Vercel:

    • Go to Project Settings β†’ Environment Variables
    • Add all 3 env vars from .env.local
    • Redeploy

Deploy Database (Supabase)

Database is already deployed when you create Supabase project:

  • βœ… Production PostgreSQL
  • βœ… Automatic backups
  • βœ… SSL encryption
  • βœ… Global CDN

πŸ“ˆ Performance

Targets (MVP)

  • Dashboard load: < 2 seconds
  • Website generation: < 60 seconds
  • Preview load: < 3 seconds
  • API response: < 500ms (p95)

Optimization Tips

  • Use React Query caching (already configured)
  • Enable Next.js Image optimization for user uploads
  • Add CDN caching for static assets
  • Database indexes on user_id, website_id (already added)

πŸ› Troubleshooting

"Cannot find module" errors

rm -rf node_modules package-lock.json
npm install

Database connection fails

  • Check NEXT_PUBLIC_SUPABASE_URL is correct
  • Verify anon key in .env.local
  • Ensure RLS policies are created (run schema.sql)

AI generation fails

Auth redirect loop

  • Clear browser cookies
  • Check Supabase Auth settings
  • Verify RLS policies allow user access

πŸ“š API Documentation

tRPC Routers

websites Router

// List websites (paginated)
trpc.websites.list.useQuery({
  page: 1,
  pageSize: 10,
  sortBy: 'created_date',
  sortOrder: 'desc'
})

// Get single website
trpc.websites.getById.useQuery({ id: 'uuid' })

// Create website
trpc.websites.create.useMutation({
  title: 'My Site',
  slug: 'my-site',
  html_content: '<html>...',
  // ... other fields
})

// Update website
trpc.websites.update.useMutation({
  id: 'uuid',
  data: { title: 'New Title' }
})

// Delete website
trpc.websites.delete.useMutation({ id: 'uuid' })

// Toggle publish status
trpc.websites.togglePublish.useMutation({ id: 'uuid' })

generation Router

// Generate new website
trpc.generation.generate.useMutation({
  title: 'My Business',
  description: 'Professional consulting...',
  category: 'business',
  theme: 'modern',
  colorScheme: 'Professional Blue',
  language: 'English'
})

// Regenerate existing
trpc.generation.regenerate.useMutation({
  id: 'uuid',
  prompt: { title: 'Updated Title' }
})

// Validate HTML
trpc.generation.validate.useMutation({
  html: '<html>...'
})

🎨 Customization

Add New Website Category

  1. Update prompt templates in src/lib/ai/prompts.ts:
export const PRODUCTION_PROMPTS = {
  templates: {
    // Add new category
    nonprofit: {
      sections: [
        'Mission statement',
        'Impact metrics',
        // ...
      ]
    }
  }
}
  1. Update form in src/app/(dashboard)/websites/new/page.tsx:
const categories = [
  // Add to dropdown
  { value: 'nonprofit', label: 'Non-Profit' },
]

Customize Quality Validation

Edit src/lib/ai/quality-validator.ts:

private validateSEO(doc: Document, html: string): ValidationCheck {
  // Add custom checks
  if (!html.includes('custom-tag')) {
    issues.push('Missing custom tag');
    score -= 5;
  }
}

πŸ“– Learn More

🀝 Contributing

This is an MVP. Contributions welcome after initial launch.

πŸ“„ License

[Your License Here]

πŸ†˜ Support

  • πŸ“§ Email: support@thundercloud.com
  • πŸ’¬ Discord: discord.gg/thundercloud
  • πŸ“š Docs: docs.thundercloud.com

Built with ❀️ using Claude Sonnet 4.5

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors