o2o-infinith-demo/scripts/sync-db-local.ts

63 lines
1.9 KiB
TypeScript

/**
* npm run db:sync
*
* Fetches all marketing_reports from Supabase and writes them to src/data/db/.
* Run this manually after SQL Editor updates if the dev server is not running.
*/
import { createClient } from '@supabase/supabase-js';
import { writeFileSync, mkdirSync, existsSync } from 'fs';
import path from 'path';
import { config } from 'dotenv';
config(); // load .env
const supabaseUrl = process.env.VITE_SUPABASE_URL!;
const key = process.env.SUPABASE_SERVICE_ROLE_KEY ?? process.env.VITE_SUPABASE_ANON_KEY!;
if (!supabaseUrl || !key) {
console.error('❌ Missing VITE_SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY in .env');
process.exit(1);
}
const supabase = createClient(supabaseUrl, key, { auth: { persistSession: false } });
const outDir = path.resolve('src/data/db');
if (!existsSync(outDir)) mkdirSync(outDir, { recursive: true });
const { data, error } = await supabase
.from('marketing_reports')
.select('id, clinic_name, url, status, report, channel_data, scrape_data, created_at, updated_at')
.order('created_at', { ascending: false });
if (error) {
console.error('❌ Supabase error:', error.message);
process.exit(1);
}
const rows = data ?? [];
for (const row of rows) {
writeFileSync(path.join(outDir, `${row.id}.json`), JSON.stringify(row, null, 2), 'utf-8');
}
// Write index
const index = rows.map((r: any) => ({
id: r.id,
clinic_name: r.clinic_name,
url: r.url,
status: r.status,
created_at: r.created_at,
gu_rating: r.channel_data?.gangnamUnni?.rating ?? null,
lead_doctor: r.report?.clinicInfo?.leadDoctor?.name ?? null,
}));
writeFileSync(path.join(outDir, '_index.json'), JSON.stringify(index, null, 2), 'utf-8');
console.log(`✅ Synced ${rows.length} report(s) → ${outDir}`);
console.table(index.map((r: any) => ({
id: r.id.slice(0, 8),
clinic: r.clinic_name,
status: r.status,
gu: r.gu_rating,
doctor: r.lead_doctor,
})));