Home / MAD1 + MAD2
MAD1 + MAD2, learned as one story
Every MAD2 idea sits on a MAD1 idea. This page lays the two courses side by side and gives one order to learn them in.
One app, two courses
Imagine a restaurant. MAD1 builds the whole restaurant in one building: the kitchen (Flask and the database), the menu cards printed fresh for each guest (Jinja2 templates), and a waiter who walks the card to the table (the browser getting a ready-made page). MAD2 turns it into a modern chain: the kitchen becomes a service window that only hands out ingredients (a JSON API), a tablet at each table (a Vue app in the browser) builds the menu by itself, a ticket system remembers who is allowed in (tokens), a back-room team prepares big orders without making guests wait (Celery and Redis), and a warming shelf keeps popular dishes ready (caching).
Same restaurant, same food, one big idea moved: who builds the page, the server or the browser.
The full-stack map
| Layer | MAD1 (server builds the page) | MAD2 (browser builds the page) |
|---|---|---|
| Talking | HTTP requests and responses (week 1) | the same HTTP, now carrying JSON (week 5) |
| Page structure | HTML and CSS (week 2) | HTML inside Vue templates (week 4) |
| Filling the page | Jinja2 on the server (week 3) | Vue directives in the browser (week 4), components (week 6) |
| Data | SQLite and SQLAlchemy (week 4) | the same database, hidden behind the API |
| Logic | Flask routes (week 5) | Flask API plus Vue methods |
| Contract | REST API and OpenAPI (week 6) | API design, tokens (week 8) |
| Speed | indexes, FTS, caching idea (week 7) | Redis cache, measuring (week 11) |
| Interactivity | a little JavaScript, fetch (week 8) | all of it: JavaScript (weeks 1 and 2), Vue, Vuex (week 7) |
| Safety | sessions, login, attacks (week 9) | tokens, CORS, cookies (week 8) |
| Quality | pytest (week 10) | tests plus performance checks |
| Shipping | Git, WSGI, servers (week 12) | Flask + Vue + Redis + Celery together (week 12) |
| Background work | cron and batch ideas (week 7) | Celery workers and beat (week 9), webhooks and email (week 10) |
The recommended order
- MAD1 weeks 1 to 6: build the server-side app. Do not skip week 4 (database design): every later week reuses it.
- MAD1 week 8 (JavaScript and fetch) before MAD2 week 1, even if you have finished all of MAD1: it is the doorway.
- MAD1 weeks 7, 9, 10, 11, 12 (backend systems, security, testing, HTML5, deployment): they are the "grown-up" topics that MAD2 builds on.
- MAD2 weeks 1 to 3 (JavaScript, async, frontend ideas), then weeks 4 to 7 (Vue, APIs, components, Vuex), then week 8 (tokens, API design), then weeks 9 to 11 (Celery, messaging, performance), and finally week 12 (the project).
Both Quiz 1 and Quiz 2 of each course reuse earlier weeks. The past papers show that fundamentals such as HTTP, HTML, CSS and SQL keep coming back even in later quizzes, so revise the early weeks on the day before every exam.
Five ideas that cross both courses
1. Request and response. Everything in both courses is a browser asking and a server answering. If you can say what is in a request (method, URL, headers, body) and a response (status code, headers, body), you can explain 80 percent of the rest.
2. Separation of concerns (MVC). MAD1: models (SQLAlchemy), views (Jinja2), controllers (Flask routes). MAD2 keeps the same split but moves the "view" into the browser (Vue) and keeps "model + controller" in Flask behind the API.
3. Stateless servers. HTTP forgets you after each request. MAD1 fixes this with sessions and cookies; MAD2 adds tokens. Both are answers to "how does the server know who you are?".
4. Do slow work somewhere else. Indexes (MAD1), cache (MAD1, MAD2), Celery workers (MAD2): all ways of not making the user wait.
5. Trust nothing from the client. Validate on the server, check roles on the server, hash passwords on the server. This is the answer to half of the security and viva questions.
Three problems that cross both courses
A Flask route @app.route("/books") returns a rendered HTML page in MAD1. (a) What must change so that a Vue app can use the same data? (b) What does the Vue side do with the response?
Need a hint?
Think about the response body and the Content-Type.
Show the full solution
(a) Return JSON instead of HTML: for example return jsonify([{"id": 1, "title": "Dune"}]) (or a Flask-RESTful Resource returning a list), with the header Content-Type: application/json. (b) Vue calls the URL with fetch or axios (usually in the mounted hook), turns the response into a JavaScript array (response.json()), stores it in data, and the template loops over it with v-for. The server no longer builds HTML; the browser does.
A user logs in. (a) In MAD1 with Flask sessions, what is sent back and what does the browser do next? (b) In MAD2 with a token, what is different?
Need a hint?
Where is the state kept?
Show the full solution
(a) The server signs a session cookie and sends it in Set-Cookie. The browser stores it and sends it automatically with every later request to that site; the server reads it to know the user. (b) The server returns a token in the response body (for example a JWT or a Flask-Security authentication token). The Vue app stores it (memory or localStorage) and sends it itself in a header such as Authentication-Token or Authorization: Bearer .... Tokens suit APIs consumed by JavaScript or other apps; cookies are sent automatically, which is why cookie-based logins need CSRF protection.
A page lists 50 products and takes 2 seconds because the query scans a large table every time. Give three ways to speed it up, in the order you would try them.
Need a hint?
Start closest to the data.
Show the full solution
- Index the column used in
WHERE,JOINorORDER BY, and select only the columns you need (MAD1 week 7). 2. Cache the query result with an expiry (TTL), for example in Redis with Flask-Caching, and invalidate it when the data changes (MAD2 week 11). 3. Move heavy work out of the request: precompute or export it with a Celery task and let the page read the finished result (MAD2 week 9). Measure before and after (for example the browser network tab) so you know which step helped.
Short on time?
Crash path for the viva (about a week). Day 1: MAD1 weeks 1 and 5 (HTTP, Flask routes). Day 2: MAD1 weeks 3 and 4 (Jinja2, SQL, SQLAlchemy). Day 3: MAD1 weeks 6 and 9 (REST, security). Day 4: MAD2 weeks 4 to 6 (Vue basics, components, router). Day 5: MAD2 weeks 7 and 8 (Vuex, tokens). Day 6: MAD2 weeks 9 and 11 (Celery, caching). Day 7: the project guide and a mock viva.