Minh Nguyen
All work

Case study — Partie

Real-time video and notifications for a gaming platform

What I owned, and what I didn't.

Role
Full stack developer, team of six
When
Nov 2020 — May 2022
Stack
Angular · ASP.NET Core · SQL Server · Agora · OneSignal
Product
Since shut down

Context, and the boundary

Partie connected gamers around the world so they could play together. I joined as a full stack developer alongside an offshore team of five or six. The architecture and framework choices were made before I arrived.

I worked across the frontend and backend, and I owned two integrations end to end: Agora for real-time video, and OneSignal for notifications. That's what this page is about. The platform ran microservices on Kubernetes with Azure DevOps pipelines, which I worked within — modifying pipeline definitions, debugging services in-cluster — but did not own.

The web application was the primary surface. iOS and Android were ports through a cross-platform wrapper, and the desktop build was Electron pointing at the web app.

Agora — keeping people in the call

Video served three purposes: group party chat, streaming to spectators, and gamers talking while playing. Sessions ran up to about 25 participants.

I built the server side — token generation and the access and refresh token exchange against Agora.

Two problems were worth the time:

Knowing who's in the room. Agora has its own identity model, and it doesn't know anything about ours. Linking our user ID to the Agora token is what let the platform answer "which of our users is in this session" — required for anything social layered on top of a call.

Staying in the room. Agora expires tokens and drops participants when they lapse. To a user that's the call ending for no reason. So the client had to exchange access tokens for refreshed ones in the background, before expiry, without interrupting anything.

Users should never learn that their session had a timer.

OneSignal — notifying the right people

Notifications went out by SMS and email, triggered by app updates, invites, friend requests, subscription payments, and group chats starting.

I built the server-side audience filtering and wired up the sending.

The interesting part isn't delivery, it's who. "Notify everyone" is one line of code and a bad idea — an app-wide announcement nominally targets every user who ever registered, most of whom left long ago, and sending to all of them burns server resources to reach people who aren't there.

So the audience narrows by recency: users active within a window, configurable rather than hard-coded, typically three to six months, adjustable per business rule. Everyone who should hear about it does, without a fan-out that costs more than the message is worth.

It shipped, and it wasn't used much

The video worked. It didn't get heavy use, because gamers were already on Discord and had no reason to move.

I'm including that because it's the honest outcome and because shipping isn't the same as succeeding. The engineering was sound; the product bet was that people would switch communication tools for a feature that wasn't better than what they had. They didn't. That was worth learning early, and it's a useful check on any feature that competes with an incumbent people already have open.

Partie has since shut down. I'd rather say that here than have you find a dead link.

What this was

Eighteen months on a consumer product at startup pace, on a distributed team, integrating real-time media against third-party services I didn't control. That's a different set of constraints from government work — faster, less permanent, and with the product question mattering more than the correctness question.

NextOrange County property tax — the system of record