Initial commit: Apothecary v0.4.0

This commit is contained in:
2026-05-03 20:19:26 -04:00
commit 027cf032be
55 changed files with 14678 additions and 0 deletions
+87
View File
@@ -0,0 +1,87 @@
import type { Bootstrap, AuditMode } from "./types.js";
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(`/api${path}`, {
...init,
headers: { "Content-Type": "application/json", ...(init?.headers ?? {}) },
});
if (!res.ok) {
const text = await res.text();
throw new Error(`${res.status} ${res.statusText}: ${text}`);
}
return res.json() as Promise<T>;
}
export const api = {
bootstrap: () => request<Bootstrap>("/bootstrap"),
createProduct: (body: {
name: string;
brandId: string;
shopId: string;
binId: string;
type: string;
kind: "bulk" | "discrete";
weight?: number;
countOriginal?: number;
unitWeight?: number;
price: number;
thc: number;
cbd: number;
totalCannabinoids: number;
purchaseDate: string;
sku?: string;
assetTag?: string;
}) => request<{ id: string }>("/products", { method: "POST", body: JSON.stringify(body) }),
finishProduct: (id: string, body: { date: string; rating?: number; notes?: string }) =>
request<{ ok: true }>(`/products/${id}/finish`, {
method: "POST",
body: JSON.stringify(body),
}),
markGone: (id: string, body: { date: string; reason: string; notes?: string }) =>
request<{ ok: true }>(`/products/${id}/gone`, {
method: "POST",
body: JSON.stringify(body),
}),
auditProduct: (
id: string,
body: { date: string; mode: AuditMode; value: number; confirmedBy?: string },
) =>
request<{ ok: true }>(`/products/${id}/audit`, {
method: "POST",
body: JSON.stringify(body),
}),
createBrand: (name: string) =>
request<{ id: string; name: string }>("/brands", {
method: "POST",
body: JSON.stringify({ name }),
}),
createShop: (body: { name: string; location?: string }) =>
request<{ id: string; name: string; location: string | null }>("/shops", {
method: "POST",
body: JSON.stringify(body),
}),
createBin: (body: { name: string; location?: string; capacity?: number }) =>
request<{ id: string; name: string; location: string | null; capacity: number }>("/bins", {
method: "POST",
body: JSON.stringify(body),
}),
updateBin: (
id: string,
body: { name?: string; location?: string | null; capacity?: number },
) =>
request<{ id: string; name: string; location: string | null; capacity: number }>(
`/bins/${id}`,
{ method: "PATCH", body: JSON.stringify(body) },
),
deleteBin: (id: string) =>
request<{ ok: true }>(`/bins/${id}`, { method: "DELETE" }),
};