Unit6 FullStack Capstone Notes
Unit6 FullStack Capstone Notes
🎯 Goal: By the end of Week 1, submit a Project Proposal Document that your teacher approves before
you start coding.
✅ Example 1
Three example problem statements for student projects:
Project Idea 1: Library Management
Problem: Students waste time searching for available books.
Solution: A web app where students search, reserve, and track
borrowed books online.
✅ Example 2
Features list for a Homework Tracker app:
Target Users: Class 9 students and their teachers
MUST HAVE:
✅ Student registration & login
✅ Add homework with subject, description, due date
✅ View all pending homework
✅ Mark homework as complete
SHOULD HAVE:
🔶 Filter homework by subject
🔶 Dashboard showing overdue items
🔶 Teacher can post assignments to whole class
COULD HAVE:
🔷 Email/SMS reminders before due date
🔷 Dark mode
Key screens to wireframe: Login page, Home/Dashboard, Main feature pages, Forms (Add/Edit), Error
pages.
✅ Example 3
Tech stack selection — choosing the right tools:
Tech Stack Decision Template:
FRONT-END:
Framework : [Link]
Styling : CSS / Tailwind CSS
Routing : React Router DOM
BACK-END:
Language : Python
Framework : Flask
Auth : Flask-JWT-Extended or Firebase Auth
DATABASE:
Option A : MySQL (for structured/relational data)
Option B : Firebase Firestore (for real-time/flexible data)
STORAGE:
Firebase Storage (for images/files)
DEPLOYMENT:
Front-end : Firebase Hosting / Vercel
Back-end : Render / Railway
VERSION CONTROL:
Git + GitHub
✅ Tip: Always start with the simplest tech stack that solves the problem. Don't add complexity you don't
need.
✏️Exercise 2
Create a Features List using MoSCoW for your app idea. List at least: 4 Must Have, 3 Should Have, 2
Could Have, and 2 Won't Have features. Justify each Must Have with one sentence.
✏️Exercise 3
Choose your Tech Stack: For your project, write down your chosen tech stack with one sentence
justifying each choice. Then draw (on paper) wireframes for at least 3 key screens of your app.
Entity: A real-world thing to store data about. E.g., Student, Teacher, Subject, Order.
Attribute: A property of an entity. E.g., Student has: id, name, email, class.
Relationship: How entities are connected. E.g., Student TAKES many Subjects.
✅ Example 1
ER Diagram for a Homework Tracker — entities and relationships:
Entities & Attributes:
USERS
user_id (PK), name, email, password_hash,
role ('student'|'teacher'), class, created_at
SUBJECTS
subject_id (PK), subject_name, teacher_id (FK→USERS)
HOMEWORK
hw_id (PK), title, description, subject_id (FK→SUBJECTS),
teacher_id (FK→USERS), due_date, created_at
SUBMISSIONS
sub_id (PK), hw_id (FK→HOMEWORK),
student_id (FK→USERS), submitted_at, status
Relationships:
USERS ──────< HOMEWORK (teacher posts many homework items)
SUBJECTS ───< HOMEWORK (subject has many homework items)
HOMEWORK ───< SUBMISSIONS (homework has many submissions)
USERS ──────< SUBMISSIONS (student makes many submissions)
✅ Example 2
MySQL Schema — CREATE TABLE statements with all constraints:
CREATE DATABASE homework_tracker;
USE homework_tracker;
✅ Example 3
Seed data — populating test data so you can develop and test:
-- Seed users
INSERT INTO users (name, email, password_hash, role, class) VALUES
('Mrs Sharma', 'sharma@[Link]', 'hashed_pw_1', 'teacher', NULL),
('Alice', 'alice@[Link]', 'hashed_pw_2', 'student', '9A'),
('Bob', 'bob@[Link]', 'hashed_pw_3', 'student', '9A');
-- Seed subjects
INSERT INTO subjects (subject_name, teacher_id) VALUES
('Mathematics', 1), ('Science', 1), ('English', 1);
-- Seed homework
INSERT INTO homework (title, description, subject_id, teacher_id, due_date) VALUES
('Algebra worksheet', 'Complete exercises 1-20', 1, 1, '2025-08-20'),
('Lab report', 'Write up experiment 3', 2, 1, '2025-08-22');
-- Verify
SELECT [Link], [Link], h.due_date
FROM homework h
JOIN users u ON h.teacher_id = u.user_id
JOIN subjects s ON h.subject_id = s.subject_id;
💡 Pro Tip: Always create seed data before building the front-end. Realistic test data helps you catch bugs
early and makes development much faster.
✏️Exercise 2
Write all CREATE TABLE statements for your project's database. Include: (a) appropriate data types, (b)
NOT NULL and UNIQUE constraints, (c) AUTO_INCREMENT primary keys, (d) FOREIGN KEY
references between tables.
✏️Exercise 3
Write seed data INSERT statements: Add at least 3 rows to each table. Make the data realistic and
connected (foreign keys must reference real records). Then write 3 SELECT queries to verify your seed
data is correct.
✅ Example 1
Flask app structure and basic GET/POST endpoints:
# [Link] — Flask back-end
from flask import Flask, jsonify, request
from flask_cors import CORS
import [Link], os
app = Flask(__name__)
CORS(app) # Allow React front-end to call this API
def get_db():
return [Link](
host=[Link]('DB_HOST','localhost'),
user=[Link]('DB_USER','root'),
password=[Link]('DB_PASS',''),
database='homework_tracker'
)
if __name__ == '__main__':
[Link](debug=True, port=5000)
✅ Example 2
Authentication endpoint — register and login with JWT:
# pip install flask-jwt-extended bcrypt
from flask_jwt_extended import JWTManager, create_access_token,
jwt_required, get_jwt_identity
import bcrypt
# REGISTER
@[Link]('/api/auth/register', methods=['POST'])
def register():
data = request.get_json()
email = [Link]('email','').strip()
password = [Link]('password','')
name = [Link]('name','')
if not email or not password or not name:
return jsonify({'error': 'All fields required'}), 400
pw_hash = [Link]([Link](), [Link]())
try:
conn = get_db()
cursor = [Link]()
[Link](
'INSERT INTO users (name,email,password_hash) VALUES (%s,%s,%s)',
(name, email, pw_hash.decode())
)
[Link](); [Link](); [Link]()
return jsonify({'message': 'Registered!'}), 201
except Exception as e:
return jsonify({'error': str(e)}), 409
# LOGIN
@[Link]('/api/auth/login', methods=['POST'])
def login():
data = request.get_json()
conn = get_db()
cur = [Link](dictionary=True)
[Link]('SELECT * FROM users WHERE email=%s', (data['email'],))
user = [Link]()
[Link](); [Link]()
if user and [Link](data['password'].encode(),
user['password_hash'].encode()):
token = create_access_token(identity=user['user_id'])
return jsonify({'token': token, 'name': user['name']}), 200
return jsonify({'error': 'Invalid credentials'}), 401
✅ Example 3
Data validation and error handling in Flask:
# Validation helper
def validate_homework(data):
errors = []
if not [Link]('title'):
[Link]('Title is required')
if len([Link]('title','')) > 100:
[Link]('Title must be under 100 characters')
if not [Link]('due_date'):
[Link]('Due date is required')
if not [Link]('subject_id'):
[Link]('Subject is required')
return errors
@[Link](500)
def server_error(e):
return jsonify({'error': 'Internal server error'}), 500
⚠️ Important: Always validate input on the back-end, even if you validate on the front-end. Never trust
data coming from the client.
✏️Exercise 2
Add authentication: Implement /api/auth/register and /api/auth/login endpoints. Use bcrypt to hash
passwords. Use JWT tokens to protect at least 3 of your endpoints. Test registering a user and logging
in.
✏️Exercise 3
Add data validation: Write a validation function for your main resource's POST and PUT endpoints.
Validate: (a) required fields are present, (b) string lengths are within limits, (c) numeric fields are positive,
(d) return clear error messages with 422 status.
TOPIC 4: Front-End Development
React components · Routing · API integration · State management
✅ Example 1
React Router — setting up page navigation:
// src/[Link]
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import LoginPage from './pages/LoginPage';
import RegisterPage from './pages/RegisterPage';
import Dashboard from './pages/Dashboard';
import HomeworkPage from './pages/HomeworkPage';
import Navbar from './components/Navbar';
function App() {
return (
<BrowserRouter>
<Navbar/>
<Routes>
<Route path='/login' element={<LoginPage/>}/>
<Route path='/register' element={<RegisterPage/>}/>
<Route path='/' element={
<PrivateRoute><Dashboard/></PrivateRoute>
}/>
<Route path='/homework' element={
<PrivateRoute><HomeworkPage/></PrivateRoute>
}/>
</Routes>
</BrowserRouter>
);
}
export default App;
✅ Example 2
API integration — calling the Flask back-end from React:
// src/services/[Link] — centralised API service
import axios from 'axios';
// src/pages/[Link]
import { useState, useEffect } from 'react';
import { getHomework, deleteHW } from '../services/api';
function HomeworkPage() {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
getHomework()
.then(res => setItems([Link]))
.catch(err => setError('Failed to load homework'))
.finally(()=> setLoading(false));
}, []);
return (
<div>
<h2>Homework ({[Link]})</h2>
{[Link](hw => (
<div key={hw.hw_id}>
<h3>{[Link]}</h3>
<p>Due: {hw.due_date}</p>
<button onClick={() => deleteHW(hw.hw_id)}>Delete</button>
</div>
))}
</div>
);
}
✅ Example 3
State management — AuthContext for global login state:
// src/context/[Link]
import { createContext, useContext, useState } from 'react';
import { loginUser } from '../services/api';
function logout() {
[Link]('token');
[Link]('user');
setUser(null);
}
return (
<[Link] value={{user, login, logout}}>
{children}
</[Link]>
);
}
✏️Exercise 2
Build the API service layer: (a) Create src/services/[Link] using axios, (b) Add the JWT interceptor, (c)
Export functions for all your API endpoints, (d) Test by calling one endpoint from a useEffect and
displaying results on screen.
✏️Exercise 3
Implement AuthContext: (a) Create AuthContext with login/logout functions, (b) Wrap [Link] with
AuthProvider, (c) Create a Login page that uses useAuth, (d) Create PrivateRoute that redirects to login
if not authenticated.
▶ Testing Levels
Unit Testing: Test one function or component in isolation.
Integration Testing: Test that multiple components work together (e.g., login flow: form → API → DB →
token → redirect).
End-to-End (E2E) Testing: Test the entire user journey in a real browser, as a real user would
experience it.
✅ Example 1
API testing checklist — test every endpoint:
Manual API Testing with Postman or curl:
AUTH ENDPOINTS:
✅ POST /api/auth/register
- with valid data → 201 + success message
- with duplicate email → 409 + error
- with missing fields → 400 + error
✅ POST /api/auth/login
- with correct credentials → 200 + JWT token
- with wrong password → 401 + error
- with unregistered email → 401 + error
HOMEWORK ENDPOINTS:
✅ GET /api/homework
- without token → 401 Unauthorized
- with valid token → 200 + array of homework
✅ POST /api/homework
- with valid data → 201 + new id
- with missing title → 422 + validation error
✅ DELETE /api/homework/<id>
- valid id → 200 + deleted message
- nonexistent id → 404 + not found
✅ Example 2
Common bugs and how to fix them:
BUG TYPE 1: CORS Error
Error: 'Access-Control-Allow-Origin' missing
Fix: Add CORS(app) in Flask, check allowed origins
from flask_cors import CORS; CORS(app)
✅ Example 3
End-to-end testing checklist and performance checks:
E2E USER JOURNEY TESTS:
CROSS-BROWSER TESTING:
✅ Chrome (primary)
✅ Firefox
✅ Edge
✅ Safari (if available)
✅ Mobile: Chrome on Android / Safari on iPhone
PERFORMANCE CHECKS:
✅ Open DevTools → Network tab
✅ API responses under 500ms
✅ No unnecessary API calls on every render
✅ Images are compressed
✅ No console errors or warnings
✏️ Exercises — Topic 5: Integration & Testing
✏️Exercise 1
API Testing: Using Postman, test EVERY endpoint in your API. For each endpoint test at least: (a) the
happy path (correct input → correct response), (b) missing fields → correct error, (c) invalid token →
401. Write down the results in a test report table.
✏️Exercise 2
Bug Hunt: Deliberately introduce 3 bugs into your code (e.g., remove token from header, use wrong field
name, skip commit()). Fix them using browser DevTools, [Link], and the Network tab. Document
what caused each bug and how you fixed it.
✏️Exercise 3
E2E Testing: Manually walk through 3 complete user journeys in your app. Test in Chrome AND Firefox.
Check mobile view using DevTools (F12 → mobile icon). List any issues found and fix them.
TOPIC 6: Deployment
Firebase Hosting / Render / Vercel · Environment variables · Domain setup
🚀 Deployment Strategy
Deployment means making your app available on the internet. A full-stack app has two parts to deploy:
the React front-end and the Flask back-end. Each part is deployed separately.
✅ Example 1
Deploying Flask back-end to Render:
# Step 1: Create [Link]
pip freeze > [Link]
# Must include:
flask
flask-cors
flask-jwt-extended
mysql-connector-python
bcrypt
gunicorn
# Step 4: On [Link]
# → New Web Service → Connect GitHub repo
# → Build Command: pip install -r [Link]
# → Start Command: gunicorn app:app
# → Add Environment Variables (DB_HOST, DB_USER, etc.)
# → Deploy!
✅ Example 2
Environment variables — keeping secrets safe:
# .env file (LOCAL development only — NEVER commit to Git!)
DB_HOST=localhost
DB_USER=root
DB_PASS=mypassword
DB_NAME=homework_tracker
JWT_SECRET=my-super-secret-key-change-this
# In code:
const API_URL = [Link].REACT_APP_API_URL;
✅ Example 3
Deploying React front-end to Vercel and connecting domains:
# Option A: Vercel (easiest for React)
npm install -g vercel
vercel login
vercel # follow prompts — auto-detects React
# Live at: [Link]
# Option B: Firebase Hosting
npm run build
firebase init hosting
firebase deploy
# Live at: [Link]
⚠️ Important: Never put database passwords, API keys, or JWT secrets directly in your code or push
them to GitHub. Always use environment variables.
✏️Exercise 2
Deploy your React app to Vercel or Firebase Hosting: (a) Set REACT_APP_API_URL to your Render
URL, (b) Build and deploy, (c) Verify the live app connects to the live API, (d) Test the full login and main
feature flow on the live URL.
✏️Exercise 3
Environment variable audit: (a) Check your codebase for any hardcoded passwords or secrets, (b) Move
them to .env files, (c) Add .env to .gitignore, (d) Set all required variables in both Render and Vercel
dashboards. Verify the app still works.
✅ Example 1
Presentation slide structure (8-10 slides recommended):
Slide 1: Title slide
- Project name, your name, class, date
✅ Example 2
Live demo script — what to show and say:
DEMO SCRIPT:
OPEN: 'I'll now show you the live application at [URL]'
TIPS:
✅ Use realistic-looking test data
✅ Have the app open before starting
✅ Practice the demo 5+ times
✅ Have a backup video if live demo fails
✅ Example 3
Project Documentation — what to include in your report:
PROJECT REPORT STRUCTURE:
1. COVER PAGE
Project name, student name, class, date, teacher
3. PROBLEM STATEMENT
Detailed description of the problem and target users
4. FEATURES LIST
Complete list of implemented features (MoSCoW format)
5. TECH STACK
Each technology used with justification
6. DATABASE DESIGN
ER diagram + all CREATE TABLE statements
7. API DOCUMENTATION
Table of all endpoints: Method | URL | Auth? | Request | Response
8. SCREENSHOTS
Key screens: login, dashboard, main features, mobile view
9. DEPLOYMENT
Live URL, deployment platform, how to run locally (setup guide)
✅ Tip: Practice your full presentation (slides + demo + likely Q&A questions) at least 3 times before the
exhibition. Time yourself — aim for under 12 minutes total.
✏️Exercise 2
Write and rehearse your demo script: Write out exactly what you will say and do during the live demo.
Practice it 5 times. Record yourself once and watch it back. Fix any parts where you stumbled.
✏️Exercise 3
Complete your project report and GitHub README: (a) Write the full project report following the structure
above, (b) Create a [Link] in your GitHub repo with: project description, screenshots, tech stack,
setup instructions, and live URL.
Unit 6: Full Stack Capstone Project | Class 9 | 7 Weeks | Plan well. Build well. Ship it. 🚀