← All work

Builder

Viya

Multi-tenant B2B SaaS that turns raw manifests into reviewed passenger data, optimized routes and driver dispatch.

Status: Early MVP, built as a product for tour agencies beyond a single customer

The problem

Tour agencies work from messy Excel and PDF manifests. Each day's passenger data has to be cleaned up, routed and sent to drivers. Express Ops solved this for one operator; Viya rebuilds the same domain as a multi-tenant product for any agency.

What I built

Viya generalizes the Express Ops domain into a SaaS for any tour agency: ingest Excel or PDF manifests, extract structured data with a routable set of LLM and OCR providers, plan routes and dispatch drivers over the messaging apps they already use.

OutcomeA working early MVP that covers manifest to driver dispatch end to end. The repo's notes list 59 backend test files (Vitest and convex-test), and CI/CD is configured but not yet cutting over production traffic. No customers or revenue are claimed.

What it does

Try it

A working replica of the real interface, running on made-up sample data.

Architecture

How the pieces connect, drawn from the project's own documentation.

Viya architectureThree rows. First, ingestion: an Excel or PDF manifest is uploaded as a tenant-scoped record, parsed by one of four providers (docling, native_sheet, mistral_ocr, llamaparse), then structured by an LLM router that uses minimax_m2_5_highspeed by default with a fallback chain across openai_gpt_4_1_mini, gemini_2_5_flash_lite, zai_glm and deepseek_chat. Second, operations: an admin reviews the rows, routes are generated only when every passenger location is resolved, drivers are dispatched over WhatsApp, Telegram or Slack, and inbound replies are resolved back to the tenant and dispatch. Third, the tenant boundary: Clerk organization context and Convex ownership guards are checked on every read and write, and channel credentials are encrypted before storage.Ingest · manifest to dataUploadExcel or PDF, stored as atenant-scoped recordParsedocling, native_sheet, mistral_ocr,llamaparse; spreadsheet fast pathLLM routerdefault: minimax_m2_5_highspeedfallback chain: openai_gpt_4_1_mini,gemini_2_5_flash_lite, zai_glm,deepseek_chatextracted passenger rowsOperate · review, route, dispatchReviewadmin corrects rows; map pin forambiguous placesRoutesblocked on missing, failed orambiguous geocodes Google or MapLibre+ OSRMDispatchWhatsApp, Telegram, Slack driver DMsDriver repliesinbound webhooks resolved to tenantand dispatchTenant boundaryClerkorganization contextConvex guardstenant ownership validated before anyread or writeTenant datachannel credentials encrypted beforestorage
Mechanism: parse and extraction providers are interchangeable behind one routing layer, route generation is gated on resolved locations, and every business read and write passes a tenant ownership check.

Engineering decisions

How it's secured and shipped

What's next

From the project's own roadmap.

Stack

Want this kind of work on your team?