Digital backbone for a nationwide agro holding: marketplace, CRM, lead generation
A grain deal, per-hectare cost, and tractor telematics — on a single data model.
Context
The Russian agricultural market is deeply data-fragmented: a farm keeps its books in 1C, document flow in an e-document system, and mandatory reporting in state traceability registries, while telematics, satellite monitoring, weather, and bank statements live in separate interfaces — per-hectare economics are consolidated by hand or not at all. An app that asks a farmer to re-key data gets opened exactly once, so the product had to embed itself into the existing landscape — and cope from day one with backends unreachable from Russian ISP networks.
The task
The client needed a working venue, not a storefront: farmers and traders meeting around real deals, auctions included. In parallel — a product CRM that computes per-hectare cost and margin rather than storing contacts, both on a shared data model so deals, field economics, and external feeds never drift into separate databases. The third component was a hard deadline: an industry trade show with a complete print kit and a live demo of real registration, offers, and an auction — plus the start of measurable B2B calling.
Approach
We split the backbone into three layers over one backend: the public marketplace, the product CRM with the farm dashboard, and the offline sales loop of print and a call tracker. All data converges in a single Supabase project — profiles, offers, requests, deals, auctions, crop catalog, market prices, geodata.
The public site is generated: 23 HTML pages come out of a Python build.py script, and a push to main triggers a full rebuild — no manual markup drift. Registration creates a full account via Supabase Auth and lands in a mandatory Buyer-or-Seller onboarding gate; anonymous fast leads flow through a SECURITY DEFINER RPC and an aiogram 3 Telegram bot into a single admin inbox.
Architecture
The backend runs on Supabase: Postgres as the single store, Auth, Realtime, Storage, and TypeScript Edge Functions on Deno. Auctions run over Supabase Realtime — a bid reaches other participants without a page reload. Delivery is an engineering layer of its own: Russian ISPs block Supabase domains, so the frontend reaches the backend through our own Caddy proxy, without which the platform would not open for a significant share of the audience.
The farm dashboard is a single-file SPA with 12 sections, from sales with a live auction to cost accounting with a live margin calculator. The integration layer is a set of edge functions — token-authorized universal intake of costs, warehouse data, and telemetry, plus live sync of weather (open-meteo) and telematics (Wialon) — grounded in a catalog of 48 agri-market systems, each mapped to an intake channel and a priority.
Print materials and lead generation
For the trade show we produced an 11-piece print kit — roll-ups, a backdrop, A5 flyers for buyers and sellers, a business card, a table runner, and more — with QR codes leading into the registration funnel, exported to PDF at exact millimeter dimensions through headless Chrome. A single-page call-tracking dashboard with three tabs — KPI summary, day-by-day breakdown, searchable database — tracks the B2B calling funnel in the same loop where platform leads live.
Outcome
The platform core is live: the marketplace on real data, Realtime auctions, registration and lead intake, the CRM landing page, and the farm dashboard. Real connectors are operational — weather, telematics, universal cost and warehouse intake — while finance and analytics dashboards move to real data as farms connect. The print kit shipped; B2B calling is tracked daily. Business metrics — conversion, turnover — are consolidated from actuals, never backfilled. The architectural core — a grain deal, per-hectare cost, and tractor telematics on one data model, backed by the 48-system integration roadmap — extends without rewriting.
What we built
B2B marketplace on real data
Profiles, offers, buyer requests, deals, a crop catalog, market prices, and geodata. Auctions with bidding run in real time over Supabase Realtime.
Static site from a generator
Dozens of HTML pages are assembled by a Python build.py script; a push to the main branch triggers the build. Editing a page means editing the generator.
Registration and onboarding gate
A full account via Supabase Auth (tax ID, company, email). A guest without a role hits a Buyer/Seller modal that cannot be dismissed.
Lead intake and Telegram bot
Anonymous fast leads go through an RPC with SECURITY DEFINER into an admin table and notify the team in Telegram. An aiogram 3 bot runs a guest questionnaire and writes leads too.
Farm dashboard
A single-file SPA with 12 sections: sales with a live auction, fields, warehouse, finance, cost accounting with a live margin calculator, a drag-and-drop deal kanban, analytics, an AI assistant, and diagnostics.
Integration layer and system catalog
Edge functions with farm-token intake; live sync of weather (open-meteo) and telematics (Wialon). A catalog of 48 agri-market systems mapped to intake channels and priorities.
Delivery infrastructure around network blocks
Our own Caddy proxy between the frontend and Supabase — without it the platform would not open for a significant share of the target audience on Russian ISP networks.
Trade-show print kit and call tracker
Roll-ups, a backdrop, flyers, a business card, posts; PDF/PNG export at exact millimeter dimensions via headless Chrome. A single-page call tracker with three tabs and automatic statuses.
Engineering challenges
ISPs block Supabase domains
For part of the target audience the platform simply would not open on a direct backend call. We deployed our own Caddy proxy that the frontend uses to reach Supabase around the blocks.
Automated 1C export fails on the client's network
After extended diagnostics the root cause was pinned down as SNI-based DPI filtering on the client's network, not a server problem. The working fallback is manual upload of the .jsn file through a browser, which has its own TLS stack. Automated POST remains an open blocker.
Antivirus flagged the diagnostic package as a trojan
The first version of the scripts, using base64/EncodedCommand, tripped antivirus heuristics. We moved to plain .ps1 files plus a thin .bat launcher — the package stopped being flagged and reached the client.
Free-tier Supabase goes to sleep
On the free plan the project pauses after roughly 7 days of inactivity. Ahead of load and the trade show, the platform has to be kept active so the demonstration and lead intake do not drop at the worst possible moment.