RZ

Preparing your experience

Back to Blog
Engineering Management

Running Two Parallel SaaS Workstreams for One Client Without Losing Sync

February 10, 20268 min read
Project ManagementGDPRHigher EducationStakeholder Management

When I picked up SIMS, a Student Information Management System built for a UK university, there was already a second, newer workstream in flight: a companion React and Node student portal being built for the same institution by the same client. Same stakeholders, same deadline pressure, two different codebases, two different technical rhythms, and — critically — two teams that had never been asked to reason about each other's roadmap.

On paper this looked like a straightforward parallel-delivery problem. In practice, the two workstreams had almost nothing in common except the client's name at the top of the invoice. SIMS was a mature, PHP-based system of record with years of institutional data modeling baked into it. The portal was a green-field React and Node application meant to sit in front of SIMS and give students a modern, self-service experience. The portal's entire value proposition depended on SIMS exposing stable, well-documented APIs. SIMS, for its part, had never been built with an external consumer in mind.

The Drift Problem

Before I introduced a shared process, the two workstreams reported status separately, to different people, on different cadences. SIMS status went into one weekly update; the portal's went into another. Nobody had explicitly mapped the point where the two systems actually depended on each other — until a SIMS API contract change quietly broke the portal's account-linking feature two days before a scheduled demo to the university's IT steering committee.

That incident is worth dwelling on, because it's a pattern I've now seen on more than one multi-team engagement. The SIMS team renamed a field during a routine data-model cleanup. From their side, it was a two-line change with no functional impact — nothing in SIMS itself broke. But the portal's account-linking flow read that field by name, and the rename silently turned a working login flow into one that failed for a subset of returning students. Nobody had flagged the change as cross-cutting because, from inside the SIMS codebase, it genuinely wasn't.

The lesson wasn't "communicate more." Both teams were already communicating. The lesson was that informal communication doesn't scale across a contract boundary — you need the dependency itself to be a tracked artifact, not a conversation that may or may not happen.

Why Status Reports Didn't Catch This

Weekly status reports are good at answering "are we on track" for a single team's own scope. They are bad at answering "will my change break something outside my scope," because that question requires the reporter to already know what's downstream — and the SIMS engineer making the rename had no visibility into the portal's account-linking code at all.

What Fixed It: Making Dependencies Explicit

We moved both workstreams onto a single fortnightly milestone board, with every cross-workstream dependency flagged as its own tracked item rather than a footnote in someone's status update. Concretely, that meant:

  • Any change to a SIMS API contract — endpoint shape, field name, authentication flow — became a labeled "cross-workstream" ticket, visible to both teams before it was merged, not after.
  • The portal team got a standing seat in the SIMS team's contract-review discussion, even though they weren't writing SIMS code.
  • A lightweight contract test suite ran against a staging SIMS instance on every portal deploy, so a breaking change would fail CI instead of surfacing in a demo.

None of this required new tooling. It required treating the API contract itself as a shared asset that both teams had a stake in, rather than an implementation detail owned unilaterally by whichever team happened to write the code first.

The GDPR Layer

Student data is sensitive by default, and this client operates under strict UK data-residency and retention rules that go well beyond what a typical SaaS project has to think about. The portal's account-linking feature, by design, needed to pull identifying student data out of SIMS and display it in a new surface — which meant every field it touched needed to be re-classified for the new context, not just inherited from SIMS's existing access model.

Before that feature shipped, we ran a full data-mapping exercise with the university's IT and data-protection staff. Every field the portal could read was classified by:

  1. Retention period — how long the data may legally be kept in the new surface.
  2. Access tier — which roles (student, staff, administrator) can view it.
  3. Purpose limitation — whether displaying it in the portal was actually within the original consent scope collected when the student enrolled.

That last point turned out to matter more than expected. A handful of fields SIMS stored for internal administrative purposes were not covered by the consent students had given for a student-facing portal, and we had to strip them from the API response entirely rather than simply hide them in the UI — a client-side hide would not have satisfied the university's data-protection officer, and rightly so.

We enforced the resulting classification with field-level access control and audit logging inside SIMS itself, so that every read of a sensitive field by the portal's service account was logged, queryable, and attributable. Skipping this step would have been faster in the short term and would have surfaced as a finding — possibly a serious one — at the client's next statutory data-protection review.

A Simplified View of the Field Classification

Field category Retention Portal access
Enrollment status Duration of enrollment + 6 years Student, self only
Disciplinary notes Internal retention schedule Not exposed to portal
Contact details Duration of enrollment Student, self only

The Reporting Fix

Three different Slack channels and two separate weekly emails were replaced with one weekly client call and a single-page RAG (red/amber/green) status summary covering both workstreams together. This sounds like a small change, but the effect on the client relationship was significant: instead of the client's programme sponsor having to mentally merge two separate updates to figure out whether the university's go-live date was actually at risk, they could see cross-workstream risk in a single glance.

The RAG summary itself was deliberately simple — three rows, one per major risk area (data migration, API stability, portal UX sign-off), each colored and with a one-sentence explanation. No status report should require the reader to already understand the project to interpret it.

Common Mistakes on Parallel Workstreams

A few patterns I'd flag for anyone running two interlocking workstreams for one client:

  • Treating "different codebase" as "different project." If the two systems share users, data, or a go-live date, they share risk, regardless of how separate the repositories are.
  • Letting API contracts live only in code. If the only place a contract is documented is the implementation itself, the consuming team has no way to review a change before it lands.
  • Under-scoping the compliance review. It's tempting to treat GDPR mapping as a one-time exercise done at project kickoff. New features that expose existing data in new contexts need their own pass.
  • Over-communicating in unstructured channels. More Slack messages is not the same as more shared understanding. A tracked dependency is worth more than ten messages about it.

Practical Checklist

Before merging any change to a shared API contract:
1. Is this field/endpoint consumed outside this codebase? (grep the other repo, don't assume)
2. Does the change alter shape, meaning, or auth requirements?
3. If yes to either — open a cross-workstream ticket before merging, not after.
4. Run the contract test suite against the consuming service's staging environment.
5. Only merge once the consuming team has acknowledged the ticket.

Where Things Stand

Both workstreams are now realigned to a shared institutional go-live date. The client's internal data-protection review came back with zero findings — a direct result of treating the field-classification exercise as mandatory rather than optional under deadline pressure. And the dependency-tracking habit, originally introduced to fix one specific incident, has outlived the problem it was built to solve: it's now the default way any new cross-workstream change gets proposed on this account.

FAQ

Q: Isn't a shared milestone board just extra process overhead for two teams that are otherwise independent?
It adds overhead only if the teams are truly independent. The moment they share users, data, or a deadline, the overhead of not tracking dependencies explicitly is larger — it just shows up later, and more expensively, as a broken demo or a compliance finding.

Q: How do you decide what counts as a "cross-workstream" change?
Any change to something the other team's code reads, writes, or depends on for its own correctness — API shape, authentication behavior, data meaning. If in doubt, flag it; the cost of an unnecessary flag is far lower than the cost of a missed one.

Q: Did the portal team ever push back on being included in SIMS contract reviews?
Initially, yes — it felt like extra meetings for a team not writing that code. That resistance went away after the first review caught a would-be breaking change before it merged, rather than after.

Conclusion

Running two parallel workstreams for one client isn't primarily a technical problem — both SIMS and the portal were, individually, well-engineered systems. It's a coordination problem, and coordination problems don't get solved by working harder inside each team's own silo. They get solved by making the dependencies between the silos visible, tracked, and reviewed before they become incidents, and by treating compliance obligations like GDPR data mapping as a recurring discipline rather than a one-time checkbox at kickoff.

Found this useful? Explore more articles on Engineering Management.

All articles