Mumbai, India · Senior Product Manager (InfoPhone + InfoToDo), Enso Webworks

Hassan Ansari

Flutter engineer turned product manager, still close to the stack.

I'm Hassan. I spent six years building Flutter, Firebase, and Node products before moving into product management. At Enso Webworks, I work on InfoPhone and InfoToDo: one is a real-time communication rebuild, the other is an offline-first productivity product. I still stay close to architecture because most of the product calls I care about have technical consequences.

open to product conversations.


Most product decisions are bets.

The best ones are the bets you don't take.

I'm still learning the difference.

Case Studies

Three decisions, written down.

Each case centers on one pivotal Bet. Supporting decisions live inside Outcome and Reflection.

Case 01

InfoPhone

  • year 2025
  • duration ongoing
  • role Product Manager (& engineer of the prior build)
  • stack Native iOS (Swift) + Native Android (Kotlin) + raw ejabberd + LiveKit + NestJS + Drizzle
  • status In testing phase. Not yet shipped to end users.

Real-time chat + voice/video at Enso Webworks. We shipped a Flutter + MirrorFly build, used it in production, and made the call to scrap it and rebuild native — raw ejabberd for chat, LiveKit for calls, NestJS for the rest. This case is about killing a working build before sunk cost killed the product.

Problem

The issue was not one bad bug; it was cumulative drag. Every workaround added more velocity tax, while the product still missed features users expect from a modern communication app.

  1. Performance issues across multiple surfaces. The core product promise was real-time communication, and the old build made that promise feel unreliable. Frequent crashes and laggy calls made users distrust the entire app, even when the rest of the product worked.
  2. MirrorFly SDK opacity. We were locked into a vendor whose code we couldn't read. Every bug routed through their support queue; basic protocol questions cost us weeks. Speed of iteration depends on access to your own stack, and we didn't have it.
  3. Closed SDK = blocked features. The roadmap was being shaped by vendor support, not user needs. Features that should have been table stakes stayed blocked, creating competitive gaps we could explain internally but not justify to users.
  4. Flutter ceiling at iOS PiP. PiP is expected behavior for a serious calling product in 2025. Missing it made the product feel dated, and another Flutter workaround would not have been a credible promise.
  5. Wrapper-on-native architecture. Every feature carried a double implementation tax. The team was moving slower while still not getting the benefits of a fully native product or a clean cross-platform one.

Options

OptionWhy we rejected (or didn't)
AStay the course and delay the rebuildThis would reduce short-term disruption but keep users on the same unreliable path. It was a deferment of the hard call, not a solution.
BTake a smaller rebuild with a different vendorIt reduced migration cost but kept the product dependent on someone else's roadmap. The risk surface changed names; the ownership problem stayed.
CFull stack ownership with no platform ceilingChosen.
DRewrite into a different cross-platform promiseThat would create migration work without changing the problem class. Different stack, same ceiling.

Bet

Choose ownership over convenience: one expensive rebuild now, instead of letting vendor opacity and platform compromises tax every future feature.

Why this stack at all — code ownership

The call was operational confidence. During an incident, the team should debug by reading code and logs, not by waiting for a vendor reply.

Why native specifically

The product should not negotiate with its framework for basic communication features. Native keeps future UX decisions open instead of pre-deciding what is impossible.

Why LiveKit specifically
  • Enso already had operational knowledge from another LiveKit app, so adoption risk was lower than a cold vendor switch.
  • Choosing LiveKit kept the door open for future provider swaps instead of betting the product on one external roadmap.
Why raw ejabberd over a wrapper

For chat, long-term stewardship mattered more than SDK convenience. The product needed a stack we could own for years, not a vendor shortcut we might outgrow again.

Outcome

The product is in testing, not shipped to end users yet. The important milestone is that the team has crossed from patching the old build to validating the new one.

Features that were previously blocked are now in scope. The team can make product commitments based on capability, not vendor limitation.

Reflection

product — ownership

I killed the old build later than I should have. Every patch sprint made the sunk cost heavier, but the signals were already clear. I should have written the kill memo two months sooner.

engineering — process learning

I should have forced SDK proof earlier: PiP, screen share, backup/restore, source-level debugging, and failure-mode ownership should have been week-one POC gates before the team built on top of MirrorFly.

Case 02

Clickked

  • year joined mid-2023; project itself started 2021
  • duration mid-2023 – present (ongoing)
  • role Sole technical lead. Every product/tech decision since joining — paywall placement, consultant web app architecture, NestJS backend design.
  • stack Flutter user app + Flutter web consultant/admin apps + Supabase dating backend + Firebase chat/notifications + GetStream video + NestJS/TypeORM consultant backend on Supabase Postgres
  • status v1 currently live on Play Store + App Store. v2 (paywall pivot + consultant flow updates) is in development, ~2 months in, not yet shipped.

Clickked is a two-sided dating + consultant marketplace. The marketplace shape was a stakeholder vision from inception, completed during 2021–2023. I joined mid-2023 as sole technical lead and have owned every product/tech call since. The product has two paywall surfaces — the dating side (the focus of this case) and the consultant side, which is always open to browse with a pay-per-session model for bookings. This case is about the v1 dating paywall placement and the v2 pivot it forced.

Problem

The hypothesis was that early gating would prove conversion intent. In practice, it asked users to pay before they had experienced the thing they were being asked to buy.

Users were gated mid-investment. They had spent effort creating a profile, but had not yet received dating-product value.

Nine out of ten users left before swiping, matching, or seeing the core loop. The paywall was collecting friction, not conversion intent.

Options

OptionWhy we rejected (or didn't)
AAccept the funnel cost and wait for intent to emergeA 90% gate-loss before value delivery is funnel breakage, not quality filtering.
BMove to a fully free dating surfaceThe marketplace still needs paid users. Removing the gate entirely defers the business problem instead of solving it.
CGate after the first aha-momentChosen.

Bet

Move the dating paywall from halfway through profile setup to after the first swipe. The v2 pivot is in development and not shipped yet.

Why "first swipe" specifically — two reasons

Consultants already give Clickked an always-open free surface. The dating paywall can act after the user tastes the dating loop, while still filtering low-quality or bot accounts.

The product instinct underneath

Paywall before value feels like a toll booth. Paywall after value feels like a fair trade.

Outcome

  • ~90%v1 drop-off at the paywall
  • ~2 monthsv2 in development

The pivot is in-flight because v1 showed a clear drop-off pattern. It is not yet a shipped win, but it is a decision grounded in observed behavior.

If users leave after the first swipe, that is a sharper signal. It means they tried the value proposition before deciding whether to pay.

Reflection

product — ownership

The paywall placement should have been after the first swipe from day one. The consultant surface already gave users a free entry point; dating needed to show value before asking for money.

engineering — process learning

I would instrument the funnel more aggressively from the first release: onboarding step exits, gate exposure, payment started, payment completed, first swipe, and retry behavior should have made the failure visible earlier.

Case 03

file_saver

  • year First release 11 March 2021 · v0.4.0 May 2026
  • duration ~5 years and counting (active maintenance)
  • role Author and sole maintainer
  • stack Dart, pub.dev, cross-platform (web + mobile + desktop)
  • status Live on pub.dev — 185k+ downloads · 491 likes · 140 pub points · v0.4.0 shipped May 2026 · active maintenance
  • repo github.com/incrediblezayed/file_saver

file_saver is an open-source Dart package that saves files cross-platform from Flutter apps — web, mobile, and desktop. I built it in 2021 for a personal project when no existing package handled the web-vs-mobile platform fork cleanly. Five years on, it's at 185k+ monthly downloads with active maintenance — most recent release v0.4.0 (May 2026) added Swift Package Manager support, streaming writes, and Wasm-friendly conditional imports without breaking the public API. This case is about the architectural call I made on day one — how to structure the abstraction — and how it has aged.

Problem

Flutter developers do not want to learn four save-file models for one feature. They need one mental model that works across target platforms.

  1. Web. A web developer expects an instant browser download, not a plugin setup story or a platform-specific detour.
  2. Mobile (iOS). iOS users expect the platform-native share/save experience. The package has to feel like the OS, not like a custom workaround.
  3. Mobile (Android). Android fragmentation is exactly what the package should absorb. The developer should not rewrite file-saving logic for each OS version.
  4. Desktop. Desktop users expect native save dialogs. A cross-platform package has to preserve that expectation while hiding the implementation split.
  5. Single import to hide the fork from developers. The value was developer ergonomics: call FileSaver.saveAs(...) and stop thinking about which platform is underneath.

The developer-facing promise was one import and one API. The platform complexity belongs inside the package, not in the user's app code.

Options

OptionWhy we rejected (or didn't)
AOne import for the developerChosen.
BArchitecturally pure, but more install frictionFor this package, asking users to add multiple packages would make the solution feel bigger than the problem.
CMake the developer choose the platform path manuallyThat defeats the core promise: one API for saving files anywhere Flutter runs.

Bet

Optimize for the developer's first five minutes: add one package, call one method, ship the feature.

The product instinct underneath

The deciding question was not architectural purity; it was how many packages the user had to add for one simple job.

Outcome

  • 185k+monthly downloads
  • 491likes on pub.dev
  • 140pub points
  • 5years active
  • v0.4.0current release

The call aged well: v0.4.0 shipped in May 2026 with SPM support, streaming downloads, and security hardening — meaningful evolution that didn't ask any user to migrate or change a single import. The architectural choice from day one keeps paying.

API stability became part of the product value. Five years and four major releases later, developers can still trust the package instead of relearning it. Adding new platforms and capabilities has been additive, not breaking.

Reflection

product — ownership

As steward of a widely used package, I should have treated maintainer experience as product surface too. The API was simple for users, but the project was too dependent on one maintainer.

engineering — process learning

The architecture held, but the project needed stronger scaffolding earlier: tests, CI, contribution guidelines, and an explicit revisit when desktop support became real.

Experience

Six years across startup chaos and enterprise structure.

  • Enso Webworks · Senior Product Manager

    Feb 2026 – presentMumbai, India

    Senior Product Manager on two Enso products. Cross-functional across both — engineering, design, and stakeholder communication.

    • InfoPhone (May 2025 – present)Real-time chat + voice/video. Owning the architectural rebuild from a wrapped-vendor SDK to native iOS/Android + raw ejabberd + LiveKit + NestJS.
    • InfoToDo (Feb 2026 – present)Personal task management with tasks, notes, reminders, and offline-first sync. Initially outsourced; I led the early tech architecture, then came back officially to close requirement gaps and make further product and technical decisions.
  • Enso Webworks · Product Manager

    May 2025 – Feb 2026Mumbai, India

    Product Manager on InfoPhone — owning the architectural rebuild from a wrapped-vendor SDK to native iOS/Android + raw ejabberd + LiveKit + NestJS. Promoted to Senior Product Manager in Feb 2026 when InfoToDo was added to my portfolio.

  • Enso Webworks · Senior Software Developer

    Oct 2024 – May 2025Mumbai, India

    Built InfoProfile from scratch with a 4-developer team. Owned core services — BLoC wrapper, API handler, environment flavors, Firebase integration, auth, notifications, and media flows. Helped shape the team's architectural conventions early. Built and maintained backend APIs in Node.js/TypeScript with Hapi.

  • Trubary Technologies Pvt. Ltd. · Full-Stack Developer

    Oct 2023 – Sep 2024Mumbai, India

    Maintained and extended Pappyon: a Flutter mobile app, Vue 2/Vuetify business portal, and Firebase Cloud Functions. Worked across Firestore, Auth, Storage, messaging, payments, QR/link preview flows, and cross-platform workflow automation.

  • Exceptions · Senior Software Engineer

    Jan 2023 – Oct 2023Mumbai, India

    End-to-end ownership across Flutter + Firebase client projects including Fin Moto Corp, ServYou 24, and GharTak. Client-facing on requirements, team-facing on code review and delivery quality. Where I learned to translate vague client asks into concrete development plans.

  • Pegasus InfoCorp · Senior Software Engineer

    Sep 2022 – Jan 2023Mumbai, India

    Worked on Caratlane's internal Digital QC app in Flutter. Wrote the test suite that took coverage from 0 to 80%, enforced linting/code standards, and made one small Ruby-side dropdown value change when the workflow needed it.

  • Capgemini · Software Associate

    Mar 2021 – Sep 2022Mumbai, India

    .NET / C# shadow project alongside senior engineers. Server operations, UAT data migrations, user-ticket triage. First exposure to enterprise-scale process — the slow, structured kind that's the opposite of startup chaos.

  • Swift Media Labs · Senior Consultant / Software Developer

    Jan 2020 – Mar 2021Mumbai, India

    Service-based Flutter app work with a 3-developer team. Architected frontend/backend boundaries with the backend team. Led 2 junior developers through requirements interpretation and project planning — first taste of being responsible for someone else's output.

  • Frynds & Co · Lead Software Developer

    Dec 2019 – Sep 2020Mumbai, India

    Built Hungry, a food delivery system, from scratch — Flutter app, Firebase backend services, and TypeScript/Node.js Cloud Functions. On-site at the client's office, with every change reviewed in person. End-to-end ownership of architecture, build, and deployment.

Education

BSc, Information TechnologyUniversity of Mumbai (BNN College)2017 – 2020

Toolkit

What I actually use, not what I aspire to claim.

Engineering

Languages
Dart · TypeScript · JavaScript · Kotlin · Swift
Mobile
Flutter · Native iOS · Native Android · Provider · Riverpod · BLoC · GetX · PowerSync · Drift
Backend
NestJS · Node.js (Express, Hapi, Fastify) · TypeORM · Drizzle · Prisma · REST APIs
Frontend (web)
Vue 2 · Vuetify · Next.js · React
Real-time / communication
XMPP · ejabberd · WebRTC · LiveKit · Janus · Method channels · UIKitView / PlatformViewLink
Cloud / infra
Firebase · Firestore · Firebase Cloud Functions · Supabase · Postgres · Redis · GCP · GitHub Actions · CodeMagic
Tooling
Git · GitHub · GitLab · AWS CodeCommit
Testing
Jest · JUnit · Flutter Integration Testing
Notable open source
file_saver — cross-platform file saving for Flutter, multi-year maintenance

Product

  • Discovery

    Signal before process.

    Most product signals currently come through shipped behavior, team feedback, leadership context, and stakeholder conversations. Direct user research is the next area I want to make more consistent, especially while the products are still early enough to change direction cheaply.

  • Strategy

    Written proposals, then alignment.

    I prefer writing the direction down first: what changed, what options exist, what we are choosing, and what we expect to learn. The Decision Log format on this site is the same habit applied publicly.

  • Analytics

    Firebase Analytics.

    I use Firebase Analytics where it exists, but I care more about whether the funnel answers the right question. Clickked's paywall decision came from exactly that kind of signal: the event shape was basic, but the drop-off was clear.

  • Communication

    Slack for speed, docs for decisions.

    Slack works for momentum; written notes are where decisions become reusable. Sprint planning already has structure, and the next maturity step is turning more product calls into short decision docs.

  • Execution

    JIRA · two-week sprints.

    Two-week cadence, JIRA for tracking, async-first communication for everything else.

  • Frameworks

    Lightweight by default.

    I don't force a framework when a clear memo will do. For now, the useful shape is simple: problem, options, bet, outcome, reflection.

Selected ships

The breadth that doesn't make the case study cut.

One line each. No Decision Log structure — just what shipped, where to find it.

Bhasusa

  • BAVBuy A Vehicle, Book A Vehicle

    EV marketplace and booking flow across user and dealer apps, with charging-station maps, payments, dealer stock/test-ride management, and GraphQL-backed data access.

    Flutter · Riverpod · Ferry GraphQL · Firebase · RazorpayLive · Play Store + App Store

Enso Webworks

  • InfoProfileProfile-first mobile app

    Built from scratch in a 4-developer team: auth, profile flows, media, notifications, maps, QR, subscriptions, and backend API work.

    Flutter · BLoC · Firebase · Hapi · MongoDBProduction

  • InfoToDoTasks, notes, reminders

    Offline-first productivity product with mobile app, admin surface, local sync, and backend APIs.

    Flutter · PowerSync · Drift · NestJS · TypeORM · Postgres · Next.jsActive product

Trubary

  • PappyonMobile app + business portal

    Maintained and extended a production Flutter app and Vue business portal with Firebase-backed workflows.

    Flutter · Firebase · Firestore · Vue 2 · Vuetify · Cloud FunctionsProduction

Exceptions

  • ServYou 24Home services platform

    Mobile app for home-services workflows across districts.

    Flutter · FirebaseLive · Play Store + App Store

  • MyGoLocal-first taxi booking

    Cabs, autos, and partner/admin workflows with Firebase-backed location and workflow automation.

    Flutter · Firebase · Firestore · TypeScript Cloud FunctionsLive · Play Store

  • Fin Moto CorpUsed-bike marketplace + financing

    OLX-style flow for second-hand two-wheelers and financing discovery.

    Flutter · FirebaseLive · Play Store · 10k+ downloads

  • GharTakOnline food delivery

    Zomato/Swiggy-style delivery system with separate customer, restaurant partner, and delivery partner apps.

    Flutter · FirebaseBeta / pre-launch

  • Gochi MeatOnline raw-meat delivery

    End-to-end meat ordering product with separate customer, shop partner, and delivery partner workflows built on Flutter + Firebase.

    Flutter · FirebaseNo longer live · taken down

Earlier work

  • HungryFood delivery system

    Food-delivery product with separate customer, restaurant partner, and delivery partner workflows, built on-site at Frynds & Co with direct client review on every change.

    Flutter · Firebase · TypeScript Cloud FunctionsNo longer live · taken down

Flutter · Kotlin · Swift · TypeScript · NestJS · ejabberd · LiveKit · Firebase · PowerSync · Riverpod · TypeORM · Prisma · Postgres · pub.dev · XMPP · Method Channels · Mumbai

© 2026 Hassan Ansari. Six skins, same content. Try the others.