126 lines
3.5 KiB
TypeScript
126 lines
3.5 KiB
TypeScript
import { PrismaClient, type Prisma } from "@prisma/client";
|
|
import { getHolidayDemoCityNamesByCountry, getHolidayDemoProfileForIndex } from "./holiday-demo-profiles.js";
|
|
import { loadWorkspaceEnv } from "./load-workspace-env.js";
|
|
|
|
loadWorkspaceEnv();
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
type CountryRecord = {
|
|
id: string;
|
|
code: string;
|
|
};
|
|
|
|
function asJsonObject(value: Prisma.JsonValue | null | undefined): Record<string, Prisma.JsonValue> {
|
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
return {};
|
|
}
|
|
|
|
return value as Record<string, Prisma.JsonValue>;
|
|
}
|
|
|
|
async function ensureCities(countryByCode: Map<string, CountryRecord>) {
|
|
const cityNamesByCountry = getHolidayDemoCityNamesByCountry();
|
|
const cityMap = new Map<string, { id: string }>();
|
|
|
|
for (const [countryCode, cityNames] of Object.entries(cityNamesByCountry)) {
|
|
const country = countryByCode.get(countryCode);
|
|
if (!country) {
|
|
continue;
|
|
}
|
|
|
|
for (const cityName of cityNames) {
|
|
const city = await prisma.metroCity.upsert({
|
|
where: {
|
|
countryId_name: {
|
|
countryId: country.id,
|
|
name: cityName,
|
|
},
|
|
},
|
|
update: {},
|
|
create: {
|
|
countryId: country.id,
|
|
name: cityName,
|
|
},
|
|
select: { id: true },
|
|
});
|
|
cityMap.set(`${countryCode}:${cityName}`, city);
|
|
}
|
|
}
|
|
|
|
return cityMap;
|
|
}
|
|
|
|
async function main() {
|
|
console.log("Normalizing active resources for holiday demo profiles...");
|
|
|
|
const countrySeeds = [
|
|
{ code: "DE", name: "Germany", dailyWorkingHours: 8 },
|
|
{ code: "ES", name: "Spain", dailyWorkingHours: 8 },
|
|
{ code: "IN", name: "India", dailyWorkingHours: 9 },
|
|
{ code: "US", name: "United States", dailyWorkingHours: 8 },
|
|
] as const;
|
|
const countries = [];
|
|
|
|
for (const countrySeed of countrySeeds) {
|
|
countries.push(await prisma.country.upsert({
|
|
where: { code: countrySeed.code },
|
|
update: { name: countrySeed.name, dailyWorkingHours: countrySeed.dailyWorkingHours },
|
|
create: countrySeed,
|
|
select: { id: true, code: true },
|
|
}));
|
|
}
|
|
|
|
const countryByCode = new Map(countries.map((country) => [country.code, country] as const));
|
|
|
|
const cityByProfile = await ensureCities(countryByCode);
|
|
const resources = await prisma.resource.findMany({
|
|
where: { isActive: true },
|
|
select: {
|
|
id: true,
|
|
eid: true,
|
|
dynamicFields: true,
|
|
},
|
|
orderBy: { eid: "asc" },
|
|
});
|
|
|
|
let updated = 0;
|
|
|
|
for (const [index, resource] of resources.entries()) {
|
|
const profile = getHolidayDemoProfileForIndex(index);
|
|
const country = countryByCode.get(profile.countryCode)!;
|
|
const metroCity = cityByProfile.get(`${profile.countryCode}:${profile.cityName}`);
|
|
|
|
if (!metroCity) {
|
|
throw new Error(`Missing metro city for profile ${profile.countryCode}/${profile.cityName}`);
|
|
}
|
|
|
|
const dynamicFields = asJsonObject(resource.dynamicFields);
|
|
|
|
await prisma.resource.update({
|
|
where: { id: resource.id },
|
|
data: {
|
|
countryId: country.id,
|
|
metroCityId: metroCity.id,
|
|
federalState: profile.stateCode,
|
|
dynamicFields: {
|
|
...dynamicFields,
|
|
city: profile.cityName,
|
|
holidayCountryCode: profile.countryCode,
|
|
holidayStateCode: profile.stateCode,
|
|
} as Prisma.InputJsonValue,
|
|
},
|
|
});
|
|
updated += 1;
|
|
}
|
|
|
|
console.log(`Updated ${updated} active resources.`);
|
|
}
|
|
|
|
main()
|
|
.catch((error) => {
|
|
console.error(error);
|
|
process.exit(1);
|
|
})
|
|
.finally(() => void prisma.$disconnect());
|