Files
stockfill/src/db/migrations.ts
T
beatzaplenty f61d078900 deleted: public/templates/areas_template.csv
deleted:    public/templates/categories_template.csv
	deleted:    public/templates/pickitems_template.csv
	deleted:    public/templates/picklists_template.csv
	modified:   src/db/migrations.ts
	modified:   src/screens/ManageCategoriesScreen.tsx
	modified:   src/screens/ManageProductsScreen.tsx
2025-11-25 11:41:15 +10:00

81 lines
2.8 KiB
TypeScript

// src/db/migrations.ts
import { StockFillDB } from './index';
import { v4 as uuidv4 } from 'uuid';
export const applyMigrations = async (db: StockFillDB) => {
// Ensure DB is open and ready
await db.open();
// Run a single transaction that normalizes products and pickLists
await db.transaction('rw', db.categories, db.products, db.pickLists, async () => {
const now = Date.now();
// Load categories (existing)
const categories = await db.categories.toArray();
const categoriesByName = new Map(categories.map((c) => [c.name, c.id]));
const categoriesById = new Map(categories.map((c) => [c.id, c.name]));
// 1) Normalize products: category -> categoryId
const products = await db.products.toArray();
await Promise.all(
products.map(async (product) => {
const cat = product.category ?? '';
// Skip empty
if (!cat) return;
// If already an id that matches a known category, skip
if (categoriesById.has(cat)) return;
// If it's a name that matches an existing category, update
const matchingId = categoriesByName.get(cat);
if (matchingId) {
await db.products.update(product.id, { category: matchingId });
return;
}
// Otherwise: create a new category with this name and use its id
const newCatId = uuidv4();
await db.categories.add({
id: newCatId,
name: cat,
created_at: now,
updated_at: now,
});
categoriesByName.set(cat, newCatId);
categoriesById.set(newCatId, cat);
await db.products.update(product.id, { category: newCatId });
}),
);
// Refresh categories maps (in case we added new ones)
const updatedCategories = await db.categories.toArray();
const updatedByName = new Map(updatedCategories.map((c) => [c.name, c.id]));
const updatedById = new Map(updatedCategories.map((c) => [c.id, c.name]));
// 2) Normalize pickLists.categories (array) to hold ids (not names)
const pickLists = await db.pickLists.toArray();
await Promise.all(
pickLists.map(async (pl) => {
if (!Array.isArray((pl as any).categories)) return;
const newCats = (pl as any).categories.map((entry: string) => {
// If the entry is already an id we know, keep it
if (updatedById.has(entry)) return entry;
// If entry is a name, return its id (if exists)
const id = updatedByName.get(entry);
if (id) return id;
// If it's neither, keep as-is (or optionally create category)
return entry;
});
// Update only if changed
if (JSON.stringify(newCats) !== JSON.stringify((pl as any).categories)) {
await db.pickLists.update(pl.id, { categories: newCats });
}
}),
);
});
};