Courses Learn Blog Contact
Get Started →
Lesson 20

Day 20: Project 4 - Work Like a Developer

A vague client brief, a team of five, and the full process: interview, scope, issues, branches, review, deploy early, and present in the client's language.

Webbo3 Level 2: JavaScript Development 12 min read Free

Webbo3 Level 2 · JavaScript Development · Day 20 of 20

Project 4: Work Like a Developer

A client brief, a team of five, and everything from the last four weeks in one build. The closest thing to a real sprint we can give you.

By the end of today you can

  • Take a vague brief from a non-technical client and turn it into scoped work
  • Break that work into issues and run it through branches and pull requests
  • Build, review, test and deploy as a team
  • Present to the client rather than to your instructor

Project 2 asked whether five of you could solve a problem together. This one asks whether you can work for somebody.

The difference is that you no longer choose what matters. A client does, and they will describe what they want in words that are not requirements.

The Brief

Project 4 · Groups of Five · The Full Week

A small business currently manages customer requests through WhatsApp and a spreadsheet. Messages get missed, two people reply to the same customer, and nobody can say how many requests are outstanding. Build a web application that helps them manage requests.

That is what a real brief looks like: a problem described by somebody who is not going to tell you what to build. Notice what it does not say. It does not say what a request contains, who the users are, what "manage" means, or what happens when a request is finished. Those gaps are the work.

Your Instructor Is Playing the Client

Ask them anything, and they will answer as the business owner would: in business terms, sometimes vaguely, occasionally changing their mind. Booking that conversation is the first task, and teams that skip it build the wrong thing on day one.

1. Before Any Code: Understand and Scope

Definition

Scoping is turning a problem into a written list of what you will build, what you will not, and what you are assuming, agreed with the client before any code is written.

Real-Life Example

A carpenter asked for "a cupboard" asks where it goes, how tall the room is and what will be kept in it, then writes down the size and price before cutting any wood. Without that, they build a beautiful cupboard that does not fit through the door.

Types: The Questions to Actually Ask

  1. Walk me through the last request you handled, from the message arriving to it being finished.
  2. Who touches a request? Just you, or staff as well?
  3. What is in a request? What do you need to know about it?
  4. What does "finished" mean? Is there anything between new and finished?
  5. What goes wrong most often right now?
  6. If this only did one thing well, what would that thing be?

The last question is the most valuable, and it is the one that protects you. The answer is your Critical priority, and everything else is ranked below it.

What this code doesWe want the interview turned into a written agreement: the problem in the client's words, the one thing, what is in, what is out, and what we assumed.
SCOPE.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Request Manager: Scope

## The problem, in the client's words
"Messages get lost in WhatsApp. Two of us reply to the same person. I cannot
tell you how many jobs are open right now."

## The one thing it must do well
Show every open request in one place, and who is handling it.

## In scope
- Log a request: customer name, phone, what they want, date received
- Statuses: new, in progress, done
- Assign a request to a staff member
- Filter by status and by assignee; search by customer
- A count of what is open, always correct
- Persists; works on a phone, because that is what they use

## Out of scope, agreed with the client
- Reading from WhatsApp directly. No API access, and not achievable this week.
- Accounts and passwords. No backend.
- Invoicing.

## Assumptions we are making
- Fewer than 200 open requests at a time, so filtering locally is fine
- Two to four staff, entered by hand rather than managed
NOTE   
Commit this before any code. Every later disagreement is settled by reading it.
The Out-of-Scope List Is What Protects the Team

When the client says on Thursday "can it also send them a text", the answer is not yes and it is not no. It is: that is outside what we agreed, here is what it would cost, shall we swap it for something? That sentence is one of the most professionally useful things in this entire course.

The One Thing, Running

Here is the Critical priority as a first working slice: every open request in one place, who is handling it, and a count that is derived, never stored (Day 15). "Take it" assigns a request to the person using the app, and a taken request cannot be taken again, which is the "two of us reply to the same person" problem solved.

What this code doesWe want the one-thing-it-must-do working: Amaka takes the first request and marks the second done, and the open count and the owners update from the state.
index.html
1
2
<p id="open-count"></p>
<ul id="requests"></ul>
style.css
1
2
li { margin: 4px 0; }
.who { color: #555; }
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
const me = 'Amaka';

const state = {
  requests: [
    { id: 1, customer: 'Mrs Bello', want: 'Two cakes for Saturday', status: 'new', owner: null },
    { id: 2, customer: 'Tunde', want: 'Price for 50 cupcakes', status: 'new', owner: null },
    { id: 3, customer: 'Ngozi', want: 'Change delivery address', status: 'in progress', owner: 'Femi' },
  ],
};

function render() {
  // Derived on every render: never stored
  const open = state.requests.filter((request) => request.status !== 'done');
  document.querySelector('#open-count').textContent = `${open.length} open requests`;

  const list = document.querySelector('#requests');
  list.replaceChildren();
  for (const request of state.requests) {
    const item = document.createElement('li');
    item.textContent = `${request.customer}: ${request.want} (${request.status}) `;

    const who = document.createElement('span');
    who.className = 'who';
    who.textContent = 'nobody yet';
    if (request.owner) who.textContent = `handled by ${request.owner}`;
    item.append(who);

    // Finished requests get no buttons
    if (request.status !== 'done') {
      // Only an unowned request can be taken, so nobody doubles up
      if (!request.owner) item.append(button('Take it', 'take', request.id));
      item.append(button('Done', 'done', request.id));
    }
    list.append(item);
  }
}

// A small helper that builds one action button
function button(label, action, id) {
  const element = document.createElement('button');
  element.textContent = label;
  element.dataset.action = action;
  element.dataset.id = id;
  return element;
}

// One listener for every button in the list
document.querySelector('#requests').addEventListener('click', (event) => {
  const clicked = event.target.closest('button');
  if (!clicked) return;
  const request = state.requests.find((item) => item.id === Number(clicked.dataset.id));

  if (clicked.dataset.action === 'take') {
    request.owner = me;
    request.status = 'in progress';
  }
  if (clicked.dataset.action === 'done') request.status = 'done';
  render();
});

render();
BROWSERindex.html · after Amaka took request 1 and finished request 2
Picture This

Picture the carpenter measuring the doorway first. The cupboard that fits is the one that was scoped.

2. The Process

Definition

The process is the agreed path every piece of work takes from idea to live site. It is what lets five people change one codebase without breaking each other's work.

Real-Life Example

A restaurant kitchen: orders on tickets, one station per dish, and the head chef checks each plate before it leaves the pass. Nobody wanders in and adds salt to someone else's pot.

StageOutput
1. Interview the clientNotes, and the one-thing-it-must-do answer
2. ScopeSCOPE.md, including out-of-scope and assumptions
3. User stories"As a shop owner, I can see every open request in one place"
4. Break it downGitHub Issues, each half a day or less, all assigned
5. BuildOne issue, one branch, one pull request, one reviewer
6. ReviewSomebody else pulls it, runs it, comments, then approves
7. TestThe QA lead works through every story on a phone before merge
8. DeployA live https URL, from day two, not day five
9. PresentTo the client, in their language, not yours
What this code doesWe want an issue small enough to finish in half a day, with a user story, a "done when" list anyone can check, and named people.
GitHub issue #7
1
2
3
4
5
6
7
8
9
10
11
Title: Show who is handling each request

As a shop owner, I can see who is handling each request,
so two of us never reply to the same customer.

Done when:
- Every request shows "handled by <name>" or "nobody yet"
- "Take it" appears only on requests nobody has taken
- Tested on a phone by somebody who did not build it

Assigned to: Amaka   Reviewer: Femi   Size: half a day
NOTE   
One issue becomes one branch and one pull request.

Here is that issue taken through the Day 10 workflow in real git: a branch named after it, commits on the branch, and a merge back into main once it is reviewed. git log --graph draws the branch and the merge.

What this code doesWe want to see one issue's whole life in git: its own branch, two commits, and a merge into main that keeps the branch visible in the history.
terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
git init -q -b main request-manager && cd request-manager
echo "<ul id='requests'></ul>" > index.html
git add . && git commit -qm "Start request list"

# Issue 7 gets its own branch
git switch -q -c 7-show-owner
echo "// show who is handling each request" > owner.js
git add . && git commit -qm "Show who is handling each request (#7)"
echo "// hide Take it once a request is taken" >> owner.js
git commit -qam "Hide Take it on taken requests (#7)"

# After review, merge it back into main
git switch -q main
git merge -q --no-ff 7-show-owner -m "Merge #7: show who is handling each request"

git log --graph --oneline --format='%s'
OUTPUT   TERMINAL
*   Merge #7: show who is handling each request
|\  
| * Hide Take it on taken requests (#7)
| * Show who is handling each request (#7)
|/  
* Start request list
Deploy on Day Two, Not on the Last Day

Teams that leave deployment until the end lose their final afternoon to path bugs and a broken build. Deploy something almost empty on day two, and every merge then updates a URL that already works. This is the single most reliable predictor of which teams finish.

Picture This

Picture the kitchen pass: every plate on a ticket, every plate checked before it goes out.

3. What It Must Include

  • Everything from Project 2: real data, search, filter, the four states, modules, phone width.
  • State handled properly and persisted: Day 11.
  • Validation with messages that say what to do: Day 13.
  • Keyboard operable, Lighthouse accessibility above 95: Day 13.
  • No XSS and no committed secrets: Day 17.
  • Deployed over https, with a README a stranger can follow: Day 18.
  • A SCOPE.md and a closed set of issues showing how the work was split.

4. The Presentation

Ten minutes, to the client. Not to your instructor, and not a tour of your code.

MinutesWhat
1The problem, in the client's own words
1What we decided to build, and what we deliberately did not
4Live demo, driven by the person who did not build that part
2What broke and what we did about it
1What we would build next, and why that order
1Questions
The Demo Is Driven by Somebody Who Did Not Build That Part

It is announced on the day, so you cannot rehearse around it. A team where only the author can operate a feature has not really shared the work, and thirty seconds of demo makes that obvious in a way a commit graph does not.

5. The Rubric

CriterionMarksWhat is judged
Understanding the client15Did you interview them, is the scope sane, is the out-of-scope list real
The product25Does it solve the stated problem on a phone, with all four states and correct derived values
Engineering20Modules, naming, no dead code, no XSS, no secrets, accessibility above 95
Process25Issues, branches, pull requests, genuine reviews, deployed early, every member committing across several days
Presentation15Clear, honest, in the client's language, and anybody can demo any part

The assessor does not guess who did the work. git shortlog -sn HEAD counts commits per author, most first. Here is what it shows for a team where one person did nearly everything.

What this code doesWe want to see the commit spread the assessor sees, for a team where one member made eight of the ten commits.
terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
git init -q -b main team && cd team

# A small helper: one commit by the named author
by() { echo "$2" >> log.txt; git add log.txt; GIT_AUTHOR_NAME="$1" git commit -qm "$2"; }

by Amaka "Add request form"
by Amaka "Add request list"
by Amaka "Add status filter"
by Amaka "Add search"
by Amaka "Save to localStorage"
by Amaka "Add open count"
by Amaka "Fix phone layout"
by Amaka "Add assignee filter"
by Femi "Update README"
by Tunde "Fix typo"

git shortlog -sn HEAD
OUTPUT   TERMINAL
     8	Amaka
     1	Femi
     1	Tunde

What Loses Marks That Teams Do Not Expect

  • One person with 80% of the commits, as above. That is a process failure however good the product is.
  • Pull requests approved within a minute of opening, with no comments. Nobody read those.
  • A demo that only works if you click in one exact order, which means nobody else tested it.
  • An impressive feature nobody asked for, while something on the Critical list is missing.
  • Presenting in developer language. The client does not know what a state object is and does not need to.

6. Finish Properly

  1. Every team member: fork or clone the final repository to your own account so it is on your profile.
  2. Add it to your pinned four if it is better than what is there.
  3. Write your own CV line for it, naming the part you owned.
  4. Write down, privately, one thing you would do differently in a team next time. Keep it, and read it before your first job.

Questions Teams Ask on This Project

The client changed their mind on day three. What do we do?

Exactly what a real team does. Do not say no and do not silently absorb it. Say what it would cost and what it would displace: we can add that, and it would mean the assignee filter does not get built this week. Which would you rather have? Then write the decision in SCOPE.md with the date. That sentence and that record are most of what project management is.

Two of us disagree about how to build something. Who decides?

Time-box it to ten minutes. If you still disagree, the Product Lead decides and the team commits to it, including whoever lost. Write the decision and the reason in the pull request so it is not argued again on Thursday. A team that cannot close a disagreement loses more to the argument than to whichever option was worse.

One of our five is not contributing. Do we carry them?

No, and do not stay silent either. Raise it in the team on day two, not in the assessment on day five, when nothing can be done. If it does not change after you have raised it directly, tell your instructor while there is still time to help. The commit history is read per person, as git shortlog showed, so carrying somebody does not protect them and it does cost you.

We are behind. Do we cut a feature or work through the night?

Cut, and say you cut it. A finished small thing with an honest "we did not get to assignment filtering, here is why and here is what we would do next" marks well. A half-built big thing that breaks in the demo does not, and nobody in industry is impressed by an all-nighter that produced a broken build.

Do This Now

  1. Book the client interview and ask all six questions.
  2. Write and commit SCOPE.md, with a real out-of-scope list and your assumptions.
  3. Turn every user story into issues of half a day or less, each with an owner and a reviewer.
  4. Deploy an almost empty page on day two.
  5. Build issue by issue: one branch, one pull request, one genuine review each.
  6. Rehearse the presentation with a different person driving each part of the demo.

Tick Before You Move On

  • ☐ We interviewed the client before writing any code
  • ☐ SCOPE.md exists, with a real out-of-scope list and our assumptions
  • ☐ We deployed on day two and every merge since has updated it
  • ☐ Every member has commits across several days, and reviewed somebody else
  • ☐ Any one of us can demo any part of it
  • ☐ Accessibility above 95, no XSS, no committed secrets

Quick Recap

A brief is a problem, not a specification; the gaps are the work. Ask what the one thing is, and rank everything else beneath it. Write the out-of-scope list down, because it is what protects you on Thursday. Deploy on day two. Present in the client's language, and let anybody demo any part.

You Are Done

Twenty days ago you could build a page that looked right and did nothing. You can now take a problem described by somebody who does not know how software is built, scope it, split it, build it in a team, review somebody else's work, find your own bugs, make it usable by people who do not use a mouse, keep it reasonably secure, ship it to a URL, and stand up and explain every decision in it.

That is not "I know JavaScript". That is a junior frontend developer, and the difference is the whole point of the last four weeks.

What Comes Next

Level 3 is React, TypeScript and production frontend architecture. Everything React does for you, you have now done by hand: rendering from state, one source of truth, deriving values rather than storing them, components as modules. That is exactly why we did it in this order. React will feel like a shortcut rather than magic, and that is the difference between using a framework and being trapped by one.

Final Scenario

On Friday the client watches Tunde, who built none of it, open the app on her own phone. He takes a request, marks another done, and the open count drops by one.

She asks whether it can send customers a text. Amaka opens SCOPE.md, reads the line they agreed on Monday, and offers to swap it for the assignee filter next week.

That is the job: the right thing, built together, shipped, and explained in the client's words.

Level 3: React, TypeScript and production frontend. You have earned it.

Learn this with a real instructor

Free lessons take you a long way on your own. The full programmes add live classes, assignments, Skill Points and a certificate — built for African students.