Skip to content

ADR-016: A removable demo shop

Status: accepted 5 October 2026 (owner decision: the demo lives in the shop itself, with a full shop’s data, a demo notice on the storefront and no ordering).

The owner wants new shops to see Flowery at work before they enter their own flowers, and to clear the example data in one click when they start selling.

A full demo touches everything the books protect:

  • order revisions are append-only;
  • every stock change is a ledger movement;
  • batches are never deleted;
  • products used in orders are only deactivated.

The alternative was a separate sandbox shop, deleted whole. The owner preferred the shop itself, so that the storefront, settings and checklist are the real ones.

  1. Marked records. is_demo on categories, flowers, bouquets, packaging, suppliers, supplies, batches and orders, and workspaces.demo_loaded_at. DemoShop::load() creates the demo through the real services:

    • batches are received through the ledger;
    • orders are created, reserved, assembled, paid and delivered by OrderCreator, OrderStatusChanger and OrderPayments.

    So the demo obeys every rule while it exists. It loads only into a shop with no products or orders of its own.

  2. Removal is the one exception, for demo data only. DemoShop::remove() deletes the marked records in one transaction, including their movements, allocations, revisions, transitions, payments and photo files. It is the only code allowed to delete movements, batches or order history. It keeps the books consistent:

    • Batches go together with their movements.
    • A demo order holding stems on a batch that stays gives them back through the ledger (release).
    • Each kept flower’s total is recomputed from its remaining batches, which is the reconciliation rule.
    • inventory:reconcile stays green; tests prove it.
  3. Real work keeps what it uses. These demo records are kept, unmarked, and become the shop’s own:

    • a bouquet or flower in a real order;
    • a flower in one of the shop’s own bouquets, or a builder bouquet a real order contains;
    • a batch a real order reserved or used;
    • a flower the shop restocked;
    • the supply, supplier and category those need.

    A customer’s builder bouquet that is still only in a cart is a draft, and goes with the demo stems it is made of.

  4. The storefront gets the demo hero and featured bouquets as a new published version. It is left alone if the owner has unpublished changes, and the profile is never touched.

    On removal, removed bouquets and the demo’s own images (“demo-…” files) are taken out of the live configuration and the draft, and the result is published as a new version. History keeps the earlier versions; reverting to one that shows a removed bouquet is refused by the usual validation.

  5. Visitors are never misled. While the demo is loaded:

    • the Storefront API’s GET /shop says demo: true;
    • both themes show “Демонстраційний магазин…” on every page;
    • checkout follows the shop’s own settings, and every order placed is a test order (see the amendment below).
  6. Who. Loading and removing need settings.edit (owners and admins). Every member sees a banner on every control-panel page.

  • Order numbers and ids the demo used may be reused by later real orders. Nobody outside the shop ever saw them.
  • A demo record the owner edited is still a demo record, and goes on removal. Anything the owner created is real.
  • The currency lock (B12) holds while the demo has prices, and lifts when it is removed.
  • The demo is Ukrainian and priced in hryvnias, like the first market.

The owner wants to take a demo shop through the whole process, from the storefront to delivery. So §5 changes: a demo shop takes orders when its checkout is on.

  • Every storefront order placed while the demo is loaded is marked is_demo, so removal deletes it with its history, payments and checkout submission.
  • Staff see a “Демо” badge on it in the order list and on the order page.
  • Both emails say it is a test: the subject starts with “[Демо]”, and the first line explains that nothing is delivered or charged.
  • A demo order never books a real Uklon courier: dispatch refuses it. Uklon’s live price at checkout is still shown, since an estimate costs nothing.
  • The storefront notice now says orders are test orders.
  • Orders staff create in the control panel during the demo stay real orders, as before. They keep any demo product they use when the demo is removed.

With Finance (ADR-018), the demo also records three small operating expenses this month (wrapping materials, an advert, a taxi), marked is_demo, so its statement shows how operating profit is made. Removal deletes them; expenses the owner recorded stay. Finance includes demo figures while the demo is loaded, with a switch to hide them.

Amendment, 12 October 2026: offered while the shop is empty

Section titled “Amendment, 12 October 2026: offered while the shop is empty”

The demo could be added only to a shop with no flowers, no bouquets and no orders, and the offer lived on the dashboard alone. A real shop that had added one flower by hand before the welcome steps existed never saw it, and its storefront showed a themed but empty catalogue. Now the demo can be added while the shop has no bouquets and no orders; flowers it added stay beside the demo’s, which are marked and leave with it. Every control-panel page shows the offer as a banner to owners and admins until the demo is loaded or the shop sells something of its own.