AI-Assisted Workflow Examples
This section shows practical examples of how to combine AI assistance with engineering discipline. Each example follows the spec-driven development workflow.
Example 1: Building a SaaS Dashboard
Step 1: Requirements
# SaaS Dashboard Requirements
## Overview
A customer dashboard showing subscription status, usage metrics, and billing history.
## Pages
1. Overview — key metrics at a glance
2. Usage — detailed usage breakdown
3. Billing — payment history and plan management
4. Settings — account and notification preferences
## Technical Requirements
- Next.js 14 with App Router
- PostgreSQL with Prisma ORM
- Authentication via NextAuth.js
- Real-time updates via WebSockets
- Responsive design (mobile-first)
Step 2: Architecture
## Architecture
### Component Tree
DashboardLayout ├── Sidebar (navigation) ├── Header (user menu, notifications) └── Main Content ├── OverviewPage │ ├── MetricCard (×4) │ └── RecentActivity ├── UsagePage │ ├── UsageChart │ └── UsageTable ├── BillingPage │ ├── CurrentPlan │ ├── PaymentHistory │ └── PlanSelector └── SettingsPage ├── ProfileForm ├── NotificationPreferences └── DangerZone
### Data Flow
- Server Components fetch initial data
- Client Components handle interactivity
- API routes for mutations
- WebSocket connection for real-time updates
Step 3: Task Decomposition
## Tasks
### Sprint 1: Foundation
- [ ] Set up Next.js project with TypeScript
- [ ] Configure Prisma with PostgreSQL schema
- [ ] Set up NextAuth.js with email/password
- [ ] Create DashboardLayout with responsive sidebar
- [ ] Implement basic routing structure
### Sprint 2: Overview Page
- [ ] Create MetricCard component
- [ ] Implement API endpoint for dashboard metrics
- [ ] Create RecentActivity component
- [ ] Add real-time updates via WebSocket
- [ ] Write unit tests for components
### Sprint 3: Usage & Billing
- [ ] Create UsageChart with Chart.js
- [ ] Implement usage data API
- [ ] Create billing history table
- [ ] Implement plan upgrade/downgrade flow
- [ ] Integrate Stripe for payment processing
Step 4: AI Prompt
Implement the MetricCard component for a SaaS dashboard.
Context:
- Next.js 14 with TypeScript
- shadcn/ui component library
- Tailwind CSS for styling
- Data comes from a server component
Requirements:
- Display a title, value, trend indicator (up/down), and icon
- Support loading state with skeleton
- Support error state
- Responsive (full width on mobile, 1/4 on desktop)
- Accessible (proper aria labels)
Props interface:
interface MetricCardProps {
title: string;
value: string | number;
trend?: {
direction: 'up' | 'down' | 'neutral';
percentage: number;
};
icon?: React.ReactNode;
loading?: boolean;
error?: string;
}
Step 5: Review
After the AI generates the component, review:
- Does it match the spec?
- Are all states handled (loading, error, empty)?
- Is it accessible?
- Does it follow project conventions?
- Are there any security concerns?
- Is the code maintainable?
Step 6: Test
import { render, screen } from '@testing-library/react';
import { MetricCard } from './MetricCard';
describe('MetricCard', () => {
it('renders title and value', () => {
render(<MetricCard title="Revenue" value="$12,345" />);
expect(screen.getByText('Revenue')).toBeInTheDocument();
expect(screen.getByText('$12,345')).toBeInTheDocument();
});
it('shows loading skeleton', () => {
render(<MetricCard title="Revenue" value="" loading />);
expect(screen.getByTestId('skeleton')).toBeInTheDocument();
});
it('shows error state', () => {
render(<MetricCard title="Revenue" value="" error="Failed to load" />);
expect(screen.getByText('Failed to load')).toBeInTheDocument();
});
it('shows positive trend', () => {
render(
<MetricCard
title="Revenue"
value="$12,345"
trend={{ direction: 'up', percentage: 12.5 }}
/>
);
expect(screen.getByText('+12.5%')).toBeInTheDocument();
});
});
Example 2: Building a REST API
Step 1: Requirements
# Task Management API
## Endpoints
- GET /api/tasks — List tasks (paginated, filterable)
- POST /api/tasks — Create a task
- GET /api/tasks/:id — Get task details
- PUT /api/tasks/:id — Update a task
- DELETE /api/tasks/:id — Delete a task
## Security
- All endpoints require authentication
- Users can only access their own tasks
- Rate limiting: 100 requests/minute
- Input validation on all mutations
Step 2: AI Prompt
Create a REST API endpoint for listing tasks.
Context:
- Express.js with TypeScript
- Prisma ORM with PostgreSQL
- JWT authentication middleware
- Express-rate-limit for rate limiting
Requirements:
- GET /api/tasks
- Pagination (page, limit query params)
- Filtering by status (pending, in_progress, completed)
- Sorting by created_at, due_date, priority
- Only return tasks belonging to authenticated user
- Return total count for pagination
- Proper error handling
- Rate limited to 100 requests/minute
Response format:
{
"data": Task[],
"pagination": {
"page": number,
"limit": number,
"total": number,
"totalPages": number
}
}
Step 3: Review
Check the generated code for:
- Authentication check on every request
- User ID scoping (can't see other users' tasks)
- Input sanitization in query parameters
- Proper pagination logic
- Error handling for invalid parameters
- Rate limiting headers in response
- Proper HTTP status codes
Example 3: Database Migration
Step 1: Requirements
# Database Migration: Add Team Feature
## Changes
1. Create teams table
2. Add team_id to users table
3. Create team_members join table
4. Add foreign key constraints
5. Create indexes for performance
6. Migrate existing users to default team
Step 2: AI Prompt
Create a Prisma migration for adding team functionality.
Requirements:
- Teams table: id, name, slug (unique), created_at, updated_at
- TeamMembers table: id, team_id, user_id, role (admin/member), joined_at
- Users table: add team_id foreign key (nullable)
- Indexes: team_members (team_id, user_id) unique, users (team_id)
- Migration should be reversible
- Include seed data for testing
Please provide:
1. The Prisma schema changes
2. The migration SQL
3. The rollback SQL
Step 3: Review
- Foreign keys are correct
- Indexes cover query patterns
- Nullable fields are appropriate
- Rollback is complete
- No data loss on migration
- Performance impact is acceptable
Key Takeaways
- Always start with requirements — even a simple bullet list improves AI output dramatically
- Decompose work — small, focused prompts produce better code than one massive prompt
- Review everything — AI-generated code needs human review, especially for security
- Test thoroughly — write tests that verify the spec, not just the code
- Iterate — use follow-up prompts to refine and improve generated code