Multi-Branch Agency Support
Multi-Branch Agency Support
Agencies can organise their account into multiple branches. Each branch has its own contact details, address, and team members. Properties, tenancies, and offers can be optionally scoped to a branch, giving per-branch visibility without breaking any existing data.
Concepts
| Term | Description |
|---|---|
| Branch | A named office or location under your agency account. |
| Branch Member | A user assigned to a branch with a manager or agent role. |
| Branch Scope | An optional filter applied to properties, tenancies, and offers. |
Setting Up Branches
Creating a Branch
- Go to Company Settings → Branches tab.
- Click New Branch.
- Fill in the required fields:
- Branch Name (required) — e.g. North London Office.
- Slug (required) — auto-generated from the name; used internally as a stable identifier. You can override it manually.
- Optionally add address and contact details (address lines, city, county, postcode, phone, email).
- Click Create Branch.
Editing a Branch
- In the Branches list, click the branch row to expand it.
- Click Edit and update the fields.
- Click Save.
Deleting a Branch
A branch can only be deleted if it has no linked properties. Remove all property associations first, then use the delete action in the branch list.
Managing Branch Members
Adding a Member
- Expand the branch row in the Branches list.
- Select a user from the Add Member dropdown (populated from your organisation's agent list).
- Choose a role: Agent or Manager.
- Click Add.
Changing a Member's Role
Use the role dropdown next to the member's name in the expanded branch panel. Changes take effect immediately.
Removing a Member
Click Remove next to the member's name. The user is unlinked from the branch but their account is not affected.
Switching Branch Context
The Branch Selector dropdown appears in the dashboard header bar. Use it to filter the dashboard view to a specific branch.
- Admins / Owners see an All Branches option (unfiltered view) plus each individual branch.
- Agents see only the branches they are assigned to.
The selected branch is saved in localStorage and stays active across page navigation and component re-renders.
Access Control
| Role | Branch Access |
|---|---|
| Owner / Admin | Full access to all branches; can create, edit, and delete branches; can manage all branch members. |
| Branch Manager | Can view all data (properties, tenancies, offers) within their assigned branch. |
| Branch Agent | Sees only data for their assigned branch(es). |
All write operations (create, update, delete branch; add/remove/change member role) require admin or owner level.
Backward Compatibility
All new branch_id columns on properties, tenancies, and offers are nullable. Existing records without a branch assignment continue to work exactly as before. No data migration is required.
Audit Logging
The following branch operations are recorded in the Audit Log (Company Settings → Audit Log tab):
- Branch created
- Branch updated
- Branch deleted
- Member added to branch
- Member removed from branch
- Member role changed
API Reference (tRPC)
All procedures are on the branch router.
branch.list
Returns all branches for the current company, including member count and property count.
branch.get
branch.get({ id: string })
Returns a single branch record by ID.
branch.create
branch.create({
name: string; // required
slug: string; // required, lowercase alphanumeric + hyphens
addressLine1?: string;
addressLine2?: string;
city?: string;
county?: string;
postcode?: string;
phone?: string;
email?: string;
})
Requires admin+ role.
branch.update
branch.update({
id: string;
name?: string;
slug?: string;
addressLine1?: string;
addressLine2?: string;
city?: string;
county?: string;
postcode?: string;
phone?: string;
email?: string;
status?: "active" | "inactive";
})
Requires admin+ role.
branch.delete
branch.delete({ id: string })
Requires admin+ role. Fails if any properties are linked to the branch.
branch.listMembers
branch.listMembers({ branchId: string })
// Returns: Array<{ id, userId, userName, userEmail, role }>
branch.addMember
branch.addMember({
branchId: string;
userId: string;
role: "manager" | "agent";
})
Requires admin+ role.
branch.removeMember
branch.removeMember({ branchId: string; userId: string })
Requires admin+ role.
branch.updateMemberRole
branch.updateMemberRole({
branchId: string;
userId: string;
role: "manager" | "agent";
})
Requires admin+ role.
branch.myBranches
Returns branches accessible to the current user. Admins receive all branches; agents receive only their assigned branches.
branch.stats
branch.stats({ branchId: string })
// Returns: { propertyCount, tenancyCount, offerCount }