import PocketBase from 'pocketbase' import { POCKETBASE_URL, PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD } from './pocketbase-config.js' const COLLECTION = 'travellers' const VACCINE_RECORDS_COLLECTION = 'records' const VACCINES_COLLECTION = 'vaccines' function parseVaccineRecord(r) { return { id: r.id, travellerId: r.traveller_id ?? r.traveller ?? '', travellerName: r.traveller_name ?? '', emrID: r.emr_id ?? '', timelines: r.timelines ?? r.vaccine_timelines ?? [], created: r.created, updated: r.updated, } } /** * Fetches all records from the vaccines collection. * Returns raw records with all fields preserved. */ export async function fetchVaccines() { await ensureAuth() const list = await getClient().collection(VACCINES_COLLECTION).getFullList({ sort: 'name' }) return list.map((r) => ({ id: r.id, name: r.name ?? '', vaccine_type: r.vaccine_type ?? '', total_doses: r.total_doses ?? 1, dose_intervals: r.dose_intervals ?? [], min_days_before_travel: r.min_days_before_travel ?? 0, allows_grace_period: r.allows_grace_period ?? false, has_accelerated_schedule: r.has_accelerated_schedule ?? false, requires_icvp_certificate: r.requires_icvp_certificate ?? false, created: r.created, updated: r.updated, })) } export async function fetchVaccineRecords() { await ensureAuth() const list = await getClient().collection(VACCINE_RECORDS_COLLECTION).getFullList({ sort: '-created' }) return list.map(parseVaccineRecord) } export async function saveVaccineRecord(data) { await ensureAuth() const client = getClient() const travellerId = data.traveller_id let existing = null try { const list = await client.collection(VACCINE_RECORDS_COLLECTION).getList(1, 50, { filter: `traveller_id = "${travellerId}"` }) if (list.items && list.items.length > 0) { existing = list.items[0] } } catch (e) { // ignore filter error } const payload = { traveller_id: travellerId, traveller_name: data.travellerName || data.traveller_name || '', emr_id: data.emrID || data.emr_id || null, timelines: data.timelines || data.vaccineTimelines || data.vaccine_timelines || [], } if (existing) { const record = await client.collection(VACCINE_RECORDS_COLLECTION).update(existing.id, payload) return parseVaccineRecord(record) } else { const record = await client.collection(VACCINE_RECORDS_COLLECTION).create(payload) return parseVaccineRecord(record) } } export async function updateVaccineRecord(id, data) { await ensureAuth() const travellerId = data.traveller_id const payload = { traveller_id: travellerId, traveller_name: data.travellerName || data.traveller_name || '', emr_id: data.emrID || data.emr_id || null, timelines: data.timelines || data.vaccineTimelines || data.vaccine_timelines || [], } const record = await getClient().collection(VACCINE_RECORDS_COLLECTION).update(id, payload) return parseVaccineRecord(record) } let pb = null let authPromise = null function getClient() { if (!pb) { pb = new PocketBase(POCKETBASE_URL) // Main process may receive overlapping IPC calls (e.g. React Strict Mode). // Default auto-cancel would abort duplicate in-flight PocketBase requests. pb.autoCancellation(false) } return pb } function parseEntry(r) { return { id: r.id, recordID: r.record_id ?? r.recordID ?? '', emrID: r.emr_id ?? '', name: r.name ?? '', location: r.location ?? '', countryISO: r.country_iso ?? '', countriesISO: r.countries_iso ?? [], status: r.status ?? '', departure: r.departure ?? '', arrival: r.arrival ?? '', created: r.created, updated: r.updated, } } export async function ensureAuth() { const client = getClient() if (client.authStore.isValid) return if (authPromise) { await authPromise return } // PocketBase v0.23+ removed /api/admins/*; superusers authenticate as a collection. authPromise = client .collection('_superusers') .authWithPassword(PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD) try { await authPromise } catch (err) { authPromise = null throw err } } export async function fetchEntries() { await ensureAuth() const list = await getClient().collection(COLLECTION).getFullList({ sort: '-created' }) return list.map(parseEntry) } export async function createEntry(trip) { await ensureAuth() const payload = { name: trip.name, location: trip.location, countries_iso: trip.countriesISO, departure: trip.departure, arrival: trip.arrival, } if (trip.status !== undefined) { payload.status = trip.status } if (trip.recordID || trip.record_id) { payload.record_id = trip.recordID || trip.record_id } if (trip.emrID !== undefined && trip.emrID !== null && trip.emrID !== '') { const emrNum = Number(trip.emrID) payload.emr_id = !isNaN(emrNum) ? emrNum : trip.emrID } const record = await getClient().collection(COLLECTION).create(payload) return parseEntry(record) } export async function updateEntry(id, trip) { await ensureAuth() const payload = { name: trip.name, location: trip.location, countries_iso: trip.countriesISO, departure: trip.departure, arrival: trip.arrival, } if (trip.status !== undefined) { payload.status = trip.status } if (trip.recordID !== undefined || trip.record_id !== undefined) { payload.record_id = trip.recordID || trip.record_id || null } if (trip.emrID !== undefined && trip.emrID !== null && trip.emrID !== '') { const emrNum = Number(trip.emrID) payload.emr_id = !isNaN(emrNum) ? emrNum : trip.emrID } else if (trip.emrID === '') { payload.emr_id = null } const record = await getClient().collection(COLLECTION).update(id, payload) return parseEntry(record) } export async function deleteEntry(id) { await ensureAuth() await getClient().collection(COLLECTION).delete(id) }