package main import ( "context" "fmt" "os" "strings" "time" "github.com/descrybe/descrybe-v2/apps/api/internal/billing" "github.com/descrybe/descrybe-v2/apps/api/internal/config" "github.com/descrybe/descrybe-v2/apps/api/internal/processing" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgxpool" ) func main() { config.LoadDotEnv() dumpPath := strings.TrimSpace(os.Getenv("SEED_A1_MYSQL_DUMP")) if dumpPath == "" && len(os.Args) > 1 { dumpPath = os.Args[1] } if dumpPath == "" { dumpPath = processing.ResolveMySQLDumpPath("") } legacy := billing.A1LegacyCompanyID companyID := uuid.MustParse("604f23a8-b66e-4b21-8b45-0d72b68f4790") fmt.Printf("dump=%s\n", dumpPath) fmt.Printf("legacy_company=%s\n", legacy) if dumpPath != "" { f, err := os.Open(dumpPath) if err != nil { fmt.Printf("dump_open_err=%v\n", err) } else { defer f.Close() byGTIN, err := processing.ScanA1ProcessedCategories(f, legacy) if err != nil { fmt.Printf("scan_err=%v\n", err) } else { withCat := 0 for _, c := range byGTIN { if strings.TrimSpace(c) != "" && !strings.EqualFold(c, "NULL") && !strings.EqualFold(c, "none") { withCat++ } } fmt.Printf("dump_pairs=%d with_nonempty_cat=%d\n", len(byGTIN), withCat) } } } else { fmt.Println("dump=NONE") } pgURL := strings.TrimSpace(os.Getenv("DATABASE_URL")) if pgURL == "" { fmt.Println("postgres=NO_DATABASE_URL") return } ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) defer cancel() pg, err := pgxpool.New(ctx, pgURL) if err != nil { fmt.Printf("postgres_err=%v\n", err) return } defer pg.Close() var legacyDB, name string _ = pg.QueryRow(ctx, `SELECT COALESCE(legacy_company_id::text,''), name FROM companies WHERE id=$1`, companyID).Scan(&legacyDB, &name) fmt.Printf("pg_company name=%q legacy=%s\n", name, legacyDB) var rawTotal, rawWith, rawWithout int err = pg.QueryRow(ctx, ` SELECT COUNT(*), COUNT(*) FILTER (WHERE COALESCE(NULLIF(trim(mapped_data->>'category'), ''), '') <> ''), COUNT(*) FILTER (WHERE COALESCE(NULLIF(trim(mapped_data->>'category'), ''), '') = '') FROM raw_products WHERE company_id=$1`, companyID).Scan(&rawTotal, &rawWith, &rawWithout) if err != nil { fmt.Printf("raw_count_err=%v\n", err) } else { pct := 0.0 if rawTotal > 0 { pct = 100.0 * float64(rawWith) / float64(rawTotal) } fmt.Printf("pg_raw total=%d with_cat=%d without_cat=%d pct_with=%.1f\n", rawTotal, rawWith, rawWithout, pct) } var ppTotal, ppWith, ppWithout int err = pg.QueryRow(ctx, ` SELECT COUNT(*), COUNT(*) FILTER (WHERE COALESCE(NULLIF(trim(category), ''), '') <> '' AND lower(trim(category)) <> 'none'), COUNT(*) FILTER (WHERE COALESCE(NULLIF(trim(category), ''), '') = '' OR lower(trim(category)) = 'none') FROM processed_products WHERE company_id=$1`, companyID).Scan(&ppTotal, &ppWith, &ppWithout) if err != nil { fmt.Printf("pp_count_err=%v\n", err) } else { fmt.Printf("pg_processed total=%d with_cat=%d without_cat=%d\n", ppTotal, ppWith, ppWithout) } // Dry-run overlap: how many dump GTINs would fill empty mapped categories if dumpPath != "" { f2, err := os.Open(dumpPath) if err == nil { byGTIN, err := processing.ScanA1ProcessedCategories(f2, legacy) _ = f2.Close() if err == nil && len(byGTIN) > 0 { gtins := make([]string, 0, len(byGTIN)) cats := make([]string, 0, len(byGTIN)) for g, c := range byGTIN { gtins = append(gtins, g) cats = append(cats, c) } var wouldUpdate, alreadyOk, noRawMatch int err = pg.QueryRow(ctx, ` WITH dump(gtin, category) AS ( SELECT * FROM unnest($2::text[], $3::text[]) ), joined AS ( SELECT r.gtin, COALESCE(NULLIF(trim(r.mapped_data->>'category'), ''), '') AS cur, COALESCE(NULLIF(trim(d.category), ''), '') AS want FROM dump d LEFT JOIN raw_products r ON r.company_id=$1 AND r.gtin=d.gtin ) SELECT COUNT(*) FILTER (WHERE gtin IS NOT NULL AND want <> '' AND (cur = '' OR cur IS DISTINCT FROM want)), COUNT(*) FILTER (WHERE gtin IS NOT NULL AND want <> '' AND cur <> '' AND cur = want), COUNT(*) FILTER (WHERE gtin IS NULL) FROM joined `, companyID, gtins, cats).Scan(&wouldUpdate, &alreadyOk, &noRawMatch) if err != nil { fmt.Printf("dry_run_err=%v\n", err) } else { fmt.Printf("dry_run would_update_mapped=%d already_ok=%d dump_gtin_no_raw_row=%d\n", wouldUpdate, alreadyOk, noRawMatch) } } } } }