← All projects
Diagonal Social · Inherited platform, migrated and shipped

Smart Síndico

Condo management · Mobile

A condo-management platform for Brazilian social housing: Flutter app, admin panel and a NestJS API with digital accounts, bank slips and cost apportionment through Asaas. I took the platform over from an outside vendor, containerized it and got it shipping again.

FlutterNestJSPrismaPostgreSQLDockerAWSAsaas
Role
Migration, infrastructure and ongoing maintenance
Timeline
2025
Tech
Flutter, NestJS, Prisma, PostgreSQL, Docker, AWS EC2, S3, CloudFront, Asaas, Firebase Cloud Messaging
Status
Live
Users
~15k
Platform
3 apps, ~120k lines
Stores
Google Play and App Store
Product showcase

Flows & screens

01   Monthly expenses and accountability, the basis for apportioning condo fees.

How it's built

Implementation

01

Taking over from an outside vendor

The platform came from an agency that had stopped delivering. I picked up the three repositories, stood the environment up, containerized the backend and took over operations. That was the job: making someone else's system run on our infrastructure, with our own release path, without losing the customer along the way.

02

Containerization and production profiles

Separate Dockerfile and compose profiles per environment, memory and timeout tuning on the Node process, and PM2 in cluster mode on EC2. Shipping stopped depending on who had access to the machine.

03

Authentication and the Asaas call

I changed how the JWT is issued and validated, and fixed the way the Asaas access token was passed to the billing API, which was causing intermittent failures when issuing bank slips. CORS and a Sentry upgrade came in the same batch, so production could be investigated with data instead of guesses.

Overview

Smart Síndico is a condo-management platform aimed at Brazilian social housing, the CDHU, Cohab and low-income condo segment. It is three applications: a Flutter app for managers, residents and staff, published on Google Play and the App Store, a React admin panel for operations, and a NestJS API with Prisma and PostgreSQL.

Together they run past 120k lines: about 60k in the app, 30k in the API and 12k in the panel, with 34 models in the Prisma schema.

My role

This is not a project I wrote from scratch, and the honest framing matters: the platform was built by an outside vendor and reached me when Diagonal pulled five products in-house. I took a large legacy codebase and made it run and ship under our own team.

What went through my hands:

  • Containerizing the backend and compose profiles per environment, with a dedicated production Dockerfile.
  • Memory and timeout tuning on the Node process, running in cluster mode with PM2 on EC2.
  • A change to the JWT strategy and a fix to how the Asaas token was sent to the billing API.
  • CORS, an upgraded Sentry and production logging, so incidents could be investigated with evidence.
  • CI/CD: panel releases to S3 with CloudFront invalidation, a staging environment for the Flutter web build, Android flavor cleanup.
  • Store publishing and ongoing maintenance since.

What the platform solves

Social-housing condos have volunteer managers, tight budgets and accountability that has to be simple enough for residents to follow. The product covers the whole cycle:

AreaWhat exists
StructureCondos, blocks, units with ideal fraction, residents, staff with roles, suppliers
FinancePayables and receivables, hierarchical categories, fee apportionment, accountability, receipts, arrears
BillingDigital sub-account per condo, bank slips with fines and interest, cards, reissues, webhook settlement
LivingDeliveries, common areas with booking and inspection, status-tracked incidents, resident classifieds with reporting
CommunicationAnnouncements, real-time chat, Firebase Cloud Messaging push, condo documents
SaaSPlans with per-module permissions, portfolios grouping condos by client

The most interesting part of the code

Apportionment is the heart of the system and the most elaborate service in the backend. It decides whether a fee is split by ideal fraction or by resident count, applies role-based exemptions, generates ledger entries per account type and only then issues the slips. Issuing 400 slips at once hits the billing API's rate limit, so issuance goes out in batches of 90 with a delay between them and three retries per batch, notifying the manager at the end with success or failure.

It is not an elegant algorithm, it is code that survives the first of the month for an entire condo.

Limits, stated plainly

Some modules appear in the marketing material but are flagged as in development inside the app: visitor control, vehicles, assemblies and water consumption. The chatbot does not exist in the code either. I would rather list that here than repeat the brochure.