State parliament: bringing a neglected video platform back to life

How we revived a state parliament's video platform: dependency updates, refactor, containerised on Kubernetes, with CI/CD and observability.

The challenge

A state parliament ran a video platform that handled live plenary streaming, session recording, transcoding into the formats viewers actually use, and an API for the public site and internal integrations. The platform worked, just barely. The agency that built it had quietly let it slip. Dependencies were several major versions behind. There were no automated tests. Static analysis was nowhere. Deployments were a manual evening for two engineers. Each release was a coordinated event, and a release was rare because every release was a risk.

The platform was getting harder to change at the worst possible time, with the legislative calendar pushing more sessions through it every year. The team had inherited the system without inheriting any of the institutional knowledge. Adding anything new was a multi-day exercise in archaeology. And nobody had a clear picture of what the platform was actually doing under load. Health was checked by reading log files after the fact.

What we did

We started where the bleeding was worst: the dependency tree. Libraries that powered ingest, transcoding, the API, and the management UI had received security patches, performance fixes, and breaking changes nobody had tracked. We brought everything current in disciplined steps, with characterisation tests filling in behind us so the platform could keep running while the floor was being replaced. For schema changes specifically, read our patterns for zero-downtime Doctrine migrations.

The refactor moved through the stack in passes. The editorial flows in the management UI got cleaner. The public API got a single contract instead of a half-dozen accidental ones. The recording pipeline got proper retries and structured logging so a failure during a plenary session is something the system surfaces, not something we discover days later. The transcoding workers got pinned to a queue with proper backoff and concurrency limits so a busy day no longer means a stalled day.

Once the application was clean enough to containerise honestly, we packaged each piece and rolled it out on a Kubernetes cluster. Ingest, transcoding workers, the API, and the management UI each deploy, restart, and recover on their own terms. Storage moved off local disks onto object storage with proper lifecycle rules, so archival is a configuration, not a project.

A CI/CD pipeline ties it all together. Every change runs PHPStan at strict level, Rector, php-cs-fixer, the test suite, and an automated deploy to staging. A fix can ship in minutes, be watched through the pipeline, and rolled back without ceremony if it bites. The day-to-day effort of keeping the platform healthy dropped dramatically, simply because so much of it stopped being manual.

To go with that, we built out Grafana dashboards covering ingest health, transcoding queue depth, API latency, recording success rate, and platform-level resource usage. The team now sees the system in real time, with alerts that fire on the things that actually matter, so problems are caught before users notice them.

What changed

The platform that was almost rotting is now a system the team can confidently change. Dependencies are current, the test suite catches regressions before they ship, and a release is a button, not an event. The video management system, the API, the recording, and the transcoding all sit on the same modern, containerised foundation, with automated quality gates running on every commit and Grafana dashboards giving real-time visibility into how the platform is actually behaving.

The parliament still owns its platform end to end. The change is that it now owns one that has been brought back to life, and that reports honestly on its own health.

Ready to Fix Your Architecture?

Book a free 30-minute call with Silas. No sales pitch, just a direct conversation about your challenges.

Typically responds within 24 hours.

Book a Free Call