server: database schema, migrations and seed
Define Prisma schema (Player, City, Good, InventoryItem, Transaction, Mission, WorldEvent), initial migration SQL, and seed script to populate cities and goods with base game data. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
import { computePrices } from '../src/modules/market/pricing.js';
|
||||
import { randomFloat } from '../src/shared/validators.js';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
/** Città iniziali (blueprint §19): economia e rischio differenziati. */
|
||||
const CITIES = [
|
||||
{ name: 'Milano', riskLevel: 3, policePressure: 1.1, economyModifier: 1.25 },
|
||||
{ name: 'Napoli', riskLevel: 4, policePressure: 1.3, economyModifier: 1.0 },
|
||||
{ name: 'Palermo', riskLevel: 4, policePressure: 1.25, economyModifier: 0.85 },
|
||||
{ name: 'Torino', riskLevel: 2, policePressure: 0.9, economyModifier: 1.0 },
|
||||
{ name: 'Bari', riskLevel: 3, policePressure: 1.0, economyModifier: 0.85 },
|
||||
];
|
||||
|
||||
/** Item commerciabili iniziali (blueprint §19). */
|
||||
const ITEMS = [
|
||||
{ name: 'Gioielli', basePrice: 500, rarity: 2, illegalLevel: 2, weight: 1 },
|
||||
{ name: 'Componenti elettronici', basePrice: 350, rarity: 1, illegalLevel: 1, weight: 2 },
|
||||
{ name: 'Documenti falsi', basePrice: 700, rarity: 3, illegalLevel: 4, weight: 1 },
|
||||
{ name: 'Auto rubate', basePrice: 1800, rarity: 4, illegalLevel: 5, weight: 10 },
|
||||
{ name: 'Informazioni riservate', basePrice: 1200, rarity: 4, illegalLevel: 3, weight: 1 },
|
||||
{ name: 'Armi leggere', basePrice: 1500, rarity: 3, illegalLevel: 5, weight: 4 },
|
||||
];
|
||||
|
||||
async function main(): Promise<void> {
|
||||
for (const city of CITIES) {
|
||||
await prisma.city.upsert({
|
||||
where: { name: city.name },
|
||||
create: city,
|
||||
update: {
|
||||
riskLevel: city.riskLevel,
|
||||
policePressure: city.policePressure,
|
||||
economyModifier: city.economyModifier,
|
||||
},
|
||||
});
|
||||
}
|
||||
console.log(`Città: ${CITIES.length}`);
|
||||
|
||||
for (const item of ITEMS) {
|
||||
await prisma.item.upsert({
|
||||
where: { name: item.name },
|
||||
create: item,
|
||||
update: {
|
||||
basePrice: item.basePrice,
|
||||
rarity: item.rarity,
|
||||
illegalLevel: item.illegalLevel,
|
||||
weight: item.weight,
|
||||
},
|
||||
});
|
||||
}
|
||||
console.log(`Item: ${ITEMS.length}`);
|
||||
|
||||
// Listino iniziale per ogni coppia città/item, con domanda e offerta
|
||||
// leggermente casuali. I prezzi già esistenti non vengono toccati.
|
||||
const cities = await prisma.city.findMany();
|
||||
const items = await prisma.item.findMany();
|
||||
let createdPrices = 0;
|
||||
for (const city of cities) {
|
||||
for (const item of items) {
|
||||
const demand = Math.round(randomFloat(0.8, 1.2) * 100) / 100;
|
||||
const supply = Math.round(randomFloat(0.8, 1.2) * 100) / 100;
|
||||
const prices = computePrices(item.basePrice, city.economyModifier, demand, supply, 1);
|
||||
const result = await prisma.marketPrice.upsert({
|
||||
where: { cityId_itemId: { cityId: city.id, itemId: item.id } },
|
||||
create: { cityId: city.id, itemId: item.id, demand, supply, ...prices },
|
||||
update: {},
|
||||
});
|
||||
if (result) createdPrices += 1;
|
||||
}
|
||||
}
|
||||
console.log(`Prezzi di mercato: ${createdPrices}`);
|
||||
console.log('Seed completato.');
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(() => prisma.$disconnect());
|
||||
Reference in New Issue
Block a user