← Build · all briefsBrief 5 · after "Connect the market" · demo next class
Brief 5

Vendor admin

A page for the market's organisers and vendors: add a stall, edit it, mark it sold out, remove it. The routes that change stalls need a token in an Authorization header, and the server says no in five different ways. The public page shows the changes on its next load. ★★★

“Churros just restocked. Can somebody take the sold-out sign off?”

You'll demo (next class): with the admin token, add "Crêpe Escape", mark Mezcal Moon as no longer sold out, delete a stall. Then each error: no token and a made-up token (401), Taco Bike's vendor token on Mezcal Moon (403), a duplicate name (409), a price of -3 (422).

The core (start in class if you've connected, the minimum for the demo)

Four things, on top of your connected market. They count when they work with chaos on (control page).

The full feature (finish at home)

What has to work for the demo next class, not how. The core above is part of it.

Requests

  • The separate page starter/admin.html (open localhost:8080/admin.html), with its own module js/admin.js.
  • A token field; the token is kept in sessionStorage and sent as Authorization: Bearer ….
  • POST a stall, PATCH fields (sold out is a checkbox), DELETE with a confirmation.

States

  • The stall list as a table, with loading, error and empty states.
  • Each row's buttons are disabled while that row has a request in flight.
  • After every success the table shows the server's version of the row.

Errors

  • 401 (no token, or an invalid one) → "Enter a valid token" and focus the token field. 403 (a valid vendor token, the wrong stall) → "This token can't edit Mezcal Moon".
  • 422 → field messages next to the fields. 409 → "A stall with that name exists".
  • 404 on PATCH or DELETE (someone else deleted it) → the row disappears with a note.

New tool: sessionStorage: like localStorage, forgotten when the tab closes.

The endpoints you need

MethodPathAnswers
POST/api/stalls201 + Location · 401 · 403 (vendor token) · 409 · 422 { fields }
PATCH/api/stalls/:id200 · 401 · 403 (another vendor's stall) · 404 · 422
DELETE/api/stalls/:id204 · 401 · 403 · 404
GET/api/stalls200 · no token needed

Tokens: harbour-admin-2026 may do everything; vendor-<stall id> (e.g. vendor-taco-bike) may only PATCH its own stall. They're printed here because this is a course server; a real token comes from a login and never appears in your code.

Edge cases (with chaos on, minutes 38–43)

Stretch, if you're done early

Stuck? One hint at a time

Network panel first: is the request sent, with what, and what came back? Then a hint.

Hint 1

Every admin request needs the same header. How many places in your code should know how to add it?

Hint 2

PATCH: what do you send, the whole stall or only what changed? What does the API's contract say?

Hint 3

A 401 and a 403 both mean "no". After which one should the user type a different token, and after which one should they ask someone else?

Traps

Open when something behaves strangely

Before you start

This brief assumes Connect the market is done: api.js works, the stalls come from the API, loading and errors are handled. Then: PATCH /api/stalls/mezcal with { "soldOut": false } answers 401 without the header and 200 with it.

Demo · next class, 3 minutes

Your 3 minutes
  1. The happy path, with the Network panel open next to the page.
  2. Chaos on: the loading state, one failure, and how the page recovers.
  3. One request in code: the call, the status codes you handle, where the state changes.
  4. One bug you hit, and the panel or the message that showed it to you.