Case file

FSHNiSTA

A social commerce platform for fashion and beauty. One identity across a Flutter app, nine services and the web, with a generated Digital Twin at the centre of it.

One identity, resolved by every service that touches it
Author
Henry CartoMSc · Software, Medical & eHealth Engineer
Role
Co-founder and CTO. Mobile app, services, website, infrastructure.
Stack
Flutter · Dart · Domain services · Postgres · Payment rails
State
In private testing on iOS and Android

Product thesis

Fashion commerce is built around the catalogue. A shopper arrives at a grid of garments photographed on someone else, filters by a size label that means something different at every brand, and is asked to imagine the rest. The industry's answer has been more photographs and a returns policy, which is why return rates on apparel sit where they do. The harder problem is that the person is missing from the transaction: the platform knows the garment in detail and knows almost nothing about the body, the taste, or the people whose judgement the shopper actually trusts.

FSHNiSTA is built the other way around. The account is a person with a generated Digital Twin, a social graph, a wallet and a location, and every surface reads from that one identity. The shop, the service bookings, the discovery map, the messaging and the try-on are not separate products stitched together behind a shared login. They resolve the same person, which is what makes a garment renderable onto the right body, a booking attributable to the right member, and a discovery pin visible only to people that member has accepted.

Architecture

Three tiers: a Flutter application for iOS and Android, a web tier, and a set of independently deployed services behind them.

The client is a feature-first monorepo of local packages, with the domain layer, the data layer and navigation contracts each isolated so that features never import one another. Widget trees are treated as replaceable and the business logic is not. Configuration is injected at build time rather than compiled in.

The services are split by domain rather than by layer: commerce and orders, service bookings, geographic discovery, messaging, a credit wallet, media brokering, moderation, logistics, and discovery boosting. Each owns its own data and none reaches across a boundary. Generation of the Digital Twin runs apart from all of them, because its runtime profile has nothing in common with a request-serving container.

The property that holds the whole thing together is single identity. One user record is the key everywhere, every service verifies a caller independently against the same source of truth, and no service maintains its own parallel notion of who someone is. That decision is what keeps the platform from becoming nine products wearing one logo.

Key engineering decisions

Independent verification over a trusted gateway. Every service authenticates the caller itself rather than trusting an upstream component to have done it. The cost is that verification lives in every service. What it buys is that no single component's compromise hands over the platform.

One concept, one store. The recurring fault this platform has paid for more than once is a single concept living in two places, with the client reading one source while the truth lived in another. Several domains had this shape and all were migrated. The rule now is that each fact has exactly one owner, and a read path does not exist for the client until it is named explicitly.

Self-hosted map tiles rather than a tile provider. Discovery runs on a basemap served directly from object storage and read by the client over range requests, with no tile server in between and no key shipped in a mobile binary. The cost is storage and a pipeline to regenerate. What it buys is a map with no per-view billing and no third-party rate limit sitting between a member and the product.

Escrow rather than direct settlement. An order is created in a pending state and is only promoted once the payment provider confirms it, either through its callback or through reconciliation on read once the order is old enough that a lost callback is the likely explanation. Funds are held and released on delivery confirmation rather than paid straight through. A lost webhook can therefore never strand a paid order, and a seller is never paid for something that has not arrived.

Payment rails chosen per market, named nowhere in the product. Currency does not route a payment and no code path names a provider inline, so entering a new market is a registration rather than a rewrite.

Deployment as a deliberate act. Releases are made explicitly and the deployed revision is read back afterwards to confirm what actually shipped. This is slower than an automatic pipeline and it is the direct expression of the rule the whole platform runs on: read the deployed artefact, not the repository, and treat a green merge as no evidence at all.

The signature element

The Digital Twin is the heart of the product, and it is deliberately never called a virtual try-on.

The Twin is generated from a small number of photographs of the member. From it the product generates a set of looks, and a try-on renders an actual catalogue garment onto that Twin rather than onto a model. The pipeline crops and normalises each render, and an identity check gates the output before a member ever sees it, so a render that has drifted from the person is never shown.

What makes it defensible rather than a demo is that the model's measured behaviour is documented alongside the code: which instructions are reliably obeyed, where they are weak, and where the practical ceiling sits. That record is what allows the ceiling to be raised deliberately rather than discovered in production.

Where it stands

In private testing on iOS and Android, with the full service set running and the web tier live. Development is active and the roadmap is not public.