import axios from 'axios'; import { getSupabaseServerAdminClient } from '@kit/supabase/server-admin-client'; import type { ISearchLoadResponse } from '~/lib/types/connected-online'; export default async function syncConnectedOnline() { const isProd = process.env.NODE_ENV === 'production'; const baseUrl = process.env.CONNECTED_ONLINE_URL; if (!baseUrl) { throw new Error('Could not access all necessary environment variables'); } const supabase = getSupabaseServerAdminClient(); try { const response = await axios.post<{ d: string }>(`${baseUrl}/Search_Load`, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, param: "{'Value':'|et|-1'}", // get all available services in Estonian }); const responseData: ISearchLoadResponse = JSON.parse(response.data.d); if (responseData?.ErrorCode !== 0) { throw new Error('Failed to get Connected Online data'); } if ( !responseData.Data.T_Lic?.length || !responseData.Data.T_Service?.length ) { return supabase.schema('audit').from('sync_entries').insert({ operation: 'CONNECTED_ONLINE_SYNC', comment: 'No clinic or service data received', status: 'FAIL', changed_by_role: 'service_role', }); } let clinics; let services; // Filter out "Dentas Demo OÜ" in prod or only sync "Dentas Demo OÜ" in any other environment if (isProd) { clinics = responseData.Data.T_Lic.filter((clinic) => clinic.ID !== 2); services = responseData.Data.T_Service.filter( (service) => service.ClinicID !== 2, ); } else { clinics = responseData.Data.T_Lic.filter((clinic) => clinic.ID === 2); services = responseData.Data.T_Service.filter( (service) => service.ClinicID === 2, ); } const mappedClinics = clinics.map((clinic) => { return { id: clinic.ID, can_select_worker: !!clinic.OnlineCanSelectWorker, email: clinic.Email || null, name: clinic.Name, personal_code_required: !!clinic.PersonalCodeRequired, phone_number: clinic.Phone || null, }; }); const mappedServices = services.map((service) => { return { id: service.ID, clinic_id: service.ClinicID, sync_id: service.SyncID, name: service.Name, description: service.Description || null, price: service.Price, requires_payment: !!service.RequiresPayment, duration: service.Duration, neto_duration: service.NetoDuration, display: service.Display, price_periods: service.PricePeriods || null, online_hide_duration: service.OnlineHideDuration, online_hide_price: service.OnlineHidePrice, code: service.Code, has_free_codes: !!service.HasFreeCodes, }; }); const { error: providersError } = await supabase .schema('medreport') .from('connected_online_providers') .upsert(mappedClinics); const { error: servicesError } = await supabase .schema('medreport') .from('connected_online_services') .upsert(mappedServices, { onConflict: 'id', ignoreDuplicates: false }); if (providersError || servicesError) { return supabase .schema('audit') .from('sync_entries') .insert({ operation: 'CONNECTED_ONLINE_SYNC', comment: providersError ? 'Error saving providers: ' + JSON.stringify(providersError) : 'Error saving services: ' + JSON.stringify(servicesError), status: 'FAIL', changed_by_role: 'service_role', }); } await supabase.schema('audit').from('sync_entries').insert({ operation: 'CONNECTED_ONLINE_SYNC', status: 'SUCCESS', changed_by_role: 'service_role', }); } catch (e) { await supabase .schema('audit') .from('sync_entries') .insert({ operation: 'CONNECTED_ONLINE_SYNC', status: 'FAIL', comment: JSON.stringify(e), changed_by_role: 'service_role', }); throw new Error( `Failed to sync Connected Online data, error: ${JSON.stringify(e)}`, ); } }