Locations
Lists and gets locations for the current tenant; create, update, delete. Locations support a typed hierarchy: region, site, building, floor, room, zone. Each location has a required location_type (default site), and optional code, address_line, and external_id. Parent-type rules apply: e.g. room/zone under floor, floor under building, building under site, site under region. Set tenant context before calling these methods.
List locations
List all locations for the current tenant (from v_locations). Rows include location_type, code, address_line, external_id.
client.locations.list()
const locations = await client.locations.list()
// Returns LocationRow[]
Get by ID
Fetch a single location by ID.
client.locations.getById(id)
const location = await client.locations.getById('uuid-of-location')
// Returns LocationRow | null
Create location
Create a new location. Returns the new location UUID.
client.locations.create(params)
const locationId = await client.locations.create({
tenantId: 'uuid-of-tenant',
name: 'Building A',
description: 'Main building',
parentLocationId: null,
locationType: 'building', // 'region' | 'site' | 'building' | 'floor' | 'room' | 'zone'; default 'site'
code: 'BLD-A',
addressLine: '123 Main St',
externalId: null,
})
// Returns string (UUID)
- Name
tenantId- Description
Required. Tenant UUID.
- Name
name- Description
Required. Location display name.
- Name
description- Description
Optional. Description.
- Name
parentLocationId- Description
Optional. Parent location UUID.
- Name
locationType- Description
Optional. One of: region, site, building, floor, room, zone. Default
site.
- Name
code- Description
Optional. Short code (unique per tenant).
- Name
addressLine- Description
Optional. Single-line address.
- Name
externalId- Description
Optional. External system id (e.g. CAFM).
Update location
Update an existing location. All fields except tenantId and locationId are optional.
client.locations.update(params)
await client.locations.update({
tenantId: 'uuid-of-tenant',
locationId: 'uuid-of-location',
name: 'Building A (North)',
description: null,
parentLocationId: null,
locationType: null,
code: null,
addressLine: null,
externalId: null,
})
Bulk import
Import many locations in one call. Each row must have name; optional fields: description, parent_location_id, location_type (default site), code, address_line, external_id.
client.locations.bulkImport(params)
const result = await client.locations.bulkImport({
tenantId: 'uuid-of-tenant',
rows: [
{ name: 'Site Alpha', location_type: 'site', code: 'SITE-A' },
{ name: 'Building 1', parent_location_id: siteId, location_type: 'building', code: 'BLD-1' },
{ name: 'Floor 2', parent_location_id: buildingId, location_type: 'floor', code: 'FL-2' },
],
})
// result.created_ids, result.errors
Hierarchy and portfolio views
With tenant context set, query these views via the raw Supabase client for tree UIs, breadcrumbs, and multi-site dashboards.
v_location_hierarchy: each location with path_ids, path_names, depth (0 = root).
Hierarchy (tree / breadcrumbs)
const { data } = await client.supabase.from('v_location_hierarchy').select('*')
// Filter by depth, or build tree from path_ids
v_site_rollup: one row per site with aggregated counts (buildings, floors, rooms, zones, assets, work orders).
Site rollup (multi-site KPIs)
const { data } = await client.supabase.from('v_site_rollup').select('*')
// site_id, site_name, building_count, floor_count, room_count, asset_count, work_order_count, ...
v_portfolio_overview: tenant-level summary plus one row per site (tenant metrics plus site breakdown).
Portfolio overview
const { data } = await client.supabase.from('v_portfolio_overview').select('*')
// tenant_id, tenant_name, member_count, location_count, asset_count, work_order_count, plus per-site: site_id, site_name, site_asset_count, site_work_order_count, ...
Map zones
Saved GeoJSON shapes on the locations map (optional link to a location) are managed with client.mapZones. See Map zones.
Delete location
Delete a location by tenant and location ID.
client.locations.delete(tenantId, locationId)
await client.locations.delete('uuid-of-tenant', 'uuid-of-location')