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
+40
View File
@@ -0,0 +1,40 @@
import Database from "better-sqlite3";
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const DB_PATH = process.env.APOTHECARY_DB ?? join(__dirname, "..", "data.db");
export const db = new Database(DB_PATH);
db.pragma("journal_mode = WAL");
db.pragma("foreign_keys = ON");
const schema = readFileSync(join(__dirname, "schema.sql"), "utf8");
db.exec(schema);
// Add strain_id to products table if missing — older DBs predate the column.
const productCols = db
.prepare(`PRAGMA table_info(products)`)
.all() as { name: string }[];
if (!productCols.some((c) => c.name === "strain_id")) {
db.exec(`ALTER TABLE products ADD COLUMN strain_id TEXT REFERENCES strains(id);`);
db.exec(`CREATE INDEX IF NOT EXISTS idx_products_strain ON products(strain_id);`);
}
export function nextId(prefix: string, table: string): string {
const row = db
.prepare<[string], { id: string }>(
`SELECT id FROM ${table} WHERE id LIKE ? ORDER BY id DESC LIMIT 1`,
)
.get(`${prefix}-%`);
const last = row ? Number(row.id.slice(prefix.length + 1)) : 0;
const pad = prefix === "prd" || prefix === "str" ? 4 : 2;
const n = String(last + 1).padStart(pad, "0");
return `${prefix}-${n}`;
}
export function randomSku(): string {
return "SKU-" + Math.random().toString(36).slice(2, 8).toUpperCase();
}