Units & Leaseholders
Units & Leaseholders
The Units & Leaseholders module manages individual flats within a block. It is the lowest level of the five-level entity hierarchy:
Agent → Owner → Block → Unit → Leaseholder
Each unit record holds the physical details of a flat, the current leaseholder's contact information, lease terms, ground rent configuration, and service charge apportionment. Every leaseholder change is recorded in an immutable audit history.
Navigating to Units
- Log in and open the dashboard.
- Click Units & Leaseholders in the left-hand navigation sidebar.
- The listing page at
/dashboard/unitsshows all units across your portfolio.
Unit Statuses
Each unit carries one of four statuses:
| Status | Description |
|---|---|
| Occupied | Leaseholder is in residence |
| Vacant | Unit is currently unoccupied |
| Sublet | Unit is sublet to a third party |
| Sold (Pending Completion) | Sale agreed, legal completion not yet complete |
Creating a Unit
- On the Units & Leaseholders page, click Add Unit.
- Complete the form sections:
Unit Details
| Field | Required | Notes |
|---|---|---|
| Block | ✅ | Select from your existing blocks |
| Unit Number | ✅ | e.g. Flat 1, 12A |
| Floor | — | e.g. Ground, 1st, 2nd |
| Bedrooms | — | Integer, 0–20 |
| Status | — | Defaults to Occupied |
Leaseholder
| Field | Notes |
|---|---|
| Full Name | Current leaseholder's legal name |
| Contact email | |
| Phone | Contact telephone |
| Correspondence Address | Leave blank if correspondence address matches the unit address |
Lease Terms
| Field | Notes |
|---|---|
| Lease Start Date | Date the original lease commenced |
| Lease Term (Years) | Total lease length in years; the UI calculates the expiry date |
Ground Rent
| Field | Notes |
|---|---|
| Ground Rent Amount | Stored in pence (e.g. 5000 = £50.00) |
| Review Period (Years) | How often ground rent is reviewed |
| Next Review Date | Auto-calculated or manually set |
Service Charge Apportionment
Stored as basis points where 10000 = 100.00%.
| Example value | Percentage |
|---|---|
1250 | 12.50% |
500 | 5.00% |
10000 | 100.00% |
The block summary view will flag blocks where apportionment across all units does not total 10,000 basis points.
- Click Save to create the unit. An initial leaseholder history record is automatically created.
Updating a Unit
Open a unit from the listing to access the detail view. You can edit unit fields (floor, bedrooms, status, lease terms, ground rent, apportionment, notes) directly from this view.
Note: Leaseholder contact details are not updated via the standard edit form. Use the Change Leaseholder action to maintain a complete audit trail.
Changing a Leaseholder
When a flat changes hands or a leaseholder's details change, use the Change Leaseholder action rather than editing the unit directly:
- Open the unit detail view.
- Click Change Leaseholder.
- Enter the new leaseholder's details, the effective date, and optional audit notes.
- Click Save.
This action:
- Closes the previous leaseholder history record with an end date.
- Opens a new history record from the effective date.
- Updates the unit's current leaseholder fields.
- Writes an entry to the platform audit trail.
Leaseholder History
Every leaseholder change is stored in an immutable leaseholder_history table. You can view the full timeline on the unit detail page under the History tab. Each entry records:
- Leaseholder name
- Start and end dates of the tenancy/ownership period
- The user who recorded the change
- Audit notes
Filtering and Searching Units
The listing page provides three filters:
- Search — matches unit number or leaseholder name
- Block filter — limits the list to units within a specific block
- Status filter — shows only units with a given status
Block Summary
The unit.blockSummary procedure (accessible programmatically via the tRPC router) returns aggregate statistics for a block:
- Occupancy breakdown by status
- Whether apportionment basis points across all units sum to 10,000 (completeness check)
Access Control
| Action | Required Role |
|---|---|
| View units / history | Any authenticated user |
| Create / update units | Admin |
| Change leaseholder | Admin |
| Delete unit | Admin |
All data is scoped to your organisation — users in other organisations cannot access your units or leaseholder history.
tRPC Procedures Reference
For developers integrating directly with the tRPC router:
| Procedure | Input highlights |
|---|---|
unit.list | { blockId?, status?, limit, cursor } |
unit.getById | { id } |
unit.create | { blockId, unitNumber, floor?, bedrooms?, status?, leaseholderName?, leaseholderEmail?, leaseholderPhone?, correspondenceAddress*, leaseStartDate?, leaseTermYears?, groundRentAmountPence?, groundRentReviewPeriodYears?, apportionmentBasisPoints?, notes? } |
unit.update | { id, ...updatable fields } |
unit.delete | { id } |
unit.changeLeaseholder | { id, leaseholderName, leaseholderEmail?, leaseholderPhone?, correspondenceAddress*, effectiveDate, notes? } |
unit.leaseholderHistory | { unitId, limit, cursor } |
unit.listByBlock | { blockId } |
unit.blockSummary | { blockId } |
* correspondence address fields: correspondenceAddressLine1, correspondenceAddressLine2, correspondenceCity, correspondencePostcode