// One-shot seed script — creates the demo depots, an owner user, and a // starter truck. Safe to re-run (idempotent on natural keys). // // Run with: PB_ADMIN_TOKEN=... node scripts/seed.mjs import PocketBase from 'pocketbase'; const PB_URL = process.env.PB_URL || 'http://pocketbase-zinlbpsext2ro0lgb2558vfy.169.239.180.130.sslip.io'; const PB_ADMIN_TOKEN = process.env.PB_ADMIN_TOKEN; if (!PB_ADMIN_TOKEN) { console.error('PB_ADMIN_TOKEN required'); process.exit(1); } const pb = new PocketBase(PB_URL); pb.authStore.save(PB_ADMIN_TOKEN, null); async function upsertByFilter(collectionName, filter, data) { const existing = await pb.collection(collectionName).getFirstListItem(filter).catch(() => null); if (existing) { console.log(` ↻ ${collectionName} matched (${existing.id}) — updating`); return pb.collection(collectionName).update(existing.id, data); } console.log(` + ${collectionName} creating`); return pb.collection(collectionName).create(data); } console.log('Seeding depots…'); // Two demo depots near Carletonville, South Africa. The name is the // long-standing "Lumelela" / "Fanie Plot" (operator-owned sites near // the West Wits gold mines). Coordinates are real WGS84 locations so // the depot map on the dashboard plots the right spots — even though // the addresses are informal, the lat/lng is the truth on the map. const lumelela = await upsertByFilter('dd_depots', 'code = "LUM"', { name: 'Lumelela Depot', code: 'LUM', capacity_litres: 23000, // 23,000 L bowser current_balance_litres: 0, address: 'Lumelela site, Carletonville area', // Mponeng Gold Mine area, just south of Carletonville CBD latitude: -26.4139, longitude: 27.4086, is_active: true, }); const faniePlot = await upsertByFilter('dd_depots', 'code = "FAN"', { name: 'Fanie Plot', code: 'FAN', capacity_litres: 23000, current_balance_litres: 0, address: 'Fanie Plot, Carletonville area', // Watersedge Small Holdings, east of Carletonville latitude: -26.3650, longitude: 27.4350, is_active: true, }); console.log('Seeding owner user…'); const OWNER_EMAIL = 'owner@dieseldepot.local'; const OWNER_PASSWORD = 'changeme'; // first-run password — user must change on first login let owner; try { owner = await pb.collection('dd_users').getFirstListItem(`email = "${OWNER_EMAIL}"`); console.log(` ↻ owner user exists (${owner.id}) — updating role/active flag`); owner = await pb.collection('dd_users').update(owner.id, { name: 'Owner', role: 'owner', is_active: true, }); } catch { owner = await pb.collection('dd_users').create({ email: OWNER_EMAIL, password: OWNER_PASSWORD, passwordConfirm: OWNER_PASSWORD, name: 'Owner', role: 'owner', is_active: true, }); console.log(` + owner user created (${owner.id}) — email: ${OWNER_EMAIL}, password: ${OWNER_PASSWORD}`); } console.log('Seeding starter truck…'); const truck = await upsertByFilter('dd_trucks', 'registration = "TBD-0001"', { registration: 'TBD-0001', description: 'Starter truck — rename once fleet registration is known', capacity_litres: 10000, current_balance_litres: 0, current_km: 0, home_depot: lumelela.id, is_active: true, }); console.log('\n✅ Seed complete.'); console.log(' Depots:', lumelela.id, faniePlot.id); console.log(' Owner user:', owner.id, '—', OWNER_EMAIL, '/', OWNER_PASSWORD); console.log(' Truck:', truck.id);