Wybrałeś Node.js jako runtime backendu i teraz musisz dostarczyć API, które nie padnie pod obciążeniem w piątkowy wieczór. Te przepisy dają Ci prompty gotowe do użycia w produkcji, które generują idiomatyczny kod Node.js — nie szablonowy kod Express z 2015 roku bez obsługi błędów.
Prompty do generowania REST API z TypeScript, walidacją i obsługą błędów
Wzorce autentykacji i autoryzacji (JWT, session, OAuth)
Integracje z bazami danych (Prisma, TypeORM, Drizzle)
Wzorce kolejek tła, WebSocket i real-time
Konfiguracje testowania dla Jest, Vitest i Supertest
Scenariusz: Zaczynasz nowy serwis Node.js i chcesz skalowalną strukturę z oddzielnymi warstwami dla routingu, logiki biznesowej i dostępu do danych.
Wskazówka
Wygeneruj szkielet projektu Node.js TypeScript w src/ z następującą strukturą folderów: controllers/ (logika route handler), services/ (logika biznesowa), repositories/ (dostęp do danych), models/ (definicje typów/encji), middleware/ (express middleware), utils/ (funkcje pomocnicze), config/ (konfiguracja env). Użyj Express z async error handling wrapper. Skonfiguruj TypeScript z strict mode, path aliases (@/controllers, @/services itd.). Dodaj inversify dla dependency injection, aby każda warstwa mogła być testowana w izolacji. Stwórz przykładowy moduł users z pełnym CRUD pokazującym, jak każda warstwa wchodzi w interakcje: UserController -> UserService -> UserRepository. Dołącz plik container.ts do wiązania DI. Dodaj nodemon do hot-reload w dev. Napisz testy jednostkowe dla każdej warstwy używając mockowych zależności.
Oczekiwany output: Struktura katalogów, pliki konfiguracyjne TypeScript, container DI, przykładowy moduł users i testy.
Scenariusz: Musisz zbudować endpoint API dla zarządzania zasobem produktów z pełną walidacją i spójną obsługą błędów.
Wskazówka
Stwórz REST API w Express lub Fastify dla zasobu products z endpointami: POST /api/products (utwórz), GET /api/products (lista z paginacją, filtrowaniem, sortowaniem), GET /api/products/:id (szczegóły), PUT /api/products/:id (aktualizuj), DELETE /api/products/:id (usuń). Użyj zod dla schematu walidacji — zdefiniuj CreateProductSchema, UpdateProductSchema, ProductQuerySchema. Zaimplementuj middleware walidacji, które parsuje req.body/query względem odpowiedniego schematu i zwraca 400 z opisowymi błędami. Stwórz globalny error handler middleware do łapania i formatowania błędów (błędy walidacji, błędy bazy danych, błędy nie znaleziono, błędy serwera). Zwracaj spójne odpowiedzi JSON: { success: true, data } dla sukcesu, { success: false, error: { code, message, details } } dla błędów. Dołącz rate limiting za pomocą express-rate-limit (100 req/15min na IP). Napisz testy integracyjne za pomocą supertest obejmujące każdy endpoint i przypadki błędów.
Oczekiwany output: Pliki routes, kontrolery, schematy Zod, middleware, error handler i pełny zestaw testów.
Scenariusz: Twoja aplikacja potrzebuje bezpiecznego systemu uwierzytelniania z access/refresh token, aby sesje użytkowników nie wygasały co 15 minut.
Wskazówka
Zaimplementuj system autentykacji JWT z access i refresh tokens. Endpointy: (1) POST /auth/register — hashuj hasło bcrypt, zapisz użytkownika, zwróć access + refresh. (2) POST /auth/login — zweryfikuj hasło, zwróć tokeny. (3) POST /auth/refresh — przyjmij refresh token, zweryfikuj, wyślij nowy access token. (4) POST /auth/logout — unieważnij refresh token (dodaj do blacklist w Redis lub oznacz w DB). Access token ma czas życia 15 min, refresh token 7 dni. Przechowuj refresh tokens w bazie danych z user_id, expiry, revoked flag. Stwórz middleware authenticate, które weryfikuje access token i dołącza req.user. Używaj jsonwebtoken z asymetrycznymi kluczami (RS256). Przechowuj klucze prywatne/publiczne w zmiennych env. Obsłuż przypadki brzegowe: wygasłe tokeny, unieważnione tokeny, brakujące tokeny. Napisz testy dla każdego flow (register, login, refresh, logout) oraz nieautoryzowanego dostępu.
Oczekiwany output: Moduł auth z routes, service, middleware, generacją JWT, tabelami DB dla refresh tokens i testami.
Scenariusz: Twoje API jest bombardowane automatycznymi narzędziami i potrzebujesz rozbudowanego rate limiting, aby chronić zasoby serwera.
Wskazówka
Zaimplementuj multi-tier rate limiting: (1) Globalny limit: 1000 req/hour na IP używając express-rate-limit z Redis store dla rozproszonego rate limiting. (2) Limit per-endpoint: bardziej restrykcyjne limity dla wrażliwych endpointów (np. /auth/login na 5 req/15min, /api/search na 100 req/hour). (3) Limit per-użytkownika: authenticated users dostają wyższe limity zidentyfikowane przez user ID zamiast IP. Zwracaj nagłówki X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset w każdej odpowiedzi. Gdy limit jest przekroczony, zwróć 429 Too Many Requests z Retry-After header. Dodaj dodatkowe zabezpieczenia: helmet.js dla secure headers, cors z whitelistą, express-validator do sanityzacji inputów, hpp dla ochrony przed pollution. Loguj podejrzane wzorce (powtarzające się 429, nieudane logowania) używając Winston z poziomami alert. Napisz middleware test, który symuluje burst requests i weryfikuje rate limit.
Oczekiwany output: Rate limiting middleware dla różnych warstw, konfiguracja Redis, helmet + cors setup, logi security i testy.
Scenariusz: Potrzebujesz type-safe database access z migracjami, relacjami i optimistic locking.
Wskazówka
Skonfiguruj Prisma dla PostgreSQL z tym schematem: modele User, Post, Comment z relacjami one-to-many. (1) User ma pola: id (uuid), email (unique), passwordHash, createdAt, updatedAt, posty (relation). (2) Post ma: id, title, content, published boolean, authorId (foreign key), userId, komentarze (relation), createdAt, updatedAt, version (dla optimistic locking). (3) Comment ma: id, content, postId, userId, createdAt. Zdefiniuj indeksy na często query’owanych polach (email, authorId, postId). Napisz migrację inicjalizującą schemat. Stwórz PrismaService z connection pooling i graceful shutdown. Zaimplementuj repository pattern: UserRepository, PostRepository, CommentRepository — każde z metodami CRUD plus custom queries (np. findPublishedPosts(), findUserWithPosts()). Użyj Prisma transactions dla operacji multi-step (np. utwórz post + powiadom obserwujących). Zaimplementuj optimistic locking dla aktualizacji postów: sprawdź version field, zwiększ przy zapisie, rzuć błąd jeśli nieaktualny. Napisz testy integracyjne używając test database.
Oczekiwany output: Schemat Prisma, pliki migracji, repository classes, service wrapper, optimistic locking logic i testy DB.
Scenariusz: Twoja aplikacja musi przetwarzać czasochłonne zadania (wysyłanie emaili, generowanie raportów, przetwarzanie obrazów) bez blokowania API responses.
Wskazówka
Skonfiguruj BullMQ z Redis jako broker kolejek. Stwórz te kolejki: (1) emailQueue — do wysyłania emaili transakcyjnych (welcome, password reset). (2) reportQueue — generowanie raportów PDF/CSV. (3) imageQueue — resize/optimize przesłanych obrazów. Dla każdej kolejki, zdefiniuj: Job data type (TypeScript interface), processor function (przetwarzający job), retry strategy (exponential backoff, max 3 próby), error handling (loguj failures, dead-letter queue). Stwórz QueueService z metodami: addEmailJob(data), addReportJob(data), addImageJob(data). Każdy processor powinien logować start/end, obsługiwać cancelację, raportować postęp. Dodaj Bull Board do wizualizacji dashboard kolejek z metrykami job (pending, active, completed, failed). Zaimplementuj graceful shutdown: czekaj na aktywne jobs przed zamknięciem workera. Napisz testy dla job processors i retry logic.
Oczekiwany output: BullMQ setup, queue definitions, job processors, QueueService wrapper, Bull Board dashboard i testy.
Scenariusz: Twój dashboard potrzebuje live updates bez pollowania API co sekundę.
Wskazówka
Zbuduj serwer WebSocket używając ws library zintegrowanej z istniejącym Express server. Features: (1) Uwierzytelnianie: klienci wysyłają JWT w initial handshake, odrzuć połączenia z niewłaściwymi tokenami. (2) Room-based messaging: klienci mogą subskrybować pokoje (np. dashboard:123, chat:456), broadcast messages tylko do członków pokoju. (3) Heartbeat ping/pong co 30 sekund do wykrywania martwych połączeń. (4) Message types: zdefiniuj TypeScript types dla różnych typów wiadomości (subscribe, unsubscribe, message, notification). (5) Error handling: złap błędy parsowania i błędy handlera, wyślij error message do klienta. (6) Graceful shutdown: wyślij close message, czekaj na ACK, rozłącz. Przechowuj mapy połączeń: connectionId -> WebSocket, roomId -> Set<connectionId>. Zintegruj z Redis pub/sub dla multi-server broadcasting (jeśli skalujesz poziomo). Napisz klienta testowego i testy integracyjne dla subskrypcji pokoi i broadcastu.
Oczekiwany output: WebSocket server, auth handling, room management, message types, Redis integration i testy klienta.
Scenariusz: Debugujesz problem produkcyjny i nie możesz znaleźć powiązanych logów rozproszonych po plikach z niespójnym formatowaniem.
Wskazówka
Skonfiguruj Winston dla structured JSON logging z tymi features: (1) Poziomy logów: error, warn, info, debug używane odpowiednio. (2) Metadata: każdy log zawiera timestamp, level, message, service (nazwa serwisu), environment (prod/dev), correlationId (request tracing). (3) Transporty: Console (dev) z kolorowym formatowaniem, File dla errorów (logs/error.log), File dla combined (logs/combined.log), opcjonalnie external service (Logtail, Datadog). (4) Express middleware logujące incoming requests: method, url, status, responseTime, userId (jeśli authenticated), correlationId (generuj UUID per request, dołącz do req object). (5) Error logging: łap unhandled rejections i exceptions, loguj pełny stack trace. (6) Child loggers: stwórz child loggery dla różnych modułów (auth, payments, notifications) z dodatkowym kontekstem. Napisz log format utility, które redaguje wrażliwe pola (password, token). Test logging przez symulację requests i weryfikację log output.
Oczekiwany output: Winston config, request logging middleware, error handlers, child logger utility, redaction logic i testy.
Scenariusz: Musisz wprowadzić breaking changes do API, ale nie możesz zepsuć istniejących klientów.
Wskazówka
Zaimplementuj API versioning używając URL path: /api/v1/..., /api/v2/.... (1) Stwórz oddzielne foldery routerów: routes/v1/, routes/v2/. Współdziel business logic gdzie możliwe przez service layer. (2) V1 endpoint GET /api/v1/users/:id zwraca { id, name, email }. V2 endpoint GET /api/v2/users/:id zwraca { id, fullName, emailAddress, createdAt } (breaking change w strukturze). (3) Dodaj deprecation headers do v1 responses: X-API-Deprecated: true, X-API-Sunset: 2025-12-31 (data usunięcia). (4) Loguj użycie deprecated endpoints z client identifiers do śledzenia migracji. (5) Stwórz middleware versionCheck, które parsuje żądaną wersję i routuje odpowiednio. (6) Dokumentuj każdą wersję API osobno. Napisz migrację guide dla klientów. Testy dla obu wersji z użyciem tego samego zestawu testów ale różnych assertion dla response shape.
Oczekiwany output: Multi-version router setup, deprecation headers, logging usage, migration guide i dual-version tests.
Scenariusz: Użytkownicy muszą przesyłać avatary, dokumenty i załączniki — potrzebujesz bezpiecznego file upload flow.
Wskazówka
Zaimplementuj file upload używając multer z tymi zabezpieczeniami: (1) Limit rozmiaru pliku: 5MB dla obrazów, 10MB dla dokumentów. (2) Whitelist MIME types: akceptuj tylko image/jpeg, image/png, application/pdf. (3) Filename sanitization: generuj UUID filenames, zapobiegaj path traversal. (4) Virus scanning: integruj z clamav (jeśli dostępny) lub rate-limit uploads. (5) Storage strategy: dla dev, przechowuj lokalnie w uploads/; dla produkcji, przesyłaj do S3/R2 używając AWS SDK. (6) Endpoint POST /api/upload przyjmuje multipart/form-data, waliduje plik, przechowuje i zwraca { url, filename, size, mimeType }. (7) Endpoint GET /api/files/:id służy do pobierania plików z signed URLs (dla prywatnych plików) lub redirect do CDN URL. (8) Stwórz tabelę DB files z polami: id, userId, filename, originalName, size, mimeType, path/url, uploadedAt. Ogranicz upload do authenticated users. Napisz testy dla udanych uploadów, rejected files (rozmiar/typ), i S3 integration (mock).
Oczekiwany output: Multer config, walidacja plików, storage handlers (local + S3), routes, DB model i testy.
Scenariusz: Twoja baza danych jest przeciążona powtarzającymi się queries dla rzadko zmieniających się danych.
Wskazówka
Zaimplementuj multi-tier caching strategy używając Redis: (1) Query caching: cache wyniki kosztownych DB queries (np. lista produktów, user profiles) z TTL 5 minut. Przed query sprawdź cache, przy miss wykonaj query i ustaw cache. (2) Cache invalidation: przy updatach/delete, usuń powiązane klucze cache. Użyj wzorców cache keys (np. user:${id}, products:page:${page}). (3) Cache-aside pattern: aplikacja zarządza cache ręcznie (nie write-through). (4) Fragment caching: cache częściowe dane (np. user permissions, feature flags) używane w każdym requescie. (5) Redis client pool z automatic reconnection. (6) Stwórz CacheService wrapper z metodami: get<T>(key), set(key, value, ttl), del(key), delPattern(pattern) (dla bulk invalidation). (7) Dodaj cache hit/miss metrics do logów. (8) Fallback: jeśli Redis jest down, kontynuuj bez cache (logged warning). Napisz testy dla cache hits, misses, invalidation i Redis failures.
Oczekiwany output: Redis client setup, CacheService, integracja z repositories, invalidation logic i testy.
Scenariusz: Twoja aplikacja Node.js potrzebuje spójnego deploymentu w dev i produkcji z bazą danych i Redis.
Wskazówka
Stwórz production-ready Dockerfile i docker-compose setup. Dockerfile: (1) Multi-stage build: stage 1 instaluje dependencies i builduje TypeScript, stage 2 kopiuje tylko zbudowany kod i prod dependencies. (2) Użyj node:20-alpine dla mniejszego obrazu. (3) Non-root user do uruchamiania app. (4) Healthcheck endpoint /health używany przez HEALTHCHECK instruction. Docker-compose: serwisy dla (1) app (Node.js), (2) postgres (database), (3) redis (cache/queue), (4) nginx (reverse proxy). App serwis: expose port, dependency na postgres + redis, env vars z .env file, restart policy. Postgres: persistent volume dla danych, POSTGRES_DB/USER/PASSWORD env vars. Redis: persistent volume (opcjonalnie), expose port lokalnie. Nginx: proxy pass do app service, SSL termination (dla produkcji). Dodaj health checks dla każdego serwisu. Stwórz oddzielne pliki docker-compose.yml (dev) i docker-compose.prod.yml (prod overrides). Napisz skrypty do budowania i deployowania: npm run docker:build, npm run docker:up.
Oczekiwany output: Multi-stage Dockerfile, docker-compose files dla dev i prod, nginx config, health checks i deployment scripts.