Multi-Location Inventory & Appointments in ViibeStack
September 7, 2026

Multi-Location Inventory & Appointments in ViibeStack

Why this breaks in spreadsheets and generic scheduling tools

Most businesses that grow from one location to three or four are still running on whatever got them through year one -- a shared spreadsheet for inventory, a booking tool like Calendly bolted on for each site, and a lot of texting between managers to reconcile stock counts. That works until location B sells the last of an item that location A's dashboard still shows as available, or a stylist gets double-booked because two sites are pulling from the same generic calendar. The core problem is structural: these tools were not built with 'location' as a first-class concept, so you end up faking it with tags, filters, or separate accounts entirely. If you're evaluating a way off Calendly-plus-spreadsheets, it's worth reading how we think about replacing Calendly as a starting point, but the deeper fix is the data model underneath, not just the booking widget.

The three tables that actually matter: Locations, Resources, Staff

Before touching any views or permissions, get the data model right. You need a Locations table as the anchor -- one row per physical site, with fields for address, timezone, hours, and a manager contact. Every other table references back to this one. Then build a Resources table that covers anything bookable or trackable per site: a treatment room, a bay, a piece of equipment, or an inventory item. Each resource row has a required 'Location' link field, not a free-text location name -- that link is what makes filtering and permissions actually work later. Finally, a Staff table where each person has a home location (and optionally a list of locations they're allowed to work at, for businesses that float technicians between sites). Appointments and inventory transactions then reference Location, Resource, and Staff as linked records rather than duplicating location info as text. This is the same normalization logic we cover generally in the Glossary, and it's the difference between a system that scales to five locations and one that needs a rebuild at location three.

Inventory: shared catalog, location-specific stock

Don't create a separate Inventory table per location -- that's how you end up with four different SKUs for the same shampoo. Instead, keep one Product/Item catalog company-wide, and add a separate Stock table that tracks quantity-on-hand per Location per Item (a join table, effectively: one row per location-item combination). When a sale or usage event happens, it decrements the Stock row tied to that location, not the catalog item itself. This lets the owner see one master list of products while each site only ever interacts with its own stock numbers. For businesses with a service component -- like auto shops or salons -- resources like bays or chairs get their own availability logic separate from inventory, but they follow the same pattern: shared definition, per-location instance. If you're coming from a tool built for a single shop, like Tekmetric or Vagaro, this per-location stock table is usually the missing piece that makes multi-site tracking finally behave.

Appointments: one calendar table, filtered by location and resource

Resist the urge to build a separate appointments view or table per location out of habit. Use one Appointments table for the whole company, with required links to Location, Resource, and Staff. The location-specific experience comes from filtered views, not separate data stores -- a view filtered to 'Location = Downtown' shows only downtown's bookings, and a similar view exists for each other site. This matters because when a resource or staff member ever needs to move between locations, or the owner wants to see everything at once, you're not stitching together four disconnected tables. It's the same principle we lay out in Role-Based Permissions in ViibeStack: permissions and views should sit on top of a unified data model, not replace it.

Locking down views so each site only sees its own data

Once the data model links everything back to Location, restricting visibility is mostly a permissions exercise. Set each staff member's role and home location, then configure record-level rules so location managers and staff can only view or edit Appointments, Stock, and Resource rows where Location matches their assignment. Front-desk staff at one site shouldn't be able to browse another site's schedule or inventory counts -- not because of trust issues, but because it's noise that slows people down and increases the odds of someone editing the wrong record. Owners and regional managers get a role that bypasses the location filter entirely. This is standard practice in ViibeStack's Role-Based Permissions guide, and it applies directly here: the same mechanism that scopes a support queue to one team scopes a location's inventory to one site.

Rolling everything up for the owner

The payoff of a shared, linked data model is that company-wide reporting is just an unfiltered view of the same tables everyone else uses -- no separate consolidation process, no exporting four spreadsheets into a fifth. Build dashboards that group Appointments by Location to compare booking volume and no-show rates site to site, and group Stock by Item across all Locations to catch a product that's overstocked at one site and out at another. Because every record carries a Location link, you can slice by day, by staff member, or by location without restructuring anything. This is exactly the kind of rollup our Analytics & Reporting tools are built for, and it's a big part of why multi-location operators moving off tools like Mindbody or Buildium find the switch worthwhile -- those platforms often charge per location or per module just to get a combined view that should be free once your data model is set up correctly.

When to bring in help

For 2-3 locations with a straightforward service or retail model, most owners can build this themselves in a weekend using the pattern above. Once you're at 4-5 locations, adding float staff across sites, transfers between locations' inventory, or location-specific pricing, it's worth a sanity check against our Operations solutions page or a short engagement through Custom App Development to make sure the permission rules and rollups hold up before you've got a year of transaction history to migrate. Getting the Locations-Resources-Staff structure right on day one is far cheaper than fixing it after five sites' worth of data has been entered against the wrong model.

← Back to the blog