Customers
Customers and the master-data tables that classify them: types, segments, and brokers. All four tables move together — types/segments/brokers exist only to classify customers.
Tables owned
| Table | Purpose |
|---|---|
org.customers | Customer records (name, type, segment, broker, parent, address, country, QBO ID, notes, active flag). |
org.customer_types | Customer classifications (e.g., Purchaser, Location). |
org.customer_segments | Customer segments (e.g., Club, Distributor, Grocery). |
org.brokers | Brokers — reusable broker entities referenced by customers and SOs. |
Operations
Writes — Customers
createCustomer(conn, input)→Customer.input:{ name, typeId?, segmentId?, brokerId?, parentId?, country?, address?, qboId?, notes? }.updateCustomer(conn, customerId, patch)→Customer. Partial update (incl. parent change for hierarchy moves).setCustomerActive(conn, customerId, isActive)→Customer. Archive / reactivate.deleteCustomer(conn, customerId)→void. Hard-delete.
Writes — Customer types
createCustomerType(conn, { name })→CustomerType.updateCustomerType(conn, typeId, patch)→CustomerType. Rename.deleteCustomerType(conn, typeId)→void. L3 enforces "no customer uses it".
Writes — Customer segments
createCustomerSegment(conn, { name })→CustomerSegment.updateCustomerSegment(conn, segmentId, patch)→CustomerSegment. Rename.deleteCustomerSegment(conn, segmentId)→void. L3 enforces "no customer uses it".
Writes — Brokers
createBroker(conn, { name })→Broker.updateBroker(conn, brokerId, patch)→Broker. Rename.deleteBroker(conn, brokerId)→void. L3 enforces "no customer or SO references it".
Reads — Customers
listCustomers(conn, filters?)→Customer[]. Filters:{ typeId?, segmentId?, isActive? }.getCustomerById(conn, customerId)→Customer | null.getCustomersByIds(conn, customerIds)→Customer[]. Batch hydration.listCustomerChildren(conn, parentId)→Customer[]. For hierarchy views.
Reads — Lookups
listCustomerTypes(conn)→CustomerType[].isCustomerTypeInUse(conn, typeId)→{ inUse: boolean, customerCount: number }.listCustomerSegments(conn)→CustomerSegment[].isCustomerSegmentInUse(conn, segmentId)→{ inUse: boolean, customerCount: number }.listBrokers(conn)→Broker[].getBrokersByIds(conn, brokerIds)→Broker[]. Batch hydration.isBrokerInUse(conn, brokerId)→{ inUse: boolean, customerCount: number, soCount: number }.