This page captures the quality requirements for the DomiDo platform — the "how well" rather than the "what". The functional requirements describe what the platform does; this page describes how fast it must be, how reliably it must recover, how accessible its surfaces must be to a keyboard and a screen reader, how observable its failures must be to the operations team, and how maintainable its code and configuration must remain over time. The current release surface is the Web/PWA beta and Web desktop is the mandatory validation target, with iOS, Android, tablet, and mobile-web layouts kept architecturally compatible without being acceptance gates until their phases open. The page does not prescribe specific infrastructure, storage, analytics, or deployment products — those choices live in a separate architecture decision once the requirements are approved, and the rules below are written so they can be satisfied by more than one product choice.
Every interactive surface must be operable from a keyboard. That covers the header and footer navigation, the modals and drawers, the forms and sliders and steppers, the upload slots and tabs and action menus, the Promo Studio controls, the dense dashboard tables, the checkout steps, the saved-cart controls, the notification inboxes, the Help comment controls, the admin content forms, and the order action panels — there is no surface that depends on the mouse alone. Modals and drawers trap focus while they are open, restore focus to the triggering element when they close, close on the Escape key where that is expected, and expose accessible labels on their close buttons and primary actions so screen readers can describe them. Form validation appears as inline text associated with the field rather than as a colour change alone, and interactive icon-only controls carry accessible names so they are still legible without their glyph.
Status announcements use accessible status regions or equivalent semantics so that the work the platform does in the background is audible. The states that announce themselves include upload progress, generation progress, model feedback submission, Promo Studio generation, payment verification, checkout step changes, saved-cart resume and discard outcomes, unsupported-jurisdiction messages, pre-order commitment and cancellation, fulfilment waits, order notifications, order actions, payout readiness, reserve and dispute updates, Help comment actions, admin help-content actions, and the save-and-publish results across the create flow. Across every surface the app maintains readable contrast — for header, footer, cards, dense tables, muted metadata, disabled controls, status badges, and the Phase A disabled-remix messages — so that information remains legible without leaning on subtle colour cues alone.
The app supports the Web desktop beta layout as the current mandatory target and preserves architecture-compatible desktop, tablet, mobile, iOS, and Android layout intent from the mock. Mobile and native layout checks are compatibility gates, not Phase A acceptance gates, but the production code remains compatible by using shared React Native primitives and platform adapters so the deferred surfaces do not require a rewrite when their phases open. Fixed-format controls — projection face selectors, model tryout cards, model feedback controls, Promo Studio scene controls, Promo Studio asset cards, BOM tables, checkout steps, pre-order status controls, payout controls, and admin content controls — do not shift layout unexpectedly when status text changes, so a user typing into a form or watching a generation progress does not see the surrounding controls jump.
Long strings are handled deliberately. Listing names, designer names, tags, Promo Studio prompts, asset metadata, addresses, tax fields, Stripe payment labels, jurisdiction notices, fulfilment notices, reserve and dispute notices, and action titles wrap or truncate in a controlled way without overlapping adjacent controls. Dense dashboard tables support horizontal or stacked responsive presentation while preserving their actions and status badges, so a designer reading their payout ledger on a small screen does not lose the row-level controls. Media previews preserve aspect ratio and do not obscure the required create, Promo Studio, checkout, or listing controls underneath them.
A user's work must survive interruption. Create drafts and saved generation states are resumable after navigation, refresh, sign-in transition, and the next wizard entry; the model feedback submission failure does not discard the generated tryout or block the user from selecting another tryout; and Promo Studio photo and video generation failures preserve the scene, the prior generated assets, the selected source photo, the keep-and-star state, and the listing-gallery publication state. Projection, model, and block-kit generation failures preserve their prior successful outputs and allow retry, while worker crashes, provider timeouts, expired leases, and duplicate network retries do not create duplicate model or provider calls or corrupt the draft, model, or block-kit state — jobs recover through lease expiry, retry backoff, or dead-letter state.
Checkout preserves cart and entered delivery and payment selections when the user navigates between Bag, Delivery, Payment, Review, and Confirmation. Saved carts and checkout drafts resume deterministically after navigation, refresh, and sign-in transition, and revalidate stale price, VAT, delivery, jurisdiction, and item availability without losing the saved snapshot. Unsupported-jurisdiction state blocks payment consistently and preserves cart data so the user can return when the jurisdiction becomes supported. Pre-order and order actions are idempotent from the user's perspective: a repeated submit after a network retry does not duplicate pre-order commitment, cancellation, order cancellation, address change, delivery preference, return, return assessment, replacement, issue report, dispute, payment retry, message, or trust challenge requests. The idempotent replay is deterministic across API, worker, and provider boundaries — a repeated request with the same key and request hash returns the existing response, while the same key with a different request hash returns an idempotency conflict rather than silently doing the work twice.
Designer payout readiness, payout release, tax, statement, projected royalty, captured royalty, ad-boost, reserve, dispute, disabled-remix, and payout-request operations show deterministic pending, success, and failure states so the designer is never left wondering whether a request landed. The build companion's progress survives close and reopen and remains usable offline once the payload has loaded, where that behaviour is supported. Translation-job failure does not roll back or block the source user-generated text mutation: the resource remains readable through source-language fallback, and retry and state repair are possible.
Phase A open beta targets 99.5% API availability over a rolling 30-day window, excluding announced maintenance, measured by successful app-facing API responses and operational readiness rather than by static marketing or publication assets alone. Durable Phase A business data has a backup and restore objective: MongoDB business records target a recovery point objective no worse than 15 minutes and a recovery time objective no worse than 4 hours, while final or public object-storage assets target a recovery point objective no worse than 24 hours. Intermediate generated artifacts may be regenerated when their source records and configuration remain intact, so the backup discipline focuses on the records that cannot be reproduced.
The backend exposes separate operational health, liveness, and readiness endpoints. Liveness proves the process can answer, readiness fails when core dependencies prevent safe traffic handling, and health returns a sanitised dependency summary without secrets or private provider details. Dependency failures follow a documented degrade-first behaviour matrix for MongoDB, object storage, Stripe, OAuth providers, AI providers, Atlas Search and Vector Search, Docusaurus publication, email and support, analytics, and workers; each matrix row defines the user-visible behaviour, the API status, the retry and recovery path, the observability signal, and the data-safety rule. Temporary MongoDB failover, transaction uncertainty, duplicate-key races, write conflicts, connection-pool exhaustion, and timeout cases map to deterministic retry, idempotent replay, reconciliation, or typed service-unavailable errors, and provider side effects are not duplicated after database retry or recovery. Extended or permanent provider failure disables or degrades only the affected capability, preserves source and domain state, exposes a safe retry or unavailable state, and requires reconciliation before changing committed payment, pre-order, payout, publication, or generated-asset state. Phase A does not require alternate providers to be active before beta.
Object storage and media metadata are recoverable together. Interrupted uploads, the object-written-but-DB-failed case, the DB-written-but-object-missing case, expired signed actions, and orphaned generated artifacts each have a defined cleanup, retry, or regeneration behaviour, and the platform never leaves an asset half-present in the database or half-present in storage. Audit write failure fails closed for payment verification, pre-order commitment and cancellation, payout readiness and release, admin content mutation, privacy, trust, security, and provider-webhook state changes; non-critical analytics failure never blocks user workflows.
Public browsing surfaces prioritise the header, primary content, listing cards, and upload entry before any non-critical secondary content, so the page becomes usable before the rails finish loading. Large media previews, gallery rails, Promo Studio asset libraries, BOM tables, payout ledgers, reserve ledgers, statement archives, help article lists, and order lists lazy-load or paginate where needed to keep interactions responsive. Projection and model previews show skeleton, placeholder, or progress states while they are processing, so the user always sees that work is happening rather than a blank pane. Search, BOM filtering, gallery filtering, order filtering, help search, and statement filtering remain responsive with realistic list sizes, and repeated dashboard and Promo Studio updates avoid full-page reloads when a targeted resource mutation can update the visible state instead. The build companion's step transitions, 3D preview loading, stuck-help panels, and progress saving remain responsive during a build session.
Docusaurus-published Help and Workshop article pages are served as static content and remain readable independently of runtime comment or support API availability; the runtime widgets may show degraded states when their backend calls fail, but the article itself does not go dark. Public search, gallery and listing reads, Help search, dashboard lists, order lists, statement lists, and Promo Studio libraries enforce query length, page, page-size, and result limits before any database work is allocated, so an oversized request never reaches the expensive stage. Model parsing, voxelisation, blockification, Promo Studio generation, large-language-model translation and text assistance, and publication and export work run within configured worker timeout, memory, CPU, concurrency, and cost or budget limits so a single user or a single job cannot exhaust the worker pool.
Closed enums defined by the data and interface specifications are enforced on both client and server, so a value that is not in the allowed set cannot survive either side of the API. Money values preserve amount, currency, formatted display string, and VAT-inclusion metadata where applicable; payment references store only masked Stripe display data, SetupIntent and PaymentIntent safe references, and the provider reference metadata the UI needs to recognise the card. The phase boundary is enforced at the data layer: Phase A interest reservations do not create Stripe, captured-charge, pre-order, receipt, invoice, shipment, or payout-release records, Phase A.5 SetupIntent verification does not create captured-charge, receipt, invoice, shipment, or payout-release records, and Phase B conversion preserves traceable links from the interest reservation to the pre-order and from the pre-order to the order where conversion occurs. Payout and tax settings maintain the separation between data held by Stripe and data held by the platform.
Royalty, projected royalty, listed price, ad-boost budget, payout fee, payout reserve, dispute adjustment, expected charge total, delivery total, jurisdictional VAT, discount, return fee, refund, receipt, and statement calculations are reproducible from stored domain data and the configuration version that was in effect when the value was computed — there are no derived numbers that exist only in transient memory. Configurable values remain traceable to a configuration version: supported jurisdictions, Stripe-supported card copy, feature phase gates, AI generation costs, Promo Studio options and costs, payout fees, thresholds and schedules, reserve and dispute rules, eligibility delay, and disabled-remix state all carry that version stamp. Help content publication state, Docusaurus publication artifacts, and admin edits are versioned alongside the editorial workflow.
Help comments, review replies, Q&A replies, designer message threads, claim actions, interest reservations, pre-order notifications, order notifications, saved carts, and pre-order or order action records retain the resource ownership, status transitions, and moderation and report references needed to reconstruct the visible UI state. Translatable user-generated text preserves source text, source language, generated translations, field and resource context, stale state, translation-job references, moderation state, and the configuration or glossary version needed to reconstruct what was shown in each language.
Cookie preferences are persistent, reviewable, and changeable from the Manage cookies surface. The privacy, data-request, terms, accessibility, and sitemap links remain available from the footer and legal surfaces regardless of authentication state, so the user does not have to be signed in to act on their rights. Account data export, delete, and request flows preserve status and user-visible history where the account mock shows it. The visible boundary is strict: uploaded media, drafts, private Promo Studio scenes and assets, private listings, unlisted listings, saved carts, checkout drafts, pre-orders, order notifications, order tracking, order action attachments, saved addresses, Stripe payment references, model feedback, payout, tax, reserve, and dispute settings, trust restrictions, Help comment reports, and support conversations are visible only to authorised users.
Blacklist and restriction records avoid storing unnecessary abusive content and expose only the minimum detail needed for authorised support, dispute, and affected-user challenge — the platform records that a restriction exists and why in safe terms without preserving the abusive payload around it. Large-language-model translation requests minimise context, exclude structured and sensitive data, redact provider logs, and preserve the same authorisation and visibility rules for translated variants as for source text. Web and PWA sessions protect unsafe cookie-authenticated requests against Cross-Site Request Forgery, and the native-compatible bearer credentials do not depend on browser-only CSRF mechanisms, so the same authorisation layer survives the move to native.
The implementation records user-visible failures for the full set of risky operations — upload, generation, model feedback, Promo Studio photo and video jobs, saved-cart resume and discard, checkout, unsupported jurisdiction, pre-order commitment and cancellation, notification read-state, order tracking and action loads, order actions, return assessment, designer review, Q&A, message and claim actions, Help comment actions, payout readiness and settings, payout transfers, reserve and dispute state, statement export, help-content admin, and support conversation creation — and emits operational alerts based on error rates and failed business operations rather than on a specific monitoring vendor. Logs and diagnostics redact raw card data, OAuth secrets, payout account secrets, tax identifiers where not needed, addresses where not needed, trust-restriction details where not needed, and uploaded private media URLs.
Translation observability records job latency, failure rate, retry count, stale-translation count, fallback-to-source count, and provider error class without exposing raw private text or provider secrets. Job observability records latency, queue age, lease expiry count, retry count, dead-letter count, cancellation count, provider timeout and error class, and stage-level failure rates by job type without exposing private storage paths, raw model files, raw provider payloads, or LLM prompts. Security and abuse controls emit observable counters for 401, 403, 409, 413, 422, 429, invalid webhook signatures, CSRF failures, idempotency conflicts, upload validation failures, provider circuit-breaker state, and job-quota rejections. Dependency health, readiness transitions, provider circuit state, MongoDB transaction retry and failover behaviour, worker drain and recovery, webhook durable-store failures, object-storage mismatch cleanup, and restore-rehearsal results are all observable without exposing secrets, raw provider payloads, private media URLs, or raw user-generated text.
Product analytics use a documented event dictionary with stable event names, versioned property schemas, owner, phase, consent class, and retention class; unknown event names are rejected or quarantined rather than silently becoming product truth. User-behaviour metrics preserve funnel and cohort usefulness while minimising personal data, so analytics events do not store raw payment data, raw addresses, OAuth secrets, unrestricted free-form text, private media URLs, or full LLM prompts and responses. Client errors, backend errors, worker errors, and provider failures carry a correlation or trace identifier that connects the app-visible failure, the backend request, the job attempt, the audit event where applicable, and the support conversation without exposing secrets to the client.
Logs are structured, levelled, redacted, and retained by environment and data class, and Phase A defines retention for raw logs, aggregated metrics, analytics events, support conversations, beta feedback, and audit events before open beta traffic starts. Alerts carry severity, owner, trigger condition, suppression and deduplication behaviour, a user-impact statement, and a first action or runbook. The Phase A minimum alert set covers API error spikes, interest-reservation failure, job queue age and dead letters, translation failure spikes, database readiness loss, object-storage failures, analytics ingestion rejection spikes, and support service-level breach. Phase A.5 adds checkout-and-pre-order failure and webhook durable-store failure alerts before SetupIntent conversion opens.
Support operations are measurable from the founder and admin operations surfaces: open conversation count, first-response overdue count, age by priority, unresolved escalations, repeat-contact rate, and top contact reasons are all visible. Beta feedback and support pain are visible as product-learning signals, and the system supports counting feedback by screen, severity, resource type, locale and language, tester or customer segment, and release version.
The implementation centralises enum definitions for OAuth providers, upload formats, upload kinds, projection faces, create stages, Promo Studio job and asset states, checkout steps, delivery phase status, commitment type, pre-order status, Stripe payment state, fulfilment readiness, visibility, royalty range, payout transfer state, reserve ledger state, sale and dispute state, return assessment reasons, trust-restriction state, and help publication state, so that an enum change happens in one place rather than scattered across the codebase. Delivery methods and search scopes are configuration-driven rather than fixed enums unless a later approved requirement closes them. Configurable values for supported jurisdictions, languages, translation target languages and fallbacks, locale and currency pairs, Stripe-supported card copy, delivery phase gates, AI generation costs, moderation rerun costs, ad-boost budget bounds, Promo Studio presets, options and costs, payout numbers and schedules, reserve and dispute rules, delivery availability, VAT behaviour, search scopes, and feature flags live in configuration or API data so future product decisions can update them without sweeping UI rewrites.
The API, data, and acceptance documents remain path-and-enum consistent with the OpenAPI file, which is the source of truth for public and private endpoint security, standard error envelopes, rate-limit headers, idempotency headers, CSRF headers, webhook signature headers, and bounded request schemas. Requirement updates do not introduce backend technology names or payment providers unless a new approved source explicitly requires them. OpenAPI schemas for saved carts, checkout step mutations, pre-orders, order notifications, tracking, order actions, designer engagement, and Help comments remain named product-domain schemas; maintainers do not replace these contracts with opaque generic object payloads. Shared application code keeps platform-specific APIs behind adapters so the React Native and Expo codebase can serve Web/PWA now and iOS and Android later without rewriting the product modules.