This page records the architectural choices that shape every other engineering page in this section. Each section below states a fact about the system as it stands today: what the architecture set is, what the customer application is built on, where the canonical contract lives, how the phase model behaves at the boundary between code and data, how commerce records are structured, what the backend runs on, and how multilingual user-generated content is handled. The choices are stated as plain present-tense facts and are written so that another engineering page can refer to them without restating them. Implementation detail belongs on the pages those choices govern — the System overview, Application architecture, Backend, Domain and data architecture, Integrations, and Security and operations pages — and this page is the index of the underlying choices that those pages assume.
The active architecture pack is the small set of pages in this section. New engineering work consults these pages; there is no second, parallel architecture catalogue and no shadow document set that an engineer is expected to discover. When a question is not answered by the pages in this section, the answer is either a code-level detail belonging in the source tree, a requirement belonging in the requirements section, or a question that is not yet answered and must be raised explicitly rather than inferred.
The DomiDo customer-facing surface is one universal application built on React Native and Expo. The same codebase compiles to Web and Progressive Web App via React Native Web, and to native iOS and Android binaries via Expo. The application is intentionally one product across runtimes rather than three parallel codebases, and frontend code paths must not introduce web-only product logic into production modules: the universal target stays universal, and any platform-specific affordances live behind a thin platform adapter rather than leaking into business code.
Web and Progressive Web App on desktop, with a mobile-width browser smoke pass, is the automated and acceptance test gate. iOS and Android compatibility is preserved continuously through the codebase architecture; native test gates become mandatory when their delivery phases open. The reason the gate is structured this way is that the active product surface is Web and Progressive Web App, and adding a native gate before the native phase opens would not catch problems that the desktop and mobile-width passes already catch through the universal layer.
The OpenAPI contract under the Interface requirements page is the single source of truth for the platform's REST surface. Architecture pages reference application-programming-interface concepts; they do not duplicate schemas, paths, or examples. When a new endpoint is needed, the change lands in the requirements contract first and architecture pages are updated to reflect the resulting shape, not the other way around.
The Phase A, Phase A.5, Phase B, and Phase C model is enforced at the application-programming-interface, frontend, domain-service, test, and audit-event layers — not only at the user interface. A button can be visible in the application while the operation behind it returns a typed gated response — one of active, readiness-only, preview, deferred, or blocked — and the gated response is the contract that the rest of the system reads. Phase gating prevents the application from accidentally implying charge, fulfilment, shipment, or payout behaviour before the business is ready, and it gives every layer of the platform a uniform way to recognise that a path is not yet open.
Phase A interest reservations, Phase A.5 pre-orders, and Phase B orders are modelled as three separate aggregates with distinct identifiers, lifecycles, and persistence. An interest reservation is the Phase A non-binding signal of demand and carries no card, no payment, no legal pre-order, and no fulfilment. A pre-order is the Phase A.5 verified-card commitment, with the card verified through a Stripe SetupIntent and no funds moving. An order is the Phase B captured-funds, fulfilment-active record, with a successful Stripe PaymentIntent and a shipping kit. Listing actions in Phase A create an interest reservation; checkout confirmation returns a checkout commitment only in Phase A.5 and Phase B; dashboards and designer attribution distinguish interest, no-capture pre-order demand, and captured sales without collapsing them into one ambiguous record at any layer.
Designer onboarding — Stripe Connect, Know Your Customer, payout settings, projected royalties, statement previews, reserve and dispute modelling, Promo Studio, and designer engagement — becomes available in Phase A.5, before Phase B begins capturing funds. Actual payout release remains a Phase B operation, gated by captured funds, delivery eligibility, reserve and dispute checks, and a positive payout-readiness state on the owning payout account. The two-step structure lets designers complete their onboarding and verify their projected entitlements before the platform starts moving money, and it lets the operations team observe payout readiness independently of payout release.
The DomiDo backend is implemented in Go. MongoDB Atlas is the primary database, and Atlas Vector Search provides semantic discovery, similarity, and recommendation workflows over the same documents. The platform uses MongoDB transactions for multi-collection commerce transitions, and MongoDB-backed jobs, idempotency state, the outbox, and search documents avoid the need for additional infrastructure during the early phases. Large binary media and model artefacts live in object storage; MongoDB stores metadata and signed references to them rather than the binaries themselves. Implementation detail beyond these choices — package layout, runtime configuration, the worker loop, the transaction runner, and the index-creation command — lives on the Backend page.
User-generated free text is stored in its source language and translated asynchronously through backend-owned text-translation jobs into the configured supported languages. The application reads localised application-programming-interface snapshots; it never calls translation providers directly. The translation configuration endpoint, the localised-text and localised-field-map types, and the text-translation job type are foundation contracts, and source text saves immediately so that a translation failure produces fallback or retry state without failing the original mutation. The architecture is provider-neutral: a deterministic fake provider supports local and test runs, and the production translation provider is an implementation configuration choice that the system can change without touching the contracts that the application reads.
Beyond the choices stated above — the universal application, the canonical application-programming-interface, the Go and MongoDB Atlas backend, and backend-owned translation — other infrastructure products are not architecture-wide mandates. Durability, security, observability, backup, async-work, and integration requirements are architectural and are stated as requirements; the specific products that satisfy them are focused integration choices that are made when a need is concrete. The reason for the asymmetry is that the requirements are stable and the product market is not, so binding the architecture to a particular vendor before that vendor is needed buys nothing and costs flexibility.