Fixed seed data

This commit is contained in:
SepehrYahyaee
2026-09-12 11:58:24 +03:30
parent fc37dd78a4
commit 0bab93e983

View File

@@ -22,6 +22,8 @@
* SEED_REPORTS_TAG=reports-load-v1 * SEED_REPORTS_TAG=reports-load-v1
* SEED_REPORTS_PUBLIC_PREFIX=RPT1 * SEED_REPORTS_PUBLIC_PREFIX=RPT1
* SEED_REPORTS_DEFAULT_PASSWORD=Reports@724 * 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 { existsSync, readFileSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
@@ -652,24 +654,31 @@ function randNationalBase(prefix: string): string {
return n.padEnd(6, "7"); 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 blameCases = db.collection("blameCases");
const claimCases = db.collection("claimCases"); const claimCases = db.collection("claimCases");
const expertFileActivities = db.collection("expertFileActivities"); const expertFileActivities = db.collection("expertFileActivities");
const fixtureFilter = {
"seedMeta.script": SCRIPT_NAME,
...(seedTag ? { "seedMeta.tag": seedTag } : {}),
};
const [existingBlames, existingClaims] = await Promise.all([ const [existingBlames, existingClaims] = await Promise.all([
blameCases.find({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, { projection: { _id: 1 } }).toArray(), blameCases.find(fixtureFilter, { projection: { _id: 1 } }).toArray(),
claimCases.find({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, { projection: { _id: 1 } }).toArray(), claimCases.find(fixtureFilter, { projection: { _id: 1 } }).toArray(),
]); ]);
const fileIds = [...existingBlames, ...existingClaims].map((d) => asObjectId(d._id)); const fileIds = [...existingBlames, ...existingClaims].map((d) => asObjectId(d._id));
const [deletedBlames, deletedClaims, deletedActivities] = await Promise.all([ const [deletedBlames, deletedClaims, deletedActivities] = await Promise.all([
blameCases.deleteMany({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }), blameCases.deleteMany(fixtureFilter),
claimCases.deleteMany({ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }), claimCases.deleteMany(fixtureFilter),
expertFileActivities.deleteMany({ expertFileActivities.deleteMany({
$or: [ $or: [
{ "seedMeta.script": SCRIPT_NAME, "seedMeta.tag": seedTag }, fixtureFilter,
...(fileIds.length ? [{ fileId: { $in: fileIds } }] : []), ...(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<UnifiedBucket, number> { function scaleBucketCounts(total: number): Record<UnifiedBucket, number> {
const keys = Object.keys(BUCKET_WEIGHTS) as UnifiedBucket[]; const keys = Object.keys(BUCKET_WEIGHTS) as UnifiedBucket[];
const raw = keys.map((key) => ({ key, exact: BUCKET_WEIGHTS[key] * total })); const raw = keys.map((key) => ({ key, exact: BUCKET_WEIGHTS[key] * total }));
@@ -2307,6 +2342,8 @@ async function main() {
const mongoUri = resolveMongoUri(); const mongoUri = resolveMongoUri();
const count = Math.max(1, Number(process.env.SEED_REPORTS_COUNT?.trim() || "1000")); 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 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 = const publicPrefix =
process.env.SEED_REPORTS_PUBLIC_PREFIX?.trim() || `RPT${shortHash(seedTag, 3)}`; process.env.SEED_REPORTS_PUBLIC_PREFIX?.trim() || `RPT${shortHash(seedTag, 3)}`;
const defaultPassword = const defaultPassword =
@@ -2325,6 +2362,29 @@ async function main() {
const clientLabel = const clientLabel =
client?.clientName?.persian || client?.clientName?.english || String(client._id); 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 rng = mulberry32(seedToInt(`${seedTag}:${clientId.toHexString()}:${count}`));
const passwordHash = await hashPassword(defaultPassword); const passwordHash = await hashPassword(defaultPassword);
const branches = await ensureBranches(db, clientId, String(clientLabel)); const branches = await ensureBranches(db, clientId, String(clientLabel));