NP / Projects/ ReportFlow Platform — Connecting the Field to the Office

ReportFlow Platform — Connecting the Field to the Office

February 8, 2026

SvelteKitHonoPostgreSQLBunTypeScript

ReportFlow solved the field side of the backflow testing workflow by giving technicians a way to capture test data and generate reports from their phone. However, once those reports are submitted, they still land on someone’s desk in the office. Office staff spend hours manually processing test results, figuring out which devices passed, which ones need repairs, putting together quotes, and getting invoices sent out. Jobs slip through the cracks because the handoff is entirely manual, data entry errors lead to lost revenue, and the whole process between the field and the office remains disconnected. ReportFlow Platform is the project I am building to close that gap. It is a workflow management system that takes submissions directly from the field and handles the entire downstream process, from review and approval to repair quoting and export for billing.

Starting with Supabase

This is not actually the first version of the platform. Before it was called ReportFlow Platform, it was called FlowSentry, and I had originally built it on top of Supabase. Much like my experience with MAUI when building the mobile app, I ran into serious friction very quickly. The development cycle with Supabase was painful. Every time I needed to update the database schema, I had to reset all the data and then manually test whatever feature I was working on from scratch. For something like the submissions workflow, which involves multiple states, locking, section-level review, and audit logging, this became an enormous time sink. The workflow was already complex enough on its own, and having to constantly tear down and rebuild my test data just to verify a single change made the whole process feel convoluted and unsustainable. I also had very little control over how the backend behaved, and I found myself fighting the platform more than I was building on it.

That experience is what made me realize how much I valued being able to own my own database and API layer, and more importantly, being able to extensively test my work. It directly shaped the architecture of the current platform. The decision to use a monorepo with Drizzle ORM and Bun’s test runner came from the frustration of not having those things with Supabase. Now I can write a migration, run my test suite, and know immediately whether something broke, without having to manually reset anything or click through a UI to verify it. The FlowSentry attempt was ultimately a failure, but it taught me exactly what I needed the real platform to be.

The Vision

The core idea behind the platform is fairly straightforward. When a tech finishes an inspection and submits their results, the system should already know what to do with them. If everything on the job passed, it gets routed toward billing. If something failed, it gets flagged for a repair quote. If there is an issue with the submitted data, it gets sent back to the tech for correction. The office still reviews and approves everything, but the system handles the routing and state management rather than relying on someone to manually sort through submissions. The long-term goal is to eliminate the gap between field work and office work entirely, creating one connected system where data flows from the test instrument all the way to the invoice without anyone having to re-key numbers into a spreadsheet.

Architecture Decisions

I am building this as a monorepo, and the guiding philosophy behind the architecture is that the API and database are the product, and everything else is a thin GUI wrapper on top of them. The monorepo is organized into four packages. The first is the API, which is built on Bun and Hono with PostgreSQL through Drizzle ORM, and this is where all of the actual business logic lives, including the submission review workflows, state machine transitions with pessimistic locking to prevent conflicts, and organization-scoped queries for multi-tenancy. The second package is the web portal, built with SvelteKit, which is intentionally kept thin and contains no business logic of its own. It simply calls the API and renders the result. The third is a shared package containing TypeScript types, Zod validators, and RFJSON mappers that both the API and web packages consume, which ensures that the contracts between field submissions and the database schema always stay in sync. The fourth is a mobile package, which is currently a placeholder. The plan is to eventually rewrite the current Flutter app as a web app using Capacitor so that it lives in the same monorepo and can share the same API client and validators from the shared package. Flutter served me very well for the original ReportFlow, but having the mobile client share types and validators with the rest of the system is too valuable to pass up.

One of the key insights I gained from building ReportFlow is that the mobile app’s job data format, which I call RFJSON, is essentially the common language of the entire system. The shared package includes bidirectional mappers between RFJSON and the database schema so that field submissions translate cleanly into structured data that the platform can work with.

I chose each piece of the tech stack deliberately. Bun gives me a fast runtime with a built-in test runner and native TypeScript support. Hono is a lightweight and middleware-friendly API framework that does not get in the way. Drizzle ORM provides type-safe database queries without the overhead or unpredictability of a heavier ORM. PostgreSQL 18 with UUIDv7 for all primary keys keeps the data layer solid and modern. Better Auth with the organization plugin handles multi-tenant authentication. SvelteKit powers the office portal because it is server-rendered, fast, and something I know well. And Turborepo orchestrates the entire build process with cached linting, type-checking, and test runs across all packages so that unchanged code does not waste time being re-evaluated.

Testing is something I take very seriously on this project. The API and shared packages have extensive test coverage using Bun’s built-in test runner, and the web package has Playwright end-to-end tests that spin up dev servers and seed real databases. Turborepo caches all of the test results so that packages with no changes do not need to re-run their tests on every build.

The Submission Workflow

The core of the platform is a state machine that manages the lifecycle of every submission review. When a tech submits their inspection data, the submission enters a pending state and waits for a reviewer to pick it up. Once a reviewer claims it, pessimistic locking ensures that no one else can modify the same submission at the same time, which prevents conflicts when multiple office staff are working through the queue. The reviewer then works through each section of the submission, including customer information, device details, and test results, and they can approve sections, flag issues, or request changes at any point. Every single edit, flag, and resolution is logged in a full audit trail, because in this industry you need to be able to trace exactly who changed what and when. Once the submission is fully approved, it moves into the export stage where it can be sent to billing or submitted to the city.

Multi-Tenancy

I designed the platform for multi-tenancy from day one. Every query is scoped to an organization, team members are assigned roles, and all data is fully isolated between tenants. The reason for this is that I do not want to build something that only works for one company. The goal is to eventually license this platform to other backflow testing companies as well, so the multi-tenant architecture needed to be baked into the foundation rather than bolted on later.

Current Status

We are closing in on the first beta release, which I am targeting for February 13th. The API and database layer are solid and well-tested, and the bulk of the remaining work is finalizing the web UI and a handful of missing features. The biggest one is the exports page, which handles the post-approval workflow for city submissions and billing, but beyond that it is mostly production deployment configuration, the member management UI for inviting and managing team roles, and wiring the dashboard statistics up to real data. Once the beta is in the hands of the office staff, that is when the real feedback loop begins, and we will find out what actually works in practice versus what looked good on paper. After that, the roadmap includes the Capacitor-based mobile rewrite, QuickBooks integration for invoicing, and opening the platform up to other companies.

Building ReportFlow taught me how to solve the problem in the field. Building the platform is about solving the whole problem, from the moment a tech walks up to a device to the moment the invoice goes out the door.