Development Workflow

Development Workflow

A structured approach to developing features in the SaaS boilerplate, covering development lifecycle, testing strategies, and optimization practices.

Table of Contents

Feature Development Process

Development Environment Setup

# Clone and install dependencies
pnpm install

# Start development server
pnpm dev

# Build packages first for dependencies
pnpm build:packages

Feature Development Lifecycle

  1. Planning Phase
    • Define feature requirements and acceptance criteria
    • Design database schema changes if needed
    • Plan service layer integration points
  2. Implementation Phase
    • Create/modify database models in src/db/schema
    • Implement repository layer in src/db/repositories
    • Add business logic in src/services
    • Create UI components and pages
    • Add Server Actions for data mutations
  3. Integration Phase
    • Connect frontend to backend services
    • Implement proper error handling
    • Add loading states and optimistic updates
    • Test authentication and authorization

Testing Strategy

Testing Layers

Test individual functions and components:
# Run unit tests
pnpm test

# Run tests in watch mode
pnpm test:watch

# Run tests with coverage
pnpm test:coverage
Testing Patterns:
  • Mock authentication context for protected components
  • Test service layer logic independently
  • Use React Testing Library for component tests

Test Data Management

// Example test utilities
import { createTestUser, createTestOrganization } from '@/lib/test-utils'

describe('User Management', () => {
  beforeEach(async () => {
    // Clean test database
    await cleanTestDatabase()
  })

  it('should create user with organization', async () => {
    const user = await createTestUser({
      email: 'test@example.com',
      role: 'admin'
    })

    const org = await createTestOrganization({
      ownerId: user.id,
      name: 'Test Organization'
    })

    expect(org.members).toContain(user.id)
  })
})

Code Quality Standards

Linting and Formatting

# Run linting
pnpm lint

# Fix linting issues automatically
pnpm lint:fix

# Lint specific directories
pnpm lint src/components
Key Rules:
  • Use React Server Components by default
  • Minimize 'use client' directive usage
  • Follow consistent import ordering
  • Use TypeScript interfaces over types

Git Workflow

Branch Strategy: Use feature branches with descriptive names like feature/user-authentication or fix/payment-webhook-handling.
# Create feature branch
git checkout -b feature/new-feature-name

# Regular commits with descriptive messages
git add .
git commit -m "feat: add user role management system"

# Push and create pull request
git push origin feature/new-feature-name

Performance Optimization

React Server Components

// Prefer Server Components for data fetching
export default async function UserDashboard() {
  const user = await getCurrentUser()
  const subscription = await getUserSubscription(user.id)

  return (
    <div>
      <UserProfile user={user} />
      <SubscriptionStatus subscription={subscription} />
    </div>
  )
}

// Use Client Components only when needed
'use client'
export function InteractiveChart({ data }: { data: ChartData }) {
  const [selectedPeriod, setSelectedPeriod] = useState('month')

  return (
    <Chart
      data={data}
      period={selectedPeriod}
      onPeriodChange={setSelectedPeriod}
    />
  )
}

Database Optimization

// Use select for specific fields
const users = await db
  .select({
    id: usersTable.id,
    email: usersTable.email,
    name: usersTable.name,
  })
  .from(usersTable)
  .where(eq(usersTable.organizationId, orgId))

// Use joins instead of multiple queries
const usersWithSubscriptions = await db
  .select()
  .from(usersTable)
  .leftJoin(subscriptionsTable, eq(usersTable.id, subscriptionsTable.userId))
  .where(eq(usersTable.organizationId, orgId))

Deployment Workflow

Pre-deployment Checklist

Always verify these items before deploying:
  • All tests passing (pnpm test)
  • No linting errors (pnpm lint)
  • Type checking passes (pnpm type-check)
  • Database migrations ready (pnpm db:generate)
  • Environment variables configured
  • Stripe webhooks endpoints updated

Build and Deploy

# Production build
pnpm build

# Verify build output
ls -la .next/

# Run database migrations (production)
pnpm db:migrate

# Deploy to hosting platform
pnpm deploy

Environment-specific Configurations

NODE_ENV=development
BETTER_AUTH_URL=http://localhost:3000
DATABASE_URL=postgresql://localhost:5432/saas_dev
STRIPE_SECRET_KEY=sk_test_...

Monitoring & Debugging

Error Tracking

// Error boundary for React components
import { ErrorBoundary } from 'next/dist/client/components/error-boundary'

export function FeatureErrorBoundary({ children }: { children: React.ReactNode }) {
  return (
    <ErrorBoundary
      errorComponent={({ error, reset }) => (
        <div className="p-4 border border-red-200 rounded">
          <h3>Something went wrong!</h3>
          <p>{error.message}</p>
          <button onClick={reset}>Try again</button>
        </div>
      )}
    >
      {children}
    </ErrorBoundary>
  )
}

// Server-side error logging
export function logError(error: Error, context: string) {
  console.error(`[${context}] ${error.message}`, {
    stack: error.stack,
    timestamp: new Date().toISOString(),
  })

  // Send to monitoring service in production
  if (process.env.NODE_ENV === 'production') {
    // sendToMonitoring(error, context)
  }
}

Performance Monitoring

// Monitor API response times
export async function withTiming<T>(
  operation: () => Promise<T>,
  label: string
): Promise<T> {
  const start = Date.now()
  try {
    const result = await operation()
    const duration = Date.now() - start
    console.log(`${label} completed in ${duration}ms`)
    return result
  } catch (error) {
    const duration = Date.now() - start
    console.error(`${label} failed after ${duration}ms:`, error)
    throw error
  }
}

// Usage in API routes
export async function GET() {
  return withTiming(async () => {
    const users = await getAllUsers()
    return NextResponse.json(users)
  }, 'GET /api/users')
}

Database Monitoring

# Monitor database performance
pnpm db:studio

# Check slow queries
# Access your database directly and run:
SELECT query, mean_time, calls
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
Development Tips:
  • Use React DevTools for component debugging
  • Enable database query logging in development
  • Set up proper logging levels for different environments
  • Monitor memory usage during development for optimization opportunities
    Development Workflow | ShipSaaS Documentation | ShipSaaS - Launch your SaaS with AI in days