← back to Sister Parish Onboarding

scripts/load_pg.sh

95 lines

#!/bin/zsh
# Load Sister Parish normalized data into dw_unified via local socket (peer auth).
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"

psql dw_unified <<'SQL'
CREATE TABLE IF NOT EXISTS sisterparish_catalog (
  sp_product_id BIGINT PRIMARY KEY,
  handle TEXT NOT NULL,
  title TEXT NOT NULL,
  vendor TEXT NOT NULL DEFAULT 'Sister Parish',
  product_type TEXT,
  tags TEXT[],
  body_html TEXT,
  source_url TEXT,
  primary_image TEXT,
  images JSONB,
  variants JSONB,
  has_sample BOOLEAN,
  has_bolt BOOLEAN,
  has_image BOOLEAN,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_sp_handle ON sisterparish_catalog(handle);
CREATE INDEX IF NOT EXISTS idx_sp_type   ON sisterparish_catalog(product_type);
SQL

# Stream normalized.json rows into a TEMP staging table, then upsert.
node -e '
const fs = require("fs");
const rows = JSON.parse(fs.readFileSync("output/normalized.json","utf8"));
process.stdout.write("BEGIN;\n");
process.stdout.write("CREATE TEMP TABLE sp_stage (j JSONB);\n");
for (const r of rows) {
  const esc = JSON.stringify(r).replace(/\x27/g,"\x27\x27");
  process.stdout.write(`INSERT INTO sp_stage(j) VALUES (\x27${esc}\x27::jsonb);\n`);
}
process.stdout.write(`
INSERT INTO sisterparish_catalog
  (sp_product_id, handle, title, vendor, product_type, tags, body_html, source_url,
   primary_image, images, variants, has_sample, has_bolt, has_image)
SELECT
  (j->>\x27sp_product_id\x27)::bigint,
  j->>\x27handle\x27,
  j->>\x27title\x27,
  COALESCE(j->>\x27vendor\x27, \x27Sister Parish\x27),
  j->>\x27product_type\x27,
  ARRAY(SELECT jsonb_array_elements_text(j->\x27tags\x27)),
  j->>\x27body_html\x27,
  j->>\x27url\x27,
  j->>\x27primary_image\x27,
  j->\x27images\x27,
  j->\x27variants\x27,
  (j->>\x27has_sample\x27)::bool,
  (j->>\x27has_bolt\x27)::bool,
  (j->>\x27has_image\x27)::bool
FROM sp_stage
ON CONFLICT (sp_product_id) DO UPDATE SET
  title=EXCLUDED.title,
  tags=EXCLUDED.tags,
  body_html=EXCLUDED.body_html,
  primary_image=EXCLUDED.primary_image,
  images=EXCLUDED.images,
  variants=EXCLUDED.variants,
  has_sample=EXCLUDED.has_sample,
  has_bolt=EXCLUDED.has_bolt,
  has_image=EXCLUDED.has_image,
  updated_at=NOW();
COMMIT;
\\echo
\\echo === counts ===
SELECT COUNT(*) AS row_count FROM sisterparish_catalog;
\\echo
\\echo === price tier (vendor retail, first variant) ===
SELECT
  CASE
    WHEN (variants->0->>\x27vendor_retail\x27)::numeric < 100 THEN \x27A: <\$100\x27
    WHEN (variants->0->>\x27vendor_retail\x27)::numeric < 300 THEN \x27B: \$100-\$299\x27
    WHEN (variants->0->>\x27vendor_retail\x27)::numeric < 500 THEN \x27C: \$300-\$499\x27
    WHEN (variants->0->>\x27vendor_retail\x27)::numeric < 700 THEN \x27D: \$500-\$699\x27
    ELSE \x27E: \$700+\x27
  END AS tier,
  COUNT(*) AS n
FROM sisterparish_catalog GROUP BY 1 ORDER BY 1;
\\echo
\\echo === DW markup spot-check (5 random) ===
SELECT title,
       (variants->0->>\x27vendor_retail\x27)::numeric AS vendor_retail,
       (variants->0->>\x27dw_retail\x27)::numeric AS dw_retail
FROM sisterparish_catalog ORDER BY random() LIMIT 5;
`);
' | psql dw_unified