guidence
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
* account ends up holding a role that matches nothing.
|
||||
*/
|
||||
|
||||
import { api, MOB, WEB } from './client';
|
||||
import { api, WEB } from './client';
|
||||
import type { PosRole, PosUser, StaffInfo, StaffShift } from './types';
|
||||
|
||||
/* ── Back-office staff ───────────────────────────────────────────────────── */
|
||||
@@ -57,15 +57,33 @@ export const staffApi = {
|
||||
* back-office roles and most accounts carry an id absent from it, so any
|
||||
* mapping written client-side is wrong."
|
||||
*
|
||||
* On the MOB prefix, and that is not a choice: `getstaffs` is registered on
|
||||
* `/v1/mob/tenants` only (`tenantroutes.go:35`) and has no `/web` twin, so the
|
||||
* path this used to call did not exist. The old console avoided the question
|
||||
* by using `users/getallusers`, whose SQL selects no `rolename` at all — it
|
||||
* had to map role ids client-side, which is the thing the backend warns
|
||||
* against above.
|
||||
* On WEB now. It used to be on MOB because `getstaffs` was registered under
|
||||
* `/v1/mob/tenants` alone and had no `/web` twin — back-office staff were
|
||||
* reachable only through the customer app's door, which is a large part of
|
||||
* why this console never had a people screen. The twin now exists; the MOB
|
||||
* registration is left in place in case something else calls it.
|
||||
*
|
||||
* Returns people with NO branch as well as people with one. That is the whole
|
||||
* point: `locationid` 0 means hired and not yet placed, and the list is
|
||||
* ordered to put them first, because they are the rows needing an action.
|
||||
*/
|
||||
list: (tenantid: number) =>
|
||||
api.list<StaffInfo>(`${MOB}/tenants/getstaffs`, { tenantid }),
|
||||
api.list<StaffInfo>(`${WEB}/tenants/getstaffs`, { tenantid }),
|
||||
|
||||
/**
|
||||
* Put somebody at a branch, or take them off one.
|
||||
*
|
||||
* `unassign` is a separate flag rather than `locationid: 0`, deliberately. A
|
||||
* body that lost the field, a form that posted a blank and a client that
|
||||
* dropped it all arrive as 0 — so a zero alone must never mean "take them off
|
||||
* their shop". The backend refuses it too; this mirrors the rule so the
|
||||
* refusal is not a round trip.
|
||||
*/
|
||||
assign: (body: { tenantid: number; userid: number; locationid: number }) =>
|
||||
api.put<unknown>(`${WEB}/tenants/assignstaff`, body),
|
||||
|
||||
unassign: (body: { tenantid: number; userid: number }) =>
|
||||
api.put<unknown>(`${WEB}/tenants/assignstaff`, { ...body, unassign: true }),
|
||||
|
||||
create: (body: CreateStaffRequest) => api.post<StaffInfo>(`${WEB}/users/create`, body),
|
||||
|
||||
|
||||
@@ -43,6 +43,21 @@ export interface CreateBranchRequest {
|
||||
deliveryradius?: number;
|
||||
deliverymins?: number;
|
||||
status?: string;
|
||||
/**
|
||||
* Who will run this outlet — an existing person, when one has been hired
|
||||
* already.
|
||||
*
|
||||
* Omitted, the backend spawns a login named after the SHOP, on the shop's
|
||||
* email address, one per outlet. That was the only option, and it is why two
|
||||
* people at a counter shared a credential and nothing recorded which of them
|
||||
* did anything.
|
||||
*
|
||||
* A branch must still arrive with SOMEBODY: name a person here, or give an
|
||||
* `email` to spawn one from. The backend refuses a branch with neither,
|
||||
* because an outlet nobody can sign in to is a dead end that shows up in
|
||||
* every list and is noticed by whoever is standing in the shop.
|
||||
*/
|
||||
operatorid?: number;
|
||||
}
|
||||
|
||||
export interface TenantListQuery {
|
||||
@@ -110,7 +125,11 @@ export const tenantsApi = {
|
||||
api.post<TenantInfo>(`${WEB}/tenants/createtenantuser`, toTenantBody(body)),
|
||||
|
||||
/**
|
||||
* Commissions a branch and spawns its login (roleid 0, empty password).
|
||||
* Commissions a branch, and gives it somebody to run it.
|
||||
*
|
||||
* Pass `operatorid` to place a person you have already hired. Without it the
|
||||
* backend spawns a login named after the shop, as it always did — kept so
|
||||
* nothing existing changes, but the named person is the better path.
|
||||
*
|
||||
* `createtenantlocation`, not `createlocation`: only this one returns the
|
||||
* created row, and the new `locationid` is what a QR code and every
|
||||
@@ -122,6 +141,48 @@ export const tenantsApi = {
|
||||
|
||||
updateBranch: (body: Partial<TenantLocation> & { locationid: number }) =>
|
||||
api.put<TenantLocation>(`${WEB}/tenants/updatelocation`, body),
|
||||
|
||||
/**
|
||||
* A merchant editing their own business record.
|
||||
*
|
||||
* The first write path `tenants` has ever had. Before it, everything about a
|
||||
* shop — its name, its photograph, its licence, how to reach it — was set
|
||||
* once at onboarding by a Nearle Admin and could never be changed by anyone.
|
||||
*
|
||||
* Only merchant-owned columns are written; the backend keeps the allowlist
|
||||
* and ignores the rest, so `approved`, `status`, `partnerid` and the billing
|
||||
* fields cannot be set from here even if a caller sends them. Anything
|
||||
* omitted is left alone rather than blanked.
|
||||
*/
|
||||
updateProfile: (body: { tenantid: number } & Partial<TenantInfo>) =>
|
||||
api.put<unknown>(`${WEB}/tenants/updatetenant`, body),
|
||||
|
||||
/**
|
||||
* One business, by id — how a store login reads its own record.
|
||||
*
|
||||
* Not `listAll`. That is `getalltenants`, paginated over 262 merchants, so a
|
||||
* shop on page two was simply absent and a profile screen built on it would
|
||||
* show nothing for no visible reason.
|
||||
*/
|
||||
byId: (tenantid: number) => api.get<TenantInfo>(`${WEB}/tenants/gettenantinfo`, { tenantid }),
|
||||
|
||||
/**
|
||||
* Somebody editing their own name, mobile or email.
|
||||
*
|
||||
* Not `users/update`. That one writes whatever struct it is handed and checks
|
||||
* only the userid — no tenant, no guard on role or branch — so a self-service
|
||||
* form built on it would let a branch user promote themselves or move shop.
|
||||
* This is scoped to the caller's own account AND business, and writes
|
||||
* identity fields only.
|
||||
*/
|
||||
updateOwnProfile: (body: {
|
||||
userid: number;
|
||||
tenantid: number;
|
||||
firstname?: string;
|
||||
lastname?: string;
|
||||
contactno?: string;
|
||||
email?: string;
|
||||
}) => api.put<unknown>(`${WEB}/tenants/updateownprofile`, body),
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -93,6 +93,14 @@ export interface TenantInfo {
|
||||
longitude?: string;
|
||||
tenantimage?: string;
|
||||
tenantinfo?: string;
|
||||
/**
|
||||
* The FSSAI or trade licence.
|
||||
*
|
||||
* Returned by the customer-facing tenant reads and displayed to shoppers,
|
||||
* and across 200 merchants not one had it filled in. For a food business in
|
||||
* India it is a display requirement, not a nicety.
|
||||
*/
|
||||
licenseno?: string;
|
||||
partnerid?: number;
|
||||
minorder?: number;
|
||||
/** Misspelled on the wire — `applolcationid`, not `applocationid`. */
|
||||
|
||||
Reference in New Issue
Block a user