Collections
Tenant and Catalog
Tenant, locations, staff, and products collections.
Tenant document
Path
tenants/{tenantId}
Operation
upsertTenant(data: Partial<Tenant>)
Creates or updates tenant metadata using merge semantics.
await client.upsertTenant({
name: "Frappe Athens",
country: "GR",
timezone: "Europe/Athens",
})
Locations collection
Path
tenants/{tenantId}/locations/{locationId}
Operation
upsertLocation(locationId: string, data: Partial<Location>)
Use this for store-level metadata (address, currency, cutover time, etc).
await client.upsertLocation("loc_syntagma", {
name: "Syntagma",
address: "Mitropoleos 10",
currency: "EUR",
businessDayCutoverTime: "05:00",
})
Staff collection
Path
tenants/{tenantId}/staff/{uid}
Operation
upsertStaff(uid: string, data: Partial<StaffMember>)
Use this to store role assignments, status, and location visibility.
await client.upsertStaff("uid_manager_1", {
roles: ["manager"],
status: "active",
locationIds: ["loc_syntagma"],
})
Products collection
Path
tenants/{tenantId}/products/{productId}
Operations
upsertProduct(productId: string, data: Partial<Product>)subscribeProducts(listener, options?)
subscribeProducts supports query options (where, orderBy, limit) through QueryOptions.
await client.upsertProduct("espresso", {
name: "Espresso",
price: 2.5,
taxRate: 0.24,
isActive: true,
categoryId: "coffee",
})
const stop = client.subscribeProducts((products) => {
console.log("products:", products.length)
}, {
where: [{ fieldPath: "isActive", op: "==", value: true }],
orderBy: [{ fieldPath: "name", direction: "asc" }],
})
// later
stop()