Skip to content

Construction management SaaS, own product

Obly

A construction management SaaS in production, used on the web and through the iOS app downloaded from the App Store. A NestJS API over PostgreSQL serves a Next.js web app and an Expo mobile app, sold by subscription in three plans and built spec first: the product intent lives in a documentation repository that precedes the code.

Role
Sole authorship: product, architecture and engineering across six repositories.
Period
2026 to present
Status
In production, on the web and on the App Store
Obly dashboard comparing a project's budget against spend, with an S-curve and category concentration.

What the system does

  • A daily log captured on site, with photos taken on the spot and document scanning through the camera.
  • Per-project finance: budget by stage, expenses, supplier quotes and planned against spent.
  • Scheduling with a work breakdown structure, assisted setup and MS Project XML import.
  • A document library at the account level, holding designs, contracts, invoices and permits.
  • Floor-plan reading from PDF and budget import from spreadsheets, both through a language model, with mandatory review before anything is written.
  • A voice assistant that classifies what was said and turns it into an entry.
  • A construction report in PDF, assembled from what was already recorded.
  • Subscriber teams and client access, with permissions by role.
  • Subscription in three plans, with a fourteen-day trial and no card.

Architecture

  • A NestJS API over PostgreSQL holds the business rules, across twenty-seven modules and seventy-seven migrations. The Next.js web app and the Expo app consume the same domain model.
  • Isolation per contracting account: team, floor plans, storage and commercial rights live at the account level, not the user level. There is no separate account entity, the account is the owning user.
  • Authentication by a Firebase token verified on the server in a route guard. The backend stores no password, session or refresh token.
  • An entitlement engine on the server: a capability catalog, a per-plan template in a table, a capability guard on write routes and an atomic monthly reservation for the model import quota.
  • Library files in S3-compatible storage on Cloudflare R2, with signed URLs for upload and download. PostgreSQL holds the object key, and reconciliation of abandoned uploads runs once a day.
  • Floor plans in PDF rendered with mupdf and read by a Gemini model. The same provider serves budget import and the assistant's classifier, always with schema-validated output before anything is written.
  • Schedule import from MS Project XML and from spreadsheets. Import is always a preview: nothing enters the domain before confirmation.
  • Subscription billing with Stripe, with prices read from the provider and never copied into the database or the UI.
  • CI against a real PostgreSQL on GitHub Actions, migrations applied before deploy, and the daily cleanup routine scheduled in the same place.
  • A code-free documentation repository holds the product intent: a single PRD, one hundred and seventy-six business rules with a status across fifteen domains, six ADRs, feature specs with acceptance criteria, and two skills describing the change procedure.

Implementation details

  • No price is written into the database or the UI: the catalog is read from the payment provider on every request.
  • The billing webhook records the event before any mapping, and a partial unique index enforces one live subscription per account.
  • The mobile app does not sell: billing happens on the web, and the app only reads the entitlement in force.

Technologies

TypeScript
One language across the three application repositories.
NestJS
The API framework, with modules, guards and dependency injection.
TypeORM
ORM and the seventy-seven versioned migrations.
PostgreSQL
The product's single database.
Next.js
The authenticated web application.
React Native e Expo
The iOS and Android app, with file-based routing and delivery through EAS.
Firebase Auth
Identity on web and mobile, with the token verified on the server.
Stripe
Checkout, customer portal, subscription and webhook.
Cloudflare R2
Storage for photos, thumbnails and documents, with signed URLs.
Gemini
Floor-plan reading, budget import and the voice assistant's classifier.
mupdf
Rendering the PDF floor plan before the model reads it.
exceljs e fast-xml-parser
Reading the budget spreadsheet and the MS Project XML.
Zod
Validating model output before it becomes a write to the domain.
TanStack Query
Data caching and synchronization on the web.
Tailwind CSS
Styling for the web application.
Jest, Supertest e Vitest
Tests for the API, the web app and the mobile app.
Swagger
API documentation.
Expo Push
Notifications delivered by the API in batches, revoking invalid tokens.
PostHog
Product analytics in the mobile app.
GitHub Actions
CI against a real PostgreSQL and the daily cleanup routine.
  • The project schedule as a Gantt chart, grouped by stage, with bars for done, in progress and pending, and today's line.
  • MS Project XML import under review: three stages and ten activities detected, with item-by-item selection before anything is created.
  • Budget import through a language model, with the item list open for review before anything is written.
  • Daily log in the mobile app, with a photo taken on site.
  • The project document library, with folders for designs, contracts, invoices and permits.
  • Cover of the construction report generated for the client.

Want to talk about architecture, technical decisions and shipping to production?

Portrait of Thiago Sanches

Contact details

Available for remote work with international teams

Name
Thiago Sanches
Location
Brazil · UTC−3 · remote
Languages
Portuguese native · professional working proficiency in English
Download résumé

Experience

  • 5 years

    on enterprise systems

  • 70%

    less time per new report

  • 50%

    less latency on GraphQL

  • Workers

    asynchronous processing with Redis queues