import { createClient as createCustomClient } from '@supabase/supabase-js'; import axios from 'axios'; import { config } from 'dotenv'; async function syncData() { if (process.env.NODE_ENV === 'local') { config({ path: `.env.${process.env.NODE_ENV}` }); } const baseUrl = process.env.CONNECTED_ONLINE_URL; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL; const supabaseServiceRoleKey = process.env.NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY; if (!baseUrl || !supabaseUrl || !supabaseServiceRoleKey) { throw new Error('Could not access all necessary environment variables'); } const supabase = createCustomClient(supabaseUrl, supabaseServiceRoleKey, { auth: { persistSession: false, autoRefreshToken: false, detectSessionInUrl: false, }, }); try { const response = await axios.post( `${baseUrl}/Search_Load`, { headers: { 'Content-Type': 'application/json; charset=utf-8', }, param: "{'Value':'|et|-1'}", // get all available services in Estonian }, ); const responseData: { Value: any; Data: any; ErrorCode: number; ErrorMessage: string; } = 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', }); } const clinics = responseData.Data.T_Lic; const services = responseData.Data.T_Service; 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, code: service.Code, description: service.Description || null, display: service.Display, duration: service.Duration, has_free_codes: !!service.HasFreeCodes, name: service.Name, neto_duration: service.NetoDuration, online_hide_duration: service.OnlineHideDuration, online_hide_price: service.OnlineHidePrice, price: service.Price, price_periods: service.PricePeriods || null, requires_payment: !!service.RequiresPayment, sync_id: service.SyncID, }; }); const { error: providersError } = await supabase .from('connected_online_providers') .upsert(mappedClinics); const { error: servicesError } = await supabase .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)}`, ); } } syncData();