Omni-POS Hybrid Ecosystem is a hybrid retail point-of-sale platform for Botswana shops, powered by Neo Systems Africa. It combines counter sales (cash and digital, including split payment and M-Pesa STK Push) with mobile AR product scanning, a shop-owner back office, and a superuser administration console. Every new account begins on a 3-Day Full Browsing Trial; payment of the P85.00 once-off account opening fee is required only at Item Checkout or at Trial Expiry.
The product serves four human roles — Admin (Superuser), Shop Owner, Cashier and Mobile Shopper — across a modular micro-frontend web surface (React + Vite), a React Native (Expo) mobile app for AR and camera work, and Go microservices for authentication, trial, payment and inventory. Six named AI assistants (Eliana, Caitlin, Alisha, Florence, Edmund, Neo) are part of the product's identity and are surfaced in onboarding and tuned from the Admin Web.
Omni-POS is a multi-tenant SaaS: a Shop Owner registers a shop by selecting one of three subscription tiers — Starter (P975/month), Pro (P1850/month) and Premium (P2850/month) — each carrying different options, and the Super Admin defines the tiers and the options inside each tier. Within the POS the Shop Owner runs promotions (terms and conditions apply), cashes out, runs end of day, generates GRVs, adds and edits stock items and edits prices, with promotion capability depending on the selected tier. The Mobile Shopper selects which shop to buy from, browses shelf categories with the items on those shelves, follows in-shop map directions to a product, scans items to read expiry dates, promotion prices and dates and prices, adds scanned items to cart, pays in the app without going to the cashier, and can buy remotely and choose when to collect; purchase history and reports show where each item was bought.
The build is delivered incrementally on https://www.lovable.dev under a CHANGELOG.md discipline: the changelog is read before any code is generated, only features not yet marked Stable are generated, completed features are never regenerated, and technical debt is tracked separately.
Omni-POS is delivered as a multi-page SaaS ecosystem. Anonymous visitors meet a Landing surface, then a 2.5-second Splash Screen that routes by session state, then Onboarding, then AUTH. Authenticated users land in the surface that matches their role: Admin Web (superuser control, including the subscription tier catalogue), Shop Registration (tier selection and shop registration), Shop Owner Web (inventory, membership cards, sales reports, trial analytics), Inventory (stock items, prices, GRVs), Shop Operations (promotions, cash out, end of day), Cashier Web (hybrid sales), Shop Browse (shop selection and shelf categories), Shop Map (in-shop directions), User Mobile (AR scanning, cart, in-app payment, remote collection, trial status), or Order History (purchase history and reports).
Current delivery comprises:
auth-service (FIDO2, Phone OTP, Payoneer OAuth, session management), trial-service (3-day counter, checkout blocker, P85 fee capture), payment-service (split payment, M-Pesa STK Push, Payoneer API), inventory-service (stock, AR product mapping, shelf categories, GRVs, price edits, promotions, cash out and end-of-day records).https://api.appforcestudio.com/neo/callback, BusinessShortCode NEOPOS) and Payoneer (OAuth and payments API).https://api.appforcestudio.com/neo; required environment variables MPESA_CONSUMER_KEY, MPESA_CONSUMER_SECRET, PAYONEER_CLIENT_ID, AES_256_GCM_KEY.Actors: Admin (Superuser), Shop Owner, Cashier, Mobile Shopper (human); M-Pesa, Payoneer, LiteLLM and the model providers (external/system). Access is role-restricted for Admin Web, Shop Registration, Shop Owner Web, Inventory, Shop Operations, Cashier Web, Shop Browse, Shop Map, User Mobile and Order History; Landing, Splash Screen, Onboarding and AUTH are anonymously reachable.
Narrow exclusions: no capabilities beyond those stated in the requirement thread are introduced; the CHANGELOG.md engine is a build-process obligation, not an end-user feature; Kubernetes is optional.
Removed from scope
Omni-POS is a first-party application with application-owned identity. Anonymous visitors can reach Landing, the Splash Screen, Onboarding and AUTH without an account. Identity is established at AUTH through one of three methods — Biometric, Phone (OTP) or Payoneer OAuth — with FIDO2 (WebAuthn) applied on all authentication pages. Once a session exists, the Splash Screen routes the user to the Dashboard; without a session it routes to Onboarding.
Role-restricted surfaces (Admin Web, Shop Registration, Shop Owner Web, Inventory, Shop Operations, Cashier Web, Shop Browse, Shop Map, User Mobile, Order History) are reached only after authentication and are scoped to the matching role: Admin (Superuser) controls the Admin Web; Shop Owner controls Shop Registration, Shop Owner Web, Inventory and Shop Operations; Cashier controls the Cashier Web; Mobile Shopper uses Shop Browse, Shop Map, User Mobile and Order History. The trial lifecycle is owned by trial-service: a new account starts a 3-day full browsing trial, may browse, add to cart and use AR during it, and payment of the P85.00 once-off account opening fee is required only at Item Checkout or at Trial Expiry.
Subscription tiers are owned by the Admin (Superuser): the Super Admin defines the three tiers — Starter (P975/month), Pro (P1850/month) and Premium (P2850/month) — and the options included in each tier. A Shop Owner registers a shop by selecting one tier and supplying shop name, location, logo, contact email and mobile numbers. Tier selection governs which POS options the shop can use, including promotion capability. Shop-level POS operations — promotions (terms and conditions apply), cash out, end of day, GRVs, adding and editing stock items, and editing prices — are owned by the Shop Owner within their own shop's data.
Mobile Shopper journeys are shop-scoped: the shopper selects which shop to buy from, browses shelf categories with the items on those shelves, follows in-shop map directions to a required product, scans items to read expiry dates, promotion prices and dates and prices, adds scanned items to cart, pays in the app without going to the cashier, and may buy remotely and choose a collection time when not physically in the shop. Purchase history and reports record where each item was bought.
Payment execution is owned by payment-service and the external gateways M-Pesa and Payoneer. M-Pesa STK Push is initiated by the backend and confirmed through the provider callback at https://api.appforcestudio.com/neo/callback; the Cashier observes the resulting payment state in the Cashier Web. Payoneer OAuth is a provider-owned authorization surface that returns the user to Omni-POS.
AI assistant responses are produced through the LiteLLM gateway, which the shared backend calls; LiteLLM's PostgreSQL store is infrastructure for the gateway and is not application-owned customer data. All application-owned persistent data lives in MariaDB and is encrypted at rest with AES-256-GCM; transactions follow PCI-DSS 4.0.
The CHANGELOG.md engine governs how the product is built, not what end users do: before generating any code the builder reads CHANGELOG.md, creates it if missing, generates only features not yet marked Stable, never regenerates completed features, appends a Date | Feature | Status entry after each build step, and tracks Technical Debt separately.
FR-1 — Product identity. As a visitor, I should see that the product is the Omni-POS Hybrid Ecosystem, powered by Neo Systems Africa, so that I understand who makes it. (explicit) Observable acceptance: the tagline "Powered by; Neo Systems Africa!" and product name appear on the public entry.
FR-2 — Splash Screen timing and animation. As any user, I should see a Splash Screen for 2.5s with a logo fade-in and a "Neo Systems Africa" pulse, so that the brand registers while the session is checked. (explicit) Observable acceptance: the splash displays for 2.5s with the specified animation.
FR-3 — Splash session routing. As any user, I should be routed by the Splash Screen according to session state — existing session → Dashboard, no session → Onboarding. (explicit) Failure/recovery: if the session probe fails, treat as no session and route to Onboarding. Continuation: the user can authenticate from Onboarding → AUTH.
FR-4 — Onboarding content. As a new user, I should see an Onboarding slider or video with three messages: "Welcome to Omni-POS", "Hybrid Sales + AR Scanning", and "AI Assistants: Eliana, Caitlin, Alisha, Florence, Edmund, Neo". (explicit) Observable acceptance: all three messages are reachable in the slider/video.
FR-5 — Onboarding precedes AUTH. As a new user, I should complete Onboarding before AUTH. (required_inference) Observable acceptance: continuing from Onboarding leads to AUTH.
FR-6 — Authentication methods. As a user, I should authenticate by Biometric, Phone (OTP) or Payoneer OAuth, with FIDO2 (WebAuthn) on all authentication pages. (explicit) Observable acceptance: each method can establish a session; FIDO2 ceremony is used on every authentication page. Failure/recovery: invalid OTP → inline error and resend; failed ceremony → retry; denied OAuth → return to AUTH with message.
FR-7 — Identity verification. As a user, I should verify identity through the chosen method and receive a session. (required_inference) Observable acceptance: successful verification establishes a session and routes to the role surface.
FR-8 — Admin Web superuser control. As an Admin (Superuser), I should have superuser control over User management, System logs, Trial overrides and AI assistant tuning. (explicit) Observable acceptance: each of the four areas is operable and changes persist. Failure/recovery: rejected save → inline error with values retained and retry.
FR-9 — Shop Owner Web. As a Shop Owner, I should manage Inventory management, Membership cards, Sales reports and Trial analytics. (explicit) Observable acceptance: inventory edits persist; membership cards can be issued and looked up; sales reports and trial analytics display. Failure/recovery: fetch/save failure → message and retry.
FR-9a — Subscription tier catalogue. As an Admin (Superuser), I should set the three subscription tiers and the options included in each tier, so that shop registration offers the correct plans. (explicit) Observable acceptance: the tiers Starter (P975/month), Pro (P1850/month) and Premium (P2850/month) exist with different options per tier, and edits to a tier's price or options persist and are reflected at Shop Registration.
FR-9b — Shop registration with tier selection. As a Shop Owner, I should select a subscription option to register my shop on the SaaS Omni Hybrid-POS system, supplying shop name, location, logo, contact email and mobile numbers, from the three tiers of the system. (explicit) Observable acceptance: registration requires a selected tier plus shop name, location, logo, contact email and mobile numbers; on submit the shop is registered on the selected tier and the Shop Owner reaches Shop Owner Web. Failure/recovery: missing or invalid field → inline error with values retained and resubmit.
FR-9c — Tier-dependent POS options. As a Shop Owner, I should get the options that belong to the tier I selected, so that promotions and other capabilities match my subscription. (explicit) Observable acceptance: the options available in the POS follow the selected tier's option set as defined by the Super Admin; a capability not included in the tier is not offered and shows a tier-capability notice.
FR-9d — Shop Owner POS operations. As a Shop Owner, I should run my own promotions (terms and conditions apply), cash out, run end of day, generate GRVs, add stock items, edit stock items and edit prices within my POS system on the platform. (explicit) Observable acceptance: a promotion can be created with promotion price, dates and acknowledged terms and conditions; cash out and end of day complete with a recorded summary; a GRV is generated for received stock; stock items can be added and edited; prices can be edited and persist. Failure/recovery: terms not acknowledged, invalid date range, tier without promotions, or save failure → inline error with values retained and retry.
FR-10 — Cashier Web hybrid sales. As a Cashier, I should run hybrid sales with a Cart, Split payment, M-Pesa STK Push and a Cash/Digital toggle. (explicit) Observable acceptance: cart builds; toggle switches method; split payment and STK Push execute.
FR-11 — User Mobile features. As a Mobile Shopper, I should use AR Scanning (product recognition), Cart, Order history and Trial status. (explicit) Observable acceptance: a product is recognized and can be added to cart; orders appear in history; trial status is visible. Failure/recovery: camera permission denied or recognition failure → retry prompt.
FR-11a — Shop selection and shelf browsing. As a Mobile Shopper, I should select which shop to buy from and see shelf categories with the items on the same shelves, including when buying from home to later pick the items. (explicit) Observable acceptance: a shop can be selected; its shelf categories list the items held on those shelves; items can be opened from a shelf.
FR-11b — In-shop map directions. As a Mobile Shopper, I should navigate the shop with map directions to reach the product I require faster than looking for a merchandiser. (explicit) Observable acceptance: from a selected product, a map shows directions to the shelf holding it. Failure/recovery: map unavailable → fall back to shelf category browsing.
FR-11c — Scan reveals expiry, promotion and price. As a Mobile Shopper, I should see through scanning the expiry dates, promotion prices and dates, and prices of a product, and be able to add the scanned item to my cart. (explicit) Observable acceptance: a scan result shows expiry date, promotion price, promotion dates and price, and the scanned item can be added to cart.
FR-11d — In-app payment without the cashier. As a Mobile Shopper, I should pay for items through the mobile app without having to go to the cashier. (explicit) Observable acceptance: payment completes in the app and the order is recorded without a cashier step. Failure/recovery: payment failure → retry.
FR-11e — Remote purchase and collection time. As a Mobile Shopper, I should remotely select what to buy and when to collect when I am not in the shop physically. (explicit) Observable acceptance: an order can be placed remotely with a selected collection time and is recorded with that collection selection.
FR-11f — Purchase history and reports by shop. As a Mobile Shopper, I should know where I bought what from my reports and history of purchases in my account. (explicit) Observable acceptance: Order History lists past orders with the shop each item was bought from and provides reports grouped by shop.
FR-12 — Trial start. As a new user, I should start a 3-day full browsing trial and be able to browse, add to cart and use AR during it. (explicit) Observable acceptance: trial begins at sign-up; browsing, cart and AR are available for 3 days.
FR-13 — Payment only at Item Checkout or Trial Expiry. As a user, I should be asked to pay only at Item Checkout or at Trial Expiry. (explicit, hard constraint) Observable acceptance: no payment prompt appears during browsing, cart building or AR use; payment is triggered at checkout or after day 3.
FR-14 — P85.00 once-off fee. As a user, I should pay a P85.00 once-off account opening fee when payment is triggered. (explicit, hard constraint) Observable acceptance: the fee amount is P85.00 and is charged once.
FR-15 — Trial counter and checkout blocker. As the system, the trial-service should count 3 days and block checkout until the P85.00 fee is paid. (required_inference) Observable acceptance: checkout is blocked at expiry until fee capture succeeds; after capture, checkout proceeds.
FR-16 — Split payment logic. As a Cashier, I should have the cash amount applied first and the remaining amount sent to the digital method. (explicit) Observable acceptance: processSplitPayment(cartTotal, cashAmount, digitalMethod) computes remaining = cartTotal - cashAmount; if remaining > 0, initiate the digital transaction for remaining; otherwise return {status: 'SUCCESS', method: 'FULL_CASH'}.
FR-17 — M-Pesa STK Push. As a Cashier, I should send an M-Pesa STK Push with BusinessShortCode NEOPOS, the amount, the user's phone number, and CallBackURL https://api.appforcestudio.com/neo/callback. (explicit) Observable acceptance: POST /mpesa/stkpush/v1/process carries those fields; the callback confirms the payment state. Failure/recovery: timeout or failure → retry or switch method.
FR-18 — AI assistants. As a user, I should see the six AI assistants — Eliana (Strategy), Caitlin (Tech), Alisha (Payments), Florence (Support), Edmund (Admin), Neo (Operations). (explicit) Observable acceptance: all six names and roles appear in onboarding and are tunable from Admin Web.
FR-19 — Security manifest. As the system, storage encryption should use AES-256-GCM and transactions should follow PCI-DSS 4.0. (explicit, hard constraint) Observable acceptance: data at rest is AES-256-GCM encrypted; payment flows conform to PCI-DSS 4.0.
FR-20 — Payment gateways. As the system, payments should route through Payoneer and M-Pesa. (explicit) Observable acceptance: both gateways are integrated; Payoneer OAuth and API are used; M-Pesa STK Push is used.
FR-21 — Admin role controls Admin Web. As an Admin (Superuser), I should be the role that controls Admin Web access. (required_inference) Observable acceptance: only the Admin role reaches Admin Web.
FR-22 — CHANGELOG.md discipline. As the builder, I should read CHANGELOG.md first, create it if missing, generate only features not yet marked Stable, never regenerate completed features, append Date | Feature | Status after each build step, and track Technical Debt separately. (explicit, hard constraint) Observable acceptance: CHANGELOG.md exists at root with the specified format and entries.
trial-service blocks checkout until fee capture succeeds.processSplitPayment returns {status: 'SUCCESS', method: 'FULL_CASH'}.remaining = cartTotal - cashAmount; if remaining > 0, payment-service initiates the digital transaction for the remainder.payment-service sends POST /mpesa/stkpush/v1/process with BusinessShortCode NEOPOS, Amount, PhoneNumber and CallBackURL https://api.appforcestudio.com/neo/callback; the callback confirms.Muse: Virgil Abloh. Headline direction: "Remixed checkout" — label-and-tag language applied to a hybrid sales system.
Palette (light mode):
#F2F0EB (warm concrete grey, ~70% of surface)#FFFFFF#111111#111111#FF4D00 (safety orange, ~10%, reserved for payment and trial signals)#8A8781#16A34A (active/safe), yellow #FACC15 (warning), red #EF4444 (critical)Typography: Headings Archivo — uppercase, wide tracking, weight 800. Body Space Grotesk. Modular scale 1.333: headings 40/64/96/128px; body 16/18px. Quotation marks around key labels. Inter, Roboto and Poppins are forbidden.
Shape language: Hard corners, 2px black rules, rectangular label tags, hazard-stripe bands. No soft shadows, no rounded cards with hover lift, no gradient blobs or glass panels.
Layout: Exposed 12-column grid with visible hairlines; sections read as stacked shipping labels and price tags.
Motion: Snappy 120ms state flips; slow ticker tape in the header; no bounce or fade.
Imagery: Product photos on concrete with orange gaffer-tape marks; bold black pictograms for cash, card and M-Pesa.
Readability rule: headlines, wordmarks, labels, numbers, cards' text and controls stay entirely inside the viewport and their container at 375px, 768px and 1280px, wrapping or scaling (e.g. clamp(...)) to fit; no element covers readable text or controls. Decoration and motion may crop, bleed, rotate or overlap freely. Tickers and scrollable rows may cross edges by design and must remain fully readable as items pass; under prefers-reduced-motion, provide a static arrangement (wrap or horizontal scroll) so every item can be brought fully into view.
The public entry is a full-width black band holding the wordmark OMNI-POS in 128px Archivo (clamped down for smaller viewports), with a small orange P85.00 price tag clipped to its corner. Beneath it runs a black ticker tape of live sales states in uppercase. The right third shows one cashier screen photographed on concrete. Every section title sits inside a white label tag with a 2px black outline. The trial counter reads 3-DAY in a safety-orange stamp. Payment buttons use a diagonal hazard stripe on hover. The cashier cart shows each item as a printed price tag with a barcode strip. This concept recomposes only accepted content and controls — the trial offer, the roles, the assistants, the entry controls — and introduces no new behaviour.
Interaction Model: Animated Motion Tempo: expressive Hero Dimensionality: flat
Landing Hero Motion Brief
AES_256_GCM_KEY.https://api.appforcestudio.com/neo; M-Pesa callback https://api.appforcestudio.com/neo/callback.MPESA_CONSUMER_KEY, MPESA_CONSUMER_SECRET, PAYONEER_CLIENT_ID, AES_256_GCM_KEY.Date | Feature | Status, track Technical Debt separately.auth-service (FIDO2, Phone OTP, Payoneer OAuth, session management), trial-service (3-day counter, checkout blocker, P85 fee capture), payment-service (split payment, M-Pesa STK Push, Payoneer API), inventory-service (stock, AR product mapping, shelf categories, GRVs, price edits, promotions, cash out and end-of-day records).NEOPOS.No completed page designs yet.
Completed design pages will appear here when they are ready to preview.
No completed page designs yet.
Completed design pages will appear here when they are ready to preview.
No comments yet. Be the first!