DEV Community

Bernard Abuto
Bernard Abuto

Posted on

Modelling the Landlord Who Isn’t There

Modelling the Landlord Who Isn’t There

Most rental software assumes both sides of a tenancy are on the platform. That assumption fails for many tenants, so Rentra had to represent the relationship before the landlord arrives.

The first version of most rental-management software makes a quiet assumption: the landlord signs up, adds a property, and invites tenants. Every record begins on the landlord’s side.

When I started building Rentra in June 2026, I began from that assumption too. The first entities in the repository were users and the passkeys a landlord issues to tenants.

It took about two weeks for the assumption to break.

If Rentra only works once a landlord has joined, a tenant whose landlord never joins gets nothing: no rent history, no reminders, and no record of what they have paid. For a product meant to make rental life more orderly, the tenant is often the person who most needs that record.

Two Kinds of Tenant

Rentra now distinguishes two kinds of tenant.

A managed tenant is linked to a real tenancy: a unit, in a building, in a landlord’s portfolio.

An independent tenant is someone whose landlord is not on Rentra. They declare their own rental—a name for the property, the rent, how often it is due, and where it is paid—and Rentra keeps the record on their behalf.

In the code, that self-declared rental is its own entity, ShadowRentalRelationship, rather than a tenancy with some fields left empty.

There were three reasons for keeping it separate.

  1. The ownership relationship is different.

A managed tenancy has an owner on the other side; a self-declared rental has only the tenant’s account of the arrangement. Mixing them in one table would mean every query about rent, arrears, or occupancy has to ask which kind of record it is looking at. Every authorisation rule would also have to account for a landlord who might not exist on the platform.

  1. The information is genuinely different.

A self-declared rental records where rent is actually paid—an M-Pesa Paybill, a Till number, or a bank—and allows daily, weekly, or monthly billing cycles, because those are the facts a tenant knows.

A managed tenancy gets its structure from the landlord’s records instead.

  1. Uncertainty remains visible.

Each self-declared rental carries a status: unverified, converted, or ended.

That distinction matters. A tenant’s declaration is useful information, but it is not the same as a tenancy verified by both sides. The data model should not imply otherwise.

When the Landlord Arrives

The interesting part is what happens when the absent landlord eventually joins.

Rentra’s approach is a passkey: a code the landlord generates for a specific unit. A new tenant can redeem it to register directly as a managed tenant. An independent tenant who already has an account can redeem it to link that account to the real unit.

But the transition is not complete yet.

The step after redemption—carrying the self-declared rental’s history into the managed tenancy—has not been implemented. The converted status exists in the schema, but no code path sets it, and payments are not yet linked to self-declared rentals at all.

I would rather leave that gap visible than paper over it, because merging two records about the same rental is where the hard questions live.

Which rent amount wins if the two disagree?

Does a payment recorded by the tenant become confirmed once the landlord can see it, or only once the landlord agrees?

What happens when the tenant’s record and the landlord’s record disagree about the history of the tenancy?

These are not merely database questions. They affect what the system claims to know, what each party can trust, and how disputes might be handled.

A conversion mechanism that simply merges records would conceal those decisions rather than resolve them.

Roles Are Not Ownership

The second modelling lesson came later, when I added role-based authorisation.

Rentra has three roles: tenant, landlord, and caretaker. The backend enforces them with guards on its controllers, so a modified mobile client cannot grant itself permissions simply by changing its local state.

But role checks answer only one question:

Is this kind of user allowed to do this kind of thing?

They do not answer the question that matters most for a tenant’s data:

Is this your record?

The tenant role might permit a user to view a tenancy, but it must not permit them to view someone else’s tenancy merely because they are a tenant.

That second check, ownership scoping, is still being built. It requires a different mechanism because it depends on the relationship between a specific user and a specific record, rather than on a label attached to the user.

Caretakers expose the same gap from the other side.

A caretaker acts on a landlord’s behalf—but for which buildings?

There is not yet an entity that scopes a caretaker to particular properties. The role exists, but the relationship that would make it safe to grant access across specific properties is not yet modelled.

The lesson is that role-based access control and resource-level authorisation solve different problems. Having the right role should not automatically grant access to every resource of that type.

Two Vocabularies

One smaller decision has held up well.

Internally, the backend talks about organisations and rooms. People using the app see a property portfolio and units.

The internal names are precise and stable, while the product names are the ones people actually use.

Keeping them separate lets the data model be refactored without rewriting the interface. It also lets the interface speak plainly without exposing database concepts to users.

The distinction is small, but it reflects a broader principle: the language used to implement a domain does not have to be the language used to explain it to customers.

What I Took From It

Domain modelling is mostly the work of noticing which real situations your first schema cannot represent.

The absent landlord is not an edge case in the markets Rentra is designed for. I suspect it is closer to the norm.

Giving that relationship its own entity, with an explicit status and an explicit path towards becoming something else, made the system more honest about what it actually knows.

It also made the unfinished work easier to identify. The conversion process still needs to reconcile conflicting records. Payments need to be linked to self-declared rentals. Ownership scoping needs to be completed. Caretaker access needs a property-level relationship.

Those gaps are easier to reason about when they are visible instead of being hidden behind a schema that pretends every tenancy starts with a landlord.

The repository’s README now lists, line by line, which pieces exist in code and which do not.

That list has been almost as useful to me as the code itself.

Project: Rentra — rental-management software designed to help tenants and landlords maintain clearer rental records, including situations where a landlord has not yet joined the platform.

Top comments (0)