diff --git a/scripts/seed-insurer-reports-fixtures.ts b/scripts/seed-insurer-reports-fixtures.ts index 7659bef..58a2d29 100644 --- a/scripts/seed-insurer-reports-fixtures.ts +++ b/scripts/seed-insurer-reports-fixtures.ts @@ -22,6 +22,8 @@ * SEED_REPORTS_TAG=reports-load-v1 * SEED_REPORTS_PUBLIC_PREFIX=RPT1 * SEED_REPORTS_DEFAULT_PASSWORD=Reports@724 + * SEED_REPORTS_PURGE_ONLY=true # remove seeded data; do not insert it again + * SEED_REPORTS_PURGE_ALL=true # with PURGE_ONLY, remove every reports seed tag */ import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; @@ -652,24 +654,31 @@ function randNationalBase(prefix: string): string { return n.padEnd(6, "7"); } -async function purgeSeedPortfolio(db: mongoose.mongo.Db, seedTag: string) { +async function purgeSeedPortfolio( + db: mongoose.mongo.Db, + seedTag?: string, +) { const blameCases = db.collection("blameCases"); const claimCases = db.collection("claimCases"); const expertFileActivities = db.collection("expertFileActivities"); + const fixtureFilter = { + "seedMeta.script": SCRIPT_NAME, + ...(seedTag ? { "seedMeta.tag": seedTag } : {}), + }; const [existingBlames, existingClaims] = await Promise.all([ - blameCases.find({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, { projection: { _id: 1 } }).toArray(), - claimCases.find({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, { projection: { _id: 1 } }).toArray(), + blameCases.find(fixtureFilter, { projection: { _id: 1 } }).toArray(), + claimCases.find(fixtureFilter, { projection: { _id: 1 } }).toArray(), ]); const fileIds = [...existingBlames, ...existingClaims].map((d) => asObjectId(d._id)); const [deletedBlames, deletedClaims, deletedActivities] = await Promise.all([ - blameCases.deleteMany({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }), - claimCases.deleteMany({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }), + blameCases.deleteMany(fixtureFilter), + claimCases.deleteMany(fixtureFilter), expertFileActivities.deleteMany({ $or: [ - { "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, + fixtureFilter, ...(fileIds.length ? [{ fileId: { $in: fileIds } }] : []), ], }), @@ -682,6 +691,32 @@ async function purgeSeedPortfolio(db: mongoose.mongo.Db, seedTag: string) { }; } +/** + * The portfolio seed creates a shared synthetic roster and three report-only + * branches. Remove those too once no fixture portfolio remains, so a purge + * actually returns the insurer tenant to its pre-fixture state. + */ +async function purgeSeedSupportData(db: mongoose.mongo.Db) { + const collectionNames = [ + "branches", + "expert", + "damage-expert", + "field-expert", + "file-maker", + "file-reviewer", + "call-center-agents", + ]; + const deleted = await Promise.all( + collectionNames.map(async (collectionName) => { + const result = await db + .collection(collectionName) + .deleteMany({ "seedMeta.script": SCRIPT_NAME }); + return [collectionName, result.deletedCount ?? 0] as const; + }), + ); + return Object.fromEntries(deleted); +} + function scaleBucketCounts(total: number): Record { const keys = Object.keys(BUCKET_WEIGHTS) as UnifiedBucket[]; const raw = keys.map((key) => ({ key, exact: BUCKET_WEIGHTS[key] * total })); @@ -2307,6 +2342,8 @@ async function main() { const mongoUri = resolveMongoUri(); const count = Math.max(1, Number(process.env.SEED_REPORTS_COUNT?.trim() || "1000")); const seedTag = process.env.SEED_REPORTS_TAG?.trim() || "reports-load-v1"; + const purgeOnly = process.env.SEED_REPORTS_PURGE_ONLY?.trim() === "true"; + const purgeAll = process.env.SEED_REPORTS_PURGE_ALL?.trim() === "true"; const publicPrefix = process.env.SEED_REPORTS_PUBLIC_PREFIX?.trim() || `RPT${shortHash(seedTag, 3)}`; const defaultPassword = @@ -2325,6 +2362,29 @@ async function main() { const clientLabel = client?.clientName?.persian || client?.clientName?.english || String(client._id); + if (purgeOnly) { + const purge = await purgeSeedPortfolio(db, purgeAll ? undefined : seedTag); + const remainingPortfolio = await Promise.all([ + db.collection("blameCases").countDocuments({ "seedMeta.script": SCRIPT_NAME }), + db.collection("claimCases").countDocuments({ "seedMeta.script": SCRIPT_NAME }), + ]); + const supportData = + remainingPortfolio[0] + remainingPortfolio[1] === 0 + ? await purgeSeedSupportData(db) + : null; + + console.log("\n=== Insurer reports seed purge complete ==="); + console.log(`Client : ${clientLabel} (${clientId.toHexString()})`); + console.log(`Seed scope : ${purgeAll ? "all tags" : seedTag}`); + console.log(`Removed : ${purge.deletedBlames} blame, ${purge.deletedClaims} claim, ${purge.deletedActivities} activities`); + if (supportData) { + console.log("Support data :", supportData); + } else { + console.log("Support data : retained because other report-fixture portfolios remain"); + } + return; + } + const rng = mulberry32(seedToInt(`${seedTag}:${clientId.toHexString()}:${count}`)); const passwordHash = await hashPassword(defaultPassword); const branches = await ensureBranches(db, clientId, String(clientLabel));