Moe Loubani
Back to projects
Norzad
KotlinAndroidNext.jspg-bossDrizzleDocker

Norzad

Offline-First Digital Signage With Safe OTA Updates

Aug 2026

Offline-first signage platform with Android players in 8 venues, staged OTA updates and auto-rollback.

A digital signage and ad network for independent barbershops. I designed, built and run the whole platform: the cloud control plane, background workers, and a fleet of Android media players installed in shops.

Visit Norzad

Overview

Norzad is a digital signage and ad network for independent barbershops in Waterloo Region, Ontario. Screens in the shops play a video loop, and local advertisers pay to appear in it. It is live in 8 venues and moving toward paid advertising.

The engineering problem is running software on hardware I do not control, on shop networks I cannot rely on, with no one on site to fix it. The screens have to keep playing and recover on their own, and I have to know why when they do not.

My Role

I founded Norzad and built it end to end: the control plane, the workers, all three Android apps, the deploy pipeline and fleet operations. I also run the business side that the software supports, including venue onboarding and ad campaigns. I make the architecture and release decisions, and I diagnose field failures myself.

Architecture

About 100k lines of TypeScript and Kotlin across several apps:

  • Control plane: a Next.js and React app backed by Postgres, using a Drizzle data layer.
  • Workers: a Postgres-backed job queue (pg-boss) for background work.
  • Shared contracts: shared typed contracts across the system.
  • Android player: plays the loop in the shop.
  • Android updater: a separate app that installs releases.
  • Android setup app: a phone-based app for provisioning devices.

The cloud runs in Docker, self-hosted on Dokploy, with scripted post-deploy checks.

Key Engineering Decisions

  • Offline-first playback. Shop Wi-Fi is unreliable, so a screen plays a verified, content-addressed local copy of its loop instead of streaming. Content addressing lets the device verify what it has before playing it.
  • Atomic release swaps with rollback. A device switches to a new release in one step and can return to the previous one, so a screen is not left half-updated.
  • Bench preloading. Devices can be loaded with content at the bench, so they play from first power-on with or without Wi-Fi in the shop.
  • Separate updater app. Releases are installed by an app independent of the player, so the thing doing the update is not the thing being replaced.
  • Classify outages instead of alerting on all of them. Every outage is classified from device evidence: power loss, network, staff pressing the power button, or a self-recovered freeze. Only unexplained outages raise an alert.
  • Characterize before shipping. I reproduce, instrument and characterize hardware lockups on the bench before sending any fix to the fleet.

Reliability & Security

  • Safe OTA updates: staged rollout rings, a probation period with automatic rollback, and bench rehearsal that gates every release before it reaches the fleet.
  • Freeze recovery in layers: kernel-panic auto-reboot, a hardware watchdog driven by a custom progress check, and an external smart-plug power watchdog as the last resort.
  • Remote diagnosis: field failures are diagnosed from uploaded diagnostic bundles, kernel logs and boot history, without a site visit.
  • Review before merge: adversarial code and product reviews run before every merge.
  • Privacy: no cameras and no tracking. Plays are logged, and a play counts only when at least 90% of the item was shown.

Results

  • Live in 8 venues on hardware Norzad installs, owns and maintains.
  • A single platform of about 100k lines covering cloud, workers and three Android apps.
  • Business flows built into the product: venue onboarding, opening-hours-aware scheduling, ad campaigns with proof of play, revenue-share agreements and owner self-service uploads.