IBS — a property-management platform, end to end
Intelligent Broker System runs the daily business of property-management companies in the UAE: units, contracts, cheques, receipts, legal cases and reports, with portals for landlords and tenants. I’m the main developer on its .NET backend and its Angular front ends.
What I did
The current platform was started in 2024 to replace an older ASP.NET Web Forms system. For the first stretch, a senior backend developer and a senior frontend developer set the direction and reviewed my work. Since then I’ve carried most of the design and delivery: new modules, the database, the background jobs, the customer portals and the releases.
In numbers: about 1,600 of the backend’s 3,400 commits are mine, the most of anyone, and since January 2025 it’s more than 80%. On the Angular agent portal it’s 516 of 547; the landlord and tenant portals are almost entirely mine.
How the pieces fit
One API and one database behind every client, with slow work handed to background functions.
Shipped through Azure DevOps pipelines. All projects share one central package list, which keeps the .NET and Angular versions current — both are on the latest major.
What the product covers
- Properties & unitsinventory, status, occupancy
- Contractsnew, renewal, approval, termination
- Paymentscheques, deposits, batches, plans
- Receiptsgenerated PDFs with VAT QR
- Final clearancemove-out settlement
- Management contractslandlord ↔ agency terms
- Legal casesdisputes and their history
- Vendors & vendor contractsmaintenance suppliers
- Bookings & appointmentstenant branch visits
- Reports & dashboardsMIS, rent forecasts, charts
- Owners Gatelandlord portal and app API
- Tenant portaltenant web and app API
- Integrationslistings, office queue sync
- Users & securityroles, Google sign-in, 2FA
Problems, and what I did about them
The code is private, so here is the reasoning instead.
Layers that know only what they need
- Problem
- One codebase serves the agent portal, two customer portals, the mobile apps and the background jobs. If business rules depend on SQL Server or Azure, every one of those pays for it.
- Decision
- Clean Architecture: Api (HTTP only), Core (features, rules, validation), Persistence (EF Core, SQL Server, auditing), Infrastructure (files, PDFs, email), and a SharedKernal of types everyone uses. Each feature is one folder in Core.
- Result
- The Azure Functions register the same Core and Persistence services as the API, so a contract PDF built in a background job follows exactly the rules the web portal does.
Slow work leaves the request
- Problem
- Contract PDFs, receipts, ZIP exports, emails and WhatsApp messages are slow and can fail for reasons outside our control. Doing them inside an API call makes the clerk wait and turns a provider outage into a failed save.
- Decision
- The API saves, drops a message on an Azure Storage queue and returns. Queue-triggered Azure Functions do the work and retry on their own, and the finished file lands in Blob storage for the portal to pick up.
- Result
- Saving a contract is instant, and a mail-server hiccup no longer undoes anything.
Search requests that can’t outgrow the URL
- Problem
- Filters with many selections were sent as query strings. On the deposit-batch list one filter alone reached 2.1 KB — past the 2 KB limit of IIS and most firewalls.
- Decision
- A written rule: lists use GET by default; as soon as a filter contains a list it becomes POST …/search with the filter in the body and paging still in the URL. Every filter has a validator that caps list sizes.
- Result
- Long filters no longer hit server limits, and paging stays visible in logs.
Every change has an author
- Problem
- This is money and legal contracts. ‘Who changed this cheque date?’ needs an answer months later — without the audit table slowing down the main database.
- Decision
- Auditing is wired into the EF Core save pipeline, so every entity change is recorded with its user and before/after values. A timer-triggered Function moves old audit rows out to Azure Table Storage on a schedule.
- Result
- Complete history, and a main database that stays lean.
Three kinds of users, three front doors
- Problem
- Agency staff, landlords and tenants need different data, different sign-in and different levels of trust.
- Decision
- Separate Angular apps and API modules for each audience, each with its own security service. Staff can sign in with Google; the landlord and tenant portals have two-factor sign-in with trusted devices that a scheduled job cleans up.
- Result
- A landlord can never reach staff endpoints, even by mistake.
Rules written down, not remembered
- Problem
- With one main developer, knowledge that lives only in my head is a risk to the company.
- Decision
- Each repo has a short conventions file: how endpoints are named, how errors are shaped, how dates are stored, how soft-deletes work — and why. When a feature is removed, I write down how to bring it back.
- Result
- New developers — and AI coding tools — produce code that matches what’s there.