{"ts": "2025-10-17T09:23:15+09:00", "task": "implement JWT authentication", "mistake": "JWT validation failed with undefined secret", "evidence": "TypeError: Cannot read property 'verify' of undefined at validateToken", "rule": "Always verify environment variables are set before implementing authentication", "fix": "Added JWT_SECRET to .env file and validated presence in startup", "tests": ["Check .env.example for required vars", "Add env validation to app startup", "Test JWT signing and verification"], "status": "adopted"}
{"ts": "2025-10-18T14:45:32+09:00", "task": "setup database migrations", "mistake": "Migration failed due to missing database connection", "evidence": "Error: connect ECONNREFUSED 127.0.0.1:5432", "rule": "Verify database is running before executing migrations", "fix": "Started PostgreSQL service and confirmed connection with psql", "tests": ["Check DB service status", "Test connection with psql", "Run migration"], "status": "adopted"}
{"ts": "2025-10-19T11:12:48+09:00", "task": "configure CORS for API", "mistake": "API calls blocked by CORS policy", "evidence": "Access to fetch blocked by CORS policy: No 'Access-Control-Allow-Origin' header", "rule": "Configure CORS middleware before defining routes in Express apps", "fix": "Added cors() middleware before route definitions in server.ts", "tests": ["Test OPTIONS preflight", "Test actual API call from frontend", "Verify CORS headers in response"], "status": "adopted"}
{"ts": "2025-10-20T16:34:21+09:00", "task": "implement file upload feature", "mistake": "File upload timeout on large files", "evidence": "Error: Request timeout after 30000ms, file size 45MB", "rule": "Increase request timeout and body size limits for file upload endpoints", "fix": "Set express.json({limit: '50mb'}) and timeout to 5 minutes", "tests": ["Test 1MB file upload", "Test 25MB file upload", "Test 45MB file upload"], "status": "adopted"}
{"ts": "2025-10-21T10:18:55+09:00", "task": "add Redis caching layer", "mistake": "Redis connection refused in production", "evidence": "Error: connect ECONNREFUSED at Redis client initialization", "rule": "Use connection string from environment variables, don't hardcode localhost", "fix": "Changed Redis.createClient({host: 'localhost'}) to Redis.createClient({url: process.env.REDIS_URL})", "tests": ["Verify REDIS_URL in production env", "Test cache read/write", "Monitor Redis connection health"], "status": "adopted"}
{"ts": "2025-10-22T13:42:17+09:00", "task": "implement email notification system", "mistake": "SMTP authentication failed", "evidence": "Error: Invalid login: 535-5.7.8 Username and Password not accepted", "rule": "For Gmail SMTP, use App Password instead of account password", "fix": "Generated Gmail App Password and updated EMAIL_PASSWORD in .env", "tests": ["Test email send with new credentials", "Verify email delivery", "Check spam folder"], "status": "adopted"}
{"ts": "2025-10-23T09:56:33+09:00", "task": "setup CI/CD pipeline", "mistake": "GitHub Actions workflow failed at npm install", "evidence": "Error: npm ERR! code ENOENT npm ERR! syscall open package.json", "rule": "Ensure working directory is set correctly in GitHub Actions steps", "fix": "Added working-directory: ./backend to npm install step", "tests": ["Verify workflow syntax", "Test workflow on feature branch", "Check all paths in actions"], "status": "adopted"}
{"ts": "2025-10-24T15:21:44+09:00", "task": "implement rate limiting", "mistake": "Rate limiter blocked legitimate requests", "evidence": "429 Too Many Requests returned after 10 requests in development", "rule": "Disable or increase rate limits in development environment", "fix": "Added NODE_ENV check: if (process.env.NODE_ENV === 'production') { useRateLimiter() }", "tests": ["Test rate limits in production mode", "Test unlimited in dev mode", "Verify env switching works"], "status": "adopted"}
{"ts": "2025-10-25T11:33:52+09:00", "task": "add TypeScript strict mode", "mistake": "Build failed with 147 type errors after enabling strict mode", "evidence": "error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'", "rule": "Enable TypeScript strict mode gradually, one file at a time", "fix": "Reverted strict mode, added @ts-strict-ignore comments, fixing files incrementally", "tests": ["Fix types in one file", "Run tsc --noEmit", "Remove @ts-strict-ignore when clean"], "status": "adopted"}
{"ts": "2025-10-26T14:17:29+09:00", "task": "optimize database queries", "mistake": "N+1 query problem caused slow API responses", "evidence": "SELECT * FROM users executed 150 times for 150 posts instead of 1 join", "rule": "Use eager loading with includes/joins to avoid N+1 queries", "fix": "Changed Post.findAll() to Post.findAll({include: [{model: User}]})", "tests": ["Check query count in logs", "Measure response time before/after", "Test with 100+ records"], "status": "adopted"}
{"ts": "2025-10-27T10:45:18+09:00", "task": "implement WebSocket real-time updates", "mistake": "WebSocket connections dropped after 60 seconds", "evidence": "WebSocket connection closed: 1006 (abnormal closure)", "rule": "Implement ping/pong heartbeat to keep WebSocket connections alive", "fix": "Added setInterval ping every 30 seconds with pong response handling", "tests": ["Monitor connection for 5 minutes", "Test multiple concurrent connections", "Verify reconnection logic"], "status": "adopted"}
{"ts": "2025-10-28T16:29:41+09:00", "task": "add Stripe payment integration", "mistake": "Webhook signature verification failed", "evidence": "Error: No signatures found matching the expected signature for payload", "rule": "Use raw body for Stripe webhooks, not parsed JSON", "fix": "Added express.raw({type: 'application/json'}) middleware for /webhook endpoint", "tests": ["Test webhook with Stripe CLI", "Verify signature validation", "Check event processing"], "status": "adopted"}
{"ts": "2025-10-29T12:08:54+09:00", "task": "implement password reset flow", "mistake": "Reset token expired immediately", "evidence": "Token validation failed: jwt expired at 2025-10-29T12:08:55Z", "rule": "Set appropriate expiration time for password reset tokens (15-30 min)", "fix": "Changed jwt.sign(..., {expiresIn: '1m'}) to {expiresIn: '30m'}", "tests": ["Generate reset token", "Wait 5 minutes", "Use token to reset password"], "status": "adopted"}
{"ts": "2025-10-30T09:42:11+09:00", "task": "deploy to production", "mistake": "Application crashed on startup in production", "evidence": "Error: Cannot find module './config/production.json'", "rule": "Use environment variables for production config, not JSON files", "fix": "Refactored config to use process.env with dotenv, removed config files", "tests": ["Build production bundle", "Test with production env vars", "Verify no hardcoded configs"], "status": "adopted"}
{"ts": "2025-10-30T14:15:27+09:00", "task": "implement image upload with S3", "mistake": "S3 upload failed with access denied", "evidence": "AccessDenied: Access Denied at S3.putObject", "rule": "Ensure IAM role has s3:PutObject permission for the specific bucket", "fix": "Updated IAM policy to include PutObject action and correct bucket ARN", "tests": ["Test upload with AWS CLI", "Test upload from application", "Verify file appears in S3 bucket"], "status": "adopted"}
