THE FUTURE MARKETACADEMY
Your classroomRoom 07 · Tech Lab
School of Data & Tech

Web Engineering: architecture, security and team practice

What you'll be able to do
  • Split an app into clear layers, draw its trust boundaries and run a threat model with your team before you build.
  • Choose a written security standard for your team (OWASP ASVS), and connect it to the NIST secure development practices and CISA's Secure by Design principles.
  • Harden the browser side with output encoding, a stronger Content Security Policy and security headers, and roll changes out safely.
  • Test like a professional team: edge cases, time-based rules, login abuse and coverage gates that stop a weak change.
  • Treat accessibility (WCAG 2.2) as an engineering standard, with automated smoke tests and manual checks.
  • Protect your software supply chain, set up review rules and lead secure code reviews.
  • Run an app responsibly: useful security logs without secrets, safe error messages, a way for people to report vulnerabilities and a plan for data breaches.
  • Lead and teach: write team standards, run a review session and coach others to apply them.

This is the expert level of the Web Development track. All the code in this course was tested with Node.js 22.23 on a computer: 18 automated tests passed, the coverage gate was run both passing and failing, and every command-line tool was run on sample files. Like course 7.7.3, it uses only modules built into Node.js. This course is defence only: it teaches you to build, test and run your own apps safely. It never teaches how to attack anyone else's system. Data protection rules differ by country, so they appear in "In your country" boxes. This is education, not legal advice.

Words in this course 80Open the Vocabulary Hall
01

Architecture you can explain and defend

In simple words

A house has rooms with different jobs: a kitchen, a bedroom, a storeroom. Some doors are locked, and the front door is where strangers come in. A good architect can point at the plan and say what each room is for and where every lock is. A good app has a plan like that too.

Before this course: Full-Stack Basics: servers, databases and deployment (course 7.7.3). You should already have built and deployed "Study Notes": a Node.js JSON API with input checks and a body size limit, a SQLite database with prepared statements, scrypt password hashing, session cookies with HttpOnly and SameSite, ownership checks on every note, 9 automated tests, and settings in environment variables. Now you stop being the only developer. In this course you design, secure, test and run an app the way a professional team does, and you learn to teach those habits to others.

Key facts
  • Layers keep each part of the code to one job:
  • The HTTP layer (routes) reads requests and writes responses: status codes, headers, JSON.
  • The service layer holds the rules: what a valid note is, who may delete it.
  • The data layer (a repository) talks to the database and nothing else.
  • Pass dependencies in instead of creating them inside. In course 7.7.3, createApp({ db }) let tests use an in-memory database. The same idea at the service layer lets tests use a fake repository, so the rules can be tested in milliseconds with no database at all.
  • An architecture decision record (ADR) is a short note a team keeps for each important choice: the context, the decision and its consequences. New people can then see why the code looks the way it does.
  • A trust boundary is a place where data moves between parts you trust differently: browser to server, server to database, your server to another company's API. Every boundary needs checks.
  • OWASP Top 10 (2025) includes A06 Insecure Design. OWASP says design flaws and coding bugs have different root causes and different fixes, and that "an insecure design cannot be fixed by a perfect implementation".
  • Threat modeling (OWASP Threat Modeling Cheat Sheet) asks four questions: "What are we working on?", "What can go wrong?", "What are we going to do about it?" and "Did we do a good enough job?"
  • STRIDE is a checklist of six kinds of threat, each breaking one security property:
ThreatBreaksStudy Notes exampleOur defence
SpoofingAuthenticationSomeone logs in as another userSlow salted hashes, login throttle (Lesson 4)
TamperingIntegrityA request changes someone else's noteOwnership check in the service layer
RepudiationAccounting"I never deleted that note"Security log of who did what (Lesson 7)
Information disclosureConfidentialityNotes or errors leak to the wrong person404 for others' notes, generic errors
Denial of serviceAvailabilityHuge requests or endless login triesBody size limit, throttling
Elevation of privilegeAuthorizationA normal user reaches admin actionsDeny by default, checks on the server
  • A data flow diagram shows the processes, data stores, external entities, data flows and trust boundaries. OWASP says threat modeling is best done early, during design, and kept up to date as the system changes.
Example (service layer with a fake repository, tested)
// Service layer: business rules only. No HTTP, no SQL.
// The repository (data layer) is passed in, so tests can use a fake one.
function createNotesService({ repo }) {
 function cleanText(text) {
  if (typeof text !== "string") return null;
  const t = text.trim();
  if (t.length < 1 || t.length > 2000) return null;
  return t;
 }
 return {
  list(userId) {
   return repo.findByOwner(userId);
  },
  create(userId, text) {
   const t = cleanText(text);
   if (!t) return { ok: false, error: "Note must be 1 to 2000 characters." };
   return { ok: true, note: repo.insert(userId, t) };
  },
  remove(userId, noteId) {
   // Ownership is checked here, once, for every caller.
   return repo.deleteOwned(userId, noteId) === 1;
  },
 };
}

// A tiny in-memory repository with the same methods as the SQL one.
function memoryRepo() {
 const rows = []; let nextId = 1;
 return {
  findByOwner: (u) => rows.filter((r) => r.userId === u),
  insert(u, text) { const r = { id: nextId++, userId: u, text }; rows.push(r); return r; },
  deleteOwned(u, id) {
   const i = rows.findIndex((r) => r.id === id && r.userId === u);
   if (i === -1) return 0;
   rows.splice(i, 1); return 1;
  },
 };
}

module.exports = { createNotesService, memoryRepo };
const test = require("node:test");
const assert = require("node:assert");
const { createNotesService, memoryRepo } = require("../src/notes-service");

test("creates a note for its owner", () => {
 const s = createNotesService({ repo: memoryRepo() });
 const r = s.create(1, " buy milk ");
 assert.strictEqual(r.ok, true);
 assert.strictEqual(r.note.text, "buy milk");
 assert.strictEqual(s.list(1).length, 1);
});

test("rejects empty and huge notes", () => {
 const s = createNotesService({ repo: memoryRepo() });
 assert.strictEqual(s.create(1, "  ").ok, false);
 assert.strictEqual(s.create(1, "x".repeat(2001)).ok, false);
 assert.strictEqual(s.create(1, 42).ok, false);
});

test("a user cannot delete someone else's note", () => {
 const s = createNotesService({ repo: memoryRepo() });
 const n = s.create(1, "mine").note;
 assert.strictEqual(s.remove(2, n.id), false);
 assert.strictEqual(s.list(1).length, 1);
 assert.strictEqual(s.remove(1, n.id), true);
 assert.strictEqual(s.list(1).length, 0);
});

Test result: all 3 tests passed. The HTTP layer from course 7.7.3 now only calls service.remove(user.id, id) and turns false into a 404. The ownership rule lives in one place.

Step by step
  1. Draw Study Notes as boxes: Browser, Node.js server, SQLite file. Add arrows for each data flow (sign-up, login, list notes, delete note).
  2. Draw a dashed line at every trust boundary. Check: there is at least one between the browser and the server, and one between the server and the database.
  3. Create src/notes-service.js and test/notes-service.test.js from the example, then run node --test. You should see 3 passing tests.
  4. With one or two classmates, ask the four threat modeling questions out loud, one at a time.
  5. Fill in a STRIDE table for your own app: one real example and one defence for each letter.
  6. Write one ADR (half a page): "We keep ownership checks in the service layer", with context, decision and consequences.
  7. Check: someone new can read your diagram and ADR and explain where the ownership rule lives, without opening the code.
Watch on YouTube
Quick threat modeling of a simple web app with STRIDENetSec · YouTube · youtube.com

Videos by other creators on YouTube, for reference. They are not made by or affiliated with The Future Market.

LESSON 01Architecture you can explain and defend
LESSON 01 / ANIMATED LESSON / AI VOICE00:00 / 01:15
Read the video script
[Host] "A good architect can point at the plan and say what every room is for. Can you do that for your app?"
[Screen: three boxes labelled HTTP layer, Service layer, Data layer] "Routes talk HTTP. The service holds the rules. The repository talks to the database. One job each."
[Screen: dashed trust boundary between browser and server] "Draw the trust boundaries. Every line where data crosses needs a check."
[Text on screen: What are we working on? What can go wrong? What will we do? Did we do enough?] "Then ask the four threat modeling questions, early, with your team."
[Text on screen: An insecure design cannot be fixed by a perfect implementation] "Because perfect code can't save a broken design."
Try it now

Run a 30-minute threat modeling session on your own app with at least one other person. Produce a data flow diagram with trust boundaries, a STRIDE table with six rows and three new tasks for your backlog.

ClaudeStuck? Copy a ready-made prompt for Claude

Copy this, open Claude, paste it, and Claude will walk you through the lesson step by step.

For a grown-up: Claude is for adults (18+). Copy this, paste it into Claude, and use the answer to explain the lesson to your child.

I'm learning "Web Engineering: architecture, security and team practice" on The Future Market. Lesson 1: "Architecture you can explain and defend".

What the lesson teaches:
- Layers keep each part of the code to one job:
- The HTTP layer (routes) reads requests and writes responses: status codes, headers, JSON.
- The service layer holds the rules: what a valid note is, who may delete it.
- The data layer (a repository) talks to the database and nothing else.
- Pass dependencies in instead of creating them inside. In course 7.7.3, createApp({ db }) let tests use an in-memory database. The same idea at the service layer lets tests use a fake repository, so the rules can be tested in milliseconds with no database at all.
- An architecture decision record (ADR) is a short note a team keeps for each important choice: the context, the decision and its consequences. New people can then see why the code looks the way it does.
- A trust boundary is a place where data moves between parts you trust differently: browser to server, server to database, your server to another company's API. Every boundary needs checks.

The exercise I'm working on:
Run a 30-minute threat modeling session on your own app with at least one other person. Produce a data flow diagram with trust boundaries, a STRIDE table with six rows and three new tasks for your backlog.

I'm stuck. Please:
1. Explain the main idea in plain, simple words with one everyday example.
2. Walk me through the exercise one small step at a time. Ask me what I've done so far before giving the next step.
3. Don't just give me the final answer. Help me do it myself, and check my work when I share it.
I'm a parent helping my child (about 8 years old) with a lesson called "Architecture you can explain and defend" from the course "Web Engineering: architecture, security and team practice".

Here's what the lesson says:
A house has rooms with different jobs: a kitchen, a bedroom, a storeroom. Some doors are locked, and the front door is where strangers come in. A good architect can point at the plan and say what each room is for and where every lock is. A good app has a plan like that too.

The activity:
Run a 30-minute threat modeling session on your own app with at least one other person. Produce a data flow diagram with trust boundaries, a STRIDE table with six rows and three new tasks for your backlog.

Please explain this so an 8-year-old understands: short sentences, a fun everyday example, and no hard words.
Then give me 3 simple questions I can ask my child to check they understood, and a way to do the activity together, one tiny step at a time.
Open Claude
Sources
My notes
02

A written security standard for your team

This lesson is part of full access: every course and every level for one payment.

03

Harden the browser side

This lesson is part of full access: every course and every level for one payment.

04

Test like a team: edge cases, time and gates

This lesson is part of full access: every course and every level for one payment.

05

Accessibility as an engineering standard

This lesson is part of full access: every course and every level for one payment.

06

Supply chain, review rules and secure code review

This lesson is part of full access: every course and every level for one payment.

07

Run it safely: logs, errors, reports and breaches

This lesson is part of full access: every course and every level for one payment.

08

Lead the team: standards, reviews and teaching

This lesson is part of full access: every course and every level for one payment.

++

Final project

This lesson is part of full access: every course and every level for one payment.

??

Quiz

  1. What are the three layers used in this course, and what does each do?

  2. What is a trust boundary?

  3. What are the four threat modeling questions?

  4. Which ASVS level does OWASP say most applications should aim for?

  5. Name the four practice groups of the NIST SSDF.

  6. What is the main defence against cross-site scripting, and what is CSP's role?

  7. Why roll out a new CSP with Content-Security-Policy-Report-Only first?

  8. Why should the login failure counter belong to the account and not the IP address?

  9. What does a coverage gate do, and what can it not tell you?

  10. Why should a login form allow paste and password managers?

  11. What should you do if a real secret was committed to Git?

  12. Which four things should every security log event record, and what must it never contain?

EX

Final exam

This lesson is part of full access: every course and every level for one payment.

CE

Certificate

This lesson is part of full access: every course and every level for one payment.