Domiraqo, a multi-surface product: mobile apps, business platform, marketing site
Three coordinated surfaces (customer-facing mobile apps, a business operations platform, and a public marketing site) engineered as one system with a shared design language and a single source of truth.
Context
Domiraqo is a Vision Nexera product built as three coordinated surfaces at once: customer-facing mobile apps (iOS and Android), a business operations platform for the team who runs the service, and a public marketing site that has to earn search traffic and convert. It is the product that made us codify how a small team ships across three surfaces without drifting into three products.
The problem
A product that lives on a phone, a laptop, and a browser tab is really three products unless the engineering is deliberate. Design tokens drift, the mobile app and the admin panel disagree about what a “customer” is, and the marketing site becomes a stale island that nobody trusts to publish from. The engineering problem: build three surfaces as one system, with one source of truth and one design language, from day one.
Constraints that shaped the build
- App-store review cycles are days, not seconds: the mobile release rhythm dictates when hard breaking changes can ship, and the architecture has to respect that.
- The business platform is where real money and real customer records move; correctness and audit trails are non-negotiable, and the mobile apps must not be able to bypass its rules.
- The marketing site has to be fast, crawlable, and independently editable, without becoming a fourth product with its own copy of the brand.
- A small senior team runs all three surfaces, so operational simplicity (one API, one deploy story per surface, one design system) is a feature, not a nice-to-have.
Architecture
The system, drawn honestly
Every surface authenticates through a single identity provider with role-scoped tokens: a mobile customer, a business operator, and a support agent hold the same shape of credential but wildly different authority, enforced at the API, not at the UI. The mobile apps and the business platform speak to a versioned, typed API backed by a single database, so a “customer,” an “order,” or a “status change” means exactly one thing across surfaces. There is no second, more permissive path in: the mobile client cannot bypass a rule the business platform enforces, because the rule lives at the API.
Domain changes emit onto an event bus that fans out to three durable consumers: background jobs (notifications, receipts, ledger writes, image processing) with idempotent handlers and dead-letter queues; the observability pipeline that traces every request across surfaces with a single correlation id; and a cache-invalidation channel that revalidates the marketing site's ISR pages when the underlying content changes. Async work is retriable and safe to replay: nothing that matters depends on a single successful HTTP round-trip.
The marketing site is a separate Next.js application that reads from the same content model, statically generated for speed and revalidated by tag on publish. All three surfaces consume the same design tokens (colour, type, spacing, motion, radius, elevation) accessible-first (contrast, hit targets, motion-reduction) by construction. Releases are gated by a shared feature-flag service: a launch shows the same flag turned on across mobile, business, and marketing on a schedule, so a press headline never lands before the feature is behind it. The mobile release train runs on a fixed cadence with over-the-air updates handling anything short of native module changes; app-store review only gates real native work.
Build notes
Decisions worth stealing
- Shared TypeScript types across every surface: the mobile apps, the business platform, and the API import the same domain types from a single package, so a rename in the schema is a compile error everywhere it matters.
- API is versioned by URL path with an explicit deprecation policy: a mobile version stuck on the app store for a week does not force server-side compromises, and clients get a written notice before an endpoint goes away.
- Identity is SSO with role-scoped tokens; the API is the enforcement point for every rule: the UI cannot request what the API refuses to return, and there is no second, more permissive path in.
- Event bus with idempotent handlers and dead-letter queues: notifications, receipts, and audit writes survive partial failures, and a replay is a supported operation rather than a scary Sunday.
- Observability is one correlation id across mobile → API → workers → email/push, so a customer report about “this didn't work” lands on a single trace, not a scavenger hunt across three dashboards.
- Feature-flag service is shared across all three surfaces (mobile, business, and marketing) so a launch is a schedule, not a coordinated deploy dance.
- Over-the-air updates on mobile for anything short of native module changes: bug fixes ship the same day, and the app-store cycle only gates real native work.
- The design system lives as tokens, not screenshots: colours, type, spacing, motion, and elevation are code, consumed directly by React (marketing + business) and React Native (mobile), with contrast and hit-target minimums enforced at the token layer.
- The marketing site is statically generated with tag-based revalidation on content updates and held to a Core Web Vitals budget enforced in CI: a slow marketing site quietly undoes the mobile app's first impression.
- One CI pipeline per surface, one shared release calendar, one shared feature-flag key namespace. Coordination is process, not folklore.
Results
What we measure
- Time to ship a coordinated three-surface change (design + copy + feature) from PR to live
- Design-token drift incidents per quarter (target: zero)
- Marketing-site Core Web Vitals against the CI-enforced budget
- Mobile app-store review latency and OTA-fix rate for non-native regressions
- API contract-break incidents caught in CI vs escaping to a surface
Domiraqo is an internal product, so the honest evidence is the architecture itself. Measured figures (release cadence, drift incidents, vitals) will be published here with source and date once the instrumentation clears our own bar.