Files
mercadodevida/project/apps/pos/src/lib/api-client.ts
2026-08-22 19:10:02 +02:00

63 lines
2.6 KiB
TypeScript

// Browser requests stay on the POS origin. The Next.js route handler proxies
// `/api/*` to the backend, so LAN clients never resolve their own localhost.
const API = '/api';
async function apiFetch<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`${API}${path}`, {
...init,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
...(init?.headers ?? {}),
},
});
if (!res.ok) {
const err = await res.json().catch(() => ({ message: res.statusText })) as {
message?: string;
error?: { message?: string; code?: string };
};
throw Object.assign(
new Error(err.error?.message ?? err.message ?? 'Request failed'),
{ status: res.status, code: err.error?.code },
);
}
return res.json() as Promise<T>;
}
export const posApi = {
/** Get current terminal info. Requires x-terminal-id header set by middleware. */
me: () => apiFetch('/pos/terminals/me'),
/** Bind terminal with code. */
bind: (bindingCode: string) =>
apiFetch<{ terminalId: string; storeId: string }>('/pos/terminals/bind', {
method: 'POST',
body: JSON.stringify({ bindingCode }),
}),
/** Get POS config (store + terminal + payment methods + session status). */
config: <T>() => apiFetch<T>('/pos/config'),
/** Open the daily cash session for the bound terminal. */
openSession: (openingCashCents: number) =>
apiFetch<{ id: string; status: 'OPEN' }>('/pos/sessions', {
method: 'POST',
body: JSON.stringify({ openingCashCents }),
}),
/** List products by query. */
searchProducts: (q: string, storeId?: string, limit = 20) =>
apiFetch(`/pos/products/search?q=${encodeURIComponent(q)}&storeId=${storeId ?? ''}&limit=${limit}`),
/** Get product by EAN. */
productByEan: (ean: string) => apiFetch(`/pos/products/by-ean/${encodeURIComponent(ean)}`),
/** Get product by SKU. */
productBySku: (sku: string) => apiFetch(`/pos/products/by-sku/${encodeURIComponent(sku)}`),
/** Search identity customers for sale association. */
searchCustomers: (q: string) => apiFetch(`/pos/customers/search?q=${encodeURIComponent(q)}`),
/** Create an identity customer from the register. */
createCustomer: <T>(data: { email: string; displayName?: string; phone?: string }) =>
apiFetch<T>('/pos/customers', { method: 'POST', body: JSON.stringify(data) }),
};
export const authApi = {
login: (email: string, password: string) =>
apiFetch('/backoffice/auth/login', { method: 'POST', body: JSON.stringify({ email, password }) }),
logout: () => apiFetch('/backoffice/auth/logout', { method: 'POST' }),
};