9.7 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
QR Rapido is an ultra-fast QR code generator built with ASP.NET Core 8.0, focusing on speed and multilingual support (PT-BR, ES, EN). It features tiered user access (anonymous, logged-in free, premium), OAuth authentication (Google/Microsoft), Stripe payment integration, and ad-free session management.
Key Performance Targets:
- QR generation: <1.2s (average), <0.4s (premium users)
- Cache hit rate: >80%
- First Contentful Paint: <2s
Common Commands
Development
# Run locally (hot reload)
dotnet watch run
# Run locally (standard)
dotnet run
# Build for release
dotnet build --configuration Release
# Restore dependencies
dotnet restore
Testing
# Run all tests
dotnet test
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Run specific test class
dotnet test --filter "QRRapidoServiceTests"
Frontend Build
# Development mode with Vite
npm run dev
# Production build (Vite)
npm run build
# Preview production build
npm run preview
Docker
# Build and run all services (MongoDB, Redis, Nginx)
docker-compose up -d
# View logs
docker-compose logs -f qrrapido
# Build production image for ARM64 (OCI Ampere servers)
docker buildx build --platform linux/arm64 -t qrrapido:latest .
# Stop all services
docker-compose down
Stripe Webhooks (Local Testing - WSL)
# Forward Stripe webhooks to local HTTPS endpoint
stripe listen --forward-to https://localhost:52428/pagamento/stripewebhook --skip-verify
Architecture
Core Technology Stack
- Backend: ASP.NET Core 8.0 (MVC + Razor Pages)
- Database: MongoDB (users, QR history, sessions)
- Cache: Redis (distributed cache) + MemoryCache (fallback)
- QR Generation: QRCoder library with ImageSharp for logo overlay
- Authentication: Cookie-based with OAuth (Google, Microsoft)
- Payments: Stripe (subscriptions)
- Logging: Serilog → OpenSearch/Console
- Frontend Build: Vite for asset bundling
Project Structure
Controllers/ # MVC controllers (Home, QR, Account, Premium, Pagamento, Health)
Services/ # Business logic (QRRapido, User, Plan, Stripe, AdDisplay)
├── Monitoring/ # Resource and MongoDB monitoring
└── HealthChecks/# Health check implementations
Models/ # Domain models and ViewModels
Data/ # MongoDbContext
Middleware/ # Custom middleware (Language redirection, LastLogin update)
Providers/ # Culture providers for localization
Resources/ # .resx files for PT-BR, ES, EN localization
Views/ # Razor views
wwwroot/ # Static assets (CSS, JS, images)
Tests/ # Unit tests (xUnit, Moq)
Key Services
QRRapidoService (Services/QRRapidoService.cs):
- Core QR generation with distributed cache support
- SemaphoreSlim limits concurrent generations (default: 100)
- Cache key based on content hash + settings
- Optimized error correction levels for speed
- Logo overlay with readability analysis
UserService (Services/UserService.cs):
- MongoDB user CRUD operations
- QR history management (anonymous vs authenticated)
- Premium status checks
- Graceful fallback when MongoDB unavailable
AdDisplayService (Services/AdDisplayService.cs):
- Controls ad visibility based on user status
- 30-day ad-free period after login
- Premium users: permanent ad-free
- Anonymous users: always show ads
StripeService (Services/StripeService.cs):
- Subscription creation and management
- Webhook handling (checkout.session.completed, etc.)
- Customer portal session creation
Middleware Pipeline (Program.cs)
- LanguageRedirectionMiddleware: Redirects root
/to/pt-BR/or user's language preference - Request Localization: Sets culture based on route (
/{culture}/...) → QueryString → Cookie - Authentication/Authorization
- Session
- LastLoginUpdateMiddleware: Updates user's last login timestamp
Localization Strategy
- Route-based culture:
/{culture:regex(^(pt-BR|es-PY)$)}/{controller}/{action} - Default culture:
pt-BR - Supported cultures:
pt-BR,es-PY - Culture providers priority: Route → QueryString → Cookie
- Resources in
Resources/SharedResource.{culture}.resx
MongoDB Collections
- Users: User profiles, premium status, OAuth data
- QRCodeHistory: Generated QR codes (linked to users or anonymous)
- AdFreeSessions: Ad-free session tracking (30-day grants)
- DataProtectionKeys: ASP.NET Core Data Protection keys (for Docker Swarm)
Docker Swarm Deployment
Production uses Docker Swarm with:
- 2 replicas across 2 ARM64 servers (OCI Ampere)
- Shared MongoDB for Data Protection keys (cross-replica cookie decryption)
- Rolling updates:
start-firststrategy, 30s delay between updates - Health checks at
/healthcheckendpoint - Exposed on port 5001 internally, proxied by Nginx
Staging uses standalone Docker containers on 2 servers.
CI/CD Pipeline (.github/workflows/deploy.yml)
-
Test Job: Runs on
ubuntu-latest- Restore → Build → Test with coverage
- Uploads coverage to Codecov
-
Build-and-Push Job: Runs on self-hosted ARM64 runner
- Builds ARM64 Docker image
- Tags:
latest(main),develop(develop branch) - Pushes to private registry:
registry.redecarneir.us
-
Deploy-Staging: SSH to 2 servers, pull image, run container
-
Deploy-Production: SSH to Swarm manager, update service with zero-downtime
Configuration Management
appsettings.json key sections:
ConnectionStrings:MongoDB: MongoDB connection stringAuthentication:Google/Microsoft: OAuth credentialsStripe: API keys and webhook secretPerformance:MaxConcurrentGenerations: Semaphore limit (default: 100)Premium:FreeQRLimit: Daily limit for logged-in free users (10)Serilog:OpenSearchUrl: Centralized logging endpointResourceMonitoring: CPU/memory thresholds for alertsHealthChecks: Timeout and test configurations
Environment-specific overrides:
appsettings.Development.jsonappsettings.Production.json
Rate Limiting & Performance
- Fixed window rate limiter: 600 requests/minute per IP on
/apiendpoints - Kestrel max connections: 2000
- QR generation timeout: 2000ms
- Redis cache expiration: 60 minutes
- MongoDB query timeouts: 5 seconds (health checks)
Health Checks
Endpoint: /healthcheck
Checks:
- MongoDbHealthCheck: Database connectivity, size metrics, test query
- ResourceHealthCheck: CPU/memory usage, GC pressure
- ExternalServicesHealthCheck: Stripe API availability
Testing Strategy
- Unit tests: Services layer (QRRapidoService, AdDisplayService, etc.)
- Mocking: MongoDB and IDistributedCache with Moq
- Coverage: Run
dotnet test --collect:"XPlat Code Coverage" - Test files in
Tests/Services/
Known Quirks & WSL Compatibility
- StaticWebAssets disabled: Set
ASPNETCORE_HOSTINGSTARTUP__STATICWEBASSETS__ENABLED=falsefor WSL path issues (see Program.cs:38-39) - DataProtection: Uses MongoDB for key persistence in production (Docker Swarm), filesystem in development
- Frontend build: Vite runs during Release build via MSBuild target (
BuildFrontendin .csproj) - Stripe local testing: Use
stripe listenin WSL (see README.md:345-347)
Monitoring & Logging
- Serilog → Console (development) + OpenSearch (production)
- ResourceMonitoringService: Background service tracking CPU/memory every 30s
- HistoryCleanupService: Cleans old anonymous QR history (7-day grace period, runs every 6 hours)
- MongoDbMonitoringService: Tracks database growth and collection stats (disabled by default)
Premium Feature Gates
Check user premium status via IUserService.GetUserAsync(userId) → user.IsPremium
Premium benefits:
- Unlimited QR codes (vs 10/day anonymous, 50/day free)
- No ads permanently
- Priority generation (faster SemaphoreSlim release)
- Dynamic QR codes (editable)
- API access
Ad-Free Logic
See AdDisplayService.ShouldShowAdsAsync():
- Anonymous users: always show ads
- Premium users: never show ads
- Free logged-in users: 30-day ad-free period from login (configurable in appsettings)
- Ad-free sessions tracked in MongoDB
AdFreeSessionscollection
Security Considerations
- OAuth secure flow with PKCE
- HTTPS redirect enforced (non-dev environments)
- Stripe webhook signature verification
- Input sanitization on QR generation
- Rate limiting on API endpoints
- HSTS enabled in production
- Forwarded headers support for reverse proxy (Nginx)
Common Workflows
Adding a new QR type:
- Update
Models/ViewModels/QRGenerationRequest.cswith new type enum - Add generation logic in
Services/QRRapidoService.cs→GenerateQRCodeOptimizedAsync() - Update frontend form in
Views/Home/Index.cshtml - Add localized strings in
Resources/SharedResource.{culture}.resx
Adding a new language:
- Create
Resources/SharedResource.{culture}.resx - Update
Program.cssupported cultures array (line 214-218) - Update route constraint regex (line 354)
- Add culture provider mapping if needed
Debugging slow QR generation:
- Check
_loggeroutput inQRRapidoService.GenerateRapidAsync()for timing - Verify cache hit rate in logs
- Check semaphore wait time (max concurrent limit)
- Review
Performance:QRGenerationTimeoutMsin appsettings - Monitor resource usage via
/healthcheck
Updating Stripe configuration:
- Update
appsettings.json→Stripesection - Verify webhook secret matches Stripe dashboard
- Test locally with
stripe listen --forward-to ... - Update
StripeService.cswebhook handlers if event types change