Documentation

How RoasteryHub thinks.

A narrative tour of the data model and the conventions behind every workflow. Read end-to-end in twenty minutes — or jump to a topic.

01

Getting started

RoasteryHub is invite-only. We onboard new roasteries through a short sales conversation — typically twenty minutes over a call. Once your tenant is set up, you receive a sign-in link directly. No self-serve signup form.

Each roastery is a separate tenant. Customers, batches, orders, prices — every row is isolated at the database level via Postgres row-level security. The app layer trusts the database, not the other way around.

02

Roast batches & inventory

Recording a roast is three numbers: bean, green weight, roasted yield. RoasteryHub computes the loss percentage and auto-splits the yield into sellable FIFO lots (default 5kg each, configurable per roastery).

Each lot has a code (e.g. G0512-001), a remaining weight, and a status (available, reserved, sold, expired). When an order is placed, the oldest available lot is consumed first. Larger orders span multiple lots automatically.

A freshness window (default 14 days) ages each lot from fresh → expiring → expired. Expired lots disappear from order forms but stay in the database for audit.

03

Customers & credit

Every customer has a tier (Small, Medium, Large), payment terms (Prepay, Net 15/30/60), a credit limit, and a current balance. Tier drives pricing; see Pricing rules below.

Credit headroom = credit limit − current balance. Every order checks the headroom atomically before allocating inventory, in the same Postgres transaction. Over-limit orders receive the status credit_blocked and never ship.

Recording a payment reduces the balance in the same transaction — the next order check sees the updated headroom immediately. No stale reads, no race conditions.

04

Orders

Orders have one of three sources: manual (created by you in the admin), standing (generated by the daily cron from a recurring schedule), or portal (placed by the café through their customer portal).

All orders share one lifecycle: draft → confirmed → fulfilled, with cancelled and credit_blocked as terminal alternatives. Cancellation reverses both inventory and balance in a single transaction — no manual cleanup, no half-states.

05

Standing orders

Set a customer to receive a recurring order: weekly, biweekly, or monthly, optionally pinned to a day of the week. Each standing order tracks its own bean, quantity, and delivery cadence.

The Vercel cron runs at 06:00 UTC daily and creates orders for any standing order whose next_run_at has elapsed. Runs are idempotent on (standing_order_id, delivery_date) — if the cron fires twice in a window, only one order is created.

Pause or resume per standing order without losing the schedule. The next eligible cron run picks it back up.

06

Café portal

Once invited, a café signs in at /portal-signin and sees only their data: their tier pricing, their balance, their credit headroom, their recent orders. They place new orders directly, which appear live in your admin via a Supabase Realtime toast.

The portal uses the same Postgres RLS as the admin — the café simply has a different role. No mirror tables, no sync jobs, no surprises. The same constraints apply: tier-priced beans, credit headroom checks, FIFO allocation.

07

Pricing rules

Pricing is per-bean × tier × effective_from. The active rule for a customer ordering bean X is the most recent rule for bean X at the customer's tier whose effective_from is on or before today.

Change a rule and the next order uses the new price — existing orders keep their snapshot in the line items, so historical orders never drift. To override a single order, edit the line item price before confirming.

08

AI assistant

Ask in plain English — Claude Sonnet writes a read-only SELECT against your tenant's data. The query is validated against an allow-list of tables before running, and Postgres RLS enforces tenant isolation as a final guard. Results stream back in real time.

The AI can also draft cupping insights (Claude Haiku) from scored batches, and re-engagement emails (Sonnet) for at-risk customers. All AI traffic is logged with the prompt, the model, the SQL (if any), and the row count returned.

Still have questions?

Email us — a human reads everything, replies within one business day.

RoasteryHub — Wholesale SaaS for Coffee Roasters