Kaynağa Gözat

remove scripts

Bernt Christian Egeland 6 ay önce
ebeveyn
işleme
1504d99b81
2 değiştirilmiş dosya ile 0 ekleme ve 292 silme
  1. 0 83
      scripts/migrate-to-multi-tenant.ts
  2. 0 209
      scripts/migrate-uploads.ts

+ 0 - 83
scripts/migrate-to-multi-tenant.ts

@@ -1,83 +0,0 @@
-/**
- * One-time migration script: backfill organizationId on all business entities.
- *
- * Run AFTER the first `prisma db push` (with organizationId as optional String?).
- * Run BEFORE the second `prisma db push` (making organizationId required String).
- *
- * Usage:
- *   npx tsx scripts/migrate-to-multi-tenant.ts
- */
-
-import { PrismaClient } from "@prisma/client";
-
-const db = new PrismaClient();
-
-async function main() {
-  const users = await db.user.findMany({ select: { id: true, name: true } });
-  console.log(`Found ${users.length} users to migrate.\n`);
-
-  for (const user of users) {
-    // Check if user already has an org membership
-    const existing = await db.organizationMember.findFirst({
-      where: { userId: user.id },
-    });
-
-    let orgId: string;
-
-    if (existing) {
-      orgId = existing.organizationId;
-      console.log(`User "${user.name}" already has org ${orgId}`);
-    } else {
-      // Create org and membership
-      const org = await db.organization.create({
-        data: { name: `${user.name}'s Workshop` },
-      });
-      await db.organizationMember.create({
-        data: { userId: user.id, organizationId: org.id, role: "owner" },
-      });
-      orgId = org.id;
-      console.log(`Created org "${org.name}" (${orgId}) for user "${user.name}"`);
-    }
-
-    // Backfill organizationId on all entities owned by this user
-    const results = await Promise.all([
-      db.vehicle.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-      db.customer.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-      db.quote.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-      db.inventoryPart.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-      db.customFieldDefinition.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-      db.appSetting.updateMany({
-        where: { userId: user.id, organizationId: null },
-        data: { organizationId: orgId },
-      }),
-    ]);
-
-    const labels = ["vehicles", "customers", "quotes", "inventory", "customFields", "settings"];
-    const counts = results.map((r, i) => `${labels[i]}: ${r.count}`).join(", ");
-    console.log(`  Backfilled: ${counts}\n`);
-  }
-
-  console.log("Migration complete!");
-}
-
-main()
-  .catch((e) => {
-    console.error("Migration failed:", e);
-    process.exit(1);
-  })
-  .finally(() => db.$disconnect());

+ 0 - 209
scripts/migrate-uploads.ts

@@ -1,209 +0,0 @@
-/**
- * Migration script: Move uploads from public/uploads/ to data/uploads/[orgId]/
- * and update all database references.
- *
- * This script:
- * 1. For each organization, creates data/uploads/[orgId]/vehicles|inventory|services|logos/
- * 2. Copies files from public/uploads/[category]/ to the correct org directory
- * 3. Updates imageUrl/fileUrl in the database from /uploads/[category]/file
- *    to /api/files/[orgId]/[category]/file
- * 4. Updates AppSetting logo URLs
- *
- * Usage:
- *   npx tsx scripts/migrate-uploads.ts
- *
- * Run this AFTER deploying the new code. The resolveUploadPath helper supports
- * both old and new URL formats, so the app works during the transition.
- */
-
-import { PrismaClient } from "@prisma/client";
-import { copyFile, mkdir, stat } from "fs/promises";
-import path from "path";
-
-const db = new PrismaClient();
-
-const PUBLIC_UPLOADS = path.join(process.cwd(), "public", "uploads");
-const DATA_UPLOADS = path.join(process.cwd(), "data", "uploads");
-
-function parseOldUrl(url: string): { category: string; filename: string } | null {
-  // Match /uploads/category/filename
-  const match = url.match(/^\/uploads\/([^/]+)\/([^/]+)$/);
-  if (!match) return null;
-  return { category: match[1], filename: match[2] };
-}
-
-async function fileExists(filePath: string): Promise<boolean> {
-  try {
-    await stat(filePath);
-    return true;
-  } catch {
-    return false;
-  }
-}
-
-async function main() {
-  console.log("Starting upload migration...\n");
-
-  // Get all organizations
-  const orgs = await db.organization.findMany({ select: { id: true, name: true } });
-  console.log(`Found ${orgs.length} organizations.\n`);
-
-  // Create directories for each org
-  for (const org of orgs) {
-    for (const category of ["vehicles", "inventory", "services", "logos"]) {
-      await mkdir(path.join(DATA_UPLOADS, org.id, category), { recursive: true });
-    }
-  }
-
-  let totalMigrated = 0;
-  let totalSkipped = 0;
-
-  // 1. Migrate Vehicle images
-  console.log("--- Migrating vehicle images ---");
-  const vehicles = await db.vehicle.findMany({
-    where: { imageUrl: { not: null } },
-    select: { id: true, imageUrl: true, organizationId: true },
-  });
-
-  for (const v of vehicles) {
-    if (!v.imageUrl || v.imageUrl.startsWith("/api/files/") || !v.organizationId) continue;
-    const parsed = parseOldUrl(v.imageUrl);
-    if (!parsed) {
-      console.log(`  [skip] Vehicle ${v.id}: unrecognized URL "${v.imageUrl}"`);
-      totalSkipped++;
-      continue;
-    }
-
-    const orgId = v.organizationId;
-    const src = path.join(PUBLIC_UPLOADS, parsed.category, parsed.filename);
-    const dst = path.join(DATA_UPLOADS, orgId, "vehicles", parsed.filename);
-    const newUrl = `/api/files/${orgId}/vehicles/${parsed.filename}`;
-
-    if (await fileExists(src)) {
-      await copyFile(src, dst);
-      await db.vehicle.update({ where: { id: v.id }, data: { imageUrl: newUrl } });
-      console.log(`  [ok] Vehicle ${v.id}: ${v.imageUrl} -> ${newUrl}`);
-      totalMigrated++;
-    } else {
-      console.log(`  [missing] Vehicle ${v.id}: source file not found "${src}"`);
-      // Update URL anyway so it points to the new path format
-      await db.vehicle.update({ where: { id: v.id }, data: { imageUrl: newUrl } });
-      totalSkipped++;
-    }
-  }
-
-  // 2. Migrate ServiceAttachment files
-  console.log("\n--- Migrating service attachments ---");
-  const attachments = await db.serviceAttachment.findMany({
-    select: {
-      id: true,
-      fileUrl: true,
-      serviceRecord: {
-        select: { vehicle: { select: { organizationId: true } } },
-      },
-    },
-  });
-
-  for (const att of attachments) {
-    if (att.fileUrl.startsWith("/api/files/")) continue;
-    const parsed = parseOldUrl(att.fileUrl);
-    if (!parsed) {
-      console.log(`  [skip] Attachment ${att.id}: unrecognized URL "${att.fileUrl}"`);
-      totalSkipped++;
-      continue;
-    }
-
-    const orgId = att.serviceRecord.vehicle.organizationId;
-    if (!orgId) continue;
-    const src = path.join(PUBLIC_UPLOADS, parsed.category, parsed.filename);
-    const dst = path.join(DATA_UPLOADS, orgId, "services", parsed.filename);
-    const newUrl = `/api/files/${orgId}/services/${parsed.filename}`;
-
-    if (await fileExists(src)) {
-      await copyFile(src, dst);
-      await db.serviceAttachment.update({ where: { id: att.id }, data: { fileUrl: newUrl } });
-      console.log(`  [ok] Attachment ${att.id}: ${att.fileUrl} -> ${newUrl}`);
-      totalMigrated++;
-    } else {
-      console.log(`  [missing] Attachment ${att.id}: source file not found "${src}"`);
-      await db.serviceAttachment.update({ where: { id: att.id }, data: { fileUrl: newUrl } });
-      totalSkipped++;
-    }
-  }
-
-  // 3. Migrate InventoryPart images
-  console.log("\n--- Migrating inventory images ---");
-  const parts = await db.inventoryPart.findMany({
-    where: { imageUrl: { not: null } },
-    select: { id: true, imageUrl: true, organizationId: true },
-  });
-
-  for (const p of parts) {
-    if (!p.imageUrl || p.imageUrl.startsWith("/api/files/") || !p.organizationId) continue;
-    const parsed = parseOldUrl(p.imageUrl);
-    if (!parsed) {
-      console.log(`  [skip] Part ${p.id}: unrecognized URL "${p.imageUrl}"`);
-      totalSkipped++;
-      continue;
-    }
-
-    const orgId = p.organizationId;
-    const src = path.join(PUBLIC_UPLOADS, parsed.category, parsed.filename);
-    const dst = path.join(DATA_UPLOADS, orgId, "inventory", parsed.filename);
-    const newUrl = `/api/files/${orgId}/inventory/${parsed.filename}`;
-
-    if (await fileExists(src)) {
-      await copyFile(src, dst);
-      await db.inventoryPart.update({ where: { id: p.id }, data: { imageUrl: newUrl } });
-      console.log(`  [ok] Part ${p.id}: ${p.imageUrl} -> ${newUrl}`);
-      totalMigrated++;
-    } else {
-      console.log(`  [missing] Part ${p.id}: source file not found "${src}"`);
-      await db.inventoryPart.update({ where: { id: p.id }, data: { imageUrl: newUrl } });
-      totalSkipped++;
-    }
-  }
-
-  // 4. Migrate AppSetting logos
-  console.log("\n--- Migrating logo settings ---");
-  const logos = await db.appSetting.findMany({
-    where: { key: "workshop.logo" },
-    select: { id: true, value: true, organizationId: true },
-  });
-
-  for (const logo of logos) {
-    if (logo.value.startsWith("/api/files/") || !logo.organizationId) continue;
-    const parsed = parseOldUrl(logo.value);
-    if (!parsed) {
-      console.log(`  [skip] Logo setting ${logo.id}: unrecognized URL "${logo.value}"`);
-      totalSkipped++;
-      continue;
-    }
-
-    const orgId = logo.organizationId;
-    const src = path.join(PUBLIC_UPLOADS, parsed.category, parsed.filename);
-    const dst = path.join(DATA_UPLOADS, orgId, "logos", parsed.filename);
-    const newUrl = `/api/files/${orgId}/logos/${parsed.filename}`;
-
-    if (await fileExists(src)) {
-      await copyFile(src, dst);
-      await db.appSetting.update({ where: { id: logo.id }, data: { value: newUrl } });
-      console.log(`  [ok] Logo ${logo.id}: ${logo.value} -> ${newUrl}`);
-      totalMigrated++;
-    } else {
-      console.log(`  [missing] Logo ${logo.id}: source file not found "${src}"`);
-      await db.appSetting.update({ where: { id: logo.id }, data: { value: newUrl } });
-      totalSkipped++;
-    }
-  }
-
-  console.log(`\nMigration complete! Migrated: ${totalMigrated}, Skipped: ${totalSkipped}`);
-  console.log("\nYou can now safely remove public/uploads/ after verifying everything works.");
-}
-
-main()
-  .catch((e) => {
-    console.error("Migration failed:", e);
-    process.exit(1);
-  })
-  .finally(() => db.$disconnect());