01
Hexagonal architecture with a Result type
Database, storage and AI providers are swappable adapters behind ports. Expected failures return Result values instead of exceptions, so callers must handle both branches.
Personal project
Photograph your clothes; get outfits built from what you already own
The adapter gets a presigned URL, uploads the photo straight to R2, asks the classifier (which reads the photo and calls the vision model), the use case validates the proposal in the domain and the garment is saved under row-level security.
Click a step to jump to it. Click a component for details.
Mirra is a native iOS/Android app (Expo / React Native) that turns a user's own clothes into a digital closet. A garment photo is uploaded to private object storage, a vision model proposes its attributes, and the user confirms them. Outfit generation is built on a pure domain model that enforces composition rules.
People own clothes they rarely combine well and have no single place that knows what is in their wardrobe. Manual cataloguing is too tedious, so the app automates classification while keeping the user in control of the result.
01
Database, storage and AI providers are swappable adapters behind ports. Expected failures return Result values instead of exceptions, so callers must handle both branches.
02
Zero egress cost and no 1 GB storage ceiling; the database stays small and holds only object keys and metadata.
03
API keys stay as server secrets, cost is measurable in one place, and the OpenAI-compatible provider can be replaced without touching the app.
04
Composite foreign keys make cross-user composition structurally impossible, so a bug in application code or RLS cannot leak data between users.
05
No passwords to store and no deep-link setup needed for the MVP; social login is deferred until credentials exist.