feat: add stuff
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-10-20 14:45:22 +02:00
parent ee06af8395
commit 1e4438ec5a
24 changed files with 1734 additions and 14 deletions
+61
View File
@@ -92,6 +92,41 @@ export interface Reminder {
status: string;
}
export type StockAdjustmentType = 'add' | 'set';
export type StockAdjustmentStatus = 'pending' | 'applied' | 'rejected' | 'cancelled';
export interface StockAdjustment {
id: string;
productId: string;
productName: string;
/** add: the stock changes by quantity (negative takes stock out); set: the stock is now quantity */
type: StockAdjustmentType;
quantity: number;
note: string | null;
requestedBy: string;
status: StockAdjustmentStatus;
/** The terminal's stock right after applying it */
stockAfter: number | null;
/** Why the terminal rejected it */
result: string | null;
createdAt: string;
processedAt: string | null;
}
export interface Product {
productId: string;
name: string;
category: string | null;
priceInCents: number;
/** Null when the terminal doesn't track stock for this product; can be negative */
stock: number | null;
lowStockThreshold: number | null;
reportedAt: string;
pendingAdjustments: StockAdjustment[];
}
export type NewStockAdjustment = { productId: string; type: StockAdjustmentType; quantity: number; note?: string };
export function getCookie(name: string): string | null {
if (typeof document === 'undefined') return null;
return document.cookie
@@ -294,6 +329,32 @@ export const remindersApi = {
api<{ ok: boolean; email: string; customerName: string }>(`/venues/${venueId}/reminders/test/${plannedTabId}`, { method: 'POST' }),
};
// Stock API
export const stockApi = {
list: (venueId: string) =>
api<{ products: Product[]; reportedAt: string | null }>(`/venues/${venueId}/stock`),
history: (venueId: string, params?: { productId?: string; limit?: number; offset?: number }) => {
const searchParams = new URLSearchParams();
if (params?.productId) searchParams.set('productId', params.productId);
if (params?.limit) searchParams.set('limit', String(params.limit));
if (params?.offset) searchParams.set('offset', String(params.offset));
const qs = searchParams.toString();
return api<{ adjustments: StockAdjustment[]; total: number }>(`/venues/${venueId}/stock/adjustments${qs ? `?${qs}` : ''}`);
},
adjust: (venueId: string, adjustments: NewStockAdjustment[]) =>
api<{ adjustments: StockAdjustment[] }>(`/venues/${venueId}/stock/adjustments`, {
method: 'POST',
body: JSON.stringify({ adjustments }),
}),
cancel: (venueId: string, id: string) =>
api(`/venues/${venueId}/stock/adjustments/${id}/cancel`, { method: 'POST' }),
setLowStockThreshold: (venueId: string, productId: string, lowStockThreshold: number | null) =>
api(`/venues/${venueId}/stock/products/${encodeURIComponent(productId)}`, {
method: 'PUT',
body: JSON.stringify({ lowStockThreshold }),
}),
};
export { setTokens, clearTokens, refreshAccessToken };
export function getAccessToken(): string | null {