Skip to content
Anton GoncharovAI systems developer

Go service · queue · approval

Purchasing agent

An agent that buys coffee on its own must not lose a request halfway through, and must not send it twice if the process dies. Here a request is a job in a River queue. It stops for approval, and “Cut off the send” drops the step: the retry finishes the same order, not a new one.

Scenario: Zerno, a fictional roastery: green coffee of three origins and a local supplier.

Demo screenshot: Purchasing agent

Open the demo

The supplier is local. The queue and the steps are a Go service and PostgreSQL.

The app runs in your browser: nothing is sent to a server.

What the demo shows

  • Request steps: stock, draft, approval, send

  • If there are not enough kilograms, the request is refused and the tape says how much was in stock

  • Sending does not start until the buyer confirms the draft

  • A cut-off send returns the same job to the queue

  • The supplier order number is written once

How to try it

  1. Buy Ethiopia

    “Buy 30 kg of Ethiopia”. The request checks stock and stops at the draft.

  2. Confirm

    “Confirm sending” — one order number goes to the supplier.

  3. Cut off the send

    A new request, then “Cut off the send”. The tape shows the cut-off and then the same order, without a second number.

  4. Ask for too much

    “Buy 50 kg of Colombia” — 6 kg are in stock, so the request is refused.

No paid neural networks

The supplier is a local database row, with no mail and no payment. The queue is real: each step is a River job in PostgreSQL, and it survives a cut-off.

The demo runs without OpenAI, YandexGPT or GigaChat API keys. Wherever a production system calls a model, there’s a local stub with the same interface — so the demo is free, always available and never makes things up.

What a production project adds

  • The supplier is MoySklad, 1C or email, rather than a row in the demo database
  • The approval goes to the buyer in Telegram
  • The same queue for other long-running agents: contracts, payments, exports
  • A separate worker that can be stopped without stopping the gateway

Stack

  • Go
  • River
  • pgx
  • sqlc
  • goose
  • PostgreSQL
  • slog
  • React 19

Want the same for your business?

Tell me about your task — I’ll tell you what from the demo fits, how long it will take and what I’ll need from you.

Other demos in this section

All demos
  • Web app · OCR · validating company details

    live

    Document recognition

    Upload an invoice or a certificate of completion — a photo, scan or PDF. The app recognizes the text, extracts company details and table rows and validates them: tax ID and account checksums, the total and VAT.

    • React
    • TypeScript
    • In-browser neural network
  • Web app · conversations · deals · analytics

    live

    Operator panel

    The workspace of an operator who receives difficult requests from a bot: a queue with a timer, a conversation summary, a reply draft, deals on a kanban board and analytics — on a live stream of customers.

    • React
    • TypeScript
  • Web app · Recharts · RBAC · audit

    live

    SaaS dashboard

    A SaaS revenue team’s workspace: MRR by plan, revenue movement, churn, customer health, CSV export for Excel and an activity log. All numbers are calculated from a single year of history — changing a plan in a customer card moves MRR on the charts immediately.

    • React
    • TypeScript
  • Web app · Laravel · PostgreSQL

    live

    Warehouse system on Laravel

    Warehouse accounting where stock is the sum of ledger entries, not a “qty--” field: orders with all-or-nothing reservation, picking by bin, receiving with CSV import, stocktaking and a ledger. A race between two real PHP processes in PostgreSQL shows why row locking is needed.

    • PHP
  • Web app · metrics · alerts

    live

    Bot monitoring

    How a bot is watched in production: how many requests, how fast it answers, how often it fails or doesn’t know the answer. A request log with a trace of every answer and rules that message the on-call engineer in Telegram when something goes wrong.

    • React
    • TypeScript
  • Go service · limits · journal

    live

    Model gateway

    One OpenAI-compatible entrance for the roastery’s bots: each has its own key, a per-minute cap and a daily token budget. Replaying the same key does not charge the budget again, and a failure of the primary model falls through to the backup.

    • Go
    • React
    • TypeScript
  • Go service · MCP · tools

    live

    Zerno MCP server

    An agent calls the roastery’s stock and orders through Model Context Protocol tools: stock, order status, a new lead. The JSON-RPC exchange is shown beside it.

    • Go
    • React
    • TypeScript
  • Python scraper · runs in the browser

    live

    Competitor price monitoring

    A Python scraper crawls the websites of three competitors of an electronics store every day: an HTML catalog with pagination, a sitemap with JSON-LD and an SPA with an API. It matches products with the catalog, sends notifications about changes, recommends a price by rules and exports a report to Excel. Python runs right in the browser.

    • Python
    • React
    • TypeScript
  • Web app · PWA · vanilla JS

    live

    Offline courier app

    A courier’s working day: orders, a call to the customer, handover with a photo and signature. The app opens and works without a network, and changes go to dispatch when the connection returns. If the dispatcher changed the same order in the meantime, the courier chooses which version is right.

    • Vanilla JS