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
- Testing Strategy
- Code Quality Standards
- Performance Optimization
- Deployment Workflow
- Monitoring & Debugging
Feature Development Process
Development Environment Setup
# Clone and install dependencies
pnpm install
# Start development server
pnpm dev
# Build packages first for dependencies
pnpm build:packagesFeature Development Lifecycle
-
Planning Phase
- Define feature requirements and acceptance criteria
- Design database schema changes if needed
- Plan service layer integration points
-
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
- Create/modify database models in
-
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:Testing Patterns:
# Run unit tests
pnpm test
# Run tests in watch mode
pnpm test:watch
# Run tests with coverage
pnpm test:coverage- 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- 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-namePerformance 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 deployEnvironment-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