import React, { useState } from 'react'; import { Award, Briefcase, TrendingUp, Code, Shield, Target, DollarSign, Users, Zap } from 'lucide-react'; const APIAgencySimulator = () => { const [gameState, setGameState] = useState({ chapter: 0, score: 0, codeQuality: 100, clientSatisfaction: 100, reputation: 50, budget: 10000, teamMorale: 100, decisions: [], completedProjects: 0 }); const [showResults, setShowResults] = useState(false); const [currentDecision, setCurrentDecision] = useState(null); const chapters = [ { id: 0, title: "Chapter 1: Your First Client", scenario: "A local coffee shop wants an API to manage their loyalty program. They need endpoints for customer registration, points tracking, and rewards redemption. How do you structure this API?", decisions: [ { text: "Use a single giant endpoint that does everything: POST /do-everything", outcome: { score: -20, codeQuality: -30, clientSatisfaction: -20, explanation: "❌ Bad REST design! Single endpoints doing everything are hard to maintain, understand, and scale.", lesson: "REST Principle: Each endpoint should represent ONE resource with CLEAR actions." } }, { text: "Design separate resource endpoints: GET/POST /customers, GET/POST /points, GET /rewards", outcome: { score: 50, codeQuality: 40, clientSatisfaction: 40, reputation: 10, explanation: "✅ Excellent REST design! Clear resources, proper HTTP methods.", lesson: "You followed REST principles perfectly. The coffee shop can easily integrate each feature." } }, { text: "Create 50+ ultra-specific endpoints for every possible action", outcome: { score: -10, codeQuality: -15, clientSatisfaction: -10, reputation: -5, explanation: "⚠️ Over-engineered! Too many endpoints make the API confusing.", lesson: "Balance is key. Use HTTP methods instead of creating separate endpoints for each action." } }, { text: "Use only GET requests with action parameters: GET /api?action=create&resource=customer", outcome: { score: -25, codeQuality: -35, clientSatisfaction: -25, explanation: "❌ Violates REST principles! GET should only retrieve data, never create or modify.", lesson: "HTTP methods have specific meanings: GET = read, POST = create, PUT = update, DELETE = remove." } } ] }, { id: 1, title: "Chapter 2: Error Handling Crisis", scenario: "A client's mobile app keeps crashing because your API returns generic '500 Internal Server Error' for everything. How do you fix error handling?", decisions: [ { text: "Return detailed error messages with proper status codes: 400, 404, 422", outcome: { score: 50, codeQuality: 40, clientSatisfaction: 50, reputation: 15, budget: 500, explanation: "✅ Perfect! Clear error messages help developers fix issues quickly.", lesson: "Status codes are a language: 2xx = success, 4xx = client error, 5xx = server error." } }, { text: "Keep using 500 for everything but add 'errorType' field in JSON", outcome: { score: 10, codeQuality: -10, clientSatisfaction: -5, explanation: "⚠️ Better than nothing, but still wrong. Status codes exist for a reason!", lesson: "Use HTTP status codes as intended. They enable standard error handling." } }, { text: "Always return 200 OK, even for errors, with success:false in response", outcome: { score: -30, codeQuality: -40, clientSatisfaction: -30, reputation: -15, explanation: "❌ Terrible practice! This breaks caching, monitoring tools, and confuses clients.", lesson: "HTTP status codes are part of the HTTP standard. Breaking them breaks everything." } }, { text: "Return different status codes but with error messages in German", outcome: { score: -15, codeQuality: -10, clientSatisfaction: -40, reputation: -20, explanation: "❌ Status codes are good, but error messages should be in English or support i18n.", lesson: "APIs should be internationally accessible. Use English for technical messages." } } ] }, { id: 2, title: "Chapter 3: The Authentication Challenge", scenario: "Your API is getting hammered by bots. You need to add authentication. Which approach do you choose?", decisions: [ { text: "Implement JWT tokens with Bearer authentication in headers", outcome: { score: 50, codeQuality: 40, clientSatisfaction: 30, reputation: 15, budget: -1000, teamMorale: 10, explanation: "✅ Industry standard! JWT is stateless, scalable, and works with REST principles.", lesson: "JWT tokens are self-contained and don't require database lookups. Perfect for REST APIs." } }, { text: "Use session cookies like traditional web apps", outcome: { score: 10, codeQuality: -15, clientSatisfaction: -10, explanation: "⚠️ Works, but violates REST's stateless principle. Makes scaling harder.", lesson: "Sessions require server-side state. REST APIs should be stateless for scalability." } }, { text: "Put API keys directly in the URL: GET /api/users?apikey=SECRET123", outcome: { score: -40, codeQuality: -50, clientSatisfaction: -20, reputation: -25, explanation: "❌ Huge security risk! URLs get logged everywhere. Keys will leak!", lesson: "Never put secrets in URLs. Use Authorization headers to keep credentials secure." } }, { text: "No authentication - just trust everyone", outcome: { score: -50, codeQuality: -40, clientSatisfaction: -50, reputation: -40, budget: -5000, explanation: "❌ Disaster! Your API will be abused and your reputation ruined.", lesson: "Always implement authentication for APIs. Trust no one on the internet." } } ] }, { id: 3, title: "Chapter 4: Design Patterns Integration", scenario: "You're building an ML API supporting multiple model types. The client wants to switch models without changing their code. How do you architect this?", decisions: [ { text: "Use Factory Pattern to create models + Strategy Pattern for prediction algorithms", outcome: { score: 60, codeQuality: 50, clientSatisfaction: 50, reputation: 20, budget: 1000, explanation: "✅ Perfect! Factory creates models, Strategy handles approaches. Exactly W4D1 patterns!", lesson: "Design patterns from W4D1 are essential for scalable APIs. Factory + Strategy = flexible code." } }, { text: "Create separate endpoints for each model: /predict-rf, /predict-svm, /predict-nn", outcome: { score: 10, codeQuality: -20, clientSatisfaction: -15, explanation: "⚠️ Works but doesn't scale. Adding models means new endpoints.", lesson: "Use patterns to handle variety in behavior, not multiple endpoints." } }, { text: "Put all model logic in one massive if-else chain", outcome: { score: -30, codeQuality: -50, clientSatisfaction: -10, teamMorale: -20, explanation: "❌ Spaghetti code nightmare! Hard to test, maintain, and extend.", lesson: "Design patterns exist to prevent this. Factory and Strategy eliminate if-else chains." } }, { text: "Make clients send Python code to execute for predictions", outcome: { score: -60, codeQuality: -70, clientSatisfaction: -60, reputation: -40, budget: -3000, explanation: "❌ Catastrophic security vulnerability! Never execute arbitrary code from clients.", lesson: "APIs should expose functionality, not raw execution. Always validate user input." } } ] }, { id: 4, title: "Chapter 5: The Scaling Challenge", scenario: "Your API went viral! You're getting 1000 requests/second and the server is dying. How do you scale?", decisions: [ { text: "Implement caching (Redis), rate limiting, and load balancing with Observer monitoring", outcome: { score: 70, codeQuality: 50, clientSatisfaction: 60, reputation: 30, budget: -2000, teamMorale: 20, explanation: "✅ Production-ready! Caching reduces load, rate limiting prevents abuse.", lesson: "Scalability is a combination of caching, rate limiting, monitoring, and smart architecture." } }, { text: "Just buy a bigger server (vertical scaling)", outcome: { score: 20, codeQuality: -10, budget: -5000, explanation: "⚠️ Expensive short-term fix. Eventually you'll hit a ceiling.", lesson: "Scale horizontally (add servers) not just vertically. Design stateless APIs." } }, { text: "Add Singleton pattern everywhere to share resources", outcome: { score: -20, codeQuality: -30, clientSatisfaction: -20, explanation: "❌ Singleton for config is good, but overusing creates bottlenecks!", lesson: "Singleton is useful for configuration, but can prevent scaling across multiple servers." } }, { text: "Block all new users until traffic decreases", outcome: { score: -50, codeQuality: 0, clientSatisfaction: -70, reputation: -50, budget: -10000, explanation: "❌ You just killed your business! Turning away customers at peak time is terrible.", lesson: "Solve scaling with engineering, not by refusing service. Plan for growth!" } } ] }, { id: 5, title: "Chapter 6: The Documentation Disaster", scenario: "Developers are constantly emailing asking how to use your API. They're confused about endpoints and parameters. What do you do?", decisions: [ { text: "Use FastAPI's automatic OpenAPI/Swagger docs with examples", outcome: { score: 60, codeQuality: 40, clientSatisfaction: 70, reputation: 25, budget: 2000, teamMorale: 30, explanation: "✅ Perfect! Auto-generated docs are always up-to-date and interactive.", lesson: "Good documentation is key to API adoption. FastAPI's built-in docs are a competitive advantage." } }, { text: "Write comprehensive docs manually in a Word document", outcome: { score: 20, codeQuality: 10, clientSatisfaction: -10, teamMorale: -20, explanation: "⚠️ Better than nothing, but docs will quickly become outdated.", lesson: "Documentation that can't be tested becomes stale quickly. Auto-generation is the future." } }, { text: "Tell developers to 'read the source code'", outcome: { score: -40, codeQuality: -10, clientSatisfaction: -60, reputation: -35, budget: -3000, explanation: "❌ Terrible developer experience! Most developers won't read your source code.", lesson: "Documentation is not optional for APIs. It's the first impression." } }, { text: "Provide examples in a GitHub README only", outcome: { score: 10, codeQuality: 10, clientSatisfaction: -5, explanation: "⚠️ GitHub README is good for getting started, but not sufficient.", lesson: "README + Auto-generated docs = best combination. One for quick start, one for reference." } } ] } ]; const handleDecision = (decisionIndex) => { const chapter = chapters[gameState.chapter]; const decision = chapter.decisions[decisionIndex]; const outcome = decision.outcome; const newState = { ...gameState, score: Math.max(0, gameState.score + (outcome.score || 0)), codeQuality: Math.max(0, Math.min(100, gameState.codeQuality + (outcome.codeQuality || 0))), clientSatisfaction: Math.max(0, Math.min(100, gameState.clientSatisfaction + (outcome.clientSatisfaction || 0))), reputation: Math.max(0, Math.min(100, gameState.reputation + (outcome.reputation || 0))), budget: gameState.budget + (outcome.budget || 0), teamMorale: Math.max(0, Math.min(100, gameState.teamMorale + (outcome.teamMorale || 0))), decisions: [...gameState.decisions, { chapter: gameState.chapter, decisionText: decision.text, outcome: outcome }] }; if (outcome.score > 0) { newState.completedProjects++; } setCurrentDecision({ decision, outcome }); setGameState(newState); }; const nextChapter = () => { if (gameState.chapter < chapters.length - 1) { setGameState({ ...gameState, chapter: gameState.chapter + 1 }); setCurrentDecision(null); } else { setShowResults(true); } }; const restartGame = () => { setGameState({ chapter: 0, score: 0, codeQuality: 100, clientSatisfaction: 100, reputation: 50, budget: 10000, teamMorale: 100, decisions: [], completedProjects: 0 }); setShowResults(false); setCurrentDecision(null); }; const calculateGrade = () => { const { score, codeQuality, clientSatisfaction, reputation } = gameState; const totalScore = score + codeQuality + clientSatisfaction + reputation; if (totalScore >= 400) return { grade: 'A+', message: 'API Architect Master!' }; if (totalScore >= 350) return { grade: 'A', message: 'Excellent API Design!' }; if (totalScore >= 300) return { grade: 'B', message: 'Good API Skills!' }; if (totalScore >= 250) return { grade: 'C', message: 'Needs Improvement' }; return { grade: 'D', message: 'Review REST Principles' }; }; if (showResults) { const finalGrade = calculateGrade(); return (

Final Results

{finalGrade.grade}

{finalGrade.message}

Total Score
{gameState.score}
Code Quality
{gameState.codeQuality}%
Client Satisfaction
{gameState.clientSatisfaction}%
Reputation
{gameState.reputation}%
Budget
${gameState.budget.toLocaleString()}
Projects Completed
{gameState.completedProjects}/{chapters.length}

What You Learned

{gameState.decisions.map((decision, idx) => (

Chapter {decision.chapter + 1}: {chapters[decision.chapter].title}

{decision.decisionText}

{decision.outcome.lesson}

))}
); } const currentChapter = chapters[gameState.chapter]; return (

🚀 API Agency Simulator

Chapter {gameState.chapter + 1} / {chapters.length}
Score
{gameState.score}
Quality
{gameState.codeQuality}%
Clients
{gameState.clientSatisfaction}%
Reputation
{gameState.reputation}%
Budget
${(gameState.budget / 1000).toFixed(1)}k
Morale
{gameState.teamMorale}%
{!currentDecision ? ( <>

{currentChapter.title}

Make your decision wisely...

{currentChapter.scenario}

What do you do?

{currentChapter.decisions.map((decision, idx) => ( ))}
) : ( <>

Decision Outcome

{currentDecision.decision.text}

{currentDecision.outcome.explanation}

💡 Lesson Learned:

{currentDecision.outcome.lesson}

{currentDecision.outcome.score !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Score
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.score > 0 ? '+' : ''}{currentDecision.outcome.score}
)} {currentDecision.outcome.codeQuality !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Code Quality
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.codeQuality > 0 ? '+' : ''}{currentDecision.outcome.codeQuality}%
)} {currentDecision.outcome.clientSatisfaction !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Client Satisfaction
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.clientSatisfaction > 0 ? '+' : ''}{currentDecision.outcome.clientSatisfaction}%
)} {currentDecision.outcome.reputation !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Reputation
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.reputation > 0 ? '+' : ''}{currentDecision.outcome.reputation}%
)} {currentDecision.outcome.budget !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Budget
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.budget > 0 ? '+' : ''}${currentDecision.outcome.budget}
)} {currentDecision.outcome.teamMorale !== undefined && (
0 ? 'bg-green-100' : 'bg-red-100'}`}>
Team Morale
0 ? 'text-green-600' : 'text-red-600'}`}> {currentDecision.outcome.teamMorale > 0 ? '+' : ''}{currentDecision.outcome.teamMorale}%
)}
)}
); }; export default APIAgencySimulator;