This is a walkthrough of everything currently built and working on the platform, organized as a script you can follow yourself. It deliberately does not cover feature-locking/entitlement UI (variants, multi-UOM, purchasing, etc. gated by plan) — that layer isn't built yet; see Architecture for what exists today versus what's planned.
Each section ends with what you should see if it's working. If something doesn't match, that's a real bug — not expected variation.
bench start running on the bench hosting pos.local (or your site name) with craftivus_core installed.
- If testing
craftivus_subscription too, it needs its own separate site, also running (see Installation: Subscription).
- Existing demo data on
pos.local you can reuse immediately, no setup needed:
- Manager login:
owner@craftivus-demo.local — ask whoever set up the site for the password, or reset it via bench --site pos.local set-password owner@craftivus-demo.local <new-password>.
- A cashier,
POS-CASHIER-00007 ("Ayesha"), already Active with pos_role = Manager — she can both ring up sales and approve manager actions, which is convenient for solo testing.
- A till,
POS-DEV-00002 ("Activation UI Test Till"), on outlet Activation UI Test Outlet, already activated.
- Test items
SKU001–SKU007 with prices already on the Standard Selling price list.
- If any of the above has been revoked/deleted since this guide was written, recreate the equivalent via Desk — see Installation: Backend for exactly what to create.
- Launch
craftivus-pos (npm run tauri dev, or the built app).
- Enter a fresh
POS Device (Pending) activation code → confirm the till shows the outlet name it's now bound to.
- Enter a fresh
POS Cashier (Pending) setup code → set a PIN → confirm you land on the login screen.
- Log in with that PIN.
Expect: the catalog loads (category chips, item images, prices, stock counts).
- Without opening a shift, try to add an item to cart and complete a sale.
- Expect: you're blocked before you even reach checkout — the till requires an open shift before it lets you sell anything. This is enforced on the server too (
complete_sale throws NoOpenShiftError), not just hidden in the UI.
- Tap Open till, enter an opening float (e.g. 1000), confirm.
- Expect: you're now on the normal POS screen, and checkout is reachable.
- Scan or search for an item, add it to cart. Try the quantity-prefix shortcut too: type
3*SKU001 in the scan box and press Enter — it should add 3 in one go.
- Adjust a line's quantity with +/−, and set a per-line discount (should clamp to that item's
max_discount, or 100% if max_discount is 0 — confirm it doesn't clamp to 0%, which is a known-fixed bug).
- Complete the sale: pick a payment method, enter an amount ≥ total, confirm.
- Expect: a receipt prints (or, if no real printer is configured, check Printer settings → "Save to file" transport and confirm a file gets written). The result screen shows change due if overpaid.
- Add items to cart, tap Discount.
- Enter a manager's PIN when prompted.
- Enter a whole-sale discount percentage, apply it.
- Complete the sale.
- Expect: the invoice reflects the discount, and (check via Desk on
pos.local) the Sales Invoice's custom_discount_approved_by field is set to the approving manager.
- Negative test: try the same flow with a non-manager cashier's PIN at the approval step — it should be rejected.
- With the till running, disconnect network access (turn off Wi-Fi, or block the bench's port).
- Complete a sale.
- Expect: the sale still completes locally, immediately — no error, no waiting on the network. It shows as queued/pending.
- Reconnect network.
- Expect: the sale syncs automatically within a few seconds, and its receipt shows a real invoice number instead of "pending sync" if you reprint it.
- Negative test: submit a sale that the server will genuinely reject (e.g. more quantity of a stock item than exists, with
allow_negative_stock off) while online. Expect: it shows up under "X sales need attention," not silently retried forever.
- Complete a normal multi-line sale (e.g. 2× one item, 1× another) and note the invoice number.
- Tap Returns & Corrections, search that invoice number.
- Return only one unit of the multi-quantity line (not the whole line).
- Approve with a manager PIN, pick a refund method (try one different from the original payment method).
- Expect: the return completes, and stock for that item goes up by exactly 1 (check the item's stock count on the till or via Desk's Bin report) — not the whole line's quantity.
- Negative test: try to return more than what's left on that line (e.g. return 5 when only 1 remains returnable). Expect: rejected, citing ERPNext's own over-return validation.
- Complete a fresh sale, note the invoice number.
- Returns & Corrections → find it → Void this sale → enter a reason → approve with a manager PIN.
- Expect: stock is fully restored, and (via Desk) the invoice's status shows Cancelled — it still exists, it's just no longer active.
- Negative test: process a return against a sale first, then try to void it. Expect: blocked — a sale with an existing return against it can't be voided.
Requires at least two Mode of Payment records each with a default account configured for the company (Desk → Mode of Payment). If you only have Cash configured, set up a second one first — see Installation: Subscription for the exact steps (same requirement applies here, not just there).
- Complete a sale paid by Cash.
- Returns & Corrections → find it → Fix payment method → select Cash as "recorded as," the correct method as "actually paid by," confirm the amount → approve with a manager PIN.
- Expect: a new Journal Entry appears (Desk → Journal Entry) correctly debiting/crediting the two accounts, and the original invoice is completely unchanged — still shows Cash, still submitted, untouched.
- After the sales/returns/corrections above, tap Close till.
- If any sale hasn't finished syncing, you should be blocked from closing until it does.
- Count what you'd expect the drawer to actually contain (opening float + cash sales − cash refunds, accounting for any Cash-involving correction you did) and enter it.
- Expect: the shown "expected cash" matches your own hand calculation exactly, including any correction's effect on the cash total — this was specifically verified to net corrections and returns in automatically.
- Go to
https://<site>/manager, log in as the demo owner.
- Staff → create a new cashier, confirm you get a setup code.
- Stock → receive stock against a (new or existing) supplier, then do a stock count with a deliberately different quantity than what's on hand — confirm the adjustment posts.
- Items & Prices → edit an item's price, confirm it's reflected on the till after its next sync.
- Sales → confirm today's totals match what you rang up during this test session.
- Tills → suspend the till you've been testing with, then try to use it. Expect: it should stop being able to sync/sell. Reactivate it and confirm it works again.
- Shifts → confirm the shift(s) you opened/closed above show up with the correct variance (should be 0 if your counted-cash matched expected).
- Log into the
craftivus_subscription site's Desk.
- Create a
Customer, note the generated push_key.
- On the customer's site (
pos.local), open the Craftivus Subscription State singleton and paste that push_key into Expected Push Key.
- Back on
craftivus_subscription, create a Subscription for that Customer against a POS-type Subscription Plan with some feature flags checked and a device cap set.
- Call
bootstrap() against pos.local with real device credentials (via curl, or just resync the till).
- Expect: the
subscription block in the response shows the exact plan/entitlements you just assigned.
- Click Change Plan on the Subscription, pick a different plan, confirm.
- Expect:
bootstrap() reflects the new plan immediately, without waiting for any billing cycle.
- Click Cancel Subscription.
- Expect: attempting a sale on the till now fails with a clear "subscription suspended" message.
- Click Restart Subscription.
- Expect: sales work again immediately.
- Click Revoke, type a reason, confirm.
- Expect: the till's device credentials stop working entirely — every API call now fails with an authentication error, not just a subscription-suspended message. This is not reversible — don't do this to a device you want to keep testing with; recreate a fresh
POS Device afterward if you need the till working again.
- No lock icons or upgrade prompts anywhere yet — every feature is fully open on every plan today, regardless of what
entitlements says.
- No self-serve "add an outlet" flow — outlet count is not enforced anywhere because there's nothing yet that would exceed it.
- No manager-app receipt-settings screen (the API works if you call it directly; there's no button for it).
- No heartbeat/telemetry — the Craftivus Subscription dashboard has no live device-count/health view yet.