{
  "date": "2026-09-29",
  "chapters": [
    {
      "id": "setup",
      "number": "0+",
      "title": "Get your computer ready.",
      "subtitle": "Before Week 1 \u00b7 terminal, Node, an editor, git, and a first server",
      "source": "Week 1 course page (Express project, Postman, Now You Try flow), the Node version in the Week 3 notes, and the Week 3 prep page. Terminal, editor and git basics are general usage. Example output was captured on one Mac.",
      "learn": true
    },
    {
      "id": "javascript",
      "number": "JS",
      "title": "Learn the language first.",
      "subtitle": "Before Week 1 \u00b7 values, objects, functions, callbacks, modules, await, and errors",
      "source": "General JavaScript usage, not course text. Examples reuse this guide\u2019s pizza order, books and products. Every example and every output shown was run with Node 24 on one Mac.",
      "learn": true
    },
    {
      "id": "foundations",
      "number": "01",
      "title": "A request becomes a response.",
      "subtitle": "Week 1 \u00b7 HTTP, Node, Express, forms, and JSON",
      "source": "Week 1 course page, both local Express activities, and the Week 1 study plan.",
      "learn": true
    },
    {
      "id": "typescript",
      "number": "02",
      "title": "Types describe your assumptions.",
      "subtitle": "TypeScript basics \u00b7 the book catalog exercise",
      "source": "TypeScript README, src/index.ts, its study plan, and type usage in Weeks 2\u20134/HW1.",
      "learn": true
    },
    {
      "id": "syntax",
      "number": "2+",
      "title": "Read any line.",
      "subtitle": "After TypeScript basics \u00b7 twelve shapes, the delete-the-types trick, and reading red errors",
      "source": "Class exercise code from Weeks 2, 3, 4 and 6, quoted from pinned snapshots of those repos. Every error and the test failure were made by typing the mistake into a copy of a class repo and running tsc 7.0 or Vitest 5.0 with Node 24 on one Mac.",
      "learn": true
    },
    {
      "id": "middleware",
      "number": "03",
      "title": "Order is part of the behavior.",
      "subtitle": "Week 2 \u00b7 routers, middleware, services, and first tests",
      "source": "Week 2 course page, books-router.ts, books-service.ts, app/index, tests, and its study plan.",
      "learn": true
    },
    {
      "id": "homework",
      "number": "04",
      "title": "Put the pieces together: SliceDrop.",
      "subtitle": "Homework 1 \u00b7 menu, role checks, order validation, and errors",
      "source": "Local HW1 implementation, all four test files, README, and the complete TEACHING_GUIDE.",
      "learn": true
    },
    {
      "id": "mongo",
      "number": "05",
      "title": "Move state into a database.",
      "subtitle": "Week 3 \u00b7 MongoDB, BSON, CRUD, ids, and Express integration",
      "source": "Full supplied Week 3 notes; db-explore.ts, db.ts, product-router.ts, validate-id.ts, tests, and study plan.",
      "learn": true
    },
    {
      "id": "rest",
      "number": "06",
      "title": "Design the public contract.",
      "subtitle": "Week 4 \u00b7 REST, representations, and controller\u2013service layers",
      "source": "Full supplied Week 4 notes (including \u201cWrite the tests\u201d), the Week 4 post-class memo, local source/test refinements, and Week 4 study plan.",
      "learn": true
    },
    {
      "id": "tests",
      "number": "07",
      "title": "Make the evidence repeatable.",
      "subtitle": "Weeks 2\u20134 + HW1 \u00b7 Vitest, Supertest, database isolation, and matchers",
      "source": "Week 2/HW1 tests, full Week 3/4 testing sections, and both Mongo test setups.",
      "learn": true
    },
    {
      "id": "mocks",
      "number": "7+",
      "title": "Mock the dependency. Test the rule.",
      "subtitle": "Week 5 \u00b7 layers, one PATCH request, test kinds, Vitest, and mocks",
      "source": "Week 5 notes (Testing), captured October 6, 2026, and the Vitest guide to mock functions. The Python example was not run.",
      "learn": true
    },
    {
      "id": "hw2",
      "number": "HW2",
      "title": "Homework 2: plan it before you build it.",
      "subtitle": "HW2 \u00b7 SliceDrop with MongoDB: what each task asks, where the course taught it, how to check yourself",
      "source": "The public HW2 instructions, read October 14, 2026 and linked, not retained, and class exercise code from the Week 4 and Week 6 repos, quoted from pinned snapshots. No homework code appears.",
      "learn": true
    },
    {
      "id": "auth",
      "number": "W6",
      "title": "Know who is asking. Decide what they may do.",
      "subtitle": "Week 6 \u00b7 passwords, bcrypt, JWTs, roles, and ownership checks",
      "source": "Week 6 notes (Auth), captured October 13, 2026. The composed tests were run with Vitest 5.0 against the Week 6 starter.",
      "learn": true
    },
    {
      "id": "practice",
      "number": "08",
      "title": "Try it before revealing it.",
      "subtitle": "Practice lab \u00b7 trace, predict, write, and check",
      "source": "Practice adapted from the linked NYT tasks and the six existing guides.",
      "learn": false
    },
    {
      "id": "recall",
      "number": "09",
      "title": "Close the notes. Explain it.",
      "subtitle": "Active recall \u00b7 42 questions with answer reveals",
      "source": "Consolidated self-checks from every topic.",
      "learn": false
    },
    {
      "id": "reference",
      "number": "10",
      "title": "The desk reference.",
      "subtitle": "Commands, ports, status codes, troubleshooting, and vocabulary",
      "source": "Scripts and source in the current seven local projects, plus course notes.",
      "learn": false
    },
    {
      "id": "sources",
      "number": "11",
      "title": "Every topic has a trail.",
      "subtitle": "Coverage, original guides, and source library",
      "source": "Current course pages, local files, and retained guides. Original guide prose is preserved.",
      "learn": false
    }
  ],
  "original_guides": [
    "Classes/si-679-f-26-ts-basics-kelvintiger/STUDY_PLAN.md",
    "Classes/si-679-f-26-week1-nyt-kelvintiger/STUDY_PLAN.md",
    "Classes/si-679-f-26-week02-nyt-kelvintiger/STUDY_PLAN.md",
    "Homework/si-679-f-26-hw1-kelvintiger/TEACHING_GUIDE.md",
    "Classes/si-679-f-26-week03-nyt-kelvintiger/STUDY_PLAN.md",
    "Classes/si-679-f-26-week-04-nyt-kelvintiger/STUDY_PLAN.md"
  ],
  "course_urls": [
    "https://umich-mia.atlassian.net/wiki/external/MmNjZTg1NDkyNDQzNDM1MDg1OTI2NTRmZmE3MzEzMTA",
    "https://umich-mia.atlassian.net/wiki/external/YmI3NWJkMDkzOGJmNDMyZjkyYzdlZWYwYTQ4MDU4Y2U",
    "https://si679-public.github.io/weeks/week03-mongo-integration/week03-notes",
    "https://si679-public.github.io/weeks/week04-rest/week04-notes#write-the-tests",
    "https://si679-public.github.io/weeks/week03-mongo-integration/prep",
    "https://si679-public.github.io/weeks/week04-rest/post-class-memo",
    "https://si679-public.github.io/weeks/week05-testing/week05-notes",
    "https://si679-public.github.io/weeks/week06-auth-rbac/week06-notes",
    "https://si679-public.github.io/hw/hw2-instructions"
  ],
  "coverage": [
    {
      "source": "Week 1 \u00b7 Getting started / first route / routes",
      "topics": "Node/npm/ESM/watch, Express app/listen, method+path, response APIs",
      "anchor": "foundations"
    },
    {
      "source": "Week 1 \u00b7 POST / forms / form middleware",
      "topics": "action/method/name, req.body, URL-encoded parser, ZIP text",
      "anchor": "request-inputs"
    },
    {
      "source": "Week 1 \u00b7 Query strings / route params / errors",
      "topics": "req.query/params, decoding, numeric guards, 400/default 200",
      "anchor": "request-inputs"
    },
    {
      "source": "Week 1 \u00b7 NYT #1",
      "topics": "catalog, play, getform/submitform, browse",
      "anchor": "week1-activities"
    },
    {
      "source": "Week 1 \u00b7 Postman / JSON / NYT #2",
      "topics": "postData, hithere, tracks/error/timestamp, products AND keywords",
      "anchor": "week1-activities"
    },
    {
      "source": "TypeScript basics \u00b7 all six tasks",
      "topics": "Interface, annotation, enum, signatures, union/narrowing, generic",
      "anchor": "typescript"
    },
    {
      "source": "Class exercise repos, Weeks 2\u20136",
      "topics": "Delete the types: colons, angle brackets, type lines, as const",
      "anchor": "syn-delete-types"
    },
    {
      "source": "Class exercise repos, Weeks 2\u20136",
      "topics": "The twelve shapes, by how often they appear in the course\u2019s .ts files",
      "anchor": "syn-shapes"
    },
    {
      "source": "Class exercise repos, Weeks 2\u20136",
      "topics": "Controller anatomy, res.status().json(), .js imports, describe/it/expect, Supertest",
      "anchor": "syn-extras"
    },
    {
      "source": "tsc on a copy of a class repo",
      "topics": "Nine real TypeScript errors and how to read each part",
      "anchor": "syn-errors"
    },
    {
      "source": "Vitest on a copy of a class repo",
      "topics": "One real test failure, line by line",
      "anchor": "syn-vitest"
    },
    {
      "source": "Class exercise repos \u00b7 review",
      "topics": "The blank-file drill",
      "anchor": "syn-drill"
    },
    {
      "source": "Week 2 \u00b7 Setting up TS / routing / NYT #1",
      "topics": "NodeNext/build/dev/typecheck, Router/service, combined exact filters",
      "anchor": "week2-setup"
    },
    {
      "source": "Week 2 \u00b7 HTTP headers / middleware",
      "topics": "Header metadata/case/custom values, logger, auth, route order",
      "anchor": "middleware-order"
    },
    {
      "source": "Week 2 \u00b7 Errors / statuses / NYT #2",
      "topics": "Four-argument handler, badroute, 201, GET by id, PATCH body id",
      "anchor": "week2-routes"
    },
    {
      "source": "Week 2 \u00b7 Supertest / app split / state leaks / NYT #3",
      "topics": "Request chains, reset, body/text assertions, auth/filter/delete cases",
      "anchor": "week2-setup"
    },
    {
      "source": "HW1 \u00b7 complete local implementation and guide",
      "topics": "Menu/filter, two roles, exact parser, all order validation, state/errors/tests",
      "anchor": "homework"
    },
    {
      "source": "Week 3 \u00b7 What is Mongo / NoSQL / BSON",
      "topics": "SQL tradeoffs, collection/document/field, nesting/types, server vs driver",
      "anchor": "mongo-vocabulary"
    },
    {
      "source": "Week 3 \u00b7 Database / starter / connection",
      "topics": "Compass/mongosh, URI, client/db/collection/ping/disconnect, watch duplicates",
      "anchor": "mongo-connect"
    },
    {
      "source": "Week 3 \u00b7 Inserts / finds / queries / updates / deletes",
      "topics": "insertOne/Many, cursor/findOne, ObjectId, comparisons, $set/results/options",
      "anchor": "mongo-crud"
    },
    {
      "source": "Week 3 \u00b7 NYT #1 + stretch",
      "topics": "Pricier products, Scotch price, Masking deletion, onSale many update",
      "anchor": "mongo-activities"
    },
    {
      "source": "Week 3 \u00b7 Express / DB / router / app / server / Postman",
      "topics": "All CRUD routes, connection before listen, type shapes and statuses",
      "anchor": "mongo-api"
    },
    {
      "source": "Week 3 \u00b7 Live DB tests / temporary Mongo / matchers",
      "topics": "Cross-run and cross-test contamination, hooks, matchers/rejections",
      "anchor": "tests"
    },
    {
      "source": "Week 3 \u00b7 NYT #2 + stretch",
      "topics": "PATCH preserved fields/404, DELETE 200/404, malformed-id middleware tests",
      "anchor": "practice-mongo"
    },
    {
      "source": "Week 4 \u00b7 REST / principles / scenario",
      "topics": "Six constraints, representation, entities/fields/endpoints/policy boundaries",
      "anchor": "rest-design"
    },
    {
      "source": "Week 4 \u00b7 Architecture / build GET / all layers",
      "topics": "Layer responsibilities, imports, converters, map, glue/errors/startup",
      "anchor": "controller-service"
    },
    {
      "source": "Week 4 \u00b7 Build POST / DB/model/service/controller/router / Postman",
      "topics": "Partial, ??, insertedId, 201/id, readback/Compass, troubleshooting",
      "anchor": "rest-post-delete"
    },
    {
      "source": "Week 4 \u00b7 NYT #1 + DELETE stretch",
      "topics": "GET single/404/public id, delete count/readback, controller HTTP decision",
      "anchor": "week4-activities"
    },
    {
      "source": "Week 4 \u00b7 Supertest / temporary DB / init / hooks / seed / assertions",
      "topics": "App vs startup boundary, direct DB fixtures, matcher examples",
      "anchor": "test-lifecycle"
    },
    {
      "source": "Week 4 \u00b7 NYT #2 / Write the tests / DELETE stretch tests",
      "topics": "Exact requested-object/404 tests; successful/absent deletion and list state",
      "anchor": "worked-tests"
    },
    {
      "source": "Week 1 \u00b7 Create an Express project / Postman setup / Classroom50 flow",
      "topics": "npm init, express@latest, type module, start script, localhost:3000, accept/clone/push",
      "anchor": "setup-project"
    },
    {
      "source": "Week 3 prep \u00b7 Install / start / verify MongoDB",
      "topics": "Community Edition, mongosh, Compass, service or --dbpath, port 27017, admin/config/local",
      "anchor": "setup-mongodb"
    },
    {
      "source": "Week 4 \u00b7 Post-class memo",
      "topics": "add() line order, defaults before insert, placeholder id beside _id, destructuring with rest, id-only return, revised NYT #2",
      "anchor": "week4-memo-bug"
    },
    {
      "source": "Week 5 \u00b7 The app you\u2019ve been given / Following one request",
      "topics": "Folder roles, repository translation, app vs index",
      "anchor": "w5-layers"
    },
    {
      "source": "Week 5 \u00b7 Router / controller / service / repository / model",
      "topics": "PATCH path, ??, find then validate then write, findOneAndUpdate, layer guarantees",
      "anchor": "w5-patch-path"
    },
    {
      "source": "Week 5 \u00b7 A brief digression into error handling",
      "topics": "ValidationError, error handler 400/500, null as 404, absent vs malformed id",
      "anchor": "w5-outcomes"
    },
    {
      "source": "Week 5 \u00b7 Unit testing / regression / integration",
      "topics": "Unit, integration, end-to-end and regression; fakes, mocks and spies named",
      "anchor": "w5-test-kinds"
    },
    {
      "source": "Week 5 \u00b7 Before anything else / Streamlining test running",
      "topics": "npm install/test, test:unit and test:e2e filters, --passWithNoTests, it.todo",
      "anchor": "w5-tools"
    },
    {
      "source": "Week 5 \u00b7 E2E testing / Test #1 to #3",
      "topics": "Arrange, act, assert; a new value unlike the seed; matchers",
      "anchor": "w5-aaa"
    },
    {
      "source": "HW2 instructions \u00b7 Overview / Your repo does not compile",
      "topics": "Memory to MongoDB, one folder per layer, async validation, the two typecheck errors",
      "anchor": "hw2-changes"
    },
    {
      "source": "HW2 instructions \u00b7 What you build / Endpoints / Status code summary",
      "topics": "Each task\u2019s layer, its lesson and its status codes",
      "anchor": "hw2-task-map"
    },
    {
      "source": "Class exercise repos, Weeks 4 and 6",
      "topics": "Repository, 409, 204, guard order, a req.query filter, Express 5 error forwarding",
      "anchor": "hw2-patterns"
    },
    {
      "source": "HW2 instructions \u00b7 Tips / Grading",
      "topics": "Typecheck first, one layer and one suite at a time, reading failures, the 120 points",
      "anchor": "hw2-build-order"
    },
    {
      "source": "Class code and this guide \u00b7 review",
      "topics": "Six questions an instructor might ask, answered from class code",
      "anchor": "hw2-explain"
    },
    {
      "source": "Week 6 \u00b7 Auth and Auth",
      "topics": "Authentication and authorization, shared secrets in HW1 and HW2, the five routes",
      "anchor": "w6-two-questions"
    },
    {
      "source": "Week 6 \u00b7 Passwords, briefly / Hashing / bcrypt",
      "topics": "One-way hash, salt, cost, the parts of a bcrypt string, HTTPS",
      "anchor": "w6-hashing"
    },
    {
      "source": "Week 6 \u00b7 What you\u2019ve been given",
      "topics": "User, NewUser and PublicUser; the users repository",
      "anchor": "w6-user-shapes"
    },
    {
      "source": "Week 6 \u00b7 Registering a user",
      "topics": "registerUser, ConflictError and 409, the error handler, controller and route",
      "anchor": "w6-register"
    },
    {
      "source": "Week 6 \u00b7 Logging in",
      "topics": "bcrypt.compare, one message for both failures, why a token is needed",
      "anchor": "w6-login"
    },
    {
      "source": "Week 6 \u00b7 Tokens and JWTs / What\u2019s in a JWT",
      "topics": "Header, payload, signature, base64url, claims, jwt.io",
      "anchor": "w6-jwt"
    },
    {
      "source": "Week 6 \u00b7 Where the secret lives / Signing a token at login",
      "topics": ".env and .env.example, --env-file, config.ts, the test secret, restarting the dev server, dotenv",
      "anchor": "w6-secret"
    },
    {
      "source": "Week 6 \u00b7 Checking the token: requireJwt middleware / GET /auth/me",
      "topics": "Bearer header, jwt.verify, res.locals.user, 401",
      "anchor": "w6-require-jwt"
    },
    {
      "source": "Week 6 \u00b7 Writing a test together / Now You Try #1",
      "topics": "Tokens signed in the test: missing, not a JWT, wrong secret, expired, edited, real login",
      "anchor": "w6-token-tests"
    },
    {
      "source": "Week 6 \u00b7 Roles in the token / Only staff: requireRole / Testing with npm test",
      "topics": "Seeded staff user, role claim, middleware factory, guard order, 401 and 403 and 201, staff and customer test tokens",
      "anchor": "w6-roles"
    },
    {
      "source": "Week 6 \u00b7 Ownership: what roles can\u2019t say / Testing ownership",
      "topics": "getUser in the service, why not middleware, the caller, GET /users/:id tests",
      "anchor": "w6-ownership"
    },
    {
      "source": "Week 6 \u00b7 A unit test for the service / How the unit test earns its place / Now You Try #2",
      "topics": "Spy on findUser, check before lookup, the id leak, four more unit tests",
      "anchor": "w6-check-first"
    },
    {
      "source": "Week 6 \u00b7 Wrapping up",
      "topics": "HTTPS, revocation, stale roles, refresh, reset, auth providers",
      "anchor": "w6-limits"
    },
    {
      "source": "Week 6 notes \u00b7 review",
      "topics": "Twelve practice questions and three tasks",
      "anchor": "w6-practice"
    }
  ],
  "additions": [
    {
      "date": "2026-10-04",
      "source": "https://si679-public.github.io/weeks/week03-mongo-integration/prep",
      "snapshots": [
        "source-snapshots/week03-prep.html.txt",
        "source-snapshots/week03-prep.txt"
      ],
      "note": "Public Week 3 prep page, added as the source for the setup chapter MongoDB topic. HTML bytes as served; text is the main-content extract."
    },
    {
      "date": "2026-10-04",
      "source": "https://si679-public.github.io/weeks/week04-rest/post-class-memo",
      "snapshots": [
        "source-snapshots/week04-memo.html.txt",
        "source-snapshots/week04-memo.txt"
      ],
      "note": "Public Week 4 post-class memo, added as the source for the week4-memo-bug topic and the revised Now You Try #2. HTML bytes as served; text is the main-content extract."
    },
    {
      "date": "2026-10-06",
      "source": "https://si679-public.github.io/weeks/week05-testing/week05-notes",
      "snapshots": [
        "source-snapshots/week05.html.txt",
        "source-snapshots/week05.txt"
      ],
      "note": "Public Week 5 notes (Testing), added as the source for chapter 7+ (mocks). HTML bytes as served; text is the main-content extract. The Vitest guide to mock functions (https://vitest.dev/guide/learn/mock-functions.html) is linked, not retained."
    },
    {
      "date": "2026-10-13",
      "source": "https://si679-public.github.io/weeks/week06-auth-rbac/week06-notes",
      "snapshots": [
        "source-snapshots/week06.html.txt",
        "source-snapshots/week06.txt"
      ],
      "note": "Public Week 6 notes (Auth), added as the source for chapter W6 (auth). HTML bytes as served; text is the main-content extract, including the text inside collapsed blocks."
    },
    {
      "date": "2026-10-14",
      "source": "Class exercise repos for Weeks 2, 3, 4 and 6 (the course posts these solutions publicly)",
      "snapshots": [
        "source-snapshots/week02-code-src-__tests__-books.test.ts.txt",
        "source-snapshots/week02-code-src-books-router.ts.txt",
        "source-snapshots/week03-code-src-__tests__-products-changes.test.ts.txt",
        "source-snapshots/week04-code-src-services-product-service.ts.txt",
        "source-snapshots/week06-code-src-__tests__-auth.e2e.test.ts.txt",
        "source-snapshots/week06-code-src-app.ts.txt",
        "source-snapshots/week06-code-src-config.ts.txt",
        "source-snapshots/week06-code-src-controllers-auth-controller.ts.txt",
        "source-snapshots/week06-code-src-controllers-products-controller.ts.txt",
        "source-snapshots/week06-code-src-controllers-users-controller.ts.txt",
        "source-snapshots/week06-code-src-db-products-repository.ts.txt",
        "source-snapshots/week06-code-src-db-users-repository.ts.txt",
        "source-snapshots/week06-code-src-errors.ts.txt",
        "source-snapshots/week06-code-src-middleware-error-handler.ts.txt",
        "source-snapshots/week06-code-src-middleware-require-jwt.ts.txt",
        "source-snapshots/week06-code-src-middleware-require-role.ts.txt",
        "source-snapshots/week06-code-src-models-user.ts.txt",
        "source-snapshots/week06-code-src-routes-products-router.ts.txt",
        "source-snapshots/week06-code-src-services-auth-service.ts.txt",
        "source-snapshots/week06-code-src-services-products-service.ts.txt"
      ],
      "note": "Each file quoted in chapter 2+ (syntax), copied byte for byte. scripts/check-si679.py checks every class-code block in that chapter against these lines."
    },
    {
      "date": "2026-10-14",
      "source": "Class exercise repo for Week 4 (the course posts these solutions publicly)",
      "snapshots": [
        "source-snapshots/week04-code-src-controllers-product-controllers.ts.txt",
        "source-snapshots/week04-code-src-routes-product-routes.ts.txt"
      ],
      "note": "Each new file quoted in chapter HW2 (hw2), copied byte for byte. Its Week 6 quotes reuse the chapter 2+ snapshots. scripts/check-si679.py checks every class-code block in that chapter against these lines."
    }
  ]
}
