GroviaDocs

Admin guide

Running the store from the dashboard: roles, products, orders, promotions.

Signing in

The sign-in page has two doors: Admin and Seller. Only staff roles pass the Admin door — admin, employee and preview — and only an approved, active seller passes the Seller door. Any other account is refused with a clear message even with valid credentials: a customer is told the account has no dashboard access, a seller on the Admin tab is pointed at the Seller tab, an applicant is told the application is still under review, a rejected or terminated seller reads the reason. Every refusal — including a signed-out visit to any dashboard or seller page — lands on /unauthorized, which explains what is wrong and offers the way out. preview is the read-only demo login — it sees every screen and the API rejects all its writes.

Roles

Users and roles
Users & Roles: add accounts with a role, or change one.
RoleCan
adminEverything, including granting roles
employee + job rolepacker, deliveryman, accounts, incharge, call_center — operational screens; accounts/incharge may change payment status
sellerThe seller portal at /seller only — their own products, stock, orders, reviews, earnings and payouts; never an admin screen
previewRead every screen, write nothing
userThe storefront only

Roles are granted, never claimed. Every signup is user. Use Users & Roles → Add user to create an account with a role, and Change role to move an existing one. The seller role is the exception: it is granted by activating a seller application and dropped by terminating it — never assigned by hand.

Inside the dashboard, roles map to named permissions in src/lib/auth/access.ts (accounts:manage, orders:write, settings:view, …). The sidebar, every page gate and every action button ask the same can(permission), on the server through auth() and in the browser through useAuth(). The API still authorises every request on its own — the permission map only keeps the UI honest.

Products

Products list
Products: table and filters, with stock and approval state.
  • Category and brand are required — the form refuses to submit without both. Seed them first, or create them under Categories & Attributes.
  • Images are staged, not uploaded. Add and remove freely; nothing reaches ImageKit until Save. On save the API uploads new files, deletes removed ones, then writes the product. Cancel costs nothing.
  • images[0] is the primary image. Deleting a product deletes its images.
  • Product images are transparent cut-outs and render on a tinted tile with object-contain — never crop them.

Orders

Orders overview
Orders: tiles per stage, the year's chart and the full table.

The lifecycle: pending → confirmed (order and address checked) → packing → packed → delivering → delivered → completed, plus cancelled from any open stage and returned after delivery. Nobody moves an order backwards; employees only move into the stages their job role owns. Stock is reserved when the order is placed: a cancellation while pending puts it straight back, a cancellation after confirmation or an accepted return opens a quality check on the order — record how many picks of each line came back sellable and only those return to the shelf. A card order cannot move to delivered until it is paid, and a cash order until the driver has flagged the cash collected; nothing moves to completed until the money is in the company's account. Line edits are repriced from the catalogue — a submitted totalAmount is discarded. Returns start on the storefront: a customer with a delivered order chooses the lines and quantities coming back and says why; the request appears under Return & Refund with those lines, and approving it refunds the card payment through Stripe (or records a manual refund for cash), marks the order returned and opens the quality check on the returned lines.

Errors also reach Sentry when the DSN variables in the root .env are set — one project per app — with the request id on every API error so a customer's reference finds the event; the dashboard's API status page keeps the built-in record regardless.

Home page control
Home Page Control: one row per home-page block, in order, each with its own switch.

The storefront home is composed from Website config → Home Page Control: one row per block (hero, categories, best selling, new arrivals, seller banner, gourmet selection, Visit our store, new launch, perks, grocery call to action, latest blogs), ordered by weight. Switch a row off to drop the block; its title becomes the heading and its notes the subtitle where the block has them.

Low stock is alerted on the crossing: when a line first reaches the catalogue threshold, administrators get an in-app digest (and an email when the Low stock touchpoint is on), once, until it is restocked and drops again. The worker checks on a schedule set under Configuration → Catalogue; every order checks its own lines; Stock Products has a Check now.

Customers are told at every step: each move an order makes — confirmed, packed, out for delivery, delivered, completed, cancelled, returned, refunded — raises an in-app notification (Account → Notifications, with the unread count on the header bell) and, for the statuses configured under Email Config, an email.

Order detail
An order: lines, payment, delivery, and the actions due at its stage.

Call centre is the queue of orders placed and not yet confirmed: the customer's phone, the delivery address and window, the lines and how it is paid. Confirm sends the order to the packers; cancelling needs a reason the customer reads and puts the stock back.

Call centre board
Call centre: confirm or cancel new orders.

Packing shows confirmed orders ready to pick and the orders being packed under each packer's name with the full pick list. A packer takes an order (or in-charge hands it to one), picks and bags it, and marks it packed — it then appears on the delivery board.

Packing board
Packing: take an order, pick it, mark it packed.

Reports & Analytics — Sales reports, Top products and Seller performance — and Promotional Deals → Clearance Deal are live reports over a date range: preset ranges or a custom from / to, a chart and tables, and an Export CSV of exactly what is on screen. Recognised sales are delivered and completed orders.

Sales report
Sales reports over any date range, exportable to CSV.

Deliveries is the delivery board. In-charge staff and administrators put each packed order on a driver and see who has what on the road; a driver opens the same page as their own route — start the delivery, flag the cash at the door on a cash order, mark it delivered.

The sidebar's Orders entry opens to an *Overview* (tiles, the year's chart and the full table) and one page per stage — Pending, Confirmed, Packing, Out for delivery, Delivered, Cancelled, Returned. Every page carries the same filters (payment, quality check, search, sort, page size) and its own CSV export.

Deliveries board
Deliveries: put packed orders on a driver and follow them on the road.

Transactions and the cash desk

Transactions
The ledger: every payment and refund, with the money overview on top.

Every payment and refund is a row in the ledger (/transactions): a card payment posts itself as *received* the moment Stripe confirms it; marking an order paid or refunded by hand posts a row stamped with who did it. Cash on delivery follows the money in three stamped steps: the driver flags the cash collected at the door from the order's Payment card (needed before the order can be delivered), hands it over at the Cash desk (/transactions/cash), and accounts confirms it — only then is the order *paid*, and only a paid order can be completed. The overview band shows order value, what is in the account, what is owed, cash with drivers, cash awaiting confirmation and refunds, received by method and the year by month.

Who does what: an employee always has a job — packer, deliveryman, accounts, in-charge or call centre — set on the Users & Roles screen. Drivers see only the cash desk (their own bag); accounts and in-charge see the overview, the ledger and every driver's cash; administrators see everything.

Promotions

  • Coupons — percentage or fixed, usage caps, date ranges.
  • Sale promos — themed landing pages at /sales/[slug] on the storefront, with a countdown and "add all" action.
  • Flash sales, featured and clearance deals — merchandising lists surfaced on the home page.

Sellers

Sellers
Sellers: every shop with an inline Active switch.

Sellers are brands with a profile. Sellers lists every shop with an inline Active switch — off hides the shop and its products from the storefront without deleting anything. The edit drawer has profile, contact and storefront sections; the eye icon opens a read-only details view with a link to the seller's products.

Seller applications are customers who applied from the storefront's /sell/apply — shop details, contact, address and bank account, with the guidelines accepted. Change the status from the badge menu: *Active* grants the seller role and opens the shop (the seller can now sign in through the Seller door); *Rejected* keeps the account a customer, needs a reason the applicant reads on sign-in, and is final — a rejected account cannot apply again; *Terminated* closes an active seller, also with a reason, hides the shop and drops the role. Admins can also create a seller for an existing account. Configuration → Sellers decides whether applications are open and whether they need approval.

Seller Management

Its own sidebar group. Sellers lists the shops and the applications. Seller products is the approval queue: everything a seller lists (or edits) waits here; approve to put it live under the seller's shop, or reject with a reason the seller reads — every decision stays on the product's approval history and the seller is emailed. Seller accounts shows, per seller, sales, commission, what they have earned, what accounts has dispatched, and what they can withdraw: only dispatched money is withdrawable, so *Dispatch* is the step that releases earnings to a seller's balance. Commission is 5 % by default (Configuration → Sellers) and can be overridden per seller from the same screen.

The seller portal

An active seller signs in through the Seller tab and lands on /seller: a dashboard (earnings after commission, available balance, orders, units sold, products, awaiting approval, low and out of stock, the year by month, recent orders, lines running low), Manage Product (their lines with the approval state; every new or edited product waits for the Grovia team's approval before it shows on the storefront), Manage Inventory (stock edited in place), Orders (only the orders containing their products, and only their lines), Product Reviews (published reviews, read-only), Earning (a month-by-month ledger and the balance), Withdraws (payout requests — one at a time, and only with complete bank details), Shop profile and Payout details, and a Seller guide. Sellers hold no admin permission; every read is scoped to their own shop by the API.

Every list, the same way

  • Tick rows to delete in bulk; the eye, pencil and bin icons on each row view, edit and delete one record.
  • Forms validate in the browser and again on the server; required fields carry a *.
  • Lists with a status column have an inline switch or menu — no drawer needed to activate, deactivate, approve or mark paid.

Finance and content

  • Withdrawals — seller payout requests. Move them Pending → Approved → Paid, or reject with a note.
  • Tax rules — the rule marked *Default* is applied at checkout; without one, TAX_RATE from .env applies.
  • FAQ and Legal documents publish straight to the storefront; unpublished entries stay in the dashboard.
  • Settings → Shop sets the delivery fee and free-delivery threshold that checkout charges. Settings → Maintenance takes the storefront offline.

Housekeeping

  • API status lists every route the running API serves and checks the read routes live — one, a selection, or all — with latency in bands, the database/app split from Server-Timing, observed p95 from the request log, and a *Why slow?* panel that names the likely cause (N+1 queries, missing index, large payload, external call, cold start) and the fix. A *Missing* verdict means the API process is an older build and needs a restart.
  • Abandoned carts shows idle account carts so you can follow up.
  • DB status reports collection sizes against MONGODB_STORAGE_QUOTA_MB.
  • Notifications is the staff inbox for orders, returns and support.
Buy GroviaFull source code$99.99