790 lines
25 KiB
JavaScript
790 lines
25 KiB
JavaScript
import sharp from 'sharp';
|
|
|
|
/**
|
|
* Creates sample PNG image buffer.
|
|
*/
|
|
async function makeSampleImage(width = 200, height = 200, color = { r: 50, g: 120, b: 220 }) {
|
|
return sharp({
|
|
create: {
|
|
width,
|
|
height,
|
|
channels: 4,
|
|
background: { ...color, alpha: 1 },
|
|
},
|
|
})
|
|
.png()
|
|
.toBuffer();
|
|
}
|
|
|
|
/**
|
|
* Creates sample AVIF thumbnail buffer.
|
|
*/
|
|
async function makeSampleThumb(width = 64, height = 64) {
|
|
return sharp({
|
|
create: {
|
|
width,
|
|
height,
|
|
channels: 4,
|
|
background: { r: 200, g: 60, b: 60, alpha: 1 },
|
|
},
|
|
})
|
|
.avif()
|
|
.toBuffer();
|
|
}
|
|
|
|
/**
|
|
* Executes Phase 1: Database Population / Fill.
|
|
* Systematically calls creation and write APIs to populate the database
|
|
* with realistic entities and relationships according to the configured scale.
|
|
*/
|
|
export async function fillDatabase(store, options = {}) {
|
|
const scale = options.scale || 'small';
|
|
const counts = {
|
|
small: { categories: 6, articles: 18, entities: 6, manifests: 6 },
|
|
medium: { categories: 15, articles: 60, entities: 20, manifests: 20 },
|
|
large: { categories: 30, articles: 200, entities: 50, manifests: 60 },
|
|
}[scale] || { categories: 6, articles: 18, entities: 6, manifests: 6 };
|
|
|
|
const ctx = {
|
|
googleAuthId: null,
|
|
company: null,
|
|
secondaryGoogleAuthId: null,
|
|
secondaryCompany: null,
|
|
categories: [],
|
|
articles: [],
|
|
parentArticles: [],
|
|
childArticles: [],
|
|
customergroups: [],
|
|
entities: [],
|
|
suppliers: [],
|
|
deliveries: [],
|
|
orders: [],
|
|
quotes: [],
|
|
terminals: [],
|
|
sampleImageHash: null,
|
|
sampleImageThumbHash: null,
|
|
attachments: [],
|
|
};
|
|
|
|
const sampleImage = await makeSampleImage();
|
|
const sampleThumb = await makeSampleThumb();
|
|
|
|
// 1. Google Auth setup
|
|
const primaryEmail = `benchmark.admin.${Date.now()}@example.com`;
|
|
const secEmail = `benchmark.secondary.${Date.now()}@example.com`;
|
|
|
|
ctx.googleAuthId = await store.google_auth.add(primaryEmail);
|
|
await store.google_auth.setProfile(ctx.googleAuthId, {
|
|
sub: `sub-${ctx.googleAuthId}`,
|
|
picture: 'https://example.com/pic.png',
|
|
});
|
|
await store.google_auth.listAllowedEmails();
|
|
|
|
ctx.secondaryGoogleAuthId = await store.google_auth.add(secEmail);
|
|
|
|
// 2. Company setup
|
|
ctx.company = await store.company.create({
|
|
name: `Bench Corp ${Date.now()}`,
|
|
iso639: 'de',
|
|
taxrate: 19,
|
|
reducedtaxrate: 7,
|
|
googleAuthId: ctx.googleAuthId,
|
|
});
|
|
await store.google_auth.setSelectedCompany(ctx.googleAuthId, ctx.company.id);
|
|
|
|
ctx.secondaryCompany = await store.company.create({
|
|
name: `Secondary Corp ${Date.now()}`,
|
|
iso639: 'en',
|
|
taxrate: 20,
|
|
reducedtaxrate: 10,
|
|
googleAuthId: ctx.secondaryGoogleAuthId,
|
|
});
|
|
await store.google_auth.setSelectedCompany(ctx.secondaryGoogleAuthId, ctx.secondaryCompany.id);
|
|
|
|
await store.company.update(ctx.company.id, {
|
|
name: `Bench Corp Updated ${Date.now()}`,
|
|
iso639: 'de',
|
|
taxrate: 19,
|
|
reducedtaxrate: 7,
|
|
});
|
|
await store.company.list(ctx.googleAuthId);
|
|
|
|
// 3. Company Users
|
|
const compUserId = await store.companyuser.add(ctx.company.id, ctx.secondaryGoogleAuthId);
|
|
ctx.compUserId = compUserId;
|
|
await store.companyuser.getByEmail(secEmail);
|
|
|
|
// 4. Lang APIs
|
|
await store.lang.ensure('en');
|
|
await store.lang.ensure('fr');
|
|
await store.lang.create('es');
|
|
await store.lang.getByIso639('en');
|
|
await store.lang.list();
|
|
|
|
// 5. Tax APIs
|
|
await store.tax.ensure(19);
|
|
await store.tax.ensure(7);
|
|
const taxIdSample = await store.tax.create(5.5);
|
|
ctx.taxSampleId = taxIdSample;
|
|
await store.tax.getByRate(19);
|
|
await store.tax.list();
|
|
|
|
// 6. Unit APIs
|
|
await store.unit.upsert(ctx.googleAuthId, {
|
|
si: 'kg',
|
|
basesi: 'g',
|
|
basesifactor: 1000,
|
|
symbol: 'kg',
|
|
name: 'Kilogramm',
|
|
});
|
|
await store.unit.upsert(ctx.googleAuthId, {
|
|
si: 'stk',
|
|
basesi: 'stk',
|
|
basesifactor: 1,
|
|
symbol: 'Stk',
|
|
name: 'Stück',
|
|
});
|
|
await store.unit.list(ctx.googleAuthId);
|
|
|
|
// 7. Company Settings
|
|
await store.companysetting.set(ctx.googleAuthId, {
|
|
key: 'ui.theme',
|
|
value: 'dark',
|
|
frontend: true,
|
|
writeonly: false,
|
|
});
|
|
await store.companysetting.set(ctx.googleAuthId, {
|
|
key: 'labelprinter.type',
|
|
value: 'zebra',
|
|
frontend: false,
|
|
writeonly: false,
|
|
});
|
|
await store.companysetting.get(ctx.googleAuthId, 'ui.theme');
|
|
await store.companysetting.list(ctx.googleAuthId);
|
|
|
|
// 8. Brand APIs
|
|
const brand1 = await store.brand.upsert(ctx.googleAuthId, {
|
|
name: 'BenchBrand Pro',
|
|
gsprpinfo: 'Manufacturer Pro GmbH',
|
|
});
|
|
const brand2 = await store.brand.upsert(ctx.googleAuthId, {
|
|
name: 'BenchBrand Ultra',
|
|
gsprpinfo: 'Manufacturer Ultra AG',
|
|
});
|
|
ctx.brands = [brand1, brand2];
|
|
await store.brand.list(ctx.googleAuthId);
|
|
|
|
// 9. Customer Groups
|
|
const cgVip = await store.customergroup.create(ctx.googleAuthId, { name: 'VIP Members' });
|
|
const cgRetail = await store.customergroup.create(ctx.googleAuthId, { name: 'Retail Customers' });
|
|
await store.customergroup.update(ctx.googleAuthId, cgVip.id, { name: 'VIP Gold Members' });
|
|
const allCgs = await store.customergroup.list(ctx.googleAuthId);
|
|
await store.customergroup.order(ctx.googleAuthId, {
|
|
customergroupIds: allCgs.map((g) => g.id).reverse(),
|
|
});
|
|
await store.customergroup.list(ctx.googleAuthId);
|
|
ctx.customergroups.push(cgRetail, cgVip);
|
|
|
|
// 10. Categories Hierarchy
|
|
const rootCatId = ctx.company.rootCategoryId;
|
|
const numCats = counts.categories;
|
|
|
|
for (let i = 1; i <= numCats; i++) {
|
|
const parentId = i > 3 && ctx.categories.length > 0 ? ctx.categories[(i % 3)].id : rootCatId;
|
|
const cat = await store.category.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId,
|
|
name: `Category ${i}`,
|
|
});
|
|
ctx.categories.push(cat);
|
|
}
|
|
|
|
// Ensure by path
|
|
const deepCatId = await store.category.ensureByPath({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: rootCatId,
|
|
path: 'Hardware / Components / Processors',
|
|
});
|
|
ctx.deepCatId = deepCatId;
|
|
|
|
// Category manipulation APIs
|
|
if (ctx.categories.length >= 2) {
|
|
await store.category.rename({
|
|
googleAuthId: ctx.googleAuthId,
|
|
id: ctx.categories[0].id,
|
|
name: 'Main Catalog Category',
|
|
});
|
|
const orderParent = await store.category.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: rootCatId,
|
|
name: 'Order Test Parent',
|
|
});
|
|
const oChild1 = await store.category.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: orderParent.id,
|
|
name: 'Order Child 1',
|
|
});
|
|
const oChild2 = await store.category.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: orderParent.id,
|
|
name: 'Order Child 2',
|
|
});
|
|
await store.category.move({
|
|
googleAuthId: ctx.googleAuthId,
|
|
id: oChild2.id,
|
|
parentId: orderParent.id,
|
|
});
|
|
await store.category.order({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: orderParent.id,
|
|
categoryIds: [oChild2.id, oChild1.id],
|
|
});
|
|
}
|
|
|
|
// Category image
|
|
await store.category.addImage(ctx.googleAuthId, ctx.categories[0].id, sampleImage);
|
|
|
|
// 11. Numbers APIs
|
|
const numList = await store.numbers.list(ctx.googleAuthId);
|
|
if (numList.length > 0) {
|
|
await store.numbers.update(ctx.googleAuthId, numList[0].id, {
|
|
prefix: 'BN-',
|
|
padding: 6,
|
|
next: 1001,
|
|
});
|
|
}
|
|
|
|
// 12. POS Terminals
|
|
const term1 = await store.posterminal.upsert(ctx.googleAuthId, {
|
|
name: 'Counter Terminal 1',
|
|
pairingpin: '1234',
|
|
});
|
|
const term2 = await store.posterminal.upsert(ctx.googleAuthId, {
|
|
name: 'Mobile Terminal 2',
|
|
pairingpin: '5678',
|
|
});
|
|
ctx.terminals.push(term1, term2);
|
|
|
|
await store.posterminal.setOn(ctx.googleAuthId, term1.id, ctx.categories[0].id);
|
|
await store.posterminal.setOff(ctx.googleAuthId, term1.id, ctx.categories[0].id);
|
|
await store.posterminal.setOnAll(ctx.googleAuthId, term1.id);
|
|
await store.posterminal.setOffAll(ctx.googleAuthId, term1.id);
|
|
await store.posterminal.getCategoryPosterminalIds(ctx.googleAuthId, ctx.categories[0].id);
|
|
await store.posterminal.list(ctx.googleAuthId);
|
|
|
|
// 13. Entities (Customers)
|
|
const numEntities = counts.entities;
|
|
for (let i = 1; i <= numEntities; i++) {
|
|
const nextNum = await store.entity.peekNextNumber(ctx.googleAuthId);
|
|
await store.entity.isNumberFree(ctx.googleAuthId, nextNum);
|
|
const ent = await store.entity.create(ctx.googleAuthId, {
|
|
customergroupId: ctx.customergroups[i % ctx.customergroups.length].id,
|
|
name: `Customer Company ${i}`,
|
|
firstName: `Firstname ${i}`,
|
|
});
|
|
ctx.entities.push(ent);
|
|
|
|
// Entity Address
|
|
const addr = await store.entityaddress.create(ctx.googleAuthId, ent.id, {
|
|
addressType: 'shipping',
|
|
name: `Branch ${i}`,
|
|
street: `Main Street ${i}`,
|
|
streetNumber: `${i}`,
|
|
zip: '10115',
|
|
city: 'Berlin',
|
|
county: 'Berlin',
|
|
sort: 1,
|
|
});
|
|
await store.entityaddress.update(ctx.googleAuthId, ent.id, addr.id, {
|
|
street: `Updated Street ${i}`,
|
|
});
|
|
|
|
// Entity Contact
|
|
const contact = await store.entitycontact.create(ctx.googleAuthId, ent.id, {
|
|
contactType: 'email',
|
|
contact: `contact${i}@benchmark.test`,
|
|
sort: 1,
|
|
});
|
|
await store.entitycontact.update(ctx.googleAuthId, ent.id, contact.id, {
|
|
contact: `updated-contact${i}@benchmark.test`,
|
|
});
|
|
}
|
|
|
|
// 14. Suppliers
|
|
for (let i = 1; i <= 3; i++) {
|
|
const sup = await store.supplier.create(ctx.googleAuthId, {
|
|
name: `Supplier Express ${i}`,
|
|
});
|
|
await store.supplier.update(ctx.googleAuthId, sup.id, {
|
|
name: `Supplier Express ${i} GmbH`,
|
|
});
|
|
ctx.suppliers.push(sup);
|
|
}
|
|
await store.supplier.list(ctx.googleAuthId);
|
|
|
|
// 15. Articles
|
|
const numArticles = counts.articles;
|
|
for (let i = 1; i <= numArticles; i++) {
|
|
const targetCat = ctx.categories[i % ctx.categories.length];
|
|
const isParent = i % 4 === 1;
|
|
const art = await store.article.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: targetCat.id,
|
|
name: `Bench Article ${i}`,
|
|
});
|
|
|
|
const sku = art.sku;
|
|
ctx.articles.push(art);
|
|
|
|
// Update article details
|
|
await store.article.updateBySku(ctx.googleAuthId, sku, {
|
|
name: `Bench Article ${i} Pro`,
|
|
unitSi: 'stk',
|
|
unitamount: 1,
|
|
});
|
|
|
|
// Prices
|
|
await store.article.setPricesBySku(ctx.googleAuthId, sku, [
|
|
{ price: 10 + i * 2.5, tax: 19, minmultiplier: 1 },
|
|
{ price: 8 + i * 2.5, tax: 19, minmultiplier: 5 },
|
|
]);
|
|
|
|
// EANs
|
|
const ean = `4012345${String(i).padStart(6, '0')}`;
|
|
await store.article.setEansBySku(ctx.googleAuthId, sku, [ean]);
|
|
|
|
// Brand
|
|
await store.article.setBrandIdBySku(ctx.googleAuthId, sku, ctx.brands[i % ctx.brands.length].id);
|
|
|
|
// Weight
|
|
await store.article.setWeightBySku(ctx.googleAuthId, sku, 0.25 * i);
|
|
|
|
// Categories
|
|
await store.article.setCategoryIdsBySku(ctx.googleAuthId, sku, [
|
|
targetCat.id,
|
|
ctx.categories[(i + 1) % ctx.categories.length].id,
|
|
]);
|
|
|
|
// V/K Parent-Child hierarchy
|
|
if (isParent) {
|
|
ctx.parentArticles.push(art);
|
|
} else if (ctx.parentArticles.length > 0) {
|
|
const parentParent = ctx.parentArticles[ctx.parentArticles.length - 1];
|
|
await store.article.setParentBySku(ctx.googleAuthId, sku, parentParent.sku);
|
|
ctx.childArticles.push(art);
|
|
}
|
|
|
|
// Add image on select articles
|
|
if (i <= 3) {
|
|
const imgRes = await store.article.addImage(ctx.googleAuthId, sku, sampleImage);
|
|
ctx.sampleImageHash = imgRes.fullHash;
|
|
ctx.sampleImageThumbHash = imgRes.thumbHash;
|
|
await store.article.orderImages(ctx.googleAuthId, sku, {
|
|
fullHashes: [imgRes.fullHash],
|
|
});
|
|
}
|
|
|
|
// Article Suppliers
|
|
if (ctx.suppliers.length > 0) {
|
|
const sup = ctx.suppliers[i % ctx.suppliers.length];
|
|
const artSup = await store.articlesupplier.create(ctx.googleAuthId, sku, {
|
|
entityId: sup.id,
|
|
sku: `SUP-SKU-${i}`,
|
|
pu: 1,
|
|
stock: 100,
|
|
sort: 1,
|
|
netPrice: 7.5 + i,
|
|
taxId: ctx.company.taxrateId,
|
|
});
|
|
await store.articlesupplier.update(ctx.googleAuthId, sku, artSup.id, {
|
|
stock: 120,
|
|
pu: 2,
|
|
});
|
|
await store.articlesupplier.order(ctx.googleAuthId, sku, {
|
|
ids: [artSup.id],
|
|
});
|
|
}
|
|
}
|
|
|
|
// 16. Article Import Rows API
|
|
const importRows = [
|
|
{
|
|
sku: `IMP-${Date.now()}-1`,
|
|
name: 'Imported Keyboard Model X',
|
|
vk: 'V',
|
|
parentCategory: 'Hardware / Components / Processors',
|
|
brand: 'BenchBrand Pro',
|
|
net: '45,50',
|
|
tax: 19,
|
|
eans: [`4262557${String(Date.now()).slice(-6)}`],
|
|
},
|
|
{
|
|
sku: `IMP-${Date.now()}-2`,
|
|
name: 'Imported Keyboard Variant Black',
|
|
vk: 'K',
|
|
parentCategory: 'Hardware / Components / Processors',
|
|
brand: 'BenchBrand Pro',
|
|
net: '45,50',
|
|
tax: 19,
|
|
parentSku: `IMP-${Date.now()}-1`,
|
|
},
|
|
];
|
|
await store.article.importRows({
|
|
googleAuthId: ctx.googleAuthId,
|
|
rows: importRows,
|
|
});
|
|
|
|
// 17. Manifests: Quotes, Orders, Deliveries
|
|
const numManifests = counts.manifests;
|
|
for (let i = 1; i <= numManifests; i++) {
|
|
const ent = ctx.entities[i % ctx.entities.length];
|
|
const sup = ctx.suppliers[i % ctx.suppliers.length];
|
|
const art = ctx.articles[i % ctx.articles.length];
|
|
|
|
// Quote
|
|
const quote = await store.quote.create(ctx.googleAuthId, {
|
|
number: `QUO-${Date.now()}-${i}`,
|
|
date: new Date().toISOString(),
|
|
entityId: ent.id,
|
|
externalNumber: `EXT-Q-${i}`,
|
|
lines: [
|
|
{
|
|
sku: art.sku,
|
|
name: `Item ${art.sku}`,
|
|
amount: 2,
|
|
net: 25.0,
|
|
pu: 1,
|
|
rebate: 0,
|
|
taxrate: 19,
|
|
comment: 'Standard quote item',
|
|
},
|
|
],
|
|
});
|
|
await store.quote.update(ctx.googleAuthId, quote.id, {
|
|
externalNumber: `EXT-Q-${i}-UPDATED`,
|
|
});
|
|
ctx.quotes.push(quote);
|
|
|
|
// Order
|
|
const order = await store.order.create(ctx.googleAuthId, {
|
|
number: `ORD-${Date.now()}-${i}`,
|
|
date: new Date().toISOString(),
|
|
entityId: ent.id,
|
|
externalNumber: `EXT-O-${i}`,
|
|
lines: [
|
|
{
|
|
sku: art.sku,
|
|
name: `Item ${art.sku}`,
|
|
amount: 5,
|
|
net: 25.0,
|
|
pu: 1,
|
|
rebate: 5,
|
|
taxrate: 19,
|
|
comment: 'Expedited delivery order',
|
|
},
|
|
],
|
|
});
|
|
await store.order.update(ctx.googleAuthId, order.id, {
|
|
externalNumber: `EXT-O-${i}-CONFIRMED`,
|
|
});
|
|
ctx.orders.push(order);
|
|
|
|
// Delivery with attached files
|
|
const delivery = await store.delivery.create(ctx.googleAuthId, {
|
|
supplierId: sup.id,
|
|
externalNumber: `DEL-${Date.now()}-${i}`,
|
|
date: new Date().toISOString(),
|
|
lines: [
|
|
{
|
|
sku: art.sku,
|
|
name: `Delivery Item ${art.sku}`,
|
|
amount: 50,
|
|
net: 15.0,
|
|
pu: 1,
|
|
rebate: 0,
|
|
taxrate: 19,
|
|
comment: 'Warehouse receipt',
|
|
},
|
|
],
|
|
files: i === 1 ? [
|
|
{
|
|
name: 'packing-slip.txt',
|
|
mimetype: 'text/plain',
|
|
content: Buffer.from(`Packing slip details for delivery ${i}`),
|
|
},
|
|
] : [],
|
|
});
|
|
await store.delivery.update(ctx.googleAuthId, delivery.id, {
|
|
externalNumber: `DEL-${Date.now()}-${i}-STOCKED`,
|
|
});
|
|
ctx.deliveries.push(delivery);
|
|
}
|
|
|
|
// 18. Manifest Attachments (file storage API)
|
|
if (ctx.deliveries.length > 0) {
|
|
const primaryManifest = ctx.deliveries[0];
|
|
const attach1 = await store.manifestattachment.add(ctx.googleAuthId, primaryManifest.id, {
|
|
name: 'invoice.pdf',
|
|
mimetype: 'application/pdf',
|
|
content: Buffer.from('%PDF-1.4 ... benchmark dummy pdf content ...'),
|
|
thumbavif: sampleThumb,
|
|
thumbw: 64,
|
|
thumbh: 64,
|
|
});
|
|
const attach2 = await store.manifestattachment.add(ctx.googleAuthId, primaryManifest.id, {
|
|
name: 'quality-report.txt',
|
|
mimetype: 'text/plain',
|
|
content: Buffer.from('Quality inspection passed successfully.'),
|
|
});
|
|
const currentList = await store.manifestattachment.listByManifestId(
|
|
ctx.googleAuthId,
|
|
primaryManifest.id,
|
|
);
|
|
await store.manifestattachment.order(ctx.googleAuthId, primaryManifest.id, {
|
|
ids: currentList.map((a) => a.id).reverse(),
|
|
});
|
|
ctx.attachments.push({ manifestId: primaryManifest.id, ...attach1 });
|
|
}
|
|
|
|
return ctx;
|
|
}
|
|
|
|
/**
|
|
* Executes Phase 2: Filled Database Performance Benchmark.
|
|
* Runs read, query, search, and lookup APIs against the populated database
|
|
* over multiple iterations to measure realistic data access speeds.
|
|
*/
|
|
export async function benchmarkFilledDatabase(store, ctx, options = {}) {
|
|
const iterations = options.iterations || 5;
|
|
|
|
for (let iter = 0; iter < iterations; iter++) {
|
|
// 1. Category Tree & Articles
|
|
await store.category.getTreeForCompany(ctx.googleAuthId);
|
|
if (ctx.categories.length > 0) {
|
|
await store.category.getCategoryArticles(ctx.googleAuthId, ctx.categories[0].id);
|
|
}
|
|
|
|
// 2. Article Catalog Read APIs
|
|
await store.article.listSearchIndex(ctx.googleAuthId);
|
|
await store.article.listExport(ctx.googleAuthId);
|
|
if (ctx.categories.length > 0) {
|
|
await store.article.listExport(ctx.googleAuthId, ctx.categories[0].id);
|
|
}
|
|
|
|
// Article SKU lookups & history
|
|
if (ctx.articles.length > 0) {
|
|
const sampleSku = ctx.articles[iter % ctx.articles.length].sku;
|
|
await store.article.getBySku(ctx.googleAuthId, sampleSku);
|
|
await store.article.getHistoryBySku(ctx.googleAuthId, sampleSku);
|
|
}
|
|
|
|
// 3. Article Supplier Lookups
|
|
if (ctx.articles.length > 0) {
|
|
const sampleSku = ctx.articles[iter % ctx.articles.length].sku;
|
|
await store.articlesupplier.listByArticleSku(ctx.googleAuthId, sampleSku);
|
|
if (ctx.suppliers.length > 0) {
|
|
await store.articlesupplier.listByEntityAndSkus(ctx.googleAuthId, {
|
|
supplierId: ctx.suppliers[0].id,
|
|
skus: [sampleSku],
|
|
});
|
|
await store.articlesupplier.listBySupplierAndSkus(ctx.googleAuthId, {
|
|
supplierId: ctx.suppliers[0].id,
|
|
skus: [sampleSku],
|
|
});
|
|
}
|
|
}
|
|
|
|
// 4. Pic & Thumbnail Reads
|
|
if (ctx.sampleImageHash) {
|
|
await store.pic.getImageByHash(ctx.googleAuthId, ctx.sampleImageHash);
|
|
await store.pic.getThumbByHash(ctx.googleAuthId, ctx.sampleImageHash);
|
|
}
|
|
|
|
// 5. Entities (Customers) Lookups
|
|
await store.entity.list(ctx.googleAuthId);
|
|
if (ctx.customergroups.length > 0) {
|
|
await store.entity.list(ctx.googleAuthId, { customergroupId: ctx.customergroups[0].id });
|
|
}
|
|
if (ctx.entities.length > 0) {
|
|
const sampleEnt = ctx.entities[iter % ctx.entities.length];
|
|
await store.entity.getById(ctx.googleAuthId, sampleEnt.id);
|
|
await store.entityaddress.list(ctx.googleAuthId, sampleEnt.id);
|
|
await store.entitycontact.list(ctx.googleAuthId, sampleEnt.id);
|
|
}
|
|
|
|
// 6. Suppliers Lookups
|
|
await store.supplier.list(ctx.googleAuthId);
|
|
|
|
// 7. Manifests Lookups (Delivery, Order, Quote)
|
|
await store.delivery.list(ctx.googleAuthId);
|
|
if (ctx.deliveries.length > 0) {
|
|
const sampleDel = ctx.deliveries[iter % ctx.deliveries.length];
|
|
await store.delivery.getById(ctx.googleAuthId, sampleDel.id);
|
|
}
|
|
|
|
await store.order.list(ctx.googleAuthId);
|
|
if (ctx.orders.length > 0) {
|
|
const sampleOrd = ctx.orders[iter % ctx.orders.length];
|
|
await store.order.getById(ctx.googleAuthId, sampleOrd.id);
|
|
}
|
|
|
|
await store.quote.list(ctx.googleAuthId);
|
|
if (ctx.quotes.length > 0) {
|
|
const sampleQuo = ctx.quotes[iter % ctx.quotes.length];
|
|
await store.quote.getById(ctx.googleAuthId, sampleQuo.id);
|
|
}
|
|
|
|
// 8. Manifest Attachments
|
|
if (ctx.attachments.length > 0) {
|
|
const sampleAttach = ctx.attachments[0];
|
|
await store.manifestattachment.listByManifestId(ctx.googleAuthId, sampleAttach.manifestId);
|
|
await store.manifestattachment.getById(ctx.googleAuthId, sampleAttach.manifestId, sampleAttach.id);
|
|
}
|
|
|
|
// 9. Auth & Admin Queries
|
|
await store.google_auth.getById(ctx.googleAuthId);
|
|
await store.google_auth.getByEmail(`benchmark.admin.${ctx.googleAuthId}`); // may return undefined or auth object
|
|
await store.companysetting.list(ctx.googleAuthId);
|
|
await store.posterminal.list(ctx.googleAuthId);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Executes Phase 3: Lifecycle & Deletion APIs.
|
|
* Uses dedicated throwaway test items to exercise all delete and removal APIs
|
|
* without destroying the core benchmarked dataset.
|
|
*/
|
|
export async function testLifecycleDeletions(store, ctx) {
|
|
const sampleImage = await makeSampleImage(80, 80, { r: 180, g: 80, b: 80 });
|
|
|
|
// 1. Temporary Category with Image & Delete
|
|
const tempCat = await store.category.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: ctx.company.rootCategoryId,
|
|
name: 'Temporary Cat for Delete',
|
|
});
|
|
await store.category.addImage(ctx.googleAuthId, tempCat.id, sampleImage);
|
|
await store.category.deleteImage(ctx.googleAuthId, tempCat.id);
|
|
await store.category.delete({ googleAuthId: ctx.googleAuthId, id: tempCat.id });
|
|
|
|
// 2. Temporary Article with Image & Delete
|
|
const tempArt = await store.article.createUnderParent({
|
|
googleAuthId: ctx.googleAuthId,
|
|
parentId: ctx.categories[0].id,
|
|
name: 'Temporary Article for Delete',
|
|
});
|
|
const artImg = await store.article.addImage(ctx.googleAuthId, tempArt.sku, sampleImage);
|
|
await store.article.deleteImage(ctx.googleAuthId, tempArt.sku, artImg.fullHash);
|
|
|
|
// Article Supplier Delete
|
|
if (ctx.suppliers.length > 0) {
|
|
const tempArtSup = await store.articlesupplier.create(ctx.googleAuthId, tempArt.sku, {
|
|
entityId: ctx.suppliers[0].id,
|
|
sku: 'TEMP-SUP-SKU',
|
|
});
|
|
await store.articlesupplier.delete(ctx.googleAuthId, tempArt.sku, tempArtSup.id);
|
|
}
|
|
await store.article.delete(ctx.googleAuthId, tempArt.sku);
|
|
|
|
// 3. Manifest Attachment Remove
|
|
if (ctx.deliveries.length > 0) {
|
|
const tempAttach = await store.manifestattachment.add(ctx.googleAuthId, ctx.deliveries[0].id, {
|
|
name: 'delete-me.txt',
|
|
mimetype: 'text/plain',
|
|
content: Buffer.from('temp file to remove'),
|
|
});
|
|
await store.manifestattachment.remove(ctx.googleAuthId, ctx.deliveries[0].id, tempAttach.id);
|
|
}
|
|
|
|
// 4. Temporary Delivery, Order, Quote Delete
|
|
if (ctx.suppliers.length > 0) {
|
|
const tempDel = await store.delivery.create(ctx.googleAuthId, {
|
|
supplierId: ctx.suppliers[0].id,
|
|
date: new Date().toISOString(),
|
|
lines: [{ name: 'Temp item', amount: 1, net: 10, taxrate: 19 }],
|
|
});
|
|
await store.delivery.delete(ctx.googleAuthId, tempDel.id);
|
|
}
|
|
|
|
const tempOrd = await store.order.create(ctx.googleAuthId, {
|
|
number: `TEMP-ORD-${Date.now()}`,
|
|
date: new Date().toISOString(),
|
|
lines: [{ name: 'Temp item', amount: 1, net: 10, taxrate: 19 }],
|
|
});
|
|
await store.order.delete(ctx.googleAuthId, tempOrd.id);
|
|
|
|
const tempQuo = await store.quote.create(ctx.googleAuthId, {
|
|
number: `TEMP-QUO-${Date.now()}`,
|
|
date: new Date().toISOString(),
|
|
lines: [{ name: 'Temp item', amount: 1, net: 10, taxrate: 19 }],
|
|
});
|
|
await store.quote.delete(ctx.googleAuthId, tempQuo.id);
|
|
|
|
// 5. Temporary Entity with Contact & Address Delete
|
|
const tempEnt = await store.entity.create(ctx.googleAuthId, {
|
|
customergroupId: ctx.customergroups[0].id,
|
|
name: 'Temporary Delete Entity',
|
|
});
|
|
const tempAddr = await store.entityaddress.create(ctx.googleAuthId, tempEnt.id, {
|
|
addressType: 'billing',
|
|
street: 'Temp St',
|
|
});
|
|
await store.entityaddress.delete(ctx.googleAuthId, tempEnt.id, tempAddr.id);
|
|
|
|
const tempContact = await store.entitycontact.create(ctx.googleAuthId, tempEnt.id, {
|
|
contactType: 'phone',
|
|
contact: '+4912345678',
|
|
});
|
|
await store.entitycontact.delete(ctx.googleAuthId, tempEnt.id, tempContact.id);
|
|
await store.entity.delete(ctx.googleAuthId, tempEnt.id);
|
|
|
|
// 6. Temporary Supplier Delete
|
|
const tempSup = await store.supplier.create(ctx.googleAuthId, { name: 'Temp Sup for Delete' });
|
|
await store.supplier.delete(ctx.googleAuthId, tempSup.id);
|
|
|
|
// 7. Temporary Customergroup Delete
|
|
const tempCg = await store.customergroup.create(ctx.googleAuthId, { name: 'Temp CG Delete' });
|
|
await store.customergroup.delete(ctx.googleAuthId, tempCg.id);
|
|
|
|
// 8. Temporary Brand Delete
|
|
const tempBrand = await store.brand.upsert(ctx.googleAuthId, { name: `TempBrand-${Date.now()}` });
|
|
await store.brand.delete(ctx.googleAuthId, tempBrand.id);
|
|
|
|
// 9. Temporary Unit Delete
|
|
const tempUnitSi = `tunit-${Date.now()}`.slice(0, 15);
|
|
await store.unit.upsert(ctx.googleAuthId, {
|
|
si: tempUnitSi,
|
|
basesi: tempUnitSi,
|
|
basesifactor: 1,
|
|
symbol: 'tu',
|
|
name: 'Temp Unit',
|
|
});
|
|
await store.unit.delete(ctx.googleAuthId, tempUnitSi);
|
|
|
|
// 10. Temporary Terminal Delete
|
|
const tempTerm = await store.posterminal.upsert(ctx.googleAuthId, {
|
|
name: 'Temp Terminal Delete',
|
|
pairingpin: '9999',
|
|
});
|
|
await store.posterminal.delete(ctx.googleAuthId, tempTerm.id);
|
|
|
|
// 11. Company User Delete
|
|
if (ctx.compUserId) {
|
|
await store.companyuser.delete(ctx.compUserId);
|
|
}
|
|
|
|
// 12. Allowed Email Remove
|
|
const tempEmail = `bench.remove.${Date.now()}@example.com`;
|
|
await store.google_auth.add(tempEmail);
|
|
await store.google_auth.removeAllowedEmail(tempEmail);
|
|
|
|
// 13. Lang Delete
|
|
const tempLangId = await store.lang.create('nl');
|
|
await store.lang.delete(tempLangId);
|
|
|
|
// 14. Secondary Company Delete
|
|
if (ctx.secondaryCompany) {
|
|
await store.company.delete(ctx.secondaryCompany.id);
|
|
}
|
|
}
|