1. Define Requirements
Start with clear user stories and acceptance criteria in your PRD
Ta treść nie jest jeszcze dostępna w Twoim języku.
Now that you’ve configured Cursor and understand its core concepts, let’s build a real feature from start to finish. We’ll implement a user authentication system with password reset functionality, demonstrating how AI assistance transforms the development process.
1. Define Requirements
Start with clear user stories and acceptance criteria in your PRD
2. Plan with Ask Mode
Break down the feature into technical tasks using AI analysis
3. Implement with Agent
Let Agent handle the heavy lifting while you guide and verify
4. Test & Iterate
Use AI to generate tests and fix issues automatically
Let’s walk through implementing a password reset feature for a web application. This touches multiple layers (database, backend API, frontend UI, email) making it perfect for demonstrating Cursor’s capabilities.
First, create a simple PRD in your project:
# Feature: Password Reset
## User Stories- As a user, I want to reset my password if I forget it- As a user, I want to receive a secure reset link via email- As a user, I want the reset link to expire after 1 hour
## Technical Requirements- Secure token generation- Email integration- Database schema updates- API endpoints- Frontend forms- Automated tests
Switch to Ask mode and include your PRD:
@docs/password-reset-prd.mdGenerate a technical implementation plan for this password reset feature.Consider security best practices and our existing auth system.
Cursor will analyze your codebase and create a detailed plan:
## Implementation Plan
1. **Database Changes** - Add password_reset_token to users table - Add token_expires_at timestamp field
2. **Backend API (2 endpoints)** - POST /auth/forgot-password - POST /auth/reset-password
3. **Email Service** - Create reset email template - Integrate with SendGrid/SMTP
4. **Frontend Components** - Forgot password form - Reset password form - Success/error messages
5. **Security Measures** - Hash tokens before storage - Rate limiting - Secure random token generation
Now switch to Agent mode for implementation. Here’s where the magic happens:
Agent: Add password reset fields to the users table
Agent will:
-- Generated migrationALTER TABLE usersADD COLUMN password_reset_token VARCHAR(255),ADD COLUMN token_expires_at TIMESTAMP;
Agent: Implement the forgot password endpoint with rate limiting
Agent creates complete endpoint with security:
// Forgot password endpointapp.post('/auth/forgot-password', rateLimiter({ max: 3, windowMs: 15 * 60 * 1000 }), async (req, res) => { const { email } = req.body;
const user = await User.findByEmail(email); if (!user) { // Don't reveal if email exists return res.json({ message: 'If email exists, reset link sent' }); }
const token = crypto.randomBytes(32).toString('hex'); const hashedToken = await bcrypt.hash(token, 10);
await user.update({ password_reset_token: hashedToken, token_expires_at: new Date(Date.now() + 3600000) // 1 hour });
await emailService.sendResetEmail(email, token);
res.json({ message: 'If email exists, reset link sent' }); });
Agent: Create a forgot password form component with validation
Agent generates a complete React component:
const ForgotPasswordForm = () => { const [email, setEmail] = useState(''); const [status, setStatus] = useState({ type: '', message: '' }); const [loading, setLoading] = useState(false);
const handleSubmit = async (e) => { e.preventDefault(); setLoading(true);
try { const response = await fetch('/api/auth/forgot-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }) });
const data = await response.json(); setStatus({ type: 'success', message: 'Check your email for reset instructions' }); } catch (error) { setStatus({ type: 'error', message: 'Something went wrong. Please try again.' }); } finally { setLoading(false); } };
return ( <form onSubmit={handleSubmit}> {/* Form fields and UI */} </form> );};
Enable YOLO mode and ask Agent to create and run tests:
Agent: Write tests for the password reset feature, then run themand fix any issues until all tests pass
Example test generation:
// Generated test filedescribe('Password Reset', () => { it('should send reset email for valid user', async () => { const user = await createTestUser();
const response = await request(app) .post('/auth/forgot-password') .send({ email: user.email });
expect(response.status).toBe(200); expect(emailService.sendResetEmail).toHaveBeenCalled(); });
it('should not reveal if email exists', async () => { const response = await request(app) .post('/auth/forgot-password') .send({ email: 'nonexistent@example.com' });
expect(response.body.message).toBe('If email exists, reset link sent'); });
it('should enforce rate limiting', async () => { // Test rate limiting logic });});
Leverage MCP servers during implementation:
Context7 for Documentation
Use context7: How do I implement secure passwordreset in Express.js?
Puppeteer for E2E Testing
Use puppeteer to test the password reset flowend-to-end on localhost:3000
Database MCP for Schema
Use postgres to verify the password_reset_tokenfield was added correctly
Real development rarely happens linearly. Here’s how to handle iterations:
Initial Implementation → Test → Discover Edge Case → Refine
Example iteration:1. Agent implements basic flow ✓2. Tests reveal token isn't being cleaned up3. "Agent: Add a cleanup job for expired tokens"4. Agent adds scheduled task5. Tests pass ✓
For features with complex business logic:
Break into sub-features
Agent: First, implement just the token generationand storage logic
Verify each piece
Let's test this part before moving to email integration
Layer complexity gradually
Now add rate limiting to the endpoint we just created
Refactor with confidence
Agent: Extract the token logic into a reusable service
# Effective prompt structure:Agent: Create a [METHOD] /api/[resource] endpoint that:- Validates input using [validation library]- Handles these edge cases: [list cases]- Returns proper HTTP status codes- Includes error handling and loggingWrite tests first, then implementation
# For React/Vue/Angular components:Agent: Create a [ComponentName] that:- Accepts these props: [list props]- Handles these user interactions: [list interactions]- Shows loading/error states- Is accessible (ARIA labels, keyboard nav)- Includes unit tests
# For database changes:Agent: Update the database to support [feature]:- Add migration for schema changes- Update ORM models- Add indexes for performance- Include rollback migration- Test with sample data
When things don’t work as expected:
Agent: Run tsc and fix all TypeScript errors
With YOLO mode, Agent will:
Agent: Debug why the password reset test is failing.Add console.logs if needed, then fix the issue.
Agent: The app crashes when clicking reset.Check the browser console and network tab,then fix the issue.
Before considering your feature complete:
Start Small
Begin with the simplest version, then iterate. AI excels at incremental improvements.
Test Early
Write tests with your implementation. AI-generated tests catch edge cases you might miss.
Use Checkpoints
Create checkpoints before major changes. Easy rollback if AI goes off track.
Verify Understanding
Ask “Explain what you just did” to ensure AI changes align with your intent.
Now that you’ve built your first AI-assisted feature: