Project Overview
Senior Capstone
This is the final project. No architecture is provided. No database schema. No API design. No implementation guidance.
The Challenge
Build a globally scalable marketplace supporting:
- Millions of users
- Thousands of sellers
- Search and recommendations
- Real-time inventory
- Orders and payments
- Notifications
- Analytics
- Administrative tooling
Your Deliverables
- Requirements document
- Architecture design
- Capacity estimation
- Database design
- API design
- Frontend architecture
- Backend architecture
- Authentication and authorization
- Caching strategy
- Messaging and background processing
- Search implementation
- Security plan
- Testing strategy
- Deployment plan
- Monitoring and alerting
- Disaster recovery plan
- Scaling strategy
- Cost considerations
- Architecture tradeoffs document
- Working implementation of core features
What This Tests
- Independent engineering judgment
- System design ability
- Tradeoff analysis
- Production thinking
- Communication skills
- Technical depth and breadth
Architecture — What Goes Where and Why
Project Architecture
Before writing any code, let's understand what files we need and where they go. Think of this like a blueprint for a house — you don't start building without a plan.
The File Tree
Every project needs a folder structure. Here is ours:
├── server.js
├── database.js
├── src/App.tsx
├── docker-compose.yml
├── .github/workflows/
├── monitoring/
What Each File Does
Let me explain each file like you're 5 years old:
server.js — Production API server
Complete backend with auth, API routes, error handling, and monitoring.
database.js — Database layer
Production database with pooling, migrations, and health checks.
src/App.tsx — Frontend application
Complete React/Astro frontend with all pages and components.
docker-compose.yml — Container orchestration
Runs all services: app, database, cache, reverse proxy.
.github/workflows/ — CI/CD pipeline
Automated testing, building, and deployment.
monitoring/ — Observability
Prometheus metrics, Grafana dashboards, alerting rules.
Why This Structure?
You might wonder: why use folders at all? Why not put everything in one place?
Because as projects grow, you might have:
- Multiple CSS files
- Many JavaScript files
- Images, fonts, and other assets
If they're all in one folder, it's chaos. Folders keep things organized.
// BAD — everything in one folder
index.html
styles.css
main.css
dark.css
app.js
utils.js
helper.js
// GOOD — organized in folders
index.html
css/
styles.css
main.css
js/
app.js
utils.js
The Golden Rule
When you start a project, ALWAYS:
- Create the folder structure FIRST
- Then fill in the files one by one
- Never write everything in one giant file
This is how professional developers work. Always.
Step 1 — Project Setup (Creating the Empty House)
Setting Up the Project
We are going to create an empty project from scratch. This is the exact process professional developers use every single day.
Open Your Terminal
Your terminal (also called "command line" or "console") is where you type commands to talk to your computer.
- Mac: Open "Terminal" app
- Windows: Open "PowerShell" or "Command Prompt"
- VS Code: Press Ctrl+` (backtick) to open the built-in terminal
Step-by-Step Commands
Type each of these commands, one at a time, pressing Enter after each:
mkdir capstone-project && cd capstone-project && git init && npm init -y
What Just Happened?
Let me explain each command like you're 5:
mkdir [folder] — "Make a new box." This creates a folder on your computer.
cd [folder] — "Go inside the box." Now when you type commands, they happen inside this folder.
git init — "Start keeping a diary." Git will now track every change you make. If you break something, you can go back in time.
npm init -y — "Create an ID card for this project." It creates package.json with default settings. The -y means "yes to all questions."
touch [file] — "Create an empty file." Think of it as a blank piece of paper.
Verify It Worked
Type this command to see your files:
ls -la
The .gitignore File
Open .gitignore and add this:
node_modules/
.DS_Store
*.log
.env
Why? Because node_modules can be HUGE — thousands of files. We don't want to save all of them in Git. We can always recreate them with npm install.
Your First Git Commit
Now save everything to Git:
git add .
git commit -m "Initial project setup"
Congratulations! You just set up a project like a real developer.
Step 2 — Building the Core (Step by Step)
Building the Application
Now let's build the application step by step. Follow each step in order.
Build Steps
- Choose your capstone project from the roadmap
- Design the architecture (draw it on paper first)
- Set up the project structure and tooling
- Build the backend API with all features
- Build the frontend with all pages
- Add authentication and authorization
- Write comprehensive tests (unit, integration, E2E)
- Set up CI/CD pipeline
- Add Docker containerization
- Set up monitoring and logging
- Write comprehensive documentation
- Deploy to production
- Prepare presentation and demo
- Commit and deploy
How Each Step Works
Step 1 — Create the entry point
Every application starts with an entry file. This is the file that runs first when someone opens your app.
Think of it like the front door of a house. Everything starts when you walk through it.
Step 2 — Set up the structure
Before writing features, we set up the basic layout. This is like putting up the walls before painting them.
Step 3 — Add the main functionality
Now we add what makes the app actually DO something. This is the "brain" of the application.
Step 4 — Connect everything
We wire the pieces together. The HTML connects to CSS. The JavaScript connects to HTML. Everything talks to each other.
Step 5 — Test and fix
We try everything, find bugs, and fix them. Real developers spend 30% of their time testing.
Save and Test
After each step, save your files and refresh the browser. If something breaks, check the browser console (F12 → Console tab).
Commit after each major step:
git add .
git commit -m "Describe what you just built"
Pro Tip
Build in small steps. Don't write 100 lines and then test. Write 10 lines, test, fix, then write 10 more. This catches errors early when they're easy to fix.
Requirements Gathering
Gathering Requirements
Functional Requirements
Before writing any code, answer:
- Who are the users? (customers, sellers, admins)
- What can they do? (browse, buy, sell, manage)
- What are the core flows? (search → add to cart → checkout → delivery)
- What are the edge cases? (out of stock, payment failure, returns)
- What are the integration points? (payment providers, shipping, email)
Non-Functional Requirements
| Requirement | Target |
|---|---|
| Availability | 99.9% |
| Latency | < 200ms for reads |
| Throughput | 10k RPS |
| Data consistency | Eventual consistency OK |
| Durability | No data loss |
| Security | PCI compliance for payments |
Capacity Estimation
Users: 10M registered, 1M daily active
Products: 5M listings
Orders: 100K per day
Search queries: 500K per day
Storage: ~10TB (images, videos)
Bandwidth: ~100GB per day
Architecture Decision Records
# ADR: Database Choice
## Context
We need to store product catalog, user data, and orders.
## Decision
Use PostgreSQL for transactional data (orders, users).
Use MongoDB for product catalog (flexible schema).
Use Elasticsearch for search.
## Alternatives
- All PostgreSQL: simpler but less flexible for catalog
- All MongoDB: less suitable for transactional integrity
## Consequences
- Two databases to maintain
- Need data synchronization between systems
- Better suited to each use case
Self-Evaluation
Evaluating Your Design
Architecture Scorecard
| Dimension | Score / 10 | Notes |
|---|---|---|
| Requirements coverage | ||
| Scalability | ||
| Reliability | ||
| Security | ||
| Maintainability | ||
| Cost efficiency | ||
| Complexity management | ||
| Tradeoff documentation | ||
| Code quality | ||
| Testing |
Questions to Justify
- Why did you choose this database?
- Why not microservices for this component?
- How does your system handle failure?
- What is the biggest bottleneck and how do you address it?
- What would you do differently with 10x the traffic?
- What would you cut if you had half the time?
- How do you ensure data consistency across services?
- What monitoring would you add in production?
- How do you handle deployments without downtime?
- What is your disaster recovery strategy?
The Goal
The goal is not to build a perfect system. The goal is to demonstrate independent engineering judgment — the ability to make reasonable decisions, justify them, and acknowledge tradeoffs.
Common Mistakes (What Goes Wrong)
Mistakes Everyone Makes
Every developer makes these mistakes. Knowing them ahead of time saves hours of debugging.
Mistake 1: Forgetting to Connect Files
<!-- WRONG — CSS is not linked, page looks ugly -->
<link rel="stylesheet" href="style.css">
<!-- RIGHT — file path matches actual location -->
<link rel="stylesheet" href="css/styles.css">
How to check: Right-click the page → Inspect → Network tab → look for red (failed) resources.
Mistake 2: JavaScript Before HTML
<!-- WRONG — JavaScript runs before HTML exists -->
<script src="app.js"></script>
<body>...</body>
<!-- RIGHT — JavaScript runs after HTML loads -->
<body>...</body>
<script src="app.js"></script>
Mistake 3: Not Using preventDefault()
// WRONG — page reloads when you submit
form.addEventListener('submit', () => {
// This code runs, but then the page reloads!
});
// RIGHT — preventDefault stops the reload
form.addEventListener('submit', (e) => {
e.preventDefault(); // Now the page doesn't reload
});
Mistake 4: Modifying State Without Re-rendering
// WRONG — changes data but screen stays the same
todos.push(newTodo);
// RIGHT — always update the screen after changing data
todos.push(newTodo);
render(); // Now the screen shows the new todo
Mistake 5: Not Handling Empty Input
// WRONG — adds empty tasks
addTodo(""); // Adds a blank todo
// RIGHT — check for empty input
if (text.trim()) {
addTodo(text);
}
Mistake 6: Ignoring Errors
How to check for errors:
- Press F12 in your browser
- Click "Console" tab
- Look for red text
- Click on it to see what went wrong
If you see red text, DON'T IGNORE IT. That's the computer telling you something is broken.
Debugging Checklist
When something doesn't work:
- Check the console — F12 → Console (red text = error)
- Check the Network — F12 → Network (red lines = failed requests)
- Check file paths — Are CSS/JS files in the right folder?
- Check spelling — Typos in IDs, class names, function names
- Check the basics — Is the server running? Is the URL correct?
The 5-Minute Rule
If you've been stuck for 5 minutes:
- Stop
- Re-read the error message
- Search the error on Google/Stack Overflow
- If still stuck, ask for help
Don't waste hours on something that might be a simple typo.
Testing Everything Works
Testing Your App
A real developer NEVER assumes code works. They TEST it.
Why Test?
- Users will find every bug you missed
- Bugs found later cost 10x more to fix
- Testing gives you confidence to make changes
Manual Testing Checklist
Go through this checklist for EVERY feature:
□ Page loads without errors (check browser console — F12)
□ All buttons work when clicked
□ All forms submit correctly
□ Input validation works (empty, special characters)
□ Data saves and loads correctly
□ Responsive on mobile (resize browser)
□ No console errors
□ All links work
□ Loading states appear during API calls
□ Error messages show when things fail
How to Check for Errors
Press F12 in your browser. Click the "Console" tab.
- Empty = Good! No errors.
- Red text = Bad. Click it to see what went wrong.
Edge Cases to Test
Real users do weird things. Test these:
- Empty input — What happens if you submit nothing?
- Very long input — Paste a 1000-character string
- Special characters — Type < > & " ' / 4. Rapid clicking — Click a button 10 times fast
- No internet — Turn off WiFi and try
- Refresh mid-action — Reload while something is happening
Browser Testing Tools
| Tool | How to Open | What It Shows |
|---|---|---|
| Console | F12 → Console | JavaScript errors and logs |
| Network | F12 → Network | API requests and responses |
| Elements | F12 → Elements | Live HTML and CSS |
| Device Mode | Ctrl+Shift+M | Mobile screen simulation |
Git Commit
After testing, commit your work:
git add .
git commit -m "Complete [project name] with testing"
What You Just Learned
Summary — Skills You Now Have
Technical Skills
- Project Structure — You know how to organize files in folders
- Git — You can initialize, add, commit, and push
- Version Control — You can track changes and go back in time
- HTML/CSS/JavaScript — You can build interactive web pages
- DOM Manipulation — You can change what's on screen with code
- Event Handling — You can respond to clicks, inputs, and other actions
- State Management — You can track and update application data
- Debugging — You can find and fix errors using browser tools
- Testing — You can verify your app works correctly
Thinking Skills
- Architecture — You planned the project BEFORE writing code
- Problem Solving — You broke a big problem into small steps
- Debugging — You systematically found and fixed errors
- Documentation — You wrote notes for future you (and other developers)
The Pattern
Every frontend application follows this pattern:
State (data) → Render (draw) → Event (respond) → Update State → Render again
React, Vue, Angular, Svelte — they ALL do this. You just learned the fundamental pattern that powers the entire web.
What's Next?
Look at the next project in the roadmap. Each new project builds on what you learned here. The skills compound — every project makes you a better developer.
Remember: every expert was once a beginner who didn't give up.
Quick Reference
Quick Reference
File Overview
- server.js: Production API server
- database.js: Database layer
- src/App.tsx: Frontend application
- docker-compose.yml: Container orchestration
- .github/workflows/: CI/CD pipeline
- monitoring/: Observability
Setup Commands
mkdir capstone-project && cd capstone-project && git init && npm init -y
Common Patterns
// Select an element
const el = document.getElementById('myId');
// Add event listener
el.addEventListener('click', (e) => {
e.preventDefault();
});
// Update the DOM
el.innerHTML = '<p>New content</p>';
el.textContent = 'Text only';
Debugging
F12 → Console → Check for errors
F12 → Network → Check API requests
F12 → Elements → Inspect HTML/CSS
Ctrl+Shift+M → Mobile view
Git Commands
git init # Start a repo
git add . # Stage all changes
git commit -m "message" # Save changes
git push # Upload to GitHub
Quiz
1. What is an ADR?
2. What is the most important quality in a senior engineer?
Flashcards
Question
What is capacity estimation?
Click to reveal answer
Answer
Estimating system requirements (storage, bandwidth, QPS) based on expected scale
Question
What is a tradeoff?
Click to reveal answer
Answer
A decision where improving one aspect requires accepting a cost in another (e.g., consistency vs availability)
Revision Notes
Key Takeaways
- 1.Requirements gathering is the first engineering step
- 2.Architecture decisions need documentation
- 3.Tradeoffs are inevitable — document and justify them
- 4.Production readiness requires more than working code
- 5.Self-evaluation demonstrates maturity
Interview Tips
- •Present your architecture to a peer
- •Defend your database choice
- •Explain what you would change with different constraints
Cheat Sheet
Capstone Evaluation
ADR Template
# ADR: [Decision]
## Context
[Why this decision is needed]
## Decision
[What was decided]
## Alternatives
[What else was considered]
## Consequences
[What this means going forward]
Scorecard
Architecture / 10, Code / 10, Testing / 10, Security / 10, Documentation / 10