Tapuli
Back office for a wholesale shoe supplier working with dropshippers: catalog and size-level stock, reservations, Nova Poshta shipping, fiscal receipts and partner settlements — all in one system.
- 5+years in production
- 2,400+commits
- 19projects in the solution
- ~200CQRS handlers
About the project
Dropshippers sell the supplier's catalog through their own shops and social channels, while the supplier has to reserve stock fast, pack and ship parcels and settle with every partner. Tapuli automates the whole cycle — from goods arriving at the warehouse to paying out partner margins.
The system has been running in production since 2021. Managers, warehouse and cashier staff use the web back office, while dropshippers work through a chat bot, the public API or an AI assistant via MCP.
What the system does
-
Catalog & stock
Products, categories, colors and sizes, photos and video on a CDN, per-warehouse stock with change history.
-
Reservations
Stock is held for a dropshipper and released automatically when the reservation expires.
-
Orders & shipments
Order building, Nova Poshta waybills, returns, refunds and missing-item tracking.
-
Labels & barcodes
Warehouse stickers with barcodes and QR codes, rendered as PDF sheets.
-
Cashier & fiscal receipts
Opening and closing shifts, fiscalising sales through a cloud cash register.
-
Reseller finances
Transactions, bonuses, payout requests with approval, budgets and partner rating.
-
Partner chat bot
Dropshippers browse products, reserve stock and track orders right in their messenger.
-
AI agents via MCP
An MCP server with OAuth 2.1 / PKCE: an AI assistant searches products, checks availability and creates reservations on a partner's behalf.
-
Public API & webhooks
Versioned API (v0–v2), catalog subscriptions and push stock updates for partner shops.
How it is built
-
Single ASP.NET Core host
Serves the back office (Razor with Vue islands), REST API with Swagger, the MCP endpoint, an OpenIddict auth server and the Hangfire dashboard.
-
CQRS with MediatR
About 200 handlers organised by feature: orders, reservations, stock, campaigns, cashier, bots, MCP.
-
Outbox-based queue
Ports and adapters: events are stored in an outbox table and executed as chained Hangfire jobs on dedicated queues.
-
Background jobs
Shipment status refresh, monthly customer churn check, Nova Poshta health check every 5 minutes, queue clean-up.
-
Infrastructure
.NET Aspire and OpenTelemetry for development and observability, a Docker image and Azure Pipelines for production, migrated from SQL Server to PostgreSQL.
External services
- Nova PoshtaWaybills, tracking and an API-key pool with turnover limits.
- CheckboxCloud cash register: shifts and fiscal receipts.
- SmartSenderChat bot and notifications for dropshippers.
- TelegramOne-time codes for linking an AI agent.
- TurboSMSSMS messaging.
- Google SheetsImport and export of products and reservations.
- Shops & webhooksProduct and stock sync with the storefront and partners.
Project stack
Backend
- .NET 8
- ASP.NET Core
- MediatR
- OpenIddict
- Model Context Protocol
- Polly
- Serilog
- Hangfire
Frontend
- Razor
- Vue 3
- Quasar
- Pinia
- TypeScript
- Vite
Data
- PostgreSQL
- EF Core
- Redis
Infrastructure
- Docker
- .NET Aspire
- OpenTelemetry
- Azure Pipelines
Have an idea or a project?
Open to collaboration on business systems, CRM and integrations. Drop me a line — let's talk.