One operator. One month. Eight things that have to hold.
Rashid runs three buildings he does not own: a 384-bed labour camp in Al Quoz, a labour village in Jebel Ali and a compound of partitioned staff villas in Dubai Investments Park. He pays three landlords and bills forty-odd companies. Follow one month of that, step by step, and by the end you will have used most of this product.
Rashid is a narrator, not a customer. There is no case study on this page, no quote from anybody and no claim about who uses this. Every figure and every name in the demonstrations below — the operator, his buildings, the contractors he bills, the men in the beds — is illustrative sample data, and none of them is a customer of ours or a record of anybody’s real trading. The capabilities described alongside them are the ones that are actually built, and where a step would naturally promise something this build does not do, the panel says so in as many words.
AvailableOccupiedReservedTurnover cleanOut of serviceMoney
384Beds in the camp he starts with
480Spaces built from a pattern, in one press
20Beds on the contract that follows them all
12Pieces of paper a year of rent arrives as
The landlord
Holds the building. Takes one head lease payment, usually as twelve post-dated cheques, and wants to know whether each one has cleared.
The corporate client
Signs for a headcount — twenty beds, forty beds — and rotates staff through them without the agreement changing. Billing follows the contract.
The occupant
Sleeps in one bed, carries four documents with four expiry dates, and is not the person being invoiced. Compliance follows him.
The camp boss
Runs the site: jobs, cleans, the gate, the stores. Holds zero permissions matching invoice, payment, cheque, deposit, expense, head-lease cost or rate.
01
Step 01 of 8 · Monday
He takes the building
The landlord wants AED 115,000 a month for Al Quoz Camp 1 — 384 beds, six blocks, AED 1,380,000 a year, twelve post-dated cheques. That number tells Rashid nothing about whether the building is worth taking, because he is not going to let the building. He is going to let 384 things inside it: most of them to two contractors on committed lines at a negotiated rate, and the rest one bed at a time to individuals at a higher one.
So the cost is one figure on one agreement and the revenue is dozens of figures on a dozen agreements against the same physical asset. The difference between them — the spread — is the only number that decides the question, and no system that models a lease as landlord-to-tenant can produce it, because it has nowhere to put the second side.
Underneath the head lease sits everything else it costs to hold the building before anybody sleeps in it: security, cleaning, the mess subsidy, unrecharged utilities. In the demonstration below, Al Quoz breaks even at about 55% occupancy measured against the lease alone, and about 70% once those costs are in. The second figure is the one an operator loses sleep over, and a break-even computed against the rent alone flatters the business.
Drag the occupancy slider down until the gold bar shrinks to the break-even line and crosses it. Then switch buildings — the villa compound and the labour village have completely different shapes.
Al Quoz Industrial 3, DubaiLabour accommodation · 6 blocks
86%330 of 384 beds
70.1%
AED 600per bed, per month
break-even
Head lease what the building costs youAED 149,000/mo
Head lease AED 115,000Security, cleaning, mess and unrecharged utilities AED 34,000
Subleases what your contracts earnAED 190,272/mo
Spread the number a rent roll cannot produce+AED 41,272/mo
AED 41,272 a month of spread at 86% occupancy. Break-even is 70.1%.
70.1%Occupancy needed to break even at this rate
+AED 107Spread per bed, per month — the unit that matters
21.7%Margin on the building, not on the rent roll
AED 672The next bed let, on the Individual residents line
Spread across the occupancy rangeEach kink is a contract line filling up. Past the last one you are selling at the headline rate, so the curve steepens.
40%100%
Sublease lines on Al Quoz Camp 1, with the beds each holds at 86% occupancy
Line
Held
Committed
Rate
Per month
Al Nakheel Contracting
160
160
AED 540
AED 86,400
Emirates Facilities Co
96
96
AED 564
AED 54,144
Individual residents
74
128 available
AED 672
AED 49,728
Two corporate lines hold 256 of the 384 beds. The rest is sold one bed at a time, at a higher rate and with a month’s notice.
A corporate line is a pooled quantity, not a list of beds: the contract says “160 beds” and allocation decides which ones, later. When occupancy falls below the commitment the line is short — the marked figures above — and that is a conversation with the client, not a billing change.
What just happened
A property carries the paperwork a Gulf operator actually holds — plot number, Makani number, title deed, DEWA premise number, emirate, handover date, timezone and currency. Properties group into estates, and a group refuses to be deleted while properties still sit in it.
The head lease reaches the profit-and-loss account. The property P&L derives the cost from the lease itself when the nightly accrual has not run, because “not yet computed” is not the same as “rent-free” — a distinction that had every property showing a 100% margin until it was fixed.
Head-lease instalments fall below the line on the Cash Ribbon, alongside supplier bills, with receipts and clearing cheques above it and a running balance threaded through — 90 days back, 180 forward, starting from cash actually held rather than from zero.
What you pay for a property is its own permission. It is one of ten readings granted individually rather than swept up by a read-only role, so a person can hold revenue and not cost — and the margin bridge demands both keys, because publishing revenue and the spread would disclose the cost by subtraction.
Head leases sit on the expiry radar with contracts, tenancy registrations, occupant documents, vendor trade licences and vendor insurances — one list, sorted by days remaining, 120 days of horizon, so nobody has to remember to look in six places for the same class of problem.
Money is a whole number of fils with a currency beside it, never a decimal that drifts. Adding dirhams to dollars throws rather than guessing a rate, and anything divided is split so the parts add back to exactly what went in.
And what it does not do
Outbound cheques to a landlord are tracked, dated and counted in the cash forecast, but clearing one does not settle a landlord or vendor payable — that side was left to the payables work.
There is no currency conversion. Each invoice keeps its own currency, and a mixed-currency filter returns per-currency figures rather than one converted total.
02
Step 02 of 8 · Monday afternoon
He builds four hundred and eighty spaces
A camp is not a list of beds. It is blocks, then floors, then units; inside a unit, rooms; inside a room, partitions; inside a partition, beds. Rashid describes that shape once — the blocks, the floors, the units on each floor, each unit a dormitory room split into partitions of three — and watches the count update as he types, until the preview reads four hundred and eighty spaces. One press writes the blocks, floors, units, rooms, partitions and beds in a single transaction. Nothing half-built is possible.
Every level of that tree is a thing somebody could let, and that is exactly the problem. The same cubic metre appears four times over, and it cannot be sold four times. So the interesting question is not how the tree is drawn but who refuses it — and the answer is PostgreSQL, not a check the application might forget.
What comes out is the tree below — a slice of that camp, small enough to read at a glance and deep enough to reach all three levels. Press “Let this room” on a room with one occupied bed inside it and the attempt is rejected, with the offending bed named. Press it on the clean room in Block B and it succeeds on the first press. The refusal is walked from the real ancestor and descendant chains, so every space in the tree answers correctly — including the ones nobody thought to script.
Expand the tree, select Room A01 and press the let button. Then try Block A from two levels up, and Room B01, which is clean.
Unit
L1 Room
L2 Partition
L3 Bedspace
No L4
HINTRoom A01 is selected. Press “Let this room”, and watch it be refused.
None of that is screen logic. It is three lines of schema, and they hold whether the request arrives from this page, the API or a script somebody ran at midnight.
EXCLUDE
USING gist (space_id WITH =, period WITH &&)
one bed, one tenant, one night
TRIGGER
space_no_ancestor_or_descendant_overlap
and never the room above it as well
CHECK
nlevel(path) <= 3
room, partition, bedspace, and stop
The eight statuses a space moves through — 29 legal moves between them, and the screen only ever offers the ones the server will accept
Four legal nesting shapes, at most three deep: room to partition, room to bedspace, partition to bedspace, cabin to bedspace. Nothing else. A bedspace claiming to hold two people is refused outright — if it holds two, it is a room — and a space cannot cross into another unit.
The plan limit is checked before the build, with the exact shortfall. The preview reads “Will create 480 spaces — your plan allows 750, 412 used → BLOCKED, need 142 more” and names the add-on that fixes it. The count and the write happen together behind one lock, so two people building at once cannot jointly slip past the limit.
A build is one batch, undoable for sixty minutes, and refused once any space in it has been reserved or occupied. Pressing build twice returns the first batch rather than building 960 beds.
Numbering matches the building people walk into. Ground floor named your way, floors numbered from wherever you start, the 13th skipped when the building skips it, unit codes from a pattern — {floor}{n:02} gives 101, 102, 103 — and a per-floor multiplier that prices the fifth floor at a premium in the same pass.
Taking a bed out of service needs a written reason and its own authority. It is the one status that removes a bed from your occupancy denominator, so a property at 70% becomes 100% by mothballing the empties. The person whose commission is measured on occupancy does not hold that permission.
Pricing a bed is a different permission from editing one, and it is checked at four doors — creating a priced space, repricing one, a bulk build setting a rate across 400 beds, and an uploaded workbook with the rate column filled in. A control with a side entrance is not a control.
A four-bed room is four sellable things, not five. The tree, the map, the dashboard and the reports all compute occupancy from one rule and show their working: how many spaces are subdivided containers, how many ancillary, how many excluded, how many genuinely lettable.
The spreadsheet round trip has a dry run that names every bad cell. A thirteen-column workbook where the download is the upload format, a second sheet listing every legal value, one upload to validate and report every problem by row and column, a second to commit — all or nothing.
Every bed gets a QR code and an A4 sheet to print them all, three to a row at 50 mm, sized to scan from a metre. It opens a report-a-problem form pre-filled for that exact bed, with no sign-in — so a resident with a broken air conditioner raises a job already tagged to the right space.
And what it does not do
No photographs of a bed or a room. The table exists with a storage key, a caption and a cover flag, and nothing in the product writes to it or reads it — there is no uploader and no gallery.
The bed map is a grid, not a scaled floor plan. There is no drawing surface, no coordinates on a space, and no way to place beds on an uploaded building plan.
Blocks and floors can be created but not renamed or deleted. Units have the full set; those two do not.
Nothing updates live. If a colleague fills a bed while you are looking at the map, your screen does not change until you reload it or move the time scrubber.
03
Step 03 of 8 · Tuesday
A contractor signs for twenty beds
ASGC want twenty beds from January, for twelve months, at AED 750 a bed. They do not care which twenty, and Rashid needs to keep the freedom to move people between rooms without opening the agreement. So the contract line says a quantity and a scope — “20 beds in Camp A” — not bed numbers.
This is the thing generic property software gets wrong in the same way every time. It models a lease as pointing at a unit, so the only way to express twenty beds is twenty leases, and then moving one man one metre becomes a contract amendment. Here the beds are chosen later, one arrival at a time, by an allocation — a time-bounded join between the agreement and the person.
Two things the instrument will not let you do. Place the twenty-first man: the line says twenty, and the way past it is a variation — a priced, approved change — not a quiet insert. And place anybody in the nine beds a rival contractor holds from March to June: they are empty tonight, and still refused, because the constraint is over the period rather than over the instant.
Fill the line to twenty and then try the twenty-first. Try one of the amber beds. Then move a man from one bed to another and watch the contract card refuse to move.
CL-1042Pooled
20 beds
ASGC Group · SUB-2026-0117
Rate
AED 750/bed/mo
Term
1 Jan 2026 — 31 Dec 2026
Billed monthly
AED 15,000
That figure is the same at nought beds allocated and at twenty. A pooled line is billed on its quantity, so the invoice never waits for the site office to decide who sleeps where.
Allocated against this line0/20
20 still to place. Click a mint bed.
line_mode
POOLED
allocations moved
0
contract_lines rows changed
0
variations raised
0
Camp A · blocks A and B · 48 beds
FreeOn this lineHeld elsewhereOut of service
A-01
A-02
A-03
A-04
B-01
B-02
B-03
B-04
Point at any bed. Click a mint one to place a man against the line.
The same bed cannot be let to two people, and fifty simultaneous attempts give one winner. The check is made by the database index at the moment of writing, not by reading first and deciding after. The refusal names who already has it and from what date rather than reporting an error code.
A man moving out on the 31st and another moving in on the 31st is legal; moving in on the 30th is refused. That is a normal Tuesday in a camp, and the rule has to know the difference.
A room and the beds inside it can never both be let. The check walks the whole tree — villa, rooms, partitions, beds — over any overlapping dates including future bookings. Subdividing is how you make the margin and also how you accidentally sell the same square metre twice.
Five conditions are checked before a contract goes live, and all failures are reported together: at least one line, somebody has signed it, the deposit has been invoiced in full, every named bed is in a lettable state, and the activation stays inside your plan allowance.
A signed contract is never edited — it is varied. The variation records what the terms are now and what they would become, with the rent total before and after, and goes for approval. Applying it is a separate deliberate act — and if the contract moved underneath it in the meantime, applying is refused rather than silently using stale figures.
A renewal is a new contract, not an edit. It points at the original, copies every live line with an escalation applied in whole fils, and starts the day after the old one ended. The year you charged AED 780 is still on record when you renew at AED 820.
The renewal radar has a horizon per contract type — 90 days for an annual contract, 30 for monthly, 7 for short-term — showing days remaining and whether each is inside its own window.
Up to 500 placements in a single all-or-nothing request. If assignment 27 of 40 fails, nothing is written and the answer says which row failed and why. Forty men off one bus with thirty-eight placed is worse than none placed, because nobody can tell which two have nowhere to sleep.
Before the contract there is a funnel: leads with a source and a requirement, viewings that move the stage by being booked rather than by somebody remembering, and quotations that hold real beds for fourteen days — a revision carries the holds across without ever dropping them back on the market, and a nightly job releases lapsed ones to the state they held before.
And what it does not do
Pooled beds are not auto-picked. The system caps the quantity and refuses the overflow; choosing which beds fill a line is a human act on the availability list or the bed map.
Nothing flips a sublease to EXPIRING on its own — the renewal radar is a query you open. Auto-renew is stored and shown, and renewal is always an explicit act.
There is no upload of the signed contract PDF. A signature is recorded as a name, a date and a method — wet ink, e-sign or stamp.
Quotations are not emailed and no PDF is produced. Sending records the send and the address; documents are print-ready HTML.
04
Step 04 of 8 · Over the fortnight
The men arrive, and the paperwork starts its clock
Twenty men arrive over two weeks. Each is placed on a specific bed against the pooled line, and each move-in completes only when all five items are true: keys issued, induction done, bedding issued, ID verified, meter reading taken. Anything outstanding is named in the refusal. Completing the checklist is what makes the allocation active and the bed occupied — not somebody changing a status.
An unanswered “keys issued” is a man in a room he cannot lock. An unanswered “ID verified” is an undocumented occupant in the camp on the morning of an inspection.
And then the part that runs for the next year without Rashid touching it. Each man carries a passport, a residence visa, an Emirates ID and a labour card, each with its own date. The expiry is not an event on the day it happens; it is the bottom rung of a ladder that started sixty days earlier — and the bottom rung is not a message. It is a refusal at the gatehouse.
Drag the scrubber from one end to the other and watch Ashraf’s residence visa walk every rung and end in a refused pass. Click a different document to make it the ladder’s subject — the passport behaves differently, deliberately.
Today1 Sep 2026
9Compliant
7Expiring, on the ladder
0Expired
0 of 4Gate passes refused
Today
OctNovDecJan 2027FebMarApr
Anika FernandesHousekeeping supervisor · C04-1
Rajesh KumarElectrician · A03-2
Bilal HaqueDriver · B01-4
Mohammed AshrafSteel fixer · A02-3
VSMohammed AshrafResidence visa · 201/2024/118392028 Dec 2026 — 118 days leftIn date
Following Mohammed Ashraf’s residence visa — pick any marker above to follow a different one.In date
T−90The resident and the file owner3 here now
A renewal notice goes out and the document acquires a date. Nothing else changes: the man works, the bed bills, the file is simply no longer quiet.
T−60The camp coordinator2 here now
A task is raised and the document joins the renewals board. It stops being a date in a folder and becomes somebody’s job, with a name against it.
T−30The site supervisor, every morning2 here now
Escalation. The supervisor is named in the daily digest until the document is replaced or the occupant is stood down. Silence is no longer an option anyone has.
T−0The gate0 here now
Not a message. The gate pass is refused, the allocation cannot be renewed and no exit permit will print. The ladder ends at a locked turnstile, which is the only rung anybody ever remembers.
GATE PASSGP-26-0311
AF
Anika Fernandes
Housekeeping supervisor · Meraas Facilities
Jebel Ali Staff Village · C04-1 · AED 1,150/mo
GATE PASSGP-26-0418
RK
Rajesh Kumar
Electrician · Gulf Steel Contracting
Al Quoz Camp 1 · A03-2 · AED 750/mo
GATE PASSGP-26-0502
BH
Bilal Haque
Driver · Emirates Logistics
Al Quoz Camp 1 · B01-4 · AED 900/mo
GATE PASSGP-26-0644
MA
Mohammed Ashraf
Steel fixer · Gulf Steel Contracting
Al Quoz Camp 1 · A02-3 · AED 750/mo
Four beds, AED 3,550 a month, contracted to three employers. Not one of those invoices pauses because a document did — the bed is still let, the head lease is still owed, and the only thing that stopped is the man. Which is why the ladder starts ninety days out and not on the morning it matters.
More than 60 days
Valid. Nothing fires, nothing is owed, and the cell on the compliance matrix is green.
60 down to 30
Expiring. The occupant and their employer contact are told, once. A renewal that pushes the date back does not re-fire it on the way out.
30 down to zero
Critical. A task is raised for the HR coordinator at 30 days; the property manager hears about it at 7.
Past zero
Expired. The person is marked not compliant, and a gate pass is written REFUSED with the document named on it.
What just happened
The compliance matrix puts the worst people on page one. Every occupant down the side, the four expected documents across the top, a coloured cell for each. The five counters above it are computed over your whole organisation, not over the page in front of you — so pressing one narrows the grid and never rewrites the counters.
A grey cell is the dangerous one. The grid draws a cell for a document you have never uploaded and says “Nothing on file — nothing will alert you about it either.” A document with no expiry date can never fire an alert, and every other system renders that as an absent row.
The worst document decides the person. One expired or rejected document makes them not compliant. A man with a perfect passport and a lapsed visa cannot work; averaging his paperwork would say he was fine.
Each rung fires once. The rung reached is written on the document, so a visa sitting at forty-five days for a fortnight produces one warning rather than fourteen. The nightly sweep runs at 06:10 in each organisation’s own local day, so a re-run or a missed hour cannot double up.
A refused pass is a record, not an error message. It appears in the register with its reason in its own column, and no movement can be recorded against it. A guard turning somebody away at six in the morning needs a sentence they can read out.
Barring a person costs a written reason — and lifting the bar costs the same authority that set it, so a supervisor cannot undo a property manager’s decision. A gate that only closes is not a gate.
Passport, visa and ID numbers are encrypted where they are stored. Screens show the last four digits. Seeing the whole number takes a separate permission, a typed reason, and an audit entry against your name and the time — so a spreadsheet of four hundred passport numbers is not one click away.
One live document of each type. Filing a new visa supersedes the old one rather than sitting beside it; the database refuses two current documents of the same type for one person. Two visas on one man is how a grid shows green next to red and nobody can tell which is true.
Somebody checked it, or nobody did. A document can be verified — a person saying they have seen the passport and it is that man’s — or rejected with a reason he can act on. Verifying does not make an expired document valid; the dates still decide.
A contractor’s roster imports from a workbook, names, nationalities, employee numbers and three documents with their numbers and expiries together, with a dry run that reports every problem and writes nothing. A half-imported roster is worse than a rejected one.
The register answers “who is on site right now” across every property at once, and a headcount check compares the people with beds allocated today against the people recorded inside — reported deliberately as a prompt to go and look, never as a conclusion.
And what it does not do
Nothing is actually sent. The sweep recomputes states, fires each rung once and writes an audit record; the delivery adapters log rather than send until an SMTP relay is configured, and today every attempt records a connection refusal that the platform console shows you.
Barring somebody stops their gate pass and nothing else. There is no blacklist check in the allocation path, so a barred person can still be given a bed.
No scan is attached to an occupant document from the compliance screen — the form captures type, number, issuing country and dates only. There is a separate document vault that stores and virus-scans a file, and the two records are not joined.
There is no bulk reminder send and no one-click “request document” from the matrix. Chasing a renewal happens outside the product.
Gate passes never expire on their own. A pass stays approved past its valid-to date until somebody records a movement.
05
Step 05 of 8 · The 1st
Month end: the invoice, then the paper
ASGC’s twenty beds at AED 750 — except the men arrived on the 14th of a thirty-one-day March. They owe eighteen of thirty-one days, and the invoice line has to say so on its face, because every disputed invoice in this business is a part month. The line prints the days and the dates next to the amount, so the argument ends at the invoice instead of in a meeting.
Everything on the document is a whole number of fils. A damaged window recovered from three men is split so the three parts add back to exactly what went in, odd fils handed out largest-remainder — not three equal shares with a fils nobody can explain. Tax is resolved line by line against the date of supply, from a rulebook that is editable rows in your own database rather than code, and each line stores the sentence explaining which rule chose that rate.
Then press Issue. The document freezes — not the screen, the database. From that moment the amounts, the customer, the number and the dates cannot be changed by anybody, including us, and a correction is a credit note with a reason code against a cap that two clerks racing each other cannot jointly exceed.
Step through it, or let it play. Stop on the proration and check the arithmetic against a calculator — every figure on the panel is computed, none is typed. Then issue it and try to edit it.
Step 1 of 8. An empty draft. Running total AED 0.00.
Tax invoice
INV-2026-1043
Gulf Falcon Contracting LLC
1–31 March 2026 · AED
Draft
Invoice lines, added one step at a time
Description
Basis
Amount
No lines yet. Press Next.
Seven invoice states — and five aging buckets an unpaid one falls through
A year of rent here does not arrive as twelve payments. It arrives once, on the day the contract is signed, as twelve pieces of paper dated a month apart — and from that moment Rashid is a custodian of physical instruments as much as a landlord. A payment schedule cannot bounce, cannot be postponed by approval, and is never in a drawer in Al Quoz. So a cheque here is its own record with its own lifecycle, its own calendar and its own custody report.
Run the clock forward. July’s cheque goes to the bank and comes back unpaid in August. A bounce is not a status change: the risk band steps down and never improves from a bounce, a bounce-fee invoice raises and issues itself, a collection case opens with a number, and the payment the cheque had already produced reverses so its invoices go back to unpaid — one transaction, and the reason you pick decides which of them happen. Pick “technical” — your own wrong date, a missing endorsement — and no fee is charged, because charging a client for your clerical mistake is how a small error becomes a lost client.
Drive the clock month by month. Stop on the bounce and watch four things land together. Then look at the custody count — which cheques the system believes you are physically holding, and where.
C-2026-0184 · Gulf Contracting LLC
Al Quoz Camp 1 · 240 of 384 beds · 01 Jan – 31 Dec 2026 · AED 2,160,000 for the year, handed over as twelve cheques on the day of signing.
Register as atDay one — 28 Dec 2025
Day one — 28 Dec 2025 12 in the safe, 0 at the bank, 0 cleared.
Click any cheque, or use the arrow keys.
01 Jan
01 Feb
01 Mar
01 Apr
01 May
01 Jun
01 Jul
01 Aug
01 Sep
15 Oct
01 Nov
01 Dec
Emirates NBD · Al Quoz004417PayGulf Space Management LLCThe sum ofOne hundred and eighty thousand dirhams onlyAED180,000Gulf Contracting LLC01 Jan 2026004417 026 0198765432
ReceivedINV-2026-0301
Received and logged against the contract28 Dec 2025
C-2026-0184 line 1 — 240 pooled beds, Al Quoz Camp 1
Scan
Both faces on file
What is physically in the safe
SAFE-A · BOX 3 · AL QUOZ
In the safe, presentable
12chequesAED 2,160,000
Lodged at the bank
0chequesAED 0
Cleared to date
0chequesAED 0
Returned or superseded, held on file
0instrumentsAED 0
12 instruments issued against this contract, 12 accounted for, counted as at 28 Dec 2025. A returned cheque is still a piece of paper in a drawer — it is worth nothing and it is still yours to hold, which is why it is counted and not deleted. A schedule of due dates cannot answer this question at all.
Against these sit four outbound cheques to the landlord — AED 1,440,000 for the whole property, all 384 beds, written the same week. This one contract of 240 beds covers every dirham of it and AED 720,000 besides. That is the two-sided lease: one asset, two chequebooks, and a spread rather than a rent roll.
Eleven cheque states, from received to recovered — only the legal next moves are ever offered
Rent invoices raise themselves nightly, and never twice for the same month. The run reads every live contract, works out which periods are now due, and raises them one per customer per period per property. Re-run it after a crash and nobody is billed twice — it reports how many lines it skipped because they were already there.
A part month can be priced four ways, and the line says which: by the real days in the real month, by a flat thirty-day month, as a whole period anyway, or free. Periods run either on the calendar or on the contract’s own anniversary, across seven billing cycles from daily to annual.
Eight seeded UAE tax rules over four tax codes, with priorities you can insert between: deposits out of scope, first supply of new residential zero-rated, serviced accommodation standard, bare land exempt, ordinary residential exempt, services standard. Zero and Exempt stay separate rows in the summary though both read 0%, because a tax return distinguishes them absolutely.
A corporate invoice carries an annexe grouped by employee and by bed. A client with forty beds does not reconcile a single total — they reconcile employee by employee. That annexe is what gets the invoice approved rather than returned.
Voiding keeps the number. It is possible while nothing has been paid, needs a written reason, and writes an equal and opposite ledger entry rather than deleting anything. A gap in your invoice numbering is the first thing a tax authority asks about.
Money in is spread across invoices the way you choose, oldest first, a named invoice or your own split — and anything left over is held as customer credit rather than forced onto this one. A reversal unwinds every allocation, restores each invoice’s balance and status, and keeps the receipt number.
The bank statement imports and is matched, never auto-applied. The system reads the header, proposes which column is the date, the credit and the reference, then scores every incoming credit against your open invoices with a reason for each candidate. Nothing is created until you confirm, and re-importing the same statement pays nothing twice.
Banking a cheque and marking it bounced are different permissions, because in a market that runs on post-dated cheques, whoever can present one must not also be able to record it returned. That is the fraud the separation exists to stop.
The custody view answers a question a spreadsheet structurally cannot: which cheques you physically hold, grouped by where they say they are — main safe, finance drawer, with the bank runner — and which have no recorded location at all. Handing one to a runner is logged as a move of paper, not a change of status.
A deposit is a liability that can never go negative and closes at zero. Its own append-only ledger, six movement types, and a settlement that nets rather than exhausts — so carrying a deposit into a renewal is two movements and no cash appears to move.
The chasing ladder fires once per rung per invoice: a reminder at day 1, a formal reminder plus late fee at day 5, escalation and a task at day 10, a final notice at day 20, a collection case at day 30. Late fees carry a grace period and a hard ceiling, and the ladder never walks backwards into sending a friendly reminder after a final notice.
A discount over your threshold, a write-off over your limit and a cheque postponement stop and ask somebody. The write-off threshold is measured against the running total already forgiven on that invoice, not against this note alone — because AED 8,000 written off as two halves passed both times before that was measured.
And what it does not do
Nothing is emailed or messaged to a customer. There is no endpoint that sends an invoice, a statement or a dunning notice; the chasing ladder records each step and returns dispatched: false.
Documents are print-ready HTML, not generated PDF files. They open in the browser and print well; no PDF is stored.
Tenants cannot pay online. Card and online record that a payment happened elsewhere — no screen accepts a card number for a rent invoice.
There is no cash refund to a customer. Deposits can be refunded; an over-paid or credited balance cannot be paid back through the system.
When no bounce-fee rule is configured, the fee falls back to a fixed AED 100 rather than asking for one.
Bank import reads CSV only — no OFX, MT940 or direct feed — and a preview matches against at most 2,000 open invoices, saying so when it truncates.
06
Step 06 of 8 · Wednesday, 06:12
Something breaks, and a bed goes empty
The air conditioning stops in C-204. The job does not arrive by phone: a resident points a phone at the sticker on the door and the fault is raised already attached to the right bed, in the right unit, in the right property, with no sign-in. That is one of seven ways a job can start — the portal, a staff member, a call logged at the desk, the QR code, a failed inspection, a planned-maintenance schedule, an incident follow-up. A work order attached to nothing is refused outright.
It is triaged by 06:41 and assigned by 07:02, and then it stops: the compressor capacitor is on order from Jebel Ali and takes 29 hours to arrive. Both of the job’s clocks stop while it is awaiting parts, and pausing needs a written reason. That single subtraction is the difference between a maintenance team that looks like it failed and one that did not — and if the clock kept running, the lesson every technician would learn is to never record a hold.
WO-2026-00418 · P2 · AC not cooling, room C-204
As the product counts it — 5 h against a 24 h fix target
Met, with 19 hours in hand
If the clock never paused — 34 h, because the compressor took 29 h to arrive
Awaiting parts · 29 h
Breached by 10 hours — the same job, the same technician
Both clocks stop while a job is on hold or awaiting parts, and pausing one requires a written reason. A supplier who takes a day and a half is not your maintenance team failing — and if the clock kept running, the lesson every technician would learn is to never record a hold, which loses you the one signal saying where the delays actually are.
P115 minfirst response4 hfixed
P22 hfirst response24 hfixed
P38 hfirst response72 hfixed
P424 hfirst response7 daysfixed
It cannot be closed on the word “fixed”. Marking it done requires a written description of what was actually done and the labour hours; a P1 or P2 also needs at least one photograph before and one after; and if the technician needed access to an occupied room, somebody signs that the room was left in order. Every missing item is listed at once, because a technician told one problem at a time on a phone in a corridor gives up and finds a way round the check.
Verification is then a separate step with its own permission, and it is refused if the verifier is the person the job was assigned to — refused by the database as well as the application, so it survives anybody rewriting the code.
And in the same week a man leaves. His bed goes into notice period before it is empty, so it appears in “coming available” while somebody still sleeps in it. When the move-out completes, the bed goes to turnover and the clean is raised in the same transaction — and passing that clean is the only thing in the product that returns a bed to available.
The bed that comes back
OCCUPIEDA man in the bed, a contract behind him
NOTICE_PERIODMove-out scheduled — it appears in “coming available” before it is empty
TURNOVERMove-out completed. The clean is raised in the same transaction
AVAILABLEEvery item of the six-item turnover checklist passed
Completing the move-out needs all five, and names whichever is outstanding
Keys returned
Inspection done
Bedding returned
Meter read
Access revoked
Then the clean, which has six items of its own. Pass every one and the bed moves from turnover back to available and the status change is recorded. Fail one and the bed is clean and still not lettable — a room whose light does not work is not a room you can sell. Nothing else in the product returns a bed from turnover, which is the point: a bed somebody left with no clean behind it would otherwise be permanently unlettable, in a business whose central number is how many beds are lettable.
Targets are copied onto the job when it is raised, not read live — so changing your targets tomorrow does not silently re-judge last month’s jobs. A warning fires at 80% of the window; past 100% it is a breach.
Tenant damage becomes an invoice with the evidence on the line. The line records the job reference, the completion date and how many before-and-after photos are on file. It cannot be charged twice, and it cannot be charged before the work was done — and it picks up the same tax treatment and the same locked-once-issued rule as any other invoice.
Fourteen standard camp maintenance plans seed onto a property in one click. A plan says what, where, how often as a recurrence rule, who does it, what it should cost and how many days ahead to raise the job — fourteen by default. A nightly run raises what is due and reports how many it skipped.
A compliance grid you can hand to an inspector: plans down the side, dates across the top, every cell reading Done, Overdue or Upcoming with the job reference behind it. A visit that was due and has not happened shows as Overdue whether or not a job was ever raised for it.
The asset register explains itself. Every AC unit, mattress, wardrobe and extinguisher tagged and placed in a space, with purchase cost, warranty, expected life and condition, and every movement written down permanently — from where, to where, why, by whom. That is what makes “it has been worked on five times” an argument rather than an anecdote.
Contractors are scored from their own work, not from opinion. Completions, average response time, average completion time and reopen rate — a job sent back after being marked complete. A contractor with no completed work gets no score at all rather than a flattering zero.
A meter reading becomes a real cost against the property in the same moment. Consumption is computed by the database; with a tariff and a standing charge it becomes a utilities expense. A reading lower than the last is refused with an explanation unless you have told the meter where it rolls over — guessing between “wrong reading” and “rolled over” is how somebody gets billed for another man’s month.
A store whose balance cannot be wrong. Five kinds of movement, each recording the balance after it, maintained under a row lock — so taking five from a store of three fails the whole transaction rather than leaving the store owing itself two mattresses. Movements can never be edited or deleted.
Mess headcount is derived from who actually had a bed that day, less anyone opted out, against what the site says was served and what the caterer billed — compared on meal count and on money separately, with a gap above 5% raising an alert. The rate is frozen onto each day’s row, so a price rise in March does not rewrite February.
An inspection’s verdict is computed, not typed, and a damaged or failed line with no photograph is refused at submission. The hand that walked the room cannot sign it off, and approving a safety round with failures raises a work order for each failed item — at approval rather than submission, so a mistaken fail corrected before sign-off leaves no job behind it.
A conduct ladder you can prove: verbal, written, final, eviction notice — one rung at a time, each pointing at the one below it, against ten kinds of breach. An eviction notice must carry a grace date. A warning issued in error is withdrawn rather than deleted: it stops counting immediately and the row stays.
Twelve escalation situations holding thirty-two rungs between them. Reaching a high rung spends the lower ones, so a situation left alone for a week produces one escalation and not three; the top rung repeats daily until a human acknowledges it, and a situation that resolves itself stops the ladder.
And what it does not do
Photographs are referenced but not uploaded. Work orders count before-and-after photos and inspection items store photo keys, but no uploader is wired into these screens — the keys have to arrive from elsewhere.
Nothing is actually sent when an escalation fires. The hourly sweep writes it and it appears on the escalations screen; no code dispatches an SMS, email or push. Of twelve situations, three are never swept at all.
SLA targets are not configurable per organisation or per category. The four priority targets are constants in code — there is no table, no route and no screen to change them.
Neither the housekeeping rota nor the mess headcount runs on a schedule. Both are on demand, from a button or an API call.
Parts used on a job do not draw from the store automatically; deducting them is a separate stock issue done by hand. And metered utilities become a cost to the property but are never recharged to an occupant.
Assets cannot be edited after creation, and vendor rate cards, bank details and contract dates are columns with no way to write them.
07
Step 07 of 8 · Any morning
His camp boss signs in
The man who runs Al Quoz needs everything about the site: the job list, the asset register, the room handover sheet, the repair history, who is inside the fence this minute, whose papers lapse this month. He needs none of the money. More than that, he must not have it — what Rashid pays that landlord is the one number that would let a competitor outbid him for the building.
A screen can hide a field. It cannot un-send one. Anything that reaches the browser is in the network tab, in any log, and in anything holding that login — so the figures a role must not see never leave the server at all. The site dashboard goes further and never asks for them: nothing in it queries an invoice, a payment, a rate or a cost, so there is no money field in the response for anything to leak.
Where a figure is withheld it is withheld, not deleted. The tile keeps its label, its unit and its definition and names the permission that would open it, because an empty cell reads as “there is no revenue” rather than “you may not read this”. This project shipped that mistake once.
Pick a tile, then step through the seven roles and watch that one figure open and close. It is not a hierarchy — look for the three places it refuses to be one.
Everything in the organisation, including billing and the danger zone.
Al Quoz Camp 1384 beds · 6 blocks · head lease to 202812 of 12 shown
OwnerThe owner sees the whole board. Nothing here is withheld from them — which is the only reason the other six views are worth looking at.
Pick any figure to see the permission key that governs it, and which of the seven roles hold it.
Withheld, not deleted — the tile keeps its label, its unit and its definition, so nobody mistakes you may not read this for this is empty. And the redaction happens before the JSON is written, not in the markup: a screen can hide a field, it cannot un-send one.
254Named permissions, in 15 groups
16Roles shipped configured — 12 staff, 4 external
57Permissions a site supervisor holds
13Actions that demand a second factor and a written reason
What just happened
Your data is walled off inside the database itself, not only by the software. Each request opens a transaction naming your organisation, and the database refuses to hand over anybody else’s row even to a query that forgot to ask. The protection is not a hand-written list of tables — it walks the catalogue and covers every table carrying an organisation column, 138 of 142 of them.
A refusal names the exact permission missing, so the person can ask for the right thing instead of “access”. And when you need somebody who can record a cheque but not mark one bounced, that is one checkbox rather than a support ticket.
A grant carries a scope, and can carry an end date. The whole organisation, one estate, or one property — a supervisor scoped to one camp cannot list, open or read the occupants of another. A three-month secondment ends by itself rather than by somebody remembering.
Nobody can hand out authority they do not hold themselves, and the same applies to reach — somebody confined to two properties cannot grant anyone access to the whole organisation. Without that second half the first is decoration: an administrator who cannot grant Owner but can reset the Owner’s password simply resets it.
Ten readings are their own permission and never a side effect: the audit trail, what you pay for a property, a landlord’s full bank account, what a repair cost, occupant passport and visa numbers, a customer’s credit file, your own subscription billing, financial reports, executive reports and the executive dashboard. A read-only role that reveals a landlord’s bank account is not a read-only role.
Seventeen lifecycle steps demand their own permission. Submitting a contract is not approving one; banking a cheque is not marking it bounced; finishing a job is not signing it off. Writing a contract that starts before today needs its own dangerous permission, judged against your organisation’s local date rather than the server’s.
You cannot approve your own request whatever role you hold, and the approver must both sit at the named desk and hold the matching authority — a rule naming a leasing agent as the discount approver is refused rather than obeyed. An approval is spent when used and matched against the exact numbers it was granted for.
The audit trail is append-only by database grant, not by convention. Who did it, in which organisation, to which record, the before and after with sensitive values masked, plus address, browser and request id. The application’s login holds only insert and select on that table — so it stays true through a bug or a compromised endpoint.
Sessions end themselves when stolen. Access lasts fifteen minutes and renews silently for up to seven days, each renewal invalidating the one before it. Present a spent renewal and the whole line is revoked and everybody signs in fresh. Revocation is checked on every request rather than at the next renewal.
Support access is a recorded session, bounded to an hour and a mode. Read-only by default; write access needs a ticket reference plus typing your organisation’s name exactly. It can never void an invoice, delete a contract, blacklist a person, read a passport number or close the organisation — and the record of who looked, when and why is written into your own audit trail.
A portal login is bound to exactly one customer, occupant or landlord, read from the database rather than from the browser’s token, and the request is refused outright if that link is missing. Asking for somebody else’s record answers “no such thing”, not “you are not allowed” — the second sentence would confirm the record exists.
Twenty-seven field names may never appear in a portal answer — what a repair cost, what you pay the landlord, your margin, a customer’s credit limit and risk band, collection notes, full passport numbers, bank details. They are not stripped out afterwards; the queries never ask for them, and a test sweeps every portal response against the list.
And what it does not do
Custom roles cannot be created. The sixteen shipped roles are assigned and revoked; there is no role editor behind the catalogue entries for it.
There is no operator-facing audit trail screen. Audit rows are readable through the platform console’s activity feed, and an auditor cannot export the trail.
Single sign-on (SAML or OIDC) is not implemented, and there is no organisation-wide “require a second factor for everyone” setting — it is mandatory only for accounts holding one of the thirteen dangerous permissions.
Approval chains are not supported: the first rule that catches a request wins. Unapproved requests are not escalated to a manager after a delay, though the setting is stored and shown.
Rate limiting is not implemented on sign-in, export or notification endpoints.
A permission change is not pushed to an open browser. The server re-derives permissions from the database on every single request, and the client learns of a change through a response header rather than a live socket.
08
Step 08 of 8 · Friday
He looks at the month
What did the month actually do? Forty-six named reports over twenty-nine published data views, thirty-three KPIs each carrying the sentence that defines it, and five dashboards written for five different jobs — because a camp supervisor and a finance controller do not want the same screen with different rows hidden.
A report Rashid’s camp boss is not allowed to run is not on his list. Not greyed out — omitted. A greyed row named “Head-lease obligations” tells a supervisor that head-lease cost exists and roughly what it is called, and the list of questions a company asks is itself information.
Withdraw financial visibility on the wall below and watch it go dark — including three reports that are not in the Financial group, because the gate is on the number rather than on the tab. Then switch to a site supervisor and press the same switch: nothing happens at all, because that role never held a money permission to withdraw. That last fact is computed from the real role bundles, not asserted.
Type “gate pass”, or “mess”, or “cheque” into the search. Switch the role. Then withdraw financial visibility and count what disappears.
46 reports in the catalogue — 46 available to a Property Manager.
Full operational and commercial control within scope. Every report declares one permission, and that declaration is the gate — there is no /reports/rent-roll endpoint to go round.
Occupancy & inventory7/77 of 7 available
Tenancy & contracts7/77 of 7 available
Financial14/1414 of 14 available
People & compliance6/66 of 6 available
Operations9/99 of 9 available
Executive3/33 of 3 available
Point at any report. 46 of them, and each one is a row in a table you can schedule, filter and export.
Blank, never zero
A property with no beds has no occupancy rate; a month with no invoices has no collection rate. Those come back empty rather than as 0% — a zero sorts worst in a league table and drags the estate average down, so a camp still in fit-out would make the whole portfolio look like it was failing.
Last night stays last night
Every night the system records that day’s KPIs, for the estate and for each property. Sparklines are drawn from those recordings rather than recomputed — so the March figure you gave your board does not silently change in June when somebody corrects an allocation.
Targets that know which way is good
A target can be set on any KPI, for the estate or one property, standing or for a single month. At or above is green, within 10% amber, below red — and it inverts automatically where lower is better, because a rising arrears ratio is not an improvement and nobody should have to invert it in their head at 7am.
What just happened
A report is data, not a bespoke page. One engine reads one of 29 published data views, projects only the columns that view declares and filters only on the columns marked filterable. Nothing a browser sends can name a table or a column that is not on that list — which is how reporting normally leaks in property systems.
A report can never be looser than the data behind it. Running one demands the stricter of two permissions: the report’s own and its underlying view’s. That applies to reports your own people build as much as to the forty-six shipped, so saving a view over sensitive data and giving it a mild-sounding name is arithmetically impossible.
Excel an accountant can actually use. A frozen header row, sized columns, the right number format per column, a bold totals row — and money exported as a number rather than as text with a currency stuck on it, because the first thing anyone does with a register is sum a column.
A cover sheet that lets somebody reproduce the figure: the report name, the question it answers, the organisation, who ran it, when, the currency and every filter applied. A disputed figure that cannot be reproduced is a figure that gets believed.
An export cut short says so on its own face. Capped at 50,000 rows, with a red warning on the cover and a truncation flag in the run log. A manager handed 50,000 of 62,000 rows who is not told will reconcile against a total that was never complete — and will trust it, because it came out of the system.
Exports cannot be weaponised or mangled. Any text a customer typed that begins with =, +, - or @ is neutralised before it reaches a CSV cell, and every file carries the marker that stops a Windows Excel turning Arabic names into gibberish.
Thirty-three KPIs, each with a one-line definition on hover. Physical and economic occupancy, revenue per available bed, vacancy loss, gross spread, net margin, cost per bed, collection rate, days sales outstanding, arrears ratio, cheque bounce rate, churn, retention, re-let days, SLA compliance, mean time to repair, PPM compliance, incidents per hundred beds. Two people arguing about “occupancy” usually mean two different numbers.
The margin bridge draws the bar no ordinary property system has anywhere to put: gross rent invoiced, less discounts and credit notes, less the head-lease rent you owe the landlord for the same period, less operating cost, less this month’s share of the fit-out — and what is left is the spread. Two camps of the same size can look completely different on it.
Six categories, 330 columns and 113 filters across the catalogue, with 87 columns carrying an automatic total in the export. The bed roster, the AR aging, the PDC register and the property P&L are already there with the right columns on the first day.
A monthly board pack in one command: seven print-ready sections — the cash ribbon, occupancy and margin, where the revenue went, receivables, the portfolio, an eight-row scorecard against target, and the risks and expiries — with five commentary boxes you type into. Every chart is drawn as vector, because a board pack is printed and projected.
A journal export that refuses to download unless it balances. Every invoice, credit note, payment, expense and deposit movement in a period, restated against eighteen account codes you change to match your accountant’s chart. An unbalanced batch does not fail on import into your ledger — it posts to suspense, and somebody finds it at year end.
And what it does not do
Scheduled reports are stored and nothing delivers them. The row is real and validated; no worker reads it, and the screen says so in a banner rather than implying a delivery. A schedule cannot be paused or deleted, and its timezone is stored but evaluated in UTC.
PDF export is a print-ready HTML page rather than a PDF file — the same for the board pack.
Receivables aging is as at today only. Point-in-time aging — what the book looked like on 30 June — is not offered, rather than offered wrongly.
The occupancy trend has no forecast band and no break-even line on the chart, though the break-even formula exists. Four written and tested KPI formulas are not yet served by the endpoint.
The personal drag-and-drop dashboard is API-only: 52 widgets, per-user layouts and role-seeded defaults all exist and are tested, and no screen in any of the four apps calls them.
Nothing on any dashboard updates in real time. Live tiles poll; there are no push updates anywhere in the product.
The end of the month
That was one month, and roughly half the product.
The tour skipped the parts that do not fit a single narrative: the CRM funnel before the contract, the resident and corporate and landlord portals, housekeeping rotas and the stores, the notification catalogue, the automation rules, and the platform side — packages, quotas and the console that runs them. Those are all in the catalogue.
46Reports, ready on the first day
254Named permissions
33KPIs, each with its definition
518Message templates shipped
6Database rules stopping a bed being sold twice
48Rules the database enforces on money
66Rules refusing bad operations data
28Rules on occupant records and compliance
Those last four are counted constraints, triggers and checks written into PostgreSQL rather than features on a list. They matter because every one of them holds against an import, a script, an emergency fix and any future version of the application — which is the only kind of promise worth making about a bed that must never be sold twice.