Initial commit: Apothecary v0.4.0
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
import { Router } from "express";
|
||||
import { db } from "../db.js";
|
||||
|
||||
export const bootstrapRouter: Router = Router();
|
||||
|
||||
type ProductRow = {
|
||||
id: string;
|
||||
sku: string;
|
||||
asset_tag: string | null;
|
||||
name: string;
|
||||
brand_id: string | null;
|
||||
shop_id: string | null;
|
||||
bin_id: string | null;
|
||||
type: string;
|
||||
kind: string;
|
||||
weight: number;
|
||||
last_audit_weight: number | null;
|
||||
count_original: number;
|
||||
count_last_audit: number | null;
|
||||
unit_weight: number;
|
||||
price: number;
|
||||
thc: number;
|
||||
cbd: number;
|
||||
total_cannabinoids: number;
|
||||
purchase_date: string;
|
||||
status: string;
|
||||
consumed_date: string | null;
|
||||
gone_date: string | null;
|
||||
rating: number | null;
|
||||
notes: string | null;
|
||||
strain_id: string | null;
|
||||
};
|
||||
|
||||
type StrainRow = {
|
||||
id: string;
|
||||
name: string;
|
||||
brand_id: string | null;
|
||||
type: string;
|
||||
default_thc: number | null;
|
||||
default_cbd: number | null;
|
||||
default_total_cannabinoids: number | null;
|
||||
notes: string | null;
|
||||
};
|
||||
|
||||
type AuditRow = {
|
||||
id: number;
|
||||
product_id: string;
|
||||
date: string;
|
||||
mode: string;
|
||||
value: number;
|
||||
prev_value: number | null;
|
||||
confirmed_by: string | null;
|
||||
};
|
||||
|
||||
bootstrapRouter.get("/bootstrap", (_req, res) => {
|
||||
const products = db.prepare<[], ProductRow>("SELECT * FROM products ORDER BY id").all();
|
||||
const audits = db
|
||||
.prepare<[], AuditRow>("SELECT * FROM audits ORDER BY product_id, date")
|
||||
.all();
|
||||
const shops = db.prepare("SELECT * FROM shops ORDER BY id").all();
|
||||
const brands = db.prepare("SELECT * FROM brands ORDER BY id").all();
|
||||
const bins = db.prepare("SELECT * FROM bins ORDER BY id").all();
|
||||
const strains = db
|
||||
.prepare<[], StrainRow>("SELECT * FROM strains ORDER BY name COLLATE NOCASE")
|
||||
.all();
|
||||
|
||||
const auditsByProduct = new Map<string, AuditRow[]>();
|
||||
for (const a of audits) {
|
||||
const arr = auditsByProduct.get(a.product_id) ?? [];
|
||||
arr.push(a);
|
||||
auditsByProduct.set(a.product_id, arr);
|
||||
}
|
||||
|
||||
const productsOut = products.map((p) => ({
|
||||
id: p.id,
|
||||
sku: p.sku,
|
||||
assetTag: p.asset_tag,
|
||||
name: p.name,
|
||||
brandId: p.brand_id,
|
||||
shopId: p.shop_id,
|
||||
binId: p.bin_id,
|
||||
type: p.type,
|
||||
kind: p.kind,
|
||||
weight: p.weight,
|
||||
lastAuditWeight: p.last_audit_weight,
|
||||
countOriginal: p.count_original,
|
||||
countLastAudit: p.count_last_audit,
|
||||
unitWeight: p.unit_weight,
|
||||
price: p.price,
|
||||
thc: p.thc,
|
||||
cbd: p.cbd,
|
||||
totalCannabinoids: p.total_cannabinoids,
|
||||
purchaseDate: p.purchase_date,
|
||||
status: p.status,
|
||||
consumedDate: p.consumed_date,
|
||||
goneDate: p.gone_date,
|
||||
rating: p.rating,
|
||||
notes: p.notes,
|
||||
strainId: p.strain_id,
|
||||
audits: (auditsByProduct.get(p.id) ?? []).map((a) => ({
|
||||
date: a.date,
|
||||
mode: a.mode,
|
||||
value: a.value,
|
||||
prev: a.prev_value,
|
||||
confirmedBy: a.confirmed_by,
|
||||
})),
|
||||
}));
|
||||
|
||||
const strainsOut = strains.map((s) => ({
|
||||
id: s.id,
|
||||
name: s.name,
|
||||
brandId: s.brand_id,
|
||||
type: s.type,
|
||||
defaultThc: s.default_thc,
|
||||
defaultCbd: s.default_cbd,
|
||||
defaultTotalCannabinoids: s.default_total_cannabinoids,
|
||||
notes: s.notes,
|
||||
}));
|
||||
|
||||
res.json({
|
||||
products: productsOut,
|
||||
shops,
|
||||
brands,
|
||||
bins,
|
||||
strains: strainsOut,
|
||||
today: "2026-04-25",
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user