← Francisco Cascalheira

Case study · ESOF (Engenharia de Software) · FEUP, LEIC-ES 2025/26

Delivered

EngineHER

Five of us built a mentorship app for engineering students, and the way we worked together is the thing worth reading — the professor who graded it agreed.

Team
Team 4.3 · LEIC-ES-2025-26-2LEIC04
Course
ESOF (Engenharia de Software) · FEUP, LEIC-ES 2025/26
Role
Architecture & integration — one of five
Stack
Flutter · Dart · Firebase · Firestore · GitHub Actions
Assessed by

The course's own grading rubric — team 4.3, assessed by the ESOF teaching team

Not a public document — the individual TPC assignments and Personal Assessment aren't in this figure, and no other team's row is either.

fig. 0 · five people, one team

  1. 109 · 34.1%Architecture & integration (me)
  2. 88 · 27.5%Teammate
  3. 60 · 18.75%Teammate
  4. 33 · 10.3%Teammate
  5. 30 · 9.4%Teammate

Three sprints, four releases

  1. v0.1.0

    Sprint 1 · 5 Apr 2026

  2. v0.2.0

    Sprint 2 · 22 Apr 2026

  3. v0.3.0

    Sprint 3 · 13 May 2026

  4. v0.4.0

    Stabilisation · 27 May 2026

fig. 0 — 320 commits, five people, nobody over 34% · four tagged releases across three sprints · git tag, git shortlog · 19 Jul 2026

What this document claims.

EngineHER connects female engineering students with mentors and role models: a mentee finds someone further along, sends a request, and — once accepted — the two talk inside the app. It was built for FEUP's ESOF course by a team of five across three Agile sprints to four tagged releases, with a CI pipeline gating every merge and a test suite that grew alongside the app. I was one of the five; my part was the architecture — the data flow and system structure the rest of the app was built on top of.

5
person team
320 commits, nobody over 34% · git shortlog · 19 Jul 2026
4
releases
v0.1.0 – v0.4.0 · 3 sprints · git tag
127
automated tests
122 Dart (unit, widget, integration) + 5 Firestore-rules · CI-gated
90%
on the team rubric
0.538 of 0.600 available weight · assessed

What a mentorship gap needs.

Engineering has a gender gap that starts before the workforce — it starts in who a student pictures when they picture an engineer, and in who they can ask when the degree gets hard. A first-year without a mentor still has classmates and forums; what she is often missing is someone a few years ahead who has already been the only woman in the room and can say plainly what that is like.

EngineHER is a Flutter app built to close that gap directly: a mentee describes what she's looking for, browses mentors and role models by field and background, and sends a request. Once a mentor accepts, the pairing moves into a chat inside the app. Role models — women already working as engineers — answer public questions from anyone in the community, so the app serves people who want an ongoing mentor and people who just have one question to ask.

The rules of the job.

A fixed academic clock

Three Agile sprints, each ending on a hard FEUP deadline, with a graded demo at the end of every one. There is no slipping a sprint to catch up — the cadence itself was a constraint the team had to plan around, not just the features inside it.

Five people, one app

Five students coordinating one Flutter codebase, most of them new to Firebase and to each other. The team had to agree on a data model and a branching discipline in week one and then actually hold to it for three months.

Real users, a real gap

The people this app is for are specific — engineering students who feel that gap firsthand — so a mockup that looked plausible wasn't enough; the team validated the flow against real prospective users before building past a prototype.

Everything had to be checkable

ESOF grades the process as much as the product: sprint backlogs, retrospectives, a CI pipeline, a growing test suite. The team wasn't just building an app — it was building a paper trail a professor could open and verify.

Five models, one mentorship.

The app stands on five Firestore collections. This is the real schema, sanitised to shapes — click a model, or walk it with the arrow keys.

MentorshipRequest

Mentorship

A mentee's request to a mentor, and its answer.

Shape

  • menteeId, mentorId, message, interest
  • status: pending | accepted | declined | ended
  • menteeName, menteeLevel — denormalised for the card

Relations

  • · mentee
  • · mentor

Why it's shaped this way — menteeName and menteeLevel are copied onto the request on purpose: a mentor's inbox reads as one query, not one read per card. This is fig. 2 — the whole request lifecycle.

fig. 1 — 5 Firestore collections · team of five · delivered for FEUP's ESOF course

A mentorship request is the app's central object: sent by a mentee, answered by a mentor, and — once accepted — the door into a chat thread between the two.

  1. 01 PENDING

    A mentee sends a request to a mentor or role model, naming what she's looking for and a short message.

  2. 02 ACCEPTED

    The mentor accepts. The pairing becomes active and a chat thread opens between the two.

Terminal states

  • DECLINED · the mentor turns down the request
  • ENDED · either side ends an active mentorship
fig. 2 — the mentorship request lifecycle, as modelled in MentorshipRequest.

How five people worked.

The product here is unremarkable by design — a course project, built to spec, in three months. What is worth reading is the process: four independent signals, each checkable against the repository or the course's own record.

releases →
v0.1.0v0.2.0v0.3.0v0.4.0
  1. Architecture & integration (me)
    1
    21
    87
  2. Teammate
    5
    30
    53
  3. Teammate
    0
    23
    37
  4. Teammate
    15
    9
    9
  5. Teammate
    0
    7
    23
MarAprMay
fig. 3 — commits by month, one lane per person (counts include merges, so each lane sums to its fig. 0 total) · git log · 19 Jul 2026

4.1No one carried the project alone

320 commits on main, split five ways: 109 mine, and the rest of the team at 88, 60, 33 and 30 — nobody past a third of the total, and four of the five names between them wrote almost two-thirds of the code. That is what the commit graph of a team that actually shared the work looks like, not a solo project with credited spectators.

source: git shortlog -sne main, deduped by email across each person's git identities

4.2The code changed hands

Thirty-nine pull requests, opened by all five of us. The work did not stay in silos: twelve of the thirty-five that merged were merged by a teammate rather than the person who opened them — one member's branch landing through another's hands. Formal review clustered on two of the five more than it spread evenly, so read this as honest evidence that the code crossed the team, not a claim that every line had a queue of reviewers.

source: GitHub PR authorship, reviews and merged_by across 39 pull requests (35 merged)

4.3Three sprints, four releases, on schedule

The team shipped a tagged GitHub release at the end of each of the three Agile sprints and one stabilisation pass after — v0.1.0 through v0.4.0, 5 April to 27 May 2026 — each one a working increment a professor could install and use, not a snapshot of source.

source: git tag, four annotated releases v0.1.0–v0.4.0

4.4A CI gate that actually failed sometimes

Every push and pull request ran the same GitHub Actions pipeline. Its history isn't a single green checkmark stamped at the end — there are real failed runs through May, followed by fixes and a re-run that passed, which is what a CI gate looks like when a team is actually using it to catch problems rather than performing one for the record.

source: GitHub Actions workflow run history, .github/workflows/ci.yml

What the rubric said.

0.538 of 0.600 available weight on every team-graded criterion (backlog refinement, design, all three construction increments, testing, DevOps automation, sprint ceremonies) — 89.7%, on the rubric FEUP's ESOF course uses to grade every team the same way.

Not a public document — the individual TPC assignments and Personal Assessment aren't in this figure, and no other team's row is either.

17.9/200.538 of 0.6 available weight · every team-graded activity
  1. Construction19.2 · 0.16
  2. Business modeling19.1 · 0.04
  3. DevOps18.8 · 0.04
  4. Testing18.4 · 0.08
  5. Analysis & design18.3 · 0.03
  6. Project management17.3 · 0.08
  7. Requirements16.9 · 0.10
  8. Environment15.8 · 0.06
  9. Change management12.2 · 0.01

activity · score /20 · weight

Managing issues, branches and pull requestsscored once per sprint — a team that got measurably better at its own process:

581719sprint 0 → 3
fig. 4 — team 4.3's weighted score per activity, out of 20 · course rubric, sheet 4.3 only

Where it stands today.

EngineHER shipped as a delivered, accepted academic project — four tagged releases across three sprints, a CI pipeline that gated every merge, and 127 automated tests behind it. It is not in production and carries no live users; it was built, demoed, graded and handed in, which is what "delivered" means on this site.

The claim this case study makes isn't about a clever piece of engineering — it's that five people coordinated well enough, for three months, that the commit graph, the pull requests and the course's own rubric all say the same thing independently. My part in it was architecture and integration: the data model above, and the plumbing between the screens the rest of the team built on top of it.

The professor's assessment is the strongest single piece of evidence here, precisely because it isn't mine to write — an examiner with no reason to flatter the team scored the process the team ran, not just the app it produced, and scored it well.