Portfolio

Gael Blair-Mbala

full-stack engineer/product analyst/data pipeline builder

I build systems that turn messy real-world data (job postings, tenant reviews, user requirements) into ranked, trustworthy decisions. My flagship project, RentWise, helps renters make better decisions from noisy review data. This portfolio also includes a newsletter signup so you can keep up with my posts and findings.

Resume ↗ gaelmbala16@gmail.com GitHub LinkedIn Boston, MA Preferred contact: Email
Explore the portfolio
|0⟩ |1⟩
Supporting project

Quantum-optimized job routing pipeline

It started from a line in my notes: "Got an 11% match on a job posting I'm totally not qualified for: requesting 11–15 years of experience for an entry-level salary." Rather than keep burning application slots on broken listings, I built a pipeline to scrape, filter, and score postings against my actual resume. Then, mostly to learn how, I rebuilt the final ranking step on top of a real IBM Quantum backend.

4
Job board APIs
53
Skills tracked
11
Qubits in prod run
≤5
Apps / company, enforced
Scrape: Adzuna, The Muse, Remotive, and JSearch/RapidAPI (which itself aggregates Indeed, LinkedIn, Glassdoor)
Filter: work type, Boston-metro location, red-flag titles ("Lead", "Senior"), and experience floors ("5+ years", "3–5 years", en-dash and em-dash ranges alike)
Score: each posting checked against 53 tracked skills pulled from my resume, not a generic keyword list
Quantum-rank: top candidates re-ranked with a QAOA solve on IBM Quantum hardware, capped at 5 applications per company
Deliver: ranked HTML digest by Gmail SMTP, plus a Flask dashboard for saving, skipping, and tracking applications
Job Routing System dashboard showing 17 matched jobs with skill tags and match percentages
Flask dashboard: ranked matches with per-job skill tags
Dashboard filtered to Boston-area matches
Location filter: Remote / Boston Area / Co-op views
Gmail inbox showing the daily Job Routing System digest email
Daily digest, delivered straight to Gmail

Framing the shortlist as a QUBO

Once each job has a match score, choosing which handful to actually apply to is a constrained optimization problem: maximize total match quality, capped at 5 applications total and 5 per company (blasting 15 applications at one place gets you flagged, not hired). That's a natural fit for a Quadratic Unconstrained Binary Optimization problem, solved with QAOA on real IBM Quantum hardware.

score(job) = |⟨ψ(resume)|ψ(job)⟩|^(1/8) Q_ii = −score(job_i) # reward selecting strong matches Q_ij = penalty(same company) # discourage over-applying to one employer
A job's quantum-kernel fidelity against my resume becomes the diagonal of a QUBO matrix; the "no more than 5 per company" rule becomes an off-diagonal penalty term. QAOA samples the bitstring that maximizes total match quality under both constraints at once.

Three bugs, three root causes

The pipeline ran silently for a while before it sent a single real email.

  1. The circuit never returned. QAOA's cost circuit doesn't auto-decompose into simulatable gates, so evaluation silently fell back to a full matrix exponential of the Hamiltonian. Fine under ~10 qubits, effectively infinite past it. Fix: decompose the circuit first → 0.02s per evaluation.
  2. The decode step read past the real variables. That first bug had been hiding a second: QUBO constraints add "slack" qubits, and the naive decode read into them as if they were job variables, crashing with an index error. Fix: decode only the true job-variable bits.
  3. Every job scored 0%. Once both were fixed, the run finished fast. And returned nothing. Across 8 qubits, per-category similarity multiplies, so unless a job hits nearly every skill category, the fidelity collapses toward zero ("exponential concentration"). Fix: take the 8th root of raw fidelity.
Early version of the experience-flag filter, a short flat list of year thresholds
Then: a handful of hardcoded "5+ years" strings
Hardened version of the experience-flag filter handling ranges, en-dashes, and em-dashes
Now: hardened against ranges, hyphens, and en/em-dashes
PowerShell output of a live scrape run, skipping red-flagged titles and reporting 17 total matches out of 53 tracked skills
A live scrape run: red-flag titles skipped inline, 17 of many postings survive the filter

The manual side still turns up bugs

The whole point of this pipeline is to cut down on manual applications, but the ones that still require a human catch real problems too. Applying through what's almost certainly a Workday-based portal (built around one-at-a-time skill entry that drains a surprising amount of patience), I hit a certification dropdown returning mismatched, clipped results mid-search: a search-relevance bug and a text-overflow bug stacked on top of each other, both visible before I'd finished typing. Same instinct as debugging my own code: spot it, document it, write it up clearly enough that someone else could act on it.

Two bugs in one dropdown, caught mid-application
PythonFlaskQiskitqiskit-ibm-runtimeqiskit-optimizationQAOACelery + RedisBeautifulSoupGmail SMTPAdzuna / JSearch / Remotive APIs
Flagship project

RentWise

A trust layer for renters, built on top of noisy review data

Team of 5 · led weekly syncs

Architected a full-stack rental-review platform on React, Express.js, and a normalized SQLite schema, with automated email workflows, a renter-verification dashboard, and team-managed moderation.

Visit rent-wise.live ↗
RentWise, start to finish: search, a verified review, and the admin side that keeps verification meaningful
  • Built a review-helpfulness regression model to score and surface high-quality reviews instead of just the newest ones.
  • Feature-engineered a topic-frequency heatmap across a Google Reviews dataset, using an independent regression analysis to define RentWise's rating categories: safety, management, noise, rent-vs-quality, parking, and responsiveness.
  • Tracked platform health through analytics dashboards while leading a 5-person team through weekly syncs, bug triage, and stakeholder communication.
Heatmap of keyword frequency by star rating across apartment reviews, with 'staff' and 'management' as the most rating-correlated topics
The topic-frequency heatmap behind RentWise's rating categories
Gmail notification confirming a RentWise residency verification was approved
Approved: verification clears, the user can post
Handwritten design notes describing the denial workflow: clicking Deny opens a dropdown of reasons, a reason must be selected before Confirm Denial activates, and the denial email includes the specific reason
Denied: design notes for the other half of the flow
Admin panel showing pending residency verifications with submitter names and documents redacted
Admin queue for pending residency verifications
RentWise update announcing the anonymous review option, with a sample anonymous review shown below
Shipped: the option to review anonymously
GA4 chart of new versus returning users over time, showing a spike after launch
New vs. returning users post-launch
GA4 chart of active users by operating system over time
Active users by platform over time
GA4 donut chart showing 55.6% mobile and 44.4% desktop active users
55.6% mobile, 44.4% desktop
Admin panel's suspicious-reviews queue with reviewer names and emails blurred
Flagging suspicious reviews for manual review
A real listing page with a verified review, reviewer name blurred
A real listing, pulled from the ingested review dataset
RentWise flyers posted on a campus dining commons bulletin board
Campus flyering in the dining commons
A RentWise flyer posted on a library bulletin board
...and in the library, driving the 7x spike
Docker Desktop showing a local Kubernetes (kind) cluster with the rentwise deployment available and its pod running
Containerized locally with Docker Desktop's Kubernetes (kind)
5m 38s
Avg. session length
7×
User growth
6
Rating categories shipped
ReactExpress.jsSQLiteRegression modelingFeature engineeringAnalytics dashboards
More builds

Smaller projects, same habit of shipping

Extension · same codebase

Boston BI job-market enrichment

A focused build on top of the job router: scrapes Data Analyst / BI roles from five no-auth APIs, fetches each hybrid/onsite Boston-area listing's full description with BeautifulSoup instead of trusting Adzuna's truncated snippet, then re-scores every posting against my actual resume text. Along the way, fixed a false-positive bug where the regex for the "R" language matched inside "or," "for," and "director"; replaced with a word-boundary match.

52 jobs enriched 76 resume-matched & ranked 5 no-auth sources
PythonBeautifulSouprequestsregexAdzuna / Muse / Remotive / Arbeitnow / Jobicy
Part of the job routing pipeline ↗
MSIS415 · Advanced Coding for Analytics

Review helpfulness analysis

A logistic regression classifier that labels apartment reviews as "helpful" from a composite score built on five features: word count, presence of photos, recency, whether the property manager responded, and rating extremity (1 or 5 stars). Trained on a large-scale Massachusetts Google Reviews dataset, skewed heavily toward 5-star ratings. Extreme ratings and manager responses turned out to be the strongest predictors, review length barely mattered. Later integrated into RentWise as a content-ranking layer.

Bar chart of review rating distribution for Massachusetts apartment reviews, heavily skewed toward 5 stars
Ratings skew hard toward 5 stars
Horizontal bar chart of logistic regression feature coefficients, showing is_extreme_rating and has_response as the strongest predictors
Extreme ratings, not length, predict helpfulness
Avg. rating: 4.10 36,882 reviews with a response (24.6%) 5 engineered features
Pythonpandasscikit-learnRegression modelingData visualization
Technical guide · agent tooling

Wiring IBM Bob into Slack over MCP

A screenshot-verified, step-by-step guide connecting the IBM Bob coding agent to Slack through the Model Context Protocol: a Slack app with correctly scoped bot token, an mcp.json entry running the community Slack MCP server, and a live smoke test where Bob posts to a channel entirely on its own.

Slack App Credentials settings page with App ID and Client ID blurred out
Setup: Slack app credentials (IDs blurred)
Slack channel showing the Bob MCP Bridge app posting 'Hello from Bob! MCP Slack is working.'
Payoff: Bob posting on its own
7 verified steps status: Connected
MCPSlack APIIBM BobOAuth scopesTechnical writing
WRIT-231 · Technical Writing coursework

Enterprise cloud integration proposal: Teams & Azure

A formal business report and executive memo proposing how a mid-size company would integrate Microsoft Teams with Azure: Azure AD access control and SSO, Logic Apps-based workflow automation, API management, and a feature comparison against Slack, built around a realistic company scenario and cited outside research. Not a hands-on build like the Bob/MCP guide above — a technical & business writing exercise in scoping and explaining an enterprise architecture decision to a non-technical exec audience.

15-slide deck Formal report + exec memo
Technical writingAzure ADLogic AppsEnterprise architectureStakeholder communication
Utility · gist

Accent toolbar

A tkinter desktop utility that puts French accents, Hausa characters, and IPA phonetic symbols one click away: seven tabbed categories, hover tooltips explaining each symbol, and one-click clipboard copy for typing across multiple languages and phonetic transcription.

7 character tabs always-on-top palette
PythonTkinterpyperclip
View gist ↗
Field notes

UX details I noticed in the wild

Field note · September 2026

FC 27 Screen Freeze: A UX-Informed Bug Report

A bug report on brief screen freezes in the EA SPORTS FC 27 trial on PS5: 16 timestamped freezes across two recordings, clustered around possession changes and shots, with the cost to the player spelled out.

Game QABug ReportUX ImpactPS5
Read the note →
Field note · September 2026

Icon Metamorphosis

A field note on a hover micro-interaction spotted on Microsoft Copilot's home page: a lightbulb icon that metamorphoses into an identity-card icon as you linger over it.

Micro-interactionHover StateCopilot Home Page
Read the note →
Experience

Product Manager Intern, Disent

  • Collaborated with engineering and product to write user stories and use cases, tracked bugs, and translated requirements into design specs: faster engineer handoffs, smoother dev cycles.
  • Diagnosed a React error causing client session failures; partnered with engineering to scope and validate the fix, improving operational stability by 60%.
  • Led a campus-wide brand awareness campaign with Student Activities and the campus IT org, driving a 70% increase in new signups in one week.
  • Designed the Disent poster in Canva using UI layout principles, lifting weekly active users 20% and earning recognition from C-suite leadership; it became the company's official poster.
Disent recruiting poster reading 'Build the story. Press play.' with app icons and a QR code, designed in Canva
The poster, now Disent's official one
Toolkit

Skills

Languages

JavaScriptTypeScriptPythonSQLPowerShellHTML/CSSBash

Frameworks & libraries

ReactNext.jsExpress.jsViteNode.jspandas

Databases & cloud

SQLitePostgreSQLRDSSnowflakeAWSUnix/Linux

AI & machine learning

Claude APIQiskitFeature engineeringRegression & classificationModel validation

Data & analytics

Power BITableauGA4ETLData warehousingCohort analysis

Practices & networking

Agile/ScrumGit/GitHubREST APIsPR reviewTCP/IPDNS/DHCPWireshark
Education

University of Massachusetts Boston

B.S. Information Technology: Business Intelligence concentration

May 2026
Back to top