Prompt file imported from kfklaihk/sample-shop-app-docker (
.github/prompts/plan-scaleAtSeaShopWithCachingMessagingAndAuth.prompt.md). Copyright stays with the author.
Plan: Scale AtSea Shop with Redis, RabbitMQ, Enhanced Auth & Stripe
Upgrade the monolithic Spring Boot application from basic JWT auth to enterprise-grade security with Spring Security, add distributed caching (Redis) for product catalog performance, message queuing (RabbitMQ) for async order processing during peak load, and integrate Stripe for real payment processing. Implement a proper login/register landing page with JWT refresh tokens, role-based access control, and restrict all catalog/order operations to authenticated users.
Steps
-
Add New Dependencies & Core Infrastructure
- Update pom.xml: Add Spring Security, Spring Data Redis (Lettuce), Spring AMQP, Stripe Java SDK, JWT libraries with refresh token support
- Update docker-compose.yml: Add Redis (Alpine) and RabbitMQ (Alpine) services with health checks
- Create new config classes: RedisConfig.java, RabbitMQConfig.java, StripeConfig.java
-
Enhance Authentication & Authorization (Spring Security + JWT Refresh Tokens)
- Replace hardcoded JWT secret with JwtConfig.java using externalized properties
- Update SecurityConfig.java: Enable password hashing (BCryptPasswordEncoder), CSRF protection, stateless session, permit-all for
/api/auth/**only - Create JwtTokenProvider.java: Access token (15 min), refresh token (7 days), token validation/extraction logic
- Create JwtAuthenticationFilter.java: Extract/validate JWT from Authorization header, populate SecurityContext
- Update CustomerEntity.java: Add password hashing migration, roles column (ROLE_USER/ROLE_ADMIN)
-
Create Landing Page & Authentication Endpoints
- Create AuthController.java:
POST /api/auth/register,POST /api/auth/login,POST /api/auth/refresh-token,POST /api/auth/logout - Create AuthRequest/Response DTOs:
LoginRequest,RegisterRequest,AuthResponse(accessToken, refreshToken, expiresIn) - Create
RefreshTokenentity and repository for token blacklisting during logout - Update React landing page: Replace index.html with login/register form, JWT token storage (localStorage), conditional routing based on auth state
- Create AuthController.java:
-
Implement Redis Caching for Product Catalog
- Create CacheService.java: Warm cache on startup, TTL=1 hour for product catalog
- Update ProductController.java: Annotate
@Cacheable("products")on getAllProducts(), cache invalidation on product updates - Create cache pre-loader in
@PostConstructto load all products into Redis on app startup - Update docker-compose.yml Redis service: Set
maxmemory-policy allkeys-lrufor eviction
-
Add RabbitMQ for Async Order Processing & Peak Load Handling
- Create OrderQueue.java: Define queues/exchanges for
orders.created,orders.processing,orders.completed - Create OrderProducer.java: Publish order events to RabbitMQ on order creation
- Create OrderConsumer.java: Async order processing listener with retry logic and DLQ
- Update OrderService.java: Call OrderProducer instead of synchronous payment processing
- Create
OrderStatusentity to track async order state (PENDING → PROCESSING → COMPLETED → FAILED)
- Create OrderQueue.java: Define queues/exchanges for
-
Integrate Stripe Payment Gateway
- Create StripeService.java: Create payment intent, handle webhook for payment_intent.succeeded/failed events
- Create PaymentController.java:
POST /api/payments/create-intent,POST /api/payments/webhook(webhook endpoint) - Store
stripeCustomerIdin CustomerEntity.java - Update OrderConsumer.java: Charge customer via Stripe instead of legacy payment gateway
- Update application.yml: Add
stripe.api-key,stripe.webhook-secretproperties
-
Add Role-Based Access Control (RBAC) & Restrict Resources
- Update SecurityConfig.java: Add
.authorizeHttpRequests()chain:/api/products/**requiresROLE_USER,/api/orders/**requiresROLE_USER,/api/admin/**requiresROLE_ADMIN - Add
@PreAuthorize("hasRole('USER')")to ProductController.java, OrderController.java, CheckoutController.java - Update React: Add route guards in App.js, check JWT token presence before rendering catalog/checkout
- Create
RoleUtilto extract roles from JWT and conditionally render admin features
- Update SecurityConfig.java: Add
-
Update Frontend for Authentication & New UX
- Create
AuthPage.jscomponent with login/register forms and JWT token state management in Redux - Create
ProtectedRoute.jsto redirect unauthenticated users to login - Update ProductsContainer.js: Add JWT token to all API requests in Authorization header
- Update CheckoutContainer.js: Create Stripe integration via
@stripe/react-stripe-js, show payment form (card element) - Create payment action in Redux to handle
/api/payments/create-intentand submit card to Stripe - Update App.js routing: Render AuthPage if not authenticated, else show main shop
- Create
-
Update Database & Docker Compose Configuration
- Update docker-compose.yml: Add Redis and RabbitMQ services, update app environment variables for Redis/RabbitMQ connection strings, add
STRIPE_API_KEYsecret - Update application.yml: Add Spring Data Redis (
spring.redis.host,.port,.timeout), Spring AMQP (spring.rabbitmq.host,.username,.password), JWT configuration, Stripe keys - Create migration script to hash existing customer passwords using BCrypt
- Update init-db.sql: Add
refresh_tokenandstripe_customer_idcolumns to customer table,order_statustable for async tracking
- Update docker-compose.yml: Add Redis and RabbitMQ services, update app environment variables for Redis/RabbitMQ connection strings, add
-
Add Monitoring & Error Handling
- Create GlobalExceptionHandler.java: Handle
JwtValidationException,StripeException,RabbitMQExceptionwith proper HTTP responses - Add structured logging to OrderConsumer with order tracking IDs
- Create health check endpoints for Redis (
/health/redis), RabbitMQ (/health/rabbitmq), Stripe (/health/stripe) - Update docker-compose.yml with healthchecks for all services
- Create GlobalExceptionHandler.java: Handle
Further Considerations
-
Token Refresh Strategy: Access tokens expire in 15 min (short-lived). Frontend must call
/api/auth/refresh-tokenwith refresh token to get new access token. Implement token blacklist in Redis on logout to prevent reuse. -
Backward Compatibility: Current customers without passwords—run DB migration to set temporary passwords, notify users to change them on first login, or accept unauthenticated product browsing but require auth for checkout.
-
Load Testing for Peak Scenarios: Use Apache JMeter or Locust to simulate panic buying (1000s concurrent orders). RabbitMQ + Redis should reduce API response time from seconds to ~200ms. Monitor queue depth and adjust consumer replicas in docker-compose.
-
Stripe Webhook Security: Stripe sends events to
/api/payments/webhook. Verify webhook signature using Stripe SDK to prevent spoofing. Store webhook events in DB for idempotency and audit. -
Redis Cluster vs Single Instance: Current plan uses single Redis for dev. For production, consider Redis Sentinel (HA) or Redis Cluster (sharding) if catalog exceeds memory limits.
-
Environment Secrets Management: Store
stripe.api-key,jwt.secret, RabbitMQ credentials in Docker secrets or external vault (AWS Secrets Manager, HashiCorp Vault), not inapplication.yml. -
Database Connection Pool Tuning: With async order processing, Hikari connection pool size may need increase. Monitor with metrics like
hikaricp.connections.active, adjustspring.datasource.hikari.maximum-pool-size(default 10). -
Frontend State Management: Redux store will hold JWT token + refresh token. Implement auto-token-refresh interceptor on 401 response before retrying request.