JEISA-WEBAPP/setup-users.js
Dave 2b56053e1c fix(po): stop PocketBase auto-cancellation from killing PO creation
The Purchase Order form never reached the server. Creating a PO with two
or more "Manual Entry" rows fired N parallel POSTs to
/api/collections/stock_items/records via Promise.all. The PocketBase JS
SDK auto-cancels any in-flight request whose method + path match a newer
one, so the first POST was aborted with:

  ClientResponseError 0: The request was autocancelled.

Promise.all then rejected before the PO create ever ran, so the PO was
never created - only an orphan stock item per attempt. Confirmed against
the production PB logs: two stock_items POSTs today, zero
purchase_orders POSTs, and two orphan stock_items rows with no PO.

Fixes:
- src/lib/pocketbase.ts: pb.autoCancellation(false) on the browser
  client. Every server-side client in this repo already did this
  (scripts/*.mjs, server/po-api.mjs) - the browser client was the one
  place it was missing.
- PurchaseOrderForm: resolve rows sequentially instead of Promise.all,
  and build the snapshot in the same pass so manual rows carry the real
  stock item id instead of "".
- PurchaseOrderForm: disable the submit button while submitting, so a
  double click cannot create two POs.
- PurchaseOrderForm: compare SKUs trimmed, so a stray trailing space
  does not create a duplicate stock item.
- po-photo-ingest.mjs, jei_skill.ts, setup-users.js: same
  autoCancellation(false) guard.
2026-10-22 07:56:30 +02:00

104 lines
3.1 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import PocketBase from 'pocketbase';
const pb = new PocketBase(process.env.VITE_PB_URL || 'http://127.0.0.1:8090');
// Never let the SDK auto-cancel a request (see src/lib/pocketbase.ts).
pb.autoCancellation(false);
async function ensureUsersCollection() {
try {
// If it exists, this will succeed
await pb.collections.getOne('users');
console.log('ℹ️ Users collection already exists');
return;
} catch (_) {
// Try create if not exists
try {
const usersCollection = await pb.collections.create({
name: 'users',
type: 'auth',
schema: [
{ name: 'name', type: 'text', required: false, options: { max: 100 } },
{ name: 'role', type: 'select', required: false, options: { maxSelect: 1, values: ['admin', 'manager', 'employee'] } },
{ name: 'active', type: 'bool', required: false },
],
// keep open for setup; tighten later in UI
listRule: null,
viewRule: null,
createRule: null,
updateRule: null,
deleteRule: null,
});
console.log('✅ Users collection created:', usersCollection.name);
} catch (err) {
console.error('❌ Error creating users collection:', err?.message || err);
}
}
}
async function ensureUser(email, data) {
try {
const existing = await pb.collection('users').getFirstListItem(`email = "${email}"`);
if (existing) {
console.log(`ℹ️ User already exists: ${email}`);
return existing;
}
} catch (_) {
// not found -> proceed to create
}
try {
const record = await pb.collection('users').create(data);
console.log(`✅ Created user: ${email}`);
return record;
} catch (err) {
// Double-check if created despite error
try {
const created = await pb.collection('users').getFirstListItem(`email = "${email}"`);
if (created) {
console.log(`✅ User is present after error (treated as success): ${email}`);
return created;
}
} catch (_) {}
console.error(`❌ Error creating user ${email}:`, err?.message || err);
throw err;
}
}
async function setupDemoUser() {
try {
console.log('🔐 Setting up demo user...');
// First authenticate as admin
await pb.admins.authWithPassword('david@wfsales.co.za', '1234567890');
console.log('✅ Admin authenticated');
await ensureUsersCollection();
await ensureUser('admin@jei.com', {
email: 'admin@jei.com',
password: 'password123',
passwordConfirm: 'password123',
name: 'Admin User',
role: 'admin',
active: true,
});
await ensureUser('manager@jei.com', {
email: 'manager@jei.com',
password: 'password123',
passwordConfirm: 'password123',
name: 'Manager User',
role: 'manager',
active: true,
});
console.log('\n🎉 Setup complete! You can now login with:');
console.log('Admin: admin@jei.com / password123');
console.log('Manager: manager@jei.com / password123');
} catch (error) {
console.error('❌ Setup failed:', error.message);
}
}
setupDemoUser();