1. Zdefiniuj wymagania
Zacznij od jasnych historii użytkownika i kryteriów akceptacji w swoim PRD
Teraz gdy skonfigurowałeś Cursor i rozumiesz jego podstawowe koncepcje, zbudujmy prawdziwą funkcję od początku do końca. Zaimplementujemy system uwierzytelniania użytkownika z funkcjonalnością resetowania hasła, demonstrując jak pomoc AI transformuje proces rozwoju.
1. Zdefiniuj wymagania
Zacznij od jasnych historii użytkownika i kryteriów akceptacji w swoim PRD
2. Planuj w trybie Ask
Rozbij funkcję na zadania techniczne używając analizy AI
3. Implementuj z Agentem
Pozwól Agentowi zająć się ciężką pracą podczas gdy ty kierujesz i weryfikujesz
4. Testuj i iteruj
Używaj AI do generowania testów i automatycznego naprawiania problemów
Przejdźmy przez implementację funkcji resetowania hasła dla aplikacji webowej. To dotyka wielu warstw (baza danych, backend API, frontend UI, email) czyniąc to idealnym do demonstracji możliwości Cursor.
Najpierw utwórz prosty PRD w swoim projekcie:
# Funkcja: Resetowanie hasła
## Historie użytkownika- Jako użytkownik chcę zresetować swoje hasło jeśli je zapomnę- Jako użytkownik chcę otrzymać bezpieczny link resetujący przez email- Jako użytkownik chcę żeby link resetujący wygasał po 1 godzinie
## Wymagania techniczne- Bezpieczne generowanie tokenów- Integracja email- Aktualizacje schematu bazy danych- Endpointy API- Formularze frontend- Zautomatyzowane testy
Przełącz na tryb Ask i dołącz swój PRD:
@docs/password-reset-prd.mdWygeneruj plan implementacji technicznej dla tej funkcji resetowania hasła.Rozważ najlepsze praktyki bezpieczeństwa i nasz istniejący system auth.
Cursor przeanalizuje twoją bazę kodu i stworzy szczegółowy plan:
## Plan implementacji
1. **Zmiany bazy danych** - Dodaj password_reset_token do tabeli users - Dodaj pole timestamp token_expires_at
2. **Backend API (2 endpointy)** - POST /auth/forgot-password - POST /auth/reset-password
3. **Serwis email** - Utwórz szablon email resetującego - Integracja z SendGrid/SMTP
4. **Komponenty frontend** - Formularz zapomniałem hasła - Formularz resetowania hasła - Wiadomości sukcesu/błędu
5. **Środki bezpieczeństwa** - Hashowanie tokenów przed przechowywaniem - Ograniczenia częstości - Bezpieczne generowanie losowych tokenów
Teraz przełącz na tryb Agent do implementacji. Tu dzieje się magia:
Agent: Dodaj pola resetowania hasła do tabeli users
Agent wykona:
-- Wygenerowana migracjaALTER TABLE usersADD COLUMN password_reset_token VARCHAR(255),ADD COLUMN token_expires_at TIMESTAMP;
Agent: Implementuj endpoint zapomniałem hasła z ograniczeniami częstości
Agent tworzy kompletny endpoint z bezpieczeństwem:
// Endpoint zapomniałem hasłaapp.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) { // Nie ujawniaj czy email istnieje return res.json({ message: 'Jeśli email istnieje, link resetujący został wysłany' }); }
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 godzina });
await emailService.sendResetEmail(email, token);
res.json({ message: 'Jeśli email istnieje, link resetujący został wysłany' }); });
Agent: Utwórz komponent formularza zapomniałem hasła z walidacją
Agent generuje kompletny komponent React:
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: 'Sprawdź swój email po instrukcje resetowania' }); } catch (error) { setStatus({ type: 'error', message: 'Coś poszło nie tak. Spróbuj ponownie.' }); } finally { setLoading(false); } };
return ( <form onSubmit={handleSubmit}> {/* Pola formularza i UI */} </form> );};
Włącz tryb YOLO i poproś Agenta o stworzenie i uruchomienie testów:
Agent: Napisz testy dla funkcji resetowania hasła, następnie je uruchomi napraw wszelkie problemy aż wszystkie testy przejdą
Przykład generowania testów:
// Wygenerowany plik testowydescribe('Resetowanie hasła', () => { it('powinien wysłać email resetujący dla ważnego użytkownika', 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('nie powinien ujawniać czy email istnieje', async () => { const response = await request(app) .post('/auth/forgot-password') .send({ email: 'nieistniejacy@example.com' });
expect(response.body.message).toBe('Jeśli email istnieje, link resetujący został wysłany'); });
it('powinien egzekwować ograniczenia częstości', async () => { // Testuj logikę ograniczeń częstości });});
Wykorzystaj serwery MCP podczas implementacji:
Context7 dla dokumentacji
Użyj context7: Jak implementować bezpieczne resetowanie hasław Express.js?
Puppeteer do testów E2E
Użyj puppeteer do przetestowania przepływu resetowania hasłaend-to-end na localhost:3000
Database MCP dla schematu
Użyj postgres aby zweryfikować że pole password_reset_tokenzostało dodane poprawnie
Prawdziwy rozwój rzadko następuje linearnie. Oto jak radzić sobie z iteracjami:
Implementacja początkowa → Test → Odkrycie przypadku brzegowego → Udoskonalenie
Przykład iteracji:1. Agent implementuje podstawowy przepływ ✓2. Testy ujawniają że token nie jest czyszczony3. "Agent: Dodaj zadanie czyszczące dla wygasłych tokenów"4. Agent dodaje zaplanowane zadanie5. Testy przechodzą ✓
Dla funkcji ze złożoną logiką biznesową:
Rozbij na pod-funkcje
Agent: Najpierw zaimplementuj tylko logikę generowaniai przechowywania tokenów
Weryfikuj każdy element
Przetestujmy tę część przed przejściem do integracji email
Dodawaj złożoność stopniowo
Teraz dodaj ograniczenia częstości do endpointu który właśnie stworzyliśmy
Refaktoryzuj z pewnością
Agent: Wyodrębnij logikę tokenów do serwisu wielokrotnego użytku
# Skuteczna struktura promptu:Agent: Utwórz endpoint [METHOD] /api/[resource] który:- Waliduje input używając [biblioteka walidacji]- Obsługuje te przypadki brzegowe: [lista przypadków]- Zwraca odpowiednie kody statusu HTTP- Zawiera obsługę błędów i logowanieNapisz testy najpierw, potem implementację
# Dla komponentów React/Vue/Angular:Agent: Utwórz [NazwaKomponentu] który:- Akceptuje te propsy: [lista propsów]- Obsługuje te interakcje użytkownika: [lista interakcji]- Pokazuje stany ładowania/błędu- Jest dostępny (etykiety ARIA, nawigacja klawiaturą)- Zawiera testy jednostkowe
# Dla zmian bazy danych:Agent: Zaktualizuj bazę danych aby wspierać [funkcję]:- Dodaj migrację dla zmian schematu- Zaktualizuj modele ORM- Dodaj indeksy dla wydajności- Dołącz migrację rollback- Testuj z przykładowymi danymi
Gdy rzeczy nie działają jak oczekiwano:
Agent: Uruchom tsc i napraw wszystkie błędy TypeScript
Z trybem YOLO Agent:
Agent: Debuguj dlaczego test resetowania hasła zawodzi.Dodaj console.logs jeśli potrzeba, następnie napraw problem.
Agent: Aplikacja crashuje przy kliknięciu reset.Sprawdź konsolę przeglądarki i zakładkę network,następnie napraw problem.
Przed uznaniem funkcji za kompletną:
Zacznij małe
Zacznij od najprostszej wersji, potem iteruj. AI świetnie radzi sobie z przyrostowymi ulepszeniami.
Testuj wcześnie
Pisz testy wraz z implementacją. Testy generowane przez AI wykrywają przypadki brzegowe które możesz przegapić.
Używaj checkpointów
Twórz checkpointy przed większymi zmianami. Łatwy rollback jeśli AI zejdzie z kursu.
Weryfikuj zrozumienie
Pytaj “Wyjaśnij co właśnie zrobiłeś” aby upewnić się że zmiany AI są zgodne z twoją intencją.
Teraz gdy zbudowałeś swoją pierwszą funkcję wspomaganą przez AI: