store user login
This commit is contained in:
@@ -20,6 +20,8 @@ export interface CreateTenantRequest {
|
||||
latitude?: string;
|
||||
longitude?: string;
|
||||
moduleid?: number;
|
||||
/** The city this merchant trades in. `app_location`, not a branch. */
|
||||
applocationid?: number;
|
||||
status?: string;
|
||||
}
|
||||
|
||||
@@ -43,13 +45,45 @@ export interface CreateBranchRequest {
|
||||
status?: string;
|
||||
}
|
||||
|
||||
export interface TenantListQuery {
|
||||
pageno?: number;
|
||||
pagesize?: number;
|
||||
/** `Active` / `InActive`. Omitted, the backend returns every state. */
|
||||
status?: string;
|
||||
applocationid?: number;
|
||||
tenanttype?: string;
|
||||
keyword?: string;
|
||||
}
|
||||
|
||||
export const tenantsApi = {
|
||||
/**
|
||||
* Every tenant on the platform. Deliberately unscoped — this is the
|
||||
* Nearle Admin's list, and the backend treats it as the platform-operator
|
||||
* endpoint rather than a tenant-scoped one.
|
||||
*/
|
||||
listAll: () => api.get<TenantInfo[]>(`${WEB}/tenants/getalltenants`),
|
||||
listAll: (query: TenantListQuery = {}) =>
|
||||
api.get<TenantInfo[]>(`${WEB}/tenants/getalltenants`, {
|
||||
pageno: query.pageno ?? 1,
|
||||
pagesize: query.pagesize ?? 100,
|
||||
status: query.status,
|
||||
applocationid: query.applocationid,
|
||||
tenanttype: query.tenanttype,
|
||||
keyword: query.keyword,
|
||||
}),
|
||||
|
||||
/**
|
||||
* Tenants by approval state — the only way to see the ones awaiting it.
|
||||
*
|
||||
* `status=pending` is not a status at all: the handler branches on the word
|
||||
* and queries `approved = 0` instead (`tenantRepository.go:45-77`). Anything
|
||||
* else means `approved = 1 AND status = ?`. So an unapproved merchant is
|
||||
* invisible to every other endpoint, including `getalltenants`.
|
||||
*
|
||||
* Nothing can approve one over HTTP. `approved` is writable only at creation,
|
||||
* so this list is a queue to work from, not one to act on.
|
||||
*/
|
||||
byApproval: (status: 'pending' | 'Active' | 'InActive', keyword?: string) =>
|
||||
api.get<TenantInfo[]>(`${WEB}/tenants/search`, { status, keyword }),
|
||||
|
||||
/** Branches under one tenant. `tenantid` is required — omit it and it 400s. */
|
||||
locations: (tenantid: number) =>
|
||||
@@ -58,14 +92,100 @@ export const tenantsApi = {
|
||||
search: (keyword: string) =>
|
||||
api.get<TenantInfo[]>(`${WEB}/tenants/searchbykeyword`, { keyword }),
|
||||
|
||||
/** Provisions the enterprise and spawns its primary Administrator account. */
|
||||
/**
|
||||
* Provisions the enterprise, its first outlet, and the primary Administrator
|
||||
* account — one transaction writing `tenants`, `ordersequences`, `app_users`
|
||||
* (roleid 1, configid forced to 1), `customers`, `customerlocations` and
|
||||
* `tenantcustomers`.
|
||||
*
|
||||
* `createtenantuser`, NOT `createtenantlocation`. The latter takes a
|
||||
* `Tenantlocations` and writes a BRANCH under a tenant that already exists —
|
||||
* pointing the merchant form at it created an outlet and no merchant.
|
||||
*
|
||||
* The primary outlet is NESTED. The backend reads it off
|
||||
* `Tenants.Tenantlocations` and creates it in the same transaction, so a
|
||||
* tenant can never exist without somewhere to trade from.
|
||||
*/
|
||||
createTenant: (body: CreateTenantRequest) =>
|
||||
api.post<TenantInfo>(`${WEB}/tenants/createtenantlocation`, body),
|
||||
api.post<TenantInfo>(`${WEB}/tenants/createtenantuser`, toTenantBody(body)),
|
||||
|
||||
/** Commissions a branch and spawns a placeholder branch-manager account. */
|
||||
/**
|
||||
* Commissions a branch and spawns its login (roleid 0, empty password).
|
||||
*
|
||||
* `createtenantlocation`, not `createlocation`: only this one returns the
|
||||
* created row, and the new `locationid` is what a QR code and every
|
||||
* follow-up write need. `createlocation` answers 201 with a message and no
|
||||
* `details` at all.
|
||||
*/
|
||||
createBranch: (body: CreateBranchRequest) =>
|
||||
api.post<TenantLocation>(`${WEB}/tenants/createlocation`, body),
|
||||
api.post<TenantLocation>(`${WEB}/tenants/createtenantlocation`, body),
|
||||
|
||||
updateBranch: (body: Partial<TenantLocation> & { locationid: number }) =>
|
||||
api.put<TenantLocation>(`${WEB}/tenants/updatelocation`, body),
|
||||
};
|
||||
|
||||
/**
|
||||
* The merchant form, in the shape `models.Tenants` expects.
|
||||
*
|
||||
* `configid` and `applocationid` are sent because the account this call spawns
|
||||
* is looked up by `configid` at every sign-in, and `applocationid` is the city
|
||||
* the tenant trades in. `approved: 1` and `status: 'Active'` are set here
|
||||
* because they can only ever be set here — there is no update or approve
|
||||
* endpoint, so a tenant created unapproved stays unapproved forever.
|
||||
*/
|
||||
function toTenantBody(form: CreateTenantRequest): Record<string, unknown> {
|
||||
return {
|
||||
tenantname: form.tenantname,
|
||||
companyname: form.companyname,
|
||||
primaryemail: form.primaryemail,
|
||||
primarycontact: form.primarycontact,
|
||||
categoryid: form.categoryid,
|
||||
subcategoryid: form.subcategoryid ?? 0,
|
||||
address: form.address,
|
||||
suburb: form.suburb ?? '',
|
||||
city: form.city,
|
||||
state: form.state,
|
||||
postcode: form.postcode,
|
||||
latitude: form.latitude ?? '',
|
||||
longitude: form.longitude ?? '',
|
||||
configid: 1,
|
||||
moduleid: form.moduleid ?? 2,
|
||||
applocationid: form.applocationid ?? 1,
|
||||
approved: 1,
|
||||
status: form.status ?? 'Active',
|
||||
// The primary outlet, created in the same transaction. Its address
|
||||
// defaults to the tenant's — a merchant's first shop is at the address
|
||||
// they just typed far more often than not, and it can be edited after.
|
||||
tenantlocations: {
|
||||
locationname: form.locationname,
|
||||
email: form.primaryemail,
|
||||
contactno: form.primarycontact,
|
||||
address: form.address,
|
||||
suburb: form.suburb ?? '',
|
||||
city: form.city,
|
||||
state: form.state,
|
||||
postcode: form.postcode,
|
||||
latitude: form.latitude ?? '',
|
||||
longitude: form.longitude ?? '',
|
||||
applocationid: form.applocationid ?? 1,
|
||||
status: 'Active',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/** One row of the `app_category` master — the business categories a tenant picks from. */
|
||||
export interface AppCategory {
|
||||
categoryid: number;
|
||||
categoryname: string;
|
||||
}
|
||||
|
||||
export const utilsApi = {
|
||||
/**
|
||||
* The business-category master.
|
||||
*
|
||||
* Read rather than hardcoded. The old console typed four values into the
|
||||
* form and never called this, which means a category added to the master is
|
||||
* invisible to onboarding until someone edits the frontend.
|
||||
*/
|
||||
appCategories: () => api.get<AppCategory[]>(`${WEB}/utils/getappcategories`),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user