letsbe-hub/CLAUDE.md

9.4 KiB

CLAUDE.md — LetsBe Hub

Purpose

You are the engineering assistant for the LetsBe Hub Dashboard. This is the admin dashboard and API for managing the LetsBe Cloud platform.

The Hub provides:

  • Admin Dashboard: Next.js admin UI for platform management
  • Customer Management: Create/manage customers and subscriptions
  • Order Management: Process and track provisioning orders
  • Server Monitoring: View and manage tenant servers
  • Netcup Integration: Full server management via Netcup SCP API
  • Token Usage Tracking: Monitor AI token consumption

Tech Stack

  • Next.js 15 (App Router)
  • TypeScript (strict mode)
  • Prisma (PostgreSQL ORM)
  • TanStack Query (React Query v5)
  • Tailwind CSS + shadcn/ui components
  • NextAuth.js (authentication)

Project Structure

src/
├── app/                    # Next.js App Router
│   ├── admin/             # Admin dashboard pages
│   │   ├── customers/     # Customer management
│   │   │   └── [id]/      # Customer detail with order creation
│   │   ├── orders/        # Order management
│   │   │   └── [id]/      # Order detail with DNS, provisioning
│   │   ├── servers/       # Server monitoring
│   │   │   └── netcup/    # Netcup servers management
│   │   │       └── [id]/  # Netcup server detail
│   │   ├── settings/      # Admin settings
│   │   └── layout.tsx     # Admin layout with sidebar
│   ├── api/v1/            # API routes
│   │   ├── admin/         # Admin API endpoints
│   │   │   ├── customers/ # Customer CRUD
│   │   │   ├── orders/    # Order CRUD + provisioning
│   │   │   ├── netcup/    # Netcup SCP API integration
│   │   │   └── servers/   # Server management
│   │   └── public/        # Public API endpoints
│   └── (auth)/            # Authentication pages
├── components/
│   ├── admin/             # Admin-specific components
│   │   ├── create-order-dialog.tsx    # Order creation wizard
│   │   ├── netcup-auth-setup.tsx      # Netcup OAuth setup
│   │   ├── netcup-server-link.tsx     # Link orders to Netcup servers
│   │   └── dns-verification-panel.tsx # DNS verification UI
│   └── ui/                # Reusable UI components (shadcn/ui)
├── hooks/                 # React Query hooks
│   ├── use-customers.ts   # Customer data hooks
│   ├── use-orders.ts      # Order data hooks
│   ├── use-netcup.ts      # Netcup API hooks
│   └── use-dns.ts         # DNS verification hooks
├── lib/                   # Utilities and shared code
│   ├── prisma.ts          # Prisma client singleton
│   └── services/          # Backend services
│       ├── netcup-service.ts    # Netcup SCP API client
│       ├── dns-service.ts       # DNS verification service
│       └── settings-service.ts  # System settings storage
└── types/                 # TypeScript type definitions

API Routes

Admin Endpoints (authenticated)

# Customers
GET    /api/v1/admin/customers         # List customers
GET    /api/v1/admin/customers/[id]    # Get customer detail
PATCH  /api/v1/admin/customers/[id]    # Update customer

# Orders
GET    /api/v1/admin/orders            # List orders
POST   /api/v1/admin/orders            # Create order
GET    /api/v1/admin/orders/[id]       # Get order detail
PATCH  /api/v1/admin/orders/[id]       # Update order
GET    /api/v1/admin/orders/[id]/logs  # Get provisioning logs (SSE)
POST   /api/v1/admin/orders/[id]/provision  # Start provisioning

# DNS Verification
GET    /api/v1/admin/orders/[id]/dns          # Get DNS status
POST   /api/v1/admin/orders/[id]/dns/verify   # Trigger DNS verification
POST   /api/v1/admin/orders/[id]/dns/skip     # Manual DNS override

# Servers
GET    /api/v1/admin/servers           # List servers (derived from orders)

# Netcup Integration
GET    /api/v1/admin/netcup/auth       # Get auth status / poll for token
POST   /api/v1/admin/netcup/auth       # Initiate device auth flow
DELETE /api/v1/admin/netcup/auth       # Disconnect Netcup account
GET    /api/v1/admin/netcup/servers    # List all Netcup servers
GET    /api/v1/admin/netcup/servers/[id]           # Get server detail
POST   /api/v1/admin/netcup/servers/[id]/power     # Power actions
POST   /api/v1/admin/netcup/servers/[id]/rescue    # Rescue mode
GET    /api/v1/admin/netcup/servers/[id]/metrics   # Performance metrics
GET    /api/v1/admin/netcup/servers/[id]/snapshots # List snapshots
POST   /api/v1/admin/netcup/servers/[id]/snapshots # Create snapshot

# Dashboard
GET    /api/v1/admin/dashboard/stats   # Dashboard statistics

Netcup SCP Integration

The Hub integrates with Netcup's Server Control Panel API for full server management.

Authentication

Uses OAuth2 Device Flow:

  1. Hub initiates device auth, gets user_code and verification_uri
  2. User visits Netcup and enters the code
  3. Hub polls for token exchange
  4. Tokens stored in SystemSettings table
  5. Access tokens auto-refresh (5min expiry, offline refresh token)

Capabilities

  • Server List: View all Netcup servers with live status
  • Power Control: ON/OFF/POWERCYCLE/RESET/POWEROFF
  • Rescue Mode: Activate/deactivate rescue system
  • Metrics: CPU, disk I/O, network throughput (up to 30 days)
  • Snapshots: Create, list, delete, revert snapshots
  • Server Linking: Link orders to Netcup servers by IP

Key Service: netcup-service.ts

// Core methods
netcupService.initiateDeviceAuth()      // Start OAuth flow
netcupService.pollForToken(deviceCode)  // Complete OAuth
netcupService.getServers()              // List with IPs from interfaces
netcupService.getServer(id, liveInfo)   // Detail with live status
netcupService.powerAction(id, action)   // Power control
netcupService.getServerInterfaces(id)   // Get IP addresses
netcupService.getAllMetrics(id, hours)  // CPU/disk/network metrics

Development Commands

# Start database (required first)
docker compose up -d

# Install dependencies
npm install

# Start development server
npm run dev

# Run database migrations
npx prisma migrate dev

# Generate Prisma client
npx prisma generate

# Seed database
npm run db:seed

# Type checking
npm run typecheck

# Build for production
npm run build

# App available at http://localhost:3000

Key Patterns

React Query Hooks

All data fetching uses React Query hooks in src/hooks/:

  • useCustomers(), useCustomer(id) - Customer data
  • useOrders(), useOrder(id) - Order data
  • useServers() - Server list
  • useDashboardStats() - Dashboard metrics
  • useNetcupServers(), useNetcupServer(id) - Netcup servers
  • useNetcupAuth() - Netcup authentication status
  • useServerMetrics(id, hours) - Server performance metrics
  • useServerSnapshots(id) - Server snapshots

Mutations follow the pattern:

  • useCreateOrder(), useUpdateOrder()
  • useNetcupPowerAction(), useNetcupRescue()
  • useCreateSnapshot(), useDeleteSnapshot(), useRevertSnapshot()
  • Automatic cache invalidation via queryClient.invalidateQueries()

API Route Pattern

export async function GET(request: NextRequest) {
  // Auth check
  const session = await auth()
  if (!session || session.user.userType !== 'staff') {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }

  // Parse query params
  const searchParams = request.nextUrl.searchParams

  // Database query with Prisma
  const data = await prisma.model.findMany({...})

  // Return JSON response
  return NextResponse.json(data)
}

Component Pattern

'use client'

export function MyComponent() {
  const { data, isLoading, error } = useMyData()

  if (isLoading) return <Skeleton />
  if (error) return <ErrorMessage error={error} />

  return <div>...</div>
}

Service Pattern

Backend services in src/lib/services/:

class MyService {
  private static instance: MyService

  static getInstance(): MyService {
    if (!MyService.instance) {
      MyService.instance = new MyService()
    }
    return MyService.instance
  }

  async doSomething(): Promise<Result> {
    // Implementation
  }
}

export const myService = MyService.getInstance()

Database Schema (Key Models)

model Customer {
  id        String   @id @default(cuid())
  name      String
  email     String   @unique
  company   String?
  orders    Order[]
}

model Order {
  id              String      @id @default(cuid())
  status          OrderStatus
  domain          String
  customerId      String
  serverIp        String?
  serverPassword  String?
  netcupServerId  String?     # Linked Netcup server
  automationMode  AutomationMode @default(MANUAL)
  customer        Customer    @relation(...)
  dnsVerification DnsVerification?
}

model SystemSettings {
  id    String @id @default(cuid())
  key   String @unique
  value String @db.Text
}

Coding Conventions

  • Use 'use client' directive for client components
  • All API routes return NextResponse.json()
  • Use Prisma for all database operations
  • Follow existing shadcn/ui component patterns
  • Use React Query for server state management
  • TypeScript strict mode - no any types
  • Services are singletons exported from lib/services/
  • Environment variables in .env.local (never commit)